1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_SYSTEM_MEDIA_CONTROLS_LINUX_SYSTEM_MEDIA_CONTROLS_LINUX_H_
6 #define COMPONENTS_SYSTEM_MEDIA_CONTROLS_LINUX_SYSTEM_MEDIA_CONTROLS_LINUX_H_
7 
8 #include <string>
9 
10 #include "base/component_export.h"
11 #include "base/containers/flat_map.h"
12 #include "base/containers/flat_set.h"
13 #include "base/memory/scoped_refptr.h"
14 #include "base/observer_list.h"
15 #include "base/timer/timer.h"
16 #include "components/dbus/properties/types.h"
17 #include "components/system_media_controls/system_media_controls.h"
18 #include "dbus/bus.h"
19 #include "dbus/exported_object.h"
20 
21 class DbusProperties;
22 
23 namespace dbus {
24 class MethodCall;
25 }  // namespace dbus
26 
27 namespace system_media_controls {
28 
29 class SystemMediaControlsObserver;
30 
31 namespace internal {
32 
33 COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS)
34 extern const char kMprisAPIServiceNamePrefix[];
35 COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS) extern const char kMprisAPIObjectPath[];
36 COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS)
37 extern const char kMprisAPIInterfaceName[];
38 COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS)
39 extern const char kMprisAPIPlayerInterfaceName[];
40 
41 // A D-Bus service conforming to the MPRIS spec:
42 // https://specifications.freedesktop.org/mpris-spec/latest/
COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS)43 class COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS) SystemMediaControlsLinux
44     : public SystemMediaControls {
45  public:
46   SystemMediaControlsLinux();
47   ~SystemMediaControlsLinux() override;
48 
49   static SystemMediaControlsLinux* GetInstance();
50 
51   // Starts the DBus service.
52   void StartService();
53 
54   // SystemMediaControls implementation.
55   void AddObserver(SystemMediaControlsObserver* observer) override;
56   void RemoveObserver(SystemMediaControlsObserver* observer) override;
57   void SetEnabled(bool enabled) override {}
58   void SetIsNextEnabled(bool value) override;
59   void SetIsPreviousEnabled(bool value) override;
60   void SetIsPlayPauseEnabled(bool value) override;
61   void SetIsStopEnabled(bool value) override {}
62   void SetPlaybackStatus(PlaybackStatus value) override;
63   void SetTitle(const base::string16& value) override;
64   void SetArtist(const base::string16& value) override;
65   void SetAlbum(const base::string16& value) override;
66   void SetThumbnail(const SkBitmap& bitmap) override {}
67   void ClearThumbnail() override {}
68   void ClearMetadata() override;
69   void UpdateDisplay() override {}
70 
71   // Returns the generated service name.
72   std::string GetServiceName() const;
73 
74   // Used for testing with a mock DBus Bus.
75   void SetBusForTesting(scoped_refptr<dbus::Bus> bus) { bus_ = bus; }
76 
77  private:
78   void InitializeProperties();
79   void InitializeDbusInterface();
80   void OnExported(const std::string& interface_name,
81                   const std::string& method_name,
82                   bool success);
83   void OnInitialized(bool success);
84   void OnOwnership(const std::string& service_name, bool success);
85 
86   // org.mpris.MediaPlayer2.Player interface.
87   void Next(dbus::MethodCall* method_call,
88             dbus::ExportedObject::ResponseSender response_sender);
89   void Previous(dbus::MethodCall* method_call,
90                 dbus::ExportedObject::ResponseSender response_sender);
91   void Pause(dbus::MethodCall* method_call,
92              dbus::ExportedObject::ResponseSender response_sender);
93   void PlayPause(dbus::MethodCall* method_call,
94                  dbus::ExportedObject::ResponseSender response_sender);
95   void Stop(dbus::MethodCall* method_call,
96             dbus::ExportedObject::ResponseSender response_sender);
97   void Play(dbus::MethodCall* method_call,
98             dbus::ExportedObject::ResponseSender response_sender);
99 
100   // Used for API methods we don't support.
101   void DoNothing(dbus::MethodCall* method_call,
102                  dbus::ExportedObject::ResponseSender response_sender);
103 
104   // Sets a value on the Metadata property map and sends a PropertiesChanged
105   // signal if necessary.
106   void SetMetadataPropertyInternal(const std::string& property_name,
107                                    DbusVariant&& new_value);
108 
109   std::unique_ptr<DbusProperties> properties_;
110 
111   scoped_refptr<dbus::Bus> bus_;
112   dbus::ExportedObject* exported_object_;
113 
114   // The generated service name given to |bus_| when requesting ownership.
115   const std::string service_name_;
116 
117   base::RepeatingCallback<void(bool)> barrier_;
118 
119   // True if we have started creating the DBus service.
120   bool started_ = false;
121 
122   // True if we have finished creating the DBus service and received ownership.
123   bool service_ready_ = false;
124 
125   base::ObserverList<SystemMediaControlsObserver> observers_;
126 
127   DISALLOW_COPY_AND_ASSIGN(SystemMediaControlsLinux);
128 };
129 
130 }  // namespace internal
131 
132 }  // namespace system_media_controls
133 
134 #endif  // COMPONENTS_SYSTEM_MEDIA_CONTROLS_LINUX_SYSTEM_MEDIA_CONTROLS_LINUX_H_
135