 Chromium Code Reviews
 Chromium Code Reviews Issue 1412863004:
  arc-bridge: Add the ARC Bridge Service  (Closed) 
  Base URL: https://chromium.googlesource.com/a/chromium/src.git@master
    
  
    Issue 1412863004:
  arc-bridge: Add the ARC Bridge Service  (Closed) 
  Base URL: https://chromium.googlesource.com/a/chromium/src.git@master| 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..772538e8b8bafa23a2f28a0e87991e4d3aa87ab5 | 
| --- /dev/null | 
| +++ b/components/arc/arc_bridge_service.h | 
| @@ -0,0 +1,185 @@ | 
| +// 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 "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 IPC::Listener { | 
| + public: | 
| + // The possible states of the bridge. In the normal flow, the state changes | 
| + // in the following sequence: | 
| + // | 
| + // STOPPED | 
| + // SetEnabled(true) + HandleStartup() -> SocketConnect() -> | 
| + // CONNECTING | 
| + // Connect() -> | 
| + // CONNECTED | 
| + // SocketConnectAfterSetsocketPermissions() -> | 
| + // STARTING | 
| + // StartInstance() -> OnInstanceReady() -> | 
| + // READY | 
| + // | 
| + // When Shutdown() is called, the state changes depending on the state it was | 
| + // at: | 
| + // | 
| + // CONNECTED/CONNECTING -> STOPPED | 
| + // STARTING/READY -> STOPPING -> StopInstance() -> STOPPED | 
| + enum State { | 
| 
dcheng
2015/11/06 01:35:28
Consider using an enum class.
 
lhc(google)
2015/11/06 04:14:16
Done.
 | 
| + // 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(); | 
| + | 
| + // 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_; } | 
| 
dcheng
2015/11/06 01:35:28
Nit: google style is to name this state(), since i
 
lhc(google)
2015/11/06 04:14:17
Done.
 | 
| + | 
| + // 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_; } | 
| 
dcheng
2015/11/06 01:35:28
Ditto: should just be:
bool enabled() const { retu
 
lhc(google)
2015/11/06 04:14:16
Done.
 | 
| + | 
| + // 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); | 
| + | 
| + // 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 SocketConnectAfterSetSocketPermissions(const base::FilePath& socket_path, | 
| + 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); | 
| + | 
| + // IPC::Listener: | 
| + bool OnMessageReceived(const IPC::Message& message) override; | 
| + | 
| + // DBus callbacks. | 
| + void OnInstanceStarted(bool success); | 
| + void OnInstanceStopped(bool success); | 
| + | 
| + // 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_; | 
| + | 
| + // A Lock that guards the |ipc_channel_|. Most of the methods are expected | 
| + // to be run in the same thread (the one in which the ArcBridgeService | 
| + // instance was created), but all the ones that send IPC messages can be | 
| + // called from any method. This will prevent the |ipc_channel_| from being | 
| + // destroyed while a message is being sent. | 
| + base::Lock ipc_channel_lock_; | 
| + | 
| + // 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_ |