| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_ |
| #define COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/files/scoped_file.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/values.h" |
| #include "components/arc/common/arc_bridge.mojom.h" |
| |
| namespace base { |
| class CommandLine; |
| } // namespace base |
| |
| namespace arc { |
| |
| class ArcBridgeBootstrap; |
| |
| // The Chrome-side service that handles ARC instances and ARC bridge creation. |
| // This service handles the lifetime of ARC instances and sets up the |
| // communication channel (the ARC bridge) used to send and receive messages. |
| class ArcBridgeService { |
| public: |
| // The possible states of the bridge. In the normal flow, the state changes |
| // in the following sequence: |
| // |
| // STOPPED |
| // PrerequisitesChanged() -> |
| // CONNECTING |
| // OnConnectionEstablished() -> |
| // CONNECTED |
| // OnInstanceBootPhase(INSTANCE_BOOT_PHASE_BRIDGE_READY) -> |
| // READY |
| // |
| // The ArcBridgeBootstrap state machine can be thought of being substates of |
| // ArcBridgeService's CONNECTING state. |
| // |
| // * |
| // StopInstance() -> |
| // STOPPING |
| // OnStopped() -> |
| // STOPPED |
| enum class State { |
| // ARC is not currently running. |
| STOPPED, |
| |
| // The request to connect has been sent. |
| CONNECTING, |
| |
| // The instance has started, and the bridge is fully established. |
| CONNECTED, |
| |
| // The ARC instance has finished initializing and is now ready for user |
| // interaction. |
| READY, |
| |
| // The ARC instance has started shutting down. |
| STOPPING, |
| }; |
| |
| // Notifies life cycle events of ArcBridgeService. |
| class Observer { |
| public: |
| // Called whenever the state of the bridge has changed. |
| virtual void OnStateChanged(State state) {} |
| |
| // Called when the instance has reached a boot phase |
| virtual void OnInstanceBootPhase(InstanceBootPhase phase) {} |
| |
| // Called whenever ARC's availability has changed for this system. |
| virtual void OnAvailableChanged(bool available) {} |
| |
| protected: |
| virtual ~Observer() {} |
| }; |
| |
| class NotificationObserver { |
| public: |
| // Called whenever a notification has been posted on Android side. This |
| // event is used for both creation and update. |
| virtual void OnNotificationPostedFromAndroid( |
| const ArcNotificationData& data) {} |
| // Called whenever a notification has been removed on Android side. |
| virtual void OnNotificationRemovedFromAndroid(const std::string& key) {} |
| |
| protected: |
| virtual ~NotificationObserver() {} |
| }; |
| |
| // Notifies ARC apps related events. |
| class AppObserver { |
| public: |
| // Called whenever ARC sends information about available apps. |
| virtual void OnAppListRefreshed(const std::vector<AppInfo>& apps) {} |
| |
| // Called whenever ARC sends app icon data for specific scale factor. |
| virtual void OnAppIcon(const std::string& package, |
| const std::string& activity, |
| ScaleFactor scale_factor, |
| const std::vector<uint8_t>& icon_png_data) {} |
| |
| protected: |
| virtual ~AppObserver() {} |
| }; |
| |
| // Notifies ARC process related events. |
| class ProcessObserver { |
| public: |
| // Called when the latest process list has been received after |
| // ArcBridgeService::RequestProcessList() was called. |
| // |
| // NB: Due to the nature of Linux PID, we can not avoid the race condition |
| // that the process info is already outdated when the message is received. |
| // Do not use the process list obtained here for security-sensitive purpose. |
| // Good news is that Android processes are designed to be ready to be killed |
| // at any time, so killing a wrong process is not a disaster. |
| virtual void OnUpdateProcessList( |
| const std::vector<RunningAppProcessInfo>& processes) {} |
| |
| protected: |
| virtual ~ProcessObserver() {} |
| }; |
| |
| virtual ~ArcBridgeService(); |
| |
| // Gets the global instance of the ARC Bridge Service. This can only be |
| // called on the thread that this class was created on. |
| static ArcBridgeService* Get(); |
| |
| // Return true if ARC has been enabled through a commandline |
| // switch. |
| static bool GetEnabled(const base::CommandLine* command_line); |
| |
| // DetectAvailability() should be called once D-Bus is available. It will |
| // call CheckArcAvailability() on the session_manager. This can only be |
| // called on the thread that this class was created on. |
| virtual void DetectAvailability() = 0; |
| |
| // HandleStartup() should be called upon profile startup. This will only |
| // launch an instance if the instance service is available and it is enabled. |
| // This can only be called on the thread that this class was created on. |
| virtual void HandleStartup() = 0; |
| |
| // Shutdown() should be called when the browser is shutting down. This can |
| // only be called on the thread that this class was created on. |
| virtual void Shutdown() = 0; |
| |
| // Adds or removes observers. This can only be called on the thread that this |
| // class was created on. |
| void AddObserver(Observer* observer); |
| void RemoveObserver(Observer* observer); |
| void AddNotificationObserver(NotificationObserver* observer); |
| void RemoveNotificationObserver(NotificationObserver* observer); |
| |
| // Adds or removes ARC app observers. This can only be called on the thread |
| // that this class was created on. |
| void AddAppObserver(AppObserver* observer); |
| void RemoveAppObserver(AppObserver* observer); |
| |
| // Adds or removes ARC process observers. This can only be called on the |
| // thread that this class was created on. |
| void AddProcessObserver(ProcessObserver* observer); |
| void RemoveProcessObserver(ProcessObserver* observer); |
| |
| // Gets the current state of the bridge service. |
| State state() const { return state_; } |
| |
| // Gets if ARC is available in this system. |
| bool available() const { return available_; } |
| |
| // Requests registration of an input device on the ARC instance. |
| // TODO(denniskempin): Make this interface more typesafe. |
| // |name| should be the displayable name of the emulated device (e.g. "Chrome |
| // OS Keyboard"), |device_type| the name of the device type (e.g. "keyboard") |
| // and |fd| a file descriptor that emulates the kernel events of the device. |
| // This can only be called on the thread that this class was created on. |
| virtual bool RegisterInputDevice(const std::string& name, |
| const std::string& device_type, |
| base::ScopedFD fd) = 0; |
| |
| // Sends a notification event to Android side. |
| virtual bool SendNotificationEventToAndroid(const std::string& key, |
| ArcNotificationEvent event) = 0; |
| |
| // Requests to refresh an app list. |
| virtual bool RefreshAppList() = 0; |
| |
| // Requests to launch an app. |
| virtual bool LaunchApp(const std::string& package, |
| const std::string& activity) = 0; |
| |
| // Requests to load an icon of specific scale_factor. |
| virtual bool RequestAppIcon(const std::string& package, |
| const std::string& activity, |
| ScaleFactor scale_factor) = 0; |
| |
| // Requests a list of processes from the ARC instance. |
| // When the result comes back, Observer::OnUpdateProcessList() is called. |
| virtual bool RequestProcessList() = 0; |
| |
| // Send an Android broadcast message to the Android package and class |
| // specified. The 'extras' DictionaryValue will be converted to an Android |
| // Bundle accessible by the broadcast receiver. |
| // |
| // Note: Broadcasts can only be sent to whitelisted packages. Packages can be |
| // added to the whitelist in ArcBridgeService.java in the Android source. |
| virtual bool SendBroadcast(const std::string& action, |
| const std::string& package, |
| const std::string& clazz, |
| const base::DictionaryValue& extras) = 0; |
| |
| protected: |
| ArcBridgeService(); |
| |
| // Changes the current state and notifies all observers. |
| void SetState(State state); |
| |
| // Changes the current availability and notifies all observers. |
| void SetAvailable(bool availability); |
| |
| base::ObserverList<Observer>& observer_list() { return observer_list_; } |
| |
| base::ObserverList<NotificationObserver>& notification_observer_list() { |
| return notification_observer_list_; |
| } |
| |
| base::ObserverList<AppObserver>& app_observer_list() { |
| return app_observer_list_; |
| } |
| |
| base::ObserverList<ProcessObserver>& process_observer_list() { |
| return process_observer_list_; |
| } |
| |
| bool CalledOnValidThread(); |
| |
| private: |
| friend class ArcBridgeTest; |
| FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, Basic); |
| FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, Prerequisites); |
| FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, ShutdownMidStartup); |
| |
| base::ObserverList<Observer> observer_list_; |
| base::ObserverList<NotificationObserver> notification_observer_list_; |
| base::ObserverList<AppObserver> app_observer_list_; |
| base::ObserverList<ProcessObserver> process_observer_list_; |
| |
| base::ThreadChecker thread_checker_; |
| |
| // If the ARC instance service is available. |
| bool available_; |
| |
| // The current state of the bridge. |
| ArcBridgeService::State state_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ArcBridgeService); |
| }; |
| |
| } // namespace arc |
| |
| #endif // COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_ |