| 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" | |
| 11 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" | 7 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" |
| 12 #include "chrome/browser/chromeos/login/screens/hid_detection_view.h" | |
| 13 #include "chrome/browser/chromeos/login/wizard_controller.h" | 8 #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 | |
| 46 | 9 |
| 47 namespace chromeos { | 10 namespace chromeos { |
| 48 | 11 |
| 49 HIDDetectionScreen::HIDDetectionScreen(BaseScreenDelegate* base_screen_delegate, | 12 HIDDetectionScreen::HIDDetectionScreen(BaseScreenDelegate* base_screen_delegate, |
| 50 HIDDetectionView* view) | 13 HIDDetectionScreenActor* actor) |
| 51 : HIDDetectionModel(base_screen_delegate), | 14 : BaseScreen(base_screen_delegate), actor_(actor) { |
| 52 view_(view), | 15 DCHECK(actor_); |
| 53 mouse_is_pairing_(false), | 16 if (actor_) |
| 54 pointing_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), | 17 actor_->SetDelegate(this); |
| 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 | |
| 64 } | 18 } |
| 65 | 19 |
| 66 HIDDetectionScreen::~HIDDetectionScreen() { | 20 HIDDetectionScreen::~HIDDetectionScreen() { |
| 67 adapter_initially_powered_.reset(); | 21 if (actor_) |
| 68 input_service_proxy_.RemoveObserver(this); | 22 actor_->SetDelegate(NULL); |
| 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); | |
| 76 } | 23 } |
| 77 | 24 |
| 78 void HIDDetectionScreen::PrepareToShow() { | 25 void HIDDetectionScreen::PrepareToShow() { |
| 79 if (view_) | |
| 80 view_->PrepareToShow(); | |
| 81 } | 26 } |
| 82 | 27 |
| 83 void HIDDetectionScreen::Show() { | 28 void HIDDetectionScreen::Show() { |
| 84 showing_ = true; | 29 if (actor_) |
| 85 GetContextEditor().SetBoolean(kContextKeyNumKeysEnteredExpected, false); | 30 actor_->Show(); |
| 86 SendPointingDeviceNotification(); | |
| 87 SendKeyboardDeviceNotification(); | |
| 88 | |
| 89 input_service_proxy_.AddObserver(this); | |
| 90 UpdateDevices(); | |
| 91 | |
| 92 if (view_) | |
| 93 view_->Show(); | |
| 94 } | 31 } |
| 95 | 32 |
| 96 void HIDDetectionScreen::Hide() { | 33 void HIDDetectionScreen::Hide() { |
| 97 showing_ = false; | 34 if (actor_) |
| 98 input_service_proxy_.RemoveObserver(this); | 35 actor_->Hide(); |
| 99 if (discovery_session_.get()) | |
| 100 discovery_session_->Stop(base::Bind(&base::DoNothing), | |
| 101 base::Bind(&base::DoNothing)); | |
| 102 if (view_) | |
| 103 view_->Hide(); | |
| 104 } | 36 } |
| 105 | 37 |
| 106 void HIDDetectionScreen::Initialize(::login::ScreenContext* context) { | 38 std::string HIDDetectionScreen::GetName() const { |
| 107 HIDDetectionModel::Initialize(context); | 39 return WizardController::kHIDDetectionScreenName; |
| 108 | |
| 109 device::BluetoothAdapterFactory::GetAdapter( | |
| 110 base::Bind(&HIDDetectionScreen::InitializeAdapter, | |
| 111 weak_ptr_factory_.GetWeakPtr())); | |
| 112 } | 40 } |
| 113 | 41 |
| 114 void HIDDetectionScreen::OnContinueButtonClicked() { | 42 void HIDDetectionScreen::OnExit() { |
| 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 | |
| 147 Finish(BaseScreenDelegate::HID_DETECTION_COMPLETED); | 43 Finish(BaseScreenDelegate::HID_DETECTION_COMPLETED); |
| 148 } | 44 } |
| 149 | 45 |
| 150 void HIDDetectionScreen::CheckIsScreenRequired( | 46 void HIDDetectionScreen::OnActorDestroyed(HIDDetectionScreenActor* actor) { |
| 151 const base::Callback<void(bool)>& on_check_done) { | 47 if (actor_ == actor) |
| 152 input_service_proxy_.GetDevices( | 48 actor_ = NULL; |
| 153 base::Bind(&HIDDetectionScreen::OnGetInputDevicesListForCheck, | |
| 154 weak_ptr_factory_.GetWeakPtr(), | |
| 155 on_check_done)); | |
| 156 } | 49 } |
| 157 | 50 |
| 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 | |
| 548 | |
| 549 } // namespace chromeos | 51 } // namespace chromeos |
| OLD | NEW |