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); |
| 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); |
| 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); |
| 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() |
| 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, ""); |
| 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); |
| 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); |
| 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 |