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