Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: components/arc/arc_bridge_service.cc

Issue 1408263006: chromeos: Add ArcInputBridge to components/arc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@arcxx
Patch Set: Arc: Extend ArcBridgeService with input bridge Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/arc_bridge_service.h" 5 #include "components/arc/arc_bridge_service.h"
6 6
7 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/prefs/pref_registry_simple.h" 9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
(...skipping 19 matching lines...) Expand all
30 ArcBridgeService::ArcBridgeService( 30 ArcBridgeService::ArcBridgeService(
31 const scoped_refptr<base::SequencedTaskRunner>& file_task_runner) 31 const scoped_refptr<base::SequencedTaskRunner>& file_task_runner)
32 : ipc_thread_("ARC bridge listener"), 32 : ipc_thread_("ARC bridge listener"),
33 origin_task_runner_(base::ThreadTaskRunnerHandle::Get()), 33 origin_task_runner_(base::ThreadTaskRunnerHandle::Get()),
34 file_task_runner_(file_task_runner), 34 file_task_runner_(file_task_runner),
35 observer_list_(new base::ObserverListThreadSafe<Observer>()), 35 observer_list_(new base::ObserverListThreadSafe<Observer>()),
36 available_(false), 36 available_(false),
37 enabled_(false), 37 enabled_(false),
38 state_(ArcBridgeService::STOPPED), 38 state_(ArcBridgeService::STOPPED),
39 weak_factory_(this) { 39 weak_factory_(this) {
40 LOG(ERROR) << "[ARC] ArcBridgeService";
elijahtaylor1 2015/11/02 22:30:29 is it appropriate to log to the error channel thes
denniskempin 2015/11/16 18:39:28 This was just for debugging. I removed them again.
40 ipc_thread_.StartWithOptions( 41 ipc_thread_.StartWithOptions(
41 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 42 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
42 } 43 }
43 44
44 ArcBridgeService::~ArcBridgeService() {} 45 ArcBridgeService::~ArcBridgeService() {}
45 46
46 // static 47 // static
47 void ArcBridgeService::RegisterPrefs(PrefRegistrySimple* registry) { 48 void ArcBridgeService::RegisterPrefs(PrefRegistrySimple* registry) {
48 registry->RegisterBooleanPref(prefs::kArcEnabled, false); 49 registry->RegisterBooleanPref(prefs::kArcEnabled, false);
49 } 50 }
50 51
51 // static 52 // static
52 bool ArcBridgeService::GetEnabledPref(PrefService* pref_service) { 53 bool ArcBridgeService::GetEnabledPref(PrefService* pref_service) {
53 // TODO(lhchavez): Once this is user-configurable, use the real pref. 54 // TODO(lhchavez): Once this is user-configurable, use the real pref.
54 return true; 55 return true;
55 } 56 }
56 57
57 void ArcBridgeService::HandleStartup() { 58 void ArcBridgeService::HandleStartup() {
59 LOG(ERROR) << "[ARC] HandleStartup";
58 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 60 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
59 if (!enabled_) 61 if (!enabled_)
60 return; 62 return;
61 SocketConnect(base::FilePath(kArcBridgeSocketPath)); 63 SocketConnect(base::FilePath(kArcBridgeSocketPath));
62 } 64 }
63 65
64 void ArcBridgeService::Shutdown() { 66 void ArcBridgeService::Shutdown() {
67 LOG(ERROR) << "[ARC] Shutdown";
65 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 68 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
66 if (state_ == ArcBridgeService::STOPPED || 69 if (state_ == ArcBridgeService::STOPPED ||
67 state_ == ArcBridgeService::STOPPING) { 70 state_ == ArcBridgeService::STOPPING) {
68 LOG(ERROR) << "Shutdown() called when ARC is not running"; 71 LOG(ERROR) << "Shutdown() called when ARC is not running";
69 return; 72 return;
70 } 73 }
71 SetState(ArcBridgeService::STOPPING); 74 SetState(ArcBridgeService::STOPPING);
75
76 // Destroying the BridgeDevices will close their file descriptors, which will
77 // cause the corresponding devices on the instance-side to be destroyed as
elijahtaylor1 2015/11/02 22:30:29 how is this guaranteed? do failed reads cause the
denniskempin 2015/11/16 18:39:28 Yes, the EventHub will close devices in two condit
78 // well.
79 bridge_devices_.clear();
80
72 ipc_channel_->Close(); 81 ipc_channel_->Close();
73 ipc_channel_.reset(); 82 ipc_channel_.reset();
74 base::PostTaskAndReplyWithResult( 83 base::PostTaskAndReplyWithResult(
75 file_task_runner_.get(), 84 file_task_runner_.get(),
76 FROM_HERE, 85 FROM_HERE,
77 base::Bind(&base::DeleteFile, base::FilePath(kArcBridgeSocketPath), 86 base::Bind(&base::DeleteFile, base::FilePath(kArcBridgeSocketPath),
78 false), 87 false),
79 base::Bind(&ArcBridgeService::FinishShutdownAfterSocketDeleted, 88 base::Bind(&ArcBridgeService::FinishShutdownAfterSocketDeleted,
80 weak_factory_.GetWeakPtr())); 89 weak_factory_.GetWeakPtr()));
81 } 90 }
(...skipping 13 matching lines...) Expand all
95 return; 104 return;
96 enabled_ = enabled; 105 enabled_ = enabled;
97 if (!enabled_ && state_ != ArcBridgeService::STOPPED && 106 if (!enabled_ && state_ != ArcBridgeService::STOPPED &&
98 state_ != ArcBridgeService::STOPPING) 107 state_ != ArcBridgeService::STOPPING)
99 Shutdown(); 108 Shutdown();
100 observer_list_->Notify(FROM_HERE, 109 observer_list_->Notify(FROM_HERE,
101 &Observer::OnEnabledChanged, 110 &Observer::OnEnabledChanged,
102 enabled_); 111 enabled_);
103 } 112 }
104 113
105 bool ArcBridgeService::RegisterInputDevice( 114 base::ScopedFD ArcBridgeService::CreateBridgeInputDevice(
106 const std::string& name, const std::string& device_type, 115 const std::string& name, const std::string& device_type) {
107 base::ScopedFD fd) { 116 LOG(ERROR) << "[ARC] CreateBridgeInputDevice";
108 // ipc_channel_->Send() is thread-safe, so there is no thread check. 117
109 if (state_ != ArcBridgeService::READY) { 118 // Create file descriptor pair for communication
110 LOG(ERROR) << "Called RegisterInputDevice when the service is not ready"; 119 int fd[2];
111 return false; 120 if (pipe(fd) < 0) {
121 LOG(ERROR) << "Cannot create pipe: " << strerror(errno);
elijahtaylor1 2015/11/02 22:30:29 https://code.google.com/p/chromium/codesearch#chro
denniskempin 2015/11/16 18:39:28 Done. PLOG does automatically append the error des
112 } 122 }
113 return ipc_channel_->Send(new ArcInstanceMsg_RegisterInputDevice( 123
114 name, device_type, base::FileDescriptor(fd.Pass()))); 124 // The read end is sent to the instance
125 ipc_channel_->Send(new ArcInstanceMsg_RegisterInputDevice(
126 name, device_type, base::FileDescriptor(fd[0], true)));
127
128 // return the write end
129 return base::ScopedFD(fd[1]);
130 }
131
132 void ArcBridgeService::SetupBridgeInputDevices() {
133 bridge_devices_.push_back(new TouchscreenBridgeInputDevice(
134 CreateBridgeInputDevice("ChromeOS Touchscreen", "touchscreen")));
115 } 135 }
116 136
117 void ArcBridgeService::SocketConnect(const base::FilePath& socket_path) { 137 void ArcBridgeService::SocketConnect(const base::FilePath& socket_path) {
118 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 138 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
139 LOG(ERROR) << "[ARC] SocketConnect";
140
119 if (state_ != ArcBridgeService::STOPPED) { 141 if (state_ != ArcBridgeService::STOPPED) {
120 LOG(ERROR) << "SocketConnect() called when instance is not stopped"; 142 LOG(ERROR) << "SocketConnect() called when instance is not stopped";
121 return; 143 return;
122 } 144 }
123 SetState(ArcBridgeService::CONNECTING); 145 SetState(ArcBridgeService::CONNECTING);
124 base::PostTaskAndReplyWithResult( 146 base::PostTaskAndReplyWithResult(
125 file_task_runner_.get(), 147 file_task_runner_.get(),
126 FROM_HERE, 148 FROM_HERE,
127 base::Bind(&base::CreateDirectory, socket_path.DirName()), 149 base::Bind(&base::CreateDirectory, socket_path.DirName()),
128 base::Bind(&ArcBridgeService::SocketConnectAfterEnsureParentDirectory, 150 base::Bind(&ArcBridgeService::SocketConnectAfterEnsureParentDirectory,
129 weak_factory_.GetWeakPtr(), 151 weak_factory_.GetWeakPtr(),
130 socket_path)); 152 socket_path));
131 } 153 }
132 154
155
133 void ArcBridgeService::SocketConnectAfterEnsureParentDirectory( 156 void ArcBridgeService::SocketConnectAfterEnsureParentDirectory(
134 const base::FilePath& socket_path, bool directory_present) { 157 const base::FilePath& socket_path, bool directory_present) {
135 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 158 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
136 if (state_ != ArcBridgeService::CONNECTING) { 159 if (state_ != ArcBridgeService::CONNECTING) {
137 LOG(ERROR) << "Shutdown requested while connecting"; 160 LOG(ERROR) << "Shutdown requested while connecting";
138 return; 161 return;
139 } 162 }
140 if (!directory_present) { 163 if (!directory_present) {
141 LOG(ERROR) << "Error creating directory for " << socket_path.value(); 164 LOG(ERROR) << "Error creating directory for " << socket_path.value();
142 Shutdown(); 165 Shutdown();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 bool ArcBridgeService::Connect(const IPC::ChannelHandle& handle, 208 bool ArcBridgeService::Connect(const IPC::ChannelHandle& handle,
186 IPC::Channel::Mode mode) { 209 IPC::Channel::Mode mode) {
187 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 210 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
188 // Testing code can have the state in STOPPED since it does not go through 211 // Testing code can have the state in STOPPED since it does not go through
189 // the whole connection flow. 212 // the whole connection flow.
190 if (state_ != ArcBridgeService::CONNECTING && 213 if (state_ != ArcBridgeService::CONNECTING &&
191 state_ != ArcBridgeService::STOPPED) { 214 state_ != ArcBridgeService::STOPPED) {
192 LOG(ERROR) << "Shutdown requested while connecting"; 215 LOG(ERROR) << "Shutdown requested while connecting";
193 return false; 216 return false;
194 } 217 }
218 LOG(ERROR) << "[ARC] Connect";
195 219
196 ipc_channel_ = IPC::ChannelProxy::Create(handle, mode, this, 220 ipc_channel_ = IPC::ChannelProxy::Create(handle, mode, this,
197 ipc_thread_.task_runner().get()); 221 ipc_thread_.task_runner().get());
198 if (!ipc_channel_) 222 if (!ipc_channel_)
199 return false; 223 return false;
200 SetState(ArcBridgeService::CONNECTED); 224 SetState(ArcBridgeService::CONNECTED);
201 return true; 225 return true;
202 } 226 }
203 227
204 void ArcBridgeService::OnInstanceReady() { 228 void ArcBridgeService::OnInstanceReady() {
205 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 229 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
206 if (state_ != ArcBridgeService::CONNECTED) { 230 if (state_ != ArcBridgeService::CONNECTED) {
207 LOG(ERROR) << "Shutdown requested while connecting"; 231 LOG(ERROR) << "Shutdown requested while connecting";
208 return; 232 return;
209 } 233 }
234 LOG(ERROR) << "[ARC] OnInstanceReady";
235 SetupBridgeInputDevices();
210 SetState(ArcBridgeService::READY); 236 SetState(ArcBridgeService::READY);
211 } 237 }
212 238
213 void ArcBridgeService::SetState(State state) { 239 void ArcBridgeService::SetState(State state) {
214 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 240 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
215 if (state_ == state) 241 if (state_ == state)
216 return; 242 return;
217 state_ = state; 243 state_ = state;
218 observer_list_->Notify(FROM_HERE, 244 observer_list_->Notify(FROM_HERE,
219 &Observer::OnStateChanged, 245 &Observer::OnStateChanged,
(...skipping 19 matching lines...) Expand all
239 IPC_END_MESSAGE_MAP() 265 IPC_END_MESSAGE_MAP()
240 266
241 if (!handled) 267 if (!handled)
242 LOG(ERROR) << "Invalid message with type = " << message.type(); 268 LOG(ERROR) << "Invalid message with type = " << message.type();
243 return handled; 269 return handled;
244 } 270 }
245 271
246 void ArcBridgeService::OnInstanceStarted( 272 void ArcBridgeService::OnInstanceStarted(
247 chromeos::DBusMethodCallStatus status) { 273 chromeos::DBusMethodCallStatus status) {
248 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 274 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
275 LOG(ERROR) << "[ARC] OnInstanceStarted";
249 if (state_ != ArcBridgeService::CONNECTED) { 276 if (state_ != ArcBridgeService::CONNECTED) {
250 LOG(ERROR) << "Shutdown requested while connecting"; 277 LOG(ERROR) << "Shutdown requested while connecting";
251 return; 278 return;
252 } 279 }
253 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS) { 280 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
254 LOG(ERROR) << "ARC instance unable to start. Shutting down the bridge"; 281 LOG(ERROR) << "ARC instance unable to start. Shutting down the bridge";
255 Shutdown(); 282 Shutdown();
256 return; 283 return;
257 } 284 }
258 SetState(ArcBridgeService::STARTING); 285 SetState(ArcBridgeService::STARTING);
259 } 286 }
260 287
261 void ArcBridgeService::OnInstanceStopped( 288 void ArcBridgeService::OnInstanceStopped(
262 chromeos::DBusMethodCallStatus status) { 289 chromeos::DBusMethodCallStatus status) {
263 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); 290 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
264 // STOPPING is the only valid state for this function. 291 // STOPPING is the only valid state for this function.
265 CHECK(state_ == ArcBridgeService::STOPPING); 292 CHECK(state_ == ArcBridgeService::STOPPING);
266 SetState(ArcBridgeService::STOPPED); 293 SetState(ArcBridgeService::STOPPED);
267 } 294 }
268 295
269 } // namespace arc 296 } // namespace arc
OLDNEW
« components/arc/arc_bridge_service.h ('K') | « components/arc/arc_bridge_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698