OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/chromeos/login/screens/hid_detection_screen.h" | 5 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h" |
6 | 6 |
7 #include "base/bind.h" | |
8 #include "base/metrics/histogram.h" | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
7 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" | 11 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" |
12 #include "chrome/browser/chromeos/login/screens/hid_detection_view.h" | |
8 #include "chrome/browser/chromeos/login/wizard_controller.h" | 13 #include "chrome/browser/chromeos/login/wizard_controller.h" |
14 #include "chrome/grit/generated_resources.h" | |
15 #include "device/bluetooth/bluetooth_adapter_factory.h" | |
16 #include "ui/base/l10n/l10n_util.h" | |
17 | |
18 namespace { | |
19 | |
20 // Possible ui-states for device-blocks. | |
21 const char kSearchingState[] = "searching"; | |
22 const char kUSBConnectedState[] = "connected"; | |
23 const char kBTPairedState[] = "paired"; | |
24 const char kBTPairingState[] = "pairing"; | |
25 | |
26 // Standard length of pincode for pairing BT keyboards. | |
27 const int kPincodeLength = 6; | |
28 | |
29 bool DeviceIsPointing(device::BluetoothDevice::DeviceType device_type) { | |
30 return device_type == device::BluetoothDevice::DEVICE_MOUSE || | |
31 device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO || | |
32 device_type == device::BluetoothDevice::DEVICE_TABLET; | |
33 } | |
34 | |
35 bool DeviceIsPointing(const device::InputServiceLinux::InputDeviceInfo& info) { | |
36 return info.is_mouse || info.is_touchpad || info.is_touchscreen || | |
37 info.is_tablet; | |
38 } | |
39 | |
40 bool DeviceIsKeyboard(device::BluetoothDevice::DeviceType device_type) { | |
41 return device_type == device::BluetoothDevice::DEVICE_KEYBOARD || | |
42 device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO; | |
43 } | |
44 | |
45 } // namespace | |
9 | 46 |
10 namespace chromeos { | 47 namespace chromeos { |
11 | 48 |
12 HIDDetectionScreen::HIDDetectionScreen(BaseScreenDelegate* base_screen_delegate, | 49 HIDDetectionScreen::HIDDetectionScreen(BaseScreenDelegate* base_screen_delegate, |
13 HIDDetectionScreenActor* actor) | 50 HIDDetectionView* view) |
14 : BaseScreen(base_screen_delegate), actor_(actor) { | 51 : HIDDetectionModel(base_screen_delegate), |
15 DCHECK(actor_); | 52 view_(view), |
16 if (actor_) | 53 mouse_is_pairing_(false), |
17 actor_->SetDelegate(this); | 54 pointing_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), |
55 keyboard_is_pairing_(false), | |
56 keyboard_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), | |
57 switch_on_adapter_when_ready_(false), | |
58 showing_(false), | |
59 weak_ptr_factory_(this) { | |
60 DCHECK(view_); | |
61 if (view_) | |
62 view_->Bind(*this); | |
63 | |
18 } | 64 } |
19 | 65 |
20 HIDDetectionScreen::~HIDDetectionScreen() { | 66 HIDDetectionScreen::~HIDDetectionScreen() { |
21 if (actor_) | 67 adapter_initially_powered_.reset(); |
22 actor_->SetDelegate(NULL); | 68 input_service_proxy_.RemoveObserver(this); |
69 if (view_) | |
70 view_->Unbind(); | |
71 if (discovery_session_.get()) | |
72 discovery_session_->Stop(base::Bind(&base::DoNothing), | |
73 base::Bind(&base::DoNothing)); | |
74 if (adapter_.get()) | |
75 adapter_->RemoveObserver(this); | |
23 } | 76 } |
24 | 77 |
25 void HIDDetectionScreen::PrepareToShow() { | 78 void HIDDetectionScreen::PrepareToShow() { |
79 if (view_) | |
80 view_->PrepareToShow(); | |
26 } | 81 } |
27 | 82 |
28 void HIDDetectionScreen::Show() { | 83 void HIDDetectionScreen::Show() { |
29 if (actor_) | 84 showing_ = true; |
30 actor_->Show(); | 85 context_.SetInteger(kContextKeyNumKeysEnteredExpected, false); |
86 SendPointingDeviceNotification(); | |
87 SendKeyboardDeviceNotification(); | |
88 | |
89 input_service_proxy_.AddObserver(this); | |
90 UpdateDevices(); | |
91 | |
92 if (view_) | |
93 view_->Show(); | |
31 } | 94 } |
32 | 95 |
33 void HIDDetectionScreen::Hide() { | 96 void HIDDetectionScreen::Hide() { |
34 if (actor_) | 97 showing_ = false; |
35 actor_->Hide(); | 98 input_service_proxy_.RemoveObserver(this); |
36 } | 99 if (discovery_session_.get()) |
37 | 100 discovery_session_->Stop(base::Bind(&base::DoNothing), |
38 std::string HIDDetectionScreen::GetName() const { | 101 base::Bind(&base::DoNothing)); |
39 return WizardController::kHIDDetectionScreenName; | 102 if (view_) |
40 } | 103 view_->Hide(); |
41 | 104 } |
42 void HIDDetectionScreen::OnExit() { | 105 |
106 void HIDDetectionScreen::Initialize(::login::ScreenContext* context) { | |
107 HIDDetectionModel::Initialize(context); | |
108 | |
109 device::BluetoothAdapterFactory::GetAdapter( | |
110 base::Bind(&HIDDetectionScreen::InitializeAdapter, | |
111 weak_ptr_factory_.GetWeakPtr())); | |
112 } | |
113 | |
114 void HIDDetectionScreen::OnContinueButtonClicked() { | |
115 | |
116 ContinueScenarioType scenario_type; | |
117 if (!pointing_device_id_.empty() && !keyboard_device_id_.empty()) | |
118 scenario_type = All_DEVICES_DETECTED; | |
119 else if (pointing_device_id_.empty()) | |
120 scenario_type = KEYBOARD_DEVICE_ONLY_DETECTED; | |
121 else | |
122 scenario_type = POINTING_DEVICE_ONLY_DETECTED; | |
123 | |
124 UMA_HISTOGRAM_ENUMERATION( | |
125 "HIDDetection.OOBEDevicesDetectedOnContinuePressed", | |
126 scenario_type, | |
127 CONTINUE_SCENARIO_TYPE_SIZE); | |
128 | |
129 // Switch off BT adapter if it was off before the screen and no BT device | |
130 // connected. | |
131 bool adapter_is_powered = | |
132 adapter_.get() && adapter_->IsPresent() && adapter_->IsPowered(); | |
133 bool use_bluetooth = | |
134 pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH || | |
135 keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH; | |
136 bool need_switching_off = adapter_initially_powered_ && | |
137 !(*adapter_initially_powered_); | |
138 if (adapter_is_powered && !use_bluetooth && need_switching_off) { | |
139 VLOG(1) << "Switching off BT adapter after HID OOBE screen as unused."; | |
140 adapter_->SetPowered( | |
141 false, | |
142 base::Bind(&base::DoNothing), | |
143 base::Bind(&HIDDetectionScreen::SetPoweredOffError, | |
144 weak_ptr_factory_.GetWeakPtr())); | |
145 } | |
146 | |
43 Finish(BaseScreenDelegate::HID_DETECTION_COMPLETED); | 147 Finish(BaseScreenDelegate::HID_DETECTION_COMPLETED); |
44 } | 148 } |
45 | 149 |
46 void HIDDetectionScreen::OnActorDestroyed(HIDDetectionScreenActor* actor) { | 150 void HIDDetectionScreen::CheckIsScreenRequired( |
47 if (actor_ == actor) | 151 const base::Callback<void(bool)>& on_check_done) { |
48 actor_ = NULL; | 152 input_service_proxy_.GetDevices( |
49 } | 153 base::Bind(&HIDDetectionScreen::OnGetInputDevicesListForCheck, |
154 weak_ptr_factory_.GetWeakPtr(), | |
155 on_check_done)); | |
156 } | |
157 | |
158 void HIDDetectionScreen::OnViewDestroyed(HIDDetectionView* view) { | |
159 if (view_ == view) | |
160 view_ = NULL; | |
161 } | |
162 | |
163 void HIDDetectionScreen::RequestPinCode(device::BluetoothDevice* device) { | |
164 VLOG(1) << "RequestPinCode id = " << device->GetDeviceID() | |
165 << " name = " << device->GetName(); | |
166 device->CancelPairing(); | |
167 } | |
168 | |
169 void HIDDetectionScreen::RequestPasskey(device::BluetoothDevice* device) { | |
170 VLOG(1) << "RequestPassKey id = " << device->GetDeviceID() | |
171 << " name = " << device->GetName(); | |
172 device->CancelPairing(); | |
173 } | |
174 | |
175 void HIDDetectionScreen::DisplayPinCode(device::BluetoothDevice* device, | |
176 const std::string& pincode) { | |
177 VLOG(1) << "DisplayPinCode id = " << device->GetDeviceID() | |
178 << " name = " << device->GetName(); | |
179 context_.SetString(kContextKeyPinCode, pincode); | |
180 SetKeyboardDeviceName_(base::UTF16ToUTF8(device->GetName())); | |
181 SendKeyboardDeviceNotification(); | |
182 CommitContextChanges(); | |
183 } | |
184 | |
185 void HIDDetectionScreen::DisplayPasskey( | |
186 device::BluetoothDevice* device, uint32 passkey) { | |
187 VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID() | |
188 << " name = " << device->GetName(); | |
189 std::string pincode = base::UintToString(passkey); | |
190 pincode = std::string(kPincodeLength - pincode.length(), '0').append(pincode); | |
191 // No differences in UI for passkey and pincode authentication calls. | |
192 DisplayPinCode(device, pincode); | |
193 } | |
194 | |
195 void HIDDetectionScreen::KeysEntered( | |
196 device::BluetoothDevice* device, uint32 entered) { | |
197 VLOG(1) << "Number of keys entered " << entered; | |
198 base::DictionaryValue params; | |
199 context_.SetInteger(kContextKeyNumKeysEnteredExpected, true); | |
200 context_.SetInteger(kContextKeyNumKeysEnteredPinCode, entered); | |
Denis Kuznetsov (DE-MUC)
2015/02/05 13:33:19
You can use a shortcut : context_.SetInteger(...).
merkulova
2015/02/09 08:54:36
Do you think it's ok from the point of readability
Denis Kuznetsov (DE-MUC)
2015/02/09 12:03:06
Yes. It would also result in fewer intermediate Ed
| |
201 SendKeyboardDeviceNotification(); | |
202 } | |
203 | |
204 void HIDDetectionScreen::ConfirmPasskey( | |
205 device::BluetoothDevice* device, uint32 passkey) { | |
206 VLOG(1) << "Confirm Passkey"; | |
207 device->CancelPairing(); | |
208 } | |
209 | |
210 void HIDDetectionScreen::AuthorizePairing(device::BluetoothDevice* device) { | |
211 // There is never any circumstance where this will be called, since the | |
212 // HID detection screen will only be used for outgoing pairing | |
213 // requests, but play it safe. | |
214 VLOG(1) << "Authorize pairing"; | |
215 device->ConfirmPairing(); | |
216 } | |
217 | |
218 void HIDDetectionScreen::AdapterPresentChanged( | |
219 device::BluetoothAdapter* adapter, bool present) { | |
220 if (present && switch_on_adapter_when_ready_) { | |
221 VLOG(1) << "Switching on BT adapter on HID OOBE screen."; | |
222 adapter_initially_powered_.reset(new bool(adapter_->IsPowered())); | |
223 adapter_->SetPowered( | |
224 true, | |
225 base::Bind(&HIDDetectionScreen::StartBTDiscoverySession, | |
226 weak_ptr_factory_.GetWeakPtr()), | |
227 base::Bind(&HIDDetectionScreen::SetPoweredError, | |
228 weak_ptr_factory_.GetWeakPtr())); | |
229 } | |
230 } | |
231 | |
232 void HIDDetectionScreen::TryPairingAsPointingDevice( | |
233 device::BluetoothDevice* device) { | |
234 if (pointing_device_id_.empty() && | |
235 DeviceIsPointing(device->GetDeviceType()) && | |
236 device->IsPairable() && | |
237 !(device->IsConnected() && device->IsPaired()) && | |
238 !mouse_is_pairing_) { | |
239 ConnectBTDevice(device); | |
240 } | |
241 } | |
242 | |
243 void HIDDetectionScreen::TryPairingAsKeyboardDevice( | |
244 device::BluetoothDevice* device) { | |
245 if (keyboard_device_id_.empty() && | |
246 DeviceIsKeyboard(device->GetDeviceType()) && | |
247 device->IsPairable() && | |
248 !(device->IsConnected() && device->IsPaired()) && | |
249 !keyboard_is_pairing_) { | |
250 ConnectBTDevice(device); | |
251 } | |
252 } | |
253 | |
254 void HIDDetectionScreen::ConnectBTDevice(device::BluetoothDevice* device) { | |
255 bool device_busy = (device->IsConnected() && device->IsPaired()) || | |
256 device->IsConnecting(); | |
257 if (!device->IsPairable() || device_busy) | |
258 return; | |
259 device::BluetoothDevice::DeviceType device_type = device->GetDeviceType(); | |
260 | |
261 if (device_type == device::BluetoothDevice::DEVICE_MOUSE || | |
262 device_type == device::BluetoothDevice::DEVICE_TABLET) { | |
263 if (mouse_is_pairing_) | |
264 return; | |
265 mouse_is_pairing_ = true; | |
266 } else if (device_type == device::BluetoothDevice::DEVICE_KEYBOARD) { | |
267 if (keyboard_is_pairing_) | |
268 return; | |
269 keyboard_is_pairing_ = true; | |
270 } else if (device_type == | |
271 device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO) { | |
272 if (mouse_is_pairing_ && keyboard_is_pairing_) | |
273 return; | |
274 mouse_is_pairing_ = true; | |
275 keyboard_is_pairing_ = true; | |
276 } | |
277 device->Connect(this, | |
278 base::Bind(&HIDDetectionScreen::BTConnected, | |
279 weak_ptr_factory_.GetWeakPtr(), device_type), | |
280 base::Bind(&HIDDetectionScreen::BTConnectError, | |
281 weak_ptr_factory_.GetWeakPtr(), | |
282 device->GetAddress(), device_type)); | |
283 } | |
284 | |
285 void HIDDetectionScreen::BTConnected( | |
286 device::BluetoothDevice::DeviceType device_type) { | |
287 if (DeviceIsPointing(device_type)) | |
288 mouse_is_pairing_ = false; | |
289 if (DeviceIsKeyboard(device_type)) { | |
290 keyboard_is_pairing_ = false; | |
291 context_.SetInteger(kContextKeyNumKeysEnteredExpected, false); | |
292 context_.SetString(kContextKeyPinCode, ""); | |
Denis Kuznetsov (DE-MUC)
2015/02/05 13:33:19
Same as above
merkulova
2015/02/09 08:54:36
Acknowledged.
| |
293 SendKeyboardDeviceNotification(); | |
294 CommitContextChanges(); | |
295 } | |
296 } | |
297 | |
298 void HIDDetectionScreen::BTConnectError( | |
299 const std::string& address, | |
300 device::BluetoothDevice::DeviceType device_type, | |
301 device::BluetoothDevice::ConnectErrorCode error_code) { | |
302 LOG(WARNING) << "BTConnectError while connecting " << address | |
303 << " error code = " << error_code; | |
304 if (DeviceIsPointing(device_type)) | |
305 mouse_is_pairing_ = false; | |
306 if (DeviceIsKeyboard(device_type)) { | |
307 keyboard_is_pairing_ = false; | |
308 context_.SetInteger(kContextKeyNumKeysEnteredExpected, false); | |
309 context_.SetString(kContextKeyPinCode, ""); | |
310 SendKeyboardDeviceNotification(); | |
311 } | |
312 | |
313 if (pointing_device_id_.empty() || keyboard_device_id_.empty()) | |
314 UpdateDevices(); | |
315 } | |
316 | |
317 void HIDDetectionScreen::SendPointingDeviceNotification() { | |
318 std::string state; | |
319 if (pointing_device_id_.empty()) | |
320 state = kSearchingState; | |
321 else if (pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) | |
322 state = kBTPairedState; | |
323 else | |
324 state = kUSBConnectedState; | |
325 context_.SetString(kContextKeyMouseState, state); | |
326 context_.SetBoolean( | |
327 kContextKeyContinueButtonEnabled, | |
328 !(pointing_device_id_.empty() && keyboard_device_id_.empty())); | |
329 CommitContextChanges(); | |
330 } | |
331 | |
332 void HIDDetectionScreen::SendKeyboardDeviceNotification() { | |
333 context_.SetString(kContextKeyKeyboardLabel, ""); | |
334 if (keyboard_device_id_.empty()) { | |
335 if (keyboard_is_pairing_) { | |
336 context_.SetString(kContextKeyKeyboardState, kBTPairingState); | |
337 context_.SetString(kContextKeyKeyboardLabel, | |
338 l10n_util::GetStringFUTF8( | |
339 IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST, | |
340 base::UTF8ToUTF16(keyboard_device_name_))); | |
341 } else { | |
342 context_.SetString(kContextKeyKeyboardState, kSearchingState); | |
343 } | |
344 } else { | |
345 if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) { | |
346 context_.SetString(kContextKeyKeyboardState, kBTPairedState); | |
347 context_.SetString(kContextKeyKeyboardLabel, | |
348 l10n_util::GetStringFUTF16( | |
349 IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD, | |
350 base::UTF8ToUTF16(keyboard_device_name_))); | |
351 } else { | |
352 context_.SetString(kContextKeyKeyboardState, kUSBConnectedState); | |
353 } | |
354 } | |
355 context_.SetString(kContextKeyKeyboardDeviceName, keyboard_device_name_); | |
356 context_.SetBoolean( | |
357 kContextKeyContinueButtonEnabled, | |
358 !(pointing_device_id_.empty() && keyboard_device_id_.empty())); | |
359 CommitContextChanges(); | |
360 } | |
361 | |
362 void HIDDetectionScreen::SetKeyboardDeviceName_(std::string name) { | |
363 if (!(keyboard_device_id_.empty()) && name.empty()) | |
364 name = l10n_util::GetStringUTF8(IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME); | |
365 keyboard_device_name_ = name; | |
366 } | |
367 | |
368 void HIDDetectionScreen::DeviceAdded( | |
369 device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { | |
370 VLOG(1) << "BT input device added id = " << device->GetDeviceID() << | |
371 " name = " << device->GetName(); | |
372 TryPairingAsPointingDevice(device); | |
373 TryPairingAsKeyboardDevice(device); | |
374 } | |
375 | |
376 void HIDDetectionScreen::DeviceChanged( | |
377 device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { | |
378 VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " << | |
379 device->GetName(); | |
380 TryPairingAsPointingDevice(device); | |
381 TryPairingAsKeyboardDevice(device); | |
382 } | |
383 | |
384 void HIDDetectionScreen::DeviceRemoved( | |
385 device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { | |
386 VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " << | |
387 device->GetName(); | |
388 } | |
389 | |
390 void HIDDetectionScreen::OnInputDeviceAdded( | |
391 const InputDeviceInfo& info) { | |
392 VLOG(1) << "Input device added id = " << info.id << " name = " << info.name; | |
393 // TODO(merkulova): deal with all available device types, e.g. joystick. | |
394 if (!keyboard_device_id_.empty() && !pointing_device_id_.empty()) | |
395 return; | |
396 | |
397 if (pointing_device_id_.empty() && DeviceIsPointing(info)) { | |
398 pointing_device_id_ = info.id; | |
399 context_.SetString(kContextKeyMouseDeviceName, info.name); | |
400 pointing_device_connect_type_ = info.type; | |
401 SendPointingDeviceNotification(); | |
402 } | |
403 if (keyboard_device_id_.empty() && info.is_keyboard) { | |
404 keyboard_device_id_ = info.id; | |
405 keyboard_device_connect_type_ = info.type; | |
406 SetKeyboardDeviceName_(info.name); | |
407 SendKeyboardDeviceNotification(); | |
408 } | |
409 } | |
410 | |
411 void HIDDetectionScreen::OnInputDeviceRemoved(const std::string& id) { | |
412 if (id == keyboard_device_id_) { | |
413 keyboard_device_id_.clear(); | |
414 keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; | |
415 SendKeyboardDeviceNotification(); | |
416 UpdateDevices(); | |
417 } | |
418 if (id == pointing_device_id_) { | |
419 pointing_device_id_.clear(); | |
420 pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; | |
421 SendPointingDeviceNotification(); | |
422 UpdateDevices(); | |
423 } | |
424 } | |
425 | |
426 void HIDDetectionScreen::InitializeAdapter( | |
427 scoped_refptr<device::BluetoothAdapter> adapter) { | |
428 adapter_ = adapter; | |
429 CHECK(adapter_.get()); | |
430 | |
431 adapter_->AddObserver(this); | |
432 UpdateDevices(); | |
433 } | |
434 | |
435 void HIDDetectionScreen::StartBTDiscoverySession() { | |
436 adapter_->StartDiscoverySession( | |
437 base::Bind(&HIDDetectionScreen::OnStartDiscoverySession, | |
438 weak_ptr_factory_.GetWeakPtr()), | |
439 base::Bind(&HIDDetectionScreen::FindDevicesError, | |
440 weak_ptr_factory_.GetWeakPtr())); | |
441 } | |
442 | |
443 void HIDDetectionScreen::ProcessConnectedDevicesList( | |
444 const std::vector<InputDeviceInfo>& devices) { | |
445 for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin(); | |
446 it != devices.end() && | |
447 (pointing_device_id_.empty() || keyboard_device_id_.empty()); | |
448 ++it) { | |
449 if (pointing_device_id_.empty() && DeviceIsPointing(*it)) { | |
450 pointing_device_id_ = it->id; | |
451 context_.SetString(kContextKeyMouseDeviceName, it->name); | |
452 pointing_device_connect_type_ = it->type; | |
453 SendPointingDeviceNotification(); | |
454 } | |
455 if (keyboard_device_id_.empty() && it->is_keyboard) { | |
456 keyboard_device_id_ = it->id; | |
457 SetKeyboardDeviceName_(it->name); | |
458 keyboard_device_connect_type_ = it->type; | |
459 SendKeyboardDeviceNotification(); | |
460 } | |
461 } | |
462 } | |
463 | |
464 void HIDDetectionScreen::TryInitiateBTDevicesUpdate() { | |
465 if ((pointing_device_id_.empty() || keyboard_device_id_.empty()) && | |
466 adapter_.get()) { | |
467 if (!adapter_->IsPresent()) { | |
468 // Switch on BT adapter later when it's available. | |
469 switch_on_adapter_when_ready_ = true; | |
470 } else if (!adapter_->IsPowered()) { | |
471 VLOG(1) << "Switching on BT adapter on HID OOBE screen."; | |
472 adapter_initially_powered_.reset(new bool(false)); | |
473 adapter_->SetPowered( | |
474 true, | |
475 base::Bind(&HIDDetectionScreen::StartBTDiscoverySession, | |
476 weak_ptr_factory_.GetWeakPtr()), | |
477 base::Bind(&HIDDetectionScreen::SetPoweredError, | |
478 weak_ptr_factory_.GetWeakPtr())); | |
479 } else { | |
480 UpdateBTDevices(); | |
481 } | |
482 } | |
483 } | |
484 | |
485 void HIDDetectionScreen::OnGetInputDevicesListForCheck( | |
486 const base::Callback<void(bool)>& on_check_done, | |
487 const std::vector<InputDeviceInfo>& devices) { | |
488 ProcessConnectedDevicesList(devices); | |
489 | |
490 // Screen is not required if both devices are present. | |
491 bool all_devices_autodetected = !pointing_device_id_.empty() && | |
492 !keyboard_device_id_.empty(); | |
493 UMA_HISTOGRAM_BOOLEAN("HIDDetection.OOBEDialogShown", | |
494 !all_devices_autodetected); | |
495 | |
496 on_check_done.Run(!all_devices_autodetected); | |
497 } | |
498 | |
499 void HIDDetectionScreen::OnGetInputDevicesList( | |
500 const std::vector<InputDeviceInfo>& devices) { | |
501 ProcessConnectedDevicesList(devices); | |
502 TryInitiateBTDevicesUpdate(); | |
503 } | |
504 | |
505 void HIDDetectionScreen::UpdateDevices() { | |
506 input_service_proxy_.GetDevices( | |
507 base::Bind(&HIDDetectionScreen::OnGetInputDevicesList, | |
508 weak_ptr_factory_.GetWeakPtr())); | |
509 } | |
510 | |
511 void HIDDetectionScreen::UpdateBTDevices() { | |
512 if (!adapter_.get() || !adapter_->IsPresent() || !adapter_->IsPowered()) | |
513 return; | |
514 | |
515 // If no connected devices found as pointing device and keyboard, we try to | |
516 // connect some type-suitable active bluetooth device. | |
517 std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices(); | |
518 for (std::vector<device::BluetoothDevice*>::const_iterator it = | |
519 bt_devices.begin(); | |
520 it != bt_devices.end() && | |
521 (keyboard_device_id_.empty() || pointing_device_id_.empty()); | |
522 ++it) { | |
523 TryPairingAsPointingDevice(*it); | |
524 TryPairingAsKeyboardDevice(*it); | |
525 } | |
526 } | |
527 | |
528 void HIDDetectionScreen::OnStartDiscoverySession( | |
529 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { | |
530 VLOG(1) << "BT Discovery session started"; | |
531 discovery_session_ = discovery_session.Pass(); | |
532 UpdateDevices(); | |
533 } | |
534 | |
535 void HIDDetectionScreen::SetPoweredError() { | |
536 LOG(ERROR) << "Failed to power BT adapter"; | |
537 } | |
538 | |
539 void HIDDetectionScreen::SetPoweredOffError() { | |
540 LOG(ERROR) << "Failed to power off BT adapter"; | |
541 } | |
542 | |
543 void HIDDetectionScreen::FindDevicesError() { | |
544 VLOG(1) << "Failed to start Bluetooth discovery."; | |
545 } | |
546 | |
50 | 547 |
51 } // namespace chromeos | 548 } // namespace chromeos |
OLD | NEW |