Chromium Code Reviews| Index: components/arc/arc_bridge_service.h |
| diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9c1bb4ef6a568d99dd708a1e3924d55ac15a8ef9 |
| --- /dev/null |
| +++ b/components/arc/arc_bridge_service.h |
| @@ -0,0 +1,180 @@ |
| +// 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 "base/macros.h" |
| +#include "base/observer_list_threadsafe.h" |
| +#include "base/sequenced_task_runner.h" |
| +#include "chromeos/dbus/dbus_method_call_status.h" |
| +#include "components/keyed_service/core/keyed_service.h" |
| +#include "ipc/ipc_channel_proxy.h" |
| +#include "ipc/ipc_listener.h" |
| +#include "ipc/ipc_message.h" |
| + |
| +class PrefRegistrySimple; |
| +class PrefService; |
| + |
| +namespace arc { |
| + |
| +class ArcBridgeTest; |
| + |
| +// 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 KeyedService, |
| + public IPC::Listener { |
| + public: |
| + // The possible states of the bridge. In the normal flow, the state changes |
| + // in the following sequence: |
| + // |
| + // STOPPED -> CONNECTING -> CONNECTED -> STARTING -> READY |
| + // |
| + // When Shutdown() is called, if it is not already stopped or in the ERROR |
|
Shuhei Takahashi
2015/10/29 00:13:08
ERROR state has been removed.
Luis Héctor Chávez
2015/10/29 23:43:53
Done.
|
| + // state, the state changes in the following way: |
| + // |
| + // (ANY) -> STOPPING -> STOPPED |
| + enum State { |
| + // ARC is not currently running. |
| + STOPPED, |
| + |
| + // The request to connect has been sent. |
| + CONNECTING, |
| + |
| + // The bridge has connected to the socket, but has not started the ARC |
| + // instance. |
| + CONNECTED, |
| + |
| + // The ARC bridge has been set up and ARC is starting up. |
| + STARTING, |
| + |
| + // The ARC instance has been fully initialized and is now ready for user |
| + // interaction. |
| + READY, |
| + |
| + // The ARC instance has started shutting down. |
| + STOPPING, |
| + }; |
| + |
| + class Observer { |
| + public: |
| + // Called whenever the state of the bridge has changed. |
| + virtual void OnStateChanged(State state) {} |
| + |
| + // Called whenever ARC's enabled status has changed for this session. |
| + virtual void OnEnabledChanged(bool enabled) {} |
| + |
| + protected: |
| + virtual ~Observer() {} |
| + }; |
| + |
| + explicit ArcBridgeService( |
| + const scoped_refptr<base::SequencedTaskRunner>& file_task_runner); |
| + virtual ~ArcBridgeService(); |
| + |
| + // Registers ARC preferences. |
| + static void RegisterPrefs(PrefRegistrySimple* registry); |
| + |
| + // Reads from the preference store if ARC has been enabled. |
| + static bool GetEnabledPref(PrefService* pref_service); |
| + |
| + // HandleStartup() should be called upon profile startup. This will only |
| + // launch an instance if the instance service is available and it is enabled. |
| + void HandleStartup(); |
| + |
| + // Shuts down the running instance, if any. This is safe to call even if |
| + // there is no instance running. |
| + void Shutdown(); |
| + |
| + // Adds or removes observers. |
| + void AddObserver(Observer* observer); |
| + void RemoveObserver(Observer* observer); |
| + |
| + // Gets the current state of the bridge service. |
| + State GetState() const { return state_; } |
| + |
| + // Enables or disables the bridge for this session. |
| + void SetEnabled(bool enabled); |
| + |
| + // Gets if the bridge is enabled for this session. |
| + bool IsEnabled() const { return enabled_; } |
| + |
| + // 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. |
| + bool RegisterInputDevice(const std::string& name, |
| + const std::string& device_type, |
| + base::ScopedFD fd); |
| + |
| + private: |
| + friend class arc::ArcBridgeTest; |
| + |
| + // Binds to the socket specified by |socket_path|. |
| + void SocketConnect(const base::FilePath& socket_path); |
| + |
| + // Binds to the socket specified by |socket_path| after creating its parent |
| + // directory is present. |
| + void SocketConnectAfterEnsureParentDirectory( |
| + const base::FilePath& socket_path, bool directory_present); |
|
hidehiko
2015/10/29 16:29:47
nit: 4 indent.
http://google-styleguide.googlecode
Luis Héctor Chávez
2015/10/29 23:43:53
Done.
|
| + |
| + // Internal connection method. Separated to make testing easier. |
| + bool Connect(const IPC::ChannelHandle& handle, IPC::Channel::Mode mode); |
| + |
| + // Finishes connecting after setting socket permissions. |
| + void FinishConnectAfterSetSocketPermissions(const base::FilePath& socket_path, |
|
hidehiko
2015/10/29 16:29:47
Maybe: SocketConnectAfterSetSocketPermissions, as
Luis Héctor Chávez
2015/10/29 23:43:53
Done.
|
| + bool socket_permissions_success); |
| + |
| + // Called when the ARC instance has finished setting up and is ready for user |
| + // interaction. |
| + void OnInstanceReady(); |
| + |
| + // Changes the current state and notify all observers. |
| + void SetState(State state); |
| + |
| + // Finishes shutdown after deleting the socket file. |
| + void FinishShutdownAfterSocketDeleted(bool socket_deleted); |
|
hidehiko
2015/10/29 16:29:47
ditto: ShutdownAfterSocketDeleted.
Luis Héctor Chávez
2015/10/29 23:43:53
Done.
|
| + |
| + // IPC::Listener: |
| + bool OnMessageReceived(const IPC::Message& message) override; |
| + |
| + // DBus callbacks. |
| + void OnInstanceStarted(chromeos::DBusMethodCallStatus status); |
| + void OnInstanceStopped(chromeos::DBusMethodCallStatus status); |
| + |
| + // Thread in which IPC messaging is performed. |
| + base::Thread ipc_thread_; |
| + |
| + // Task runner on which incoming messages are handled. |
| + scoped_refptr<base::SequencedTaskRunner> origin_task_runner_; |
| + |
| + // Task runner on which file operations are performed. |
| + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; |
| + |
| + // The channel through which messages are sent. |
| + scoped_ptr<IPC::ChannelProxy> ipc_channel_; |
| + |
| + // List of observers to notify of state changes. |
| + scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; |
| + |
| + // If the ARC instance service is available. |
| + bool available_; |
| + |
| + // If ARC has been enabled by policy and user choice. |
| + bool enabled_; |
| + |
| + // The current state of the bridge. |
| + ArcBridgeService::State state_; |
| + |
| + // WeakPtrFactory to use callbacks. |
| + base::WeakPtrFactory<ArcBridgeService> weak_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ArcBridgeService); |
| +}; |
| + |
| +} // namespace arc |
| + |
| +#endif // COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_ |