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 GetContextEditor().SetBoolean(kContextKeyNumKeysEnteredExpected, false); |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
Here update will be sent in the end of the method,
| |
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 GetContextEditor().SetString(kContextKeyPinCode, pincode); | |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
Same as above, make sure that expectations on JS s
| |
180 SetKeyboardDeviceName_(base::UTF16ToUTF8(device->GetName())); | |
181 SendKeyboardDeviceNotification(); | |
182 } | |
183 | |
184 void HIDDetectionScreen::DisplayPasskey( | |
185 device::BluetoothDevice* device, uint32 passkey) { | |
186 VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID() | |
187 << " name = " << device->GetName(); | |
188 std::string pincode = base::UintToString(passkey); | |
189 pincode = std::string(kPincodeLength - pincode.length(), '0').append(pincode); | |
190 // No differences in UI for passkey and pincode authentication calls. | |
191 DisplayPinCode(device, pincode); | |
192 } | |
193 | |
194 void HIDDetectionScreen::KeysEntered( | |
195 device::BluetoothDevice* device, uint32 entered) { | |
196 VLOG(1) << "Number of keys entered " << entered; | |
197 GetContextEditor() | |
198 .SetBoolean(kContextKeyNumKeysEnteredExpected, true) | |
199 .SetInteger(kContextKeyNumKeysEnteredPinCode, entered); | |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
Same as above.
| |
200 SendKeyboardDeviceNotification(); | |
201 } | |
202 | |
203 void HIDDetectionScreen::ConfirmPasskey( | |
204 device::BluetoothDevice* device, uint32 passkey) { | |
205 VLOG(1) << "Confirm Passkey"; | |
206 device->CancelPairing(); | |
207 } | |
208 | |
209 void HIDDetectionScreen::AuthorizePairing(device::BluetoothDevice* device) { | |
210 // There is never any circumstance where this will be called, since the | |
211 // HID detection screen will only be used for outgoing pairing | |
212 // requests, but play it safe. | |
213 VLOG(1) << "Authorize pairing"; | |
214 device->ConfirmPairing(); | |
215 } | |
216 | |
217 void HIDDetectionScreen::AdapterPresentChanged( | |
218 device::BluetoothAdapter* adapter, bool present) { | |
219 if (present && switch_on_adapter_when_ready_) { | |
220 VLOG(1) << "Switching on BT adapter on HID OOBE screen."; | |
221 adapter_initially_powered_.reset(new bool(adapter_->IsPowered())); | |
222 adapter_->SetPowered( | |
223 true, | |
224 base::Bind(&HIDDetectionScreen::StartBTDiscoverySession, | |
225 weak_ptr_factory_.GetWeakPtr()), | |
226 base::Bind(&HIDDetectionScreen::SetPoweredError, | |
227 weak_ptr_factory_.GetWeakPtr())); | |
228 } | |
229 } | |
230 | |
231 void HIDDetectionScreen::TryPairingAsPointingDevice( | |
232 device::BluetoothDevice* device) { | |
233 if (pointing_device_id_.empty() && | |
234 DeviceIsPointing(device->GetDeviceType()) && | |
235 device->IsPairable() && | |
236 !(device->IsConnected() && device->IsPaired()) && | |
237 !mouse_is_pairing_) { | |
238 ConnectBTDevice(device); | |
239 } | |
240 } | |
241 | |
242 void HIDDetectionScreen::TryPairingAsKeyboardDevice( | |
243 device::BluetoothDevice* device) { | |
244 if (keyboard_device_id_.empty() && | |
245 DeviceIsKeyboard(device->GetDeviceType()) && | |
246 device->IsPairable() && | |
247 !(device->IsConnected() && device->IsPaired()) && | |
248 !keyboard_is_pairing_) { | |
249 ConnectBTDevice(device); | |
250 } | |
251 } | |
252 | |
253 void HIDDetectionScreen::ConnectBTDevice(device::BluetoothDevice* device) { | |
254 bool device_busy = (device->IsConnected() && device->IsPaired()) || | |
255 device->IsConnecting(); | |
256 if (!device->IsPairable() || device_busy) | |
257 return; | |
258 device::BluetoothDevice::DeviceType device_type = device->GetDeviceType(); | |
259 | |
260 if (device_type == device::BluetoothDevice::DEVICE_MOUSE || | |
261 device_type == device::BluetoothDevice::DEVICE_TABLET) { | |
262 if (mouse_is_pairing_) | |
263 return; | |
264 mouse_is_pairing_ = true; | |
265 } else if (device_type == device::BluetoothDevice::DEVICE_KEYBOARD) { | |
266 if (keyboard_is_pairing_) | |
267 return; | |
268 keyboard_is_pairing_ = true; | |
269 } else if (device_type == | |
270 device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO) { | |
271 if (mouse_is_pairing_ && keyboard_is_pairing_) | |
272 return; | |
273 mouse_is_pairing_ = true; | |
274 keyboard_is_pairing_ = true; | |
275 } | |
276 device->Connect(this, | |
277 base::Bind(&HIDDetectionScreen::BTConnected, | |
278 weak_ptr_factory_.GetWeakPtr(), device_type), | |
279 base::Bind(&HIDDetectionScreen::BTConnectError, | |
280 weak_ptr_factory_.GetWeakPtr(), | |
281 device->GetAddress(), device_type)); | |
282 } | |
283 | |
284 void HIDDetectionScreen::BTConnected( | |
285 device::BluetoothDevice::DeviceType device_type) { | |
286 if (DeviceIsPointing(device_type)) | |
287 mouse_is_pairing_ = false; | |
288 if (DeviceIsKeyboard(device_type)) { | |
289 keyboard_is_pairing_ = false; | |
290 GetContextEditor() | |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
same here
| |
291 .SetBoolean(kContextKeyNumKeysEnteredExpected, false) | |
292 .SetString(kContextKeyPinCode, ""); | |
293 SendKeyboardDeviceNotification(); | |
294 } | |
295 } | |
296 | |
297 void HIDDetectionScreen::BTConnectError( | |
298 const std::string& address, | |
299 device::BluetoothDevice::DeviceType device_type, | |
300 device::BluetoothDevice::ConnectErrorCode error_code) { | |
301 LOG(WARNING) << "BTConnectError while connecting " << address | |
302 << " error code = " << error_code; | |
303 if (DeviceIsPointing(device_type)) | |
304 mouse_is_pairing_ = false; | |
305 if (DeviceIsKeyboard(device_type)) { | |
306 keyboard_is_pairing_ = false; | |
307 GetContextEditor() | |
308 .SetInteger(kContextKeyNumKeysEnteredExpected, false) | |
309 .SetString(kContextKeyPinCode, ""); | |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
same here
| |
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 GetContextEditor().SetString(kContextKeyMouseState, state) | |
326 .SetBoolean( | |
327 kContextKeyContinueButtonEnabled, | |
328 !(pointing_device_id_.empty() && keyboard_device_id_.empty())); | |
329 } | |
330 | |
331 void HIDDetectionScreen::SendKeyboardDeviceNotification() { | |
332 ContextEditor editor = GetContextEditor(); | |
333 editor.SetString(kContextKeyKeyboardLabel, ""); | |
334 if (keyboard_device_id_.empty()) { | |
335 if (keyboard_is_pairing_) { | |
336 editor.SetString(kContextKeyKeyboardState, kBTPairingState) | |
337 .SetString( | |
338 kContextKeyKeyboardLabel, | |
339 l10n_util::GetStringFUTF8( | |
340 IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST, | |
341 base::UTF8ToUTF16(keyboard_device_name_))); | |
342 } else { | |
343 editor.SetString(kContextKeyKeyboardState, kSearchingState); | |
344 } | |
345 } else { | |
346 if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) { | |
347 editor.SetString(kContextKeyKeyboardState, kBTPairedState) | |
348 .SetString( | |
349 kContextKeyKeyboardLabel, | |
350 l10n_util::GetStringFUTF16( | |
351 IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD, | |
352 base::UTF8ToUTF16(keyboard_device_name_))); | |
353 } else { | |
354 editor.SetString(kContextKeyKeyboardState, kUSBConnectedState); | |
355 } | |
356 } | |
357 editor.SetString(kContextKeyKeyboardDeviceName, keyboard_device_name_) | |
358 .SetBoolean( | |
359 kContextKeyContinueButtonEnabled, | |
360 !(pointing_device_id_.empty() && keyboard_device_id_.empty())); | |
361 } | |
362 | |
363 void HIDDetectionScreen::SetKeyboardDeviceName_(std::string name) { | |
364 if (!(keyboard_device_id_.empty()) && name.empty()) | |
365 name = l10n_util::GetStringUTF8(IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME); | |
366 keyboard_device_name_ = name; | |
367 } | |
368 | |
369 void HIDDetectionScreen::DeviceAdded( | |
370 device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { | |
371 VLOG(1) << "BT input device added id = " << device->GetDeviceID() << | |
372 " name = " << device->GetName(); | |
373 TryPairingAsPointingDevice(device); | |
374 TryPairingAsKeyboardDevice(device); | |
375 } | |
376 | |
377 void HIDDetectionScreen::DeviceChanged( | |
378 device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { | |
379 VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " << | |
380 device->GetName(); | |
381 TryPairingAsPointingDevice(device); | |
382 TryPairingAsKeyboardDevice(device); | |
383 } | |
384 | |
385 void HIDDetectionScreen::DeviceRemoved( | |
386 device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { | |
387 VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " << | |
388 device->GetName(); | |
389 } | |
390 | |
391 void HIDDetectionScreen::OnInputDeviceAdded( | |
392 const InputDeviceInfo& info) { | |
393 VLOG(1) << "Input device added id = " << info.id << " name = " << info.name; | |
394 // TODO(merkulova): deal with all available device types, e.g. joystick. | |
395 if (!keyboard_device_id_.empty() && !pointing_device_id_.empty()) | |
396 return; | |
397 | |
398 if (pointing_device_id_.empty() && DeviceIsPointing(info)) { | |
399 pointing_device_id_ = info.id; | |
400 GetContextEditor().SetString(kContextKeyMouseDeviceName, info.name); | |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
same here
| |
401 pointing_device_connect_type_ = info.type; | |
402 SendPointingDeviceNotification(); | |
403 } | |
404 if (keyboard_device_id_.empty() && info.is_keyboard) { | |
405 keyboard_device_id_ = info.id; | |
406 keyboard_device_connect_type_ = info.type; | |
407 SetKeyboardDeviceName_(info.name); | |
408 SendKeyboardDeviceNotification(); | |
409 } | |
410 } | |
411 | |
412 void HIDDetectionScreen::OnInputDeviceRemoved(const std::string& id) { | |
413 if (id == keyboard_device_id_) { | |
414 keyboard_device_id_.clear(); | |
415 keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; | |
416 SendKeyboardDeviceNotification(); | |
417 UpdateDevices(); | |
418 } | |
419 if (id == pointing_device_id_) { | |
420 pointing_device_id_.clear(); | |
421 pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; | |
422 SendPointingDeviceNotification(); | |
423 UpdateDevices(); | |
424 } | |
425 } | |
426 | |
427 void HIDDetectionScreen::InitializeAdapter( | |
428 scoped_refptr<device::BluetoothAdapter> adapter) { | |
429 adapter_ = adapter; | |
430 CHECK(adapter_.get()); | |
431 | |
432 adapter_->AddObserver(this); | |
433 UpdateDevices(); | |
434 } | |
435 | |
436 void HIDDetectionScreen::StartBTDiscoverySession() { | |
437 adapter_->StartDiscoverySession( | |
438 base::Bind(&HIDDetectionScreen::OnStartDiscoverySession, | |
439 weak_ptr_factory_.GetWeakPtr()), | |
440 base::Bind(&HIDDetectionScreen::FindDevicesError, | |
441 weak_ptr_factory_.GetWeakPtr())); | |
442 } | |
443 | |
444 void HIDDetectionScreen::ProcessConnectedDevicesList( | |
445 const std::vector<InputDeviceInfo>& devices) { | |
446 for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin(); | |
447 it != devices.end() && | |
448 (pointing_device_id_.empty() || keyboard_device_id_.empty()); | |
449 ++it) { | |
450 if (pointing_device_id_.empty() && DeviceIsPointing(*it)) { | |
451 pointing_device_id_ = it->id; | |
452 GetContextEditor().SetString(kContextKeyMouseDeviceName, it->name); | |
Denis Kuznetsov (DE-MUC)
2015/02/11 16:09:24
same here
| |
453 pointing_device_connect_type_ = it->type; | |
454 SendPointingDeviceNotification(); | |
455 } | |
456 if (keyboard_device_id_.empty() && it->is_keyboard) { | |
457 keyboard_device_id_ = it->id; | |
458 SetKeyboardDeviceName_(it->name); | |
459 keyboard_device_connect_type_ = it->type; | |
460 SendKeyboardDeviceNotification(); | |
461 } | |
462 } | |
463 } | |
464 | |
465 void HIDDetectionScreen::TryInitiateBTDevicesUpdate() { | |
466 if ((pointing_device_id_.empty() || keyboard_device_id_.empty()) && | |
467 adapter_.get()) { | |
468 if (!adapter_->IsPresent()) { | |
469 // Switch on BT adapter later when it's available. | |
470 switch_on_adapter_when_ready_ = true; | |
471 } else if (!adapter_->IsPowered()) { | |
472 VLOG(1) << "Switching on BT adapter on HID OOBE screen."; | |
473 adapter_initially_powered_.reset(new bool(false)); | |
474 adapter_->SetPowered( | |
475 true, | |
476 base::Bind(&HIDDetectionScreen::StartBTDiscoverySession, | |
477 weak_ptr_factory_.GetWeakPtr()), | |
478 base::Bind(&HIDDetectionScreen::SetPoweredError, | |
479 weak_ptr_factory_.GetWeakPtr())); | |
480 } else { | |
481 UpdateBTDevices(); | |
482 } | |
483 } | |
484 } | |
485 | |
486 void HIDDetectionScreen::OnGetInputDevicesListForCheck( | |
487 const base::Callback<void(bool)>& on_check_done, | |
488 const std::vector<InputDeviceInfo>& devices) { | |
489 ProcessConnectedDevicesList(devices); | |
490 | |
491 // Screen is not required if both devices are present. | |
492 bool all_devices_autodetected = !pointing_device_id_.empty() && | |
493 !keyboard_device_id_.empty(); | |
494 UMA_HISTOGRAM_BOOLEAN("HIDDetection.OOBEDialogShown", | |
495 !all_devices_autodetected); | |
496 | |
497 on_check_done.Run(!all_devices_autodetected); | |
498 } | |
499 | |
500 void HIDDetectionScreen::OnGetInputDevicesList( | |
501 const std::vector<InputDeviceInfo>& devices) { | |
502 ProcessConnectedDevicesList(devices); | |
503 TryInitiateBTDevicesUpdate(); | |
504 } | |
505 | |
506 void HIDDetectionScreen::UpdateDevices() { | |
507 input_service_proxy_.GetDevices( | |
508 base::Bind(&HIDDetectionScreen::OnGetInputDevicesList, | |
509 weak_ptr_factory_.GetWeakPtr())); | |
510 } | |
511 | |
512 void HIDDetectionScreen::UpdateBTDevices() { | |
513 if (!adapter_.get() || !adapter_->IsPresent() || !adapter_->IsPowered()) | |
514 return; | |
515 | |
516 // If no connected devices found as pointing device and keyboard, we try to | |
517 // connect some type-suitable active bluetooth device. | |
518 std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices(); | |
519 for (std::vector<device::BluetoothDevice*>::const_iterator it = | |
520 bt_devices.begin(); | |
521 it != bt_devices.end() && | |
522 (keyboard_device_id_.empty() || pointing_device_id_.empty()); | |
523 ++it) { | |
524 TryPairingAsPointingDevice(*it); | |
525 TryPairingAsKeyboardDevice(*it); | |
526 } | |
527 } | |
528 | |
529 void HIDDetectionScreen::OnStartDiscoverySession( | |
530 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { | |
531 VLOG(1) << "BT Discovery session started"; | |
532 discovery_session_ = discovery_session.Pass(); | |
533 UpdateDevices(); | |
534 } | |
535 | |
536 void HIDDetectionScreen::SetPoweredError() { | |
537 LOG(ERROR) << "Failed to power BT adapter"; | |
538 } | |
539 | |
540 void HIDDetectionScreen::SetPoweredOffError() { | |
541 LOG(ERROR) << "Failed to power off BT adapter"; | |
542 } | |
543 | |
544 void HIDDetectionScreen::FindDevicesError() { | |
545 VLOG(1) << "Failed to start Bluetooth discovery."; | |
546 } | |
547 | |
50 | 548 |
51 } // namespace chromeos | 549 } // namespace chromeos |
OLD | NEW |