hid_detection_screen_handler.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// found in the LICENSE file. 4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h" 6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/bind.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/command_line.h" 9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/compiler_specific.h" 10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/macros.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/histogram.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/prefs/pref_service.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string16.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/browser_process.h" 17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/pref_names.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/chromeos_switches.h" 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h" 21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "grit/chromium_strings.h" 22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "grit/generated_resources.h" 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace { 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst char kJsScreenPath[] = "login.HIDDetectionScreen"; 28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Variants of pairing state. 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kRemotePinCode[] = "bluetoothRemotePinCode"; 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kRemotePasskey[] = "bluetoothRemotePasskey"; 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Possible ui-states for device-blocks. 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kSearchingState[] = "searching"; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kUSBConnectedState[] = "connected"; 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kBTPairedState[] = "paired"; 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kBTPairingState[] = "pairing"; 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Special state for notifications that don't switch ui-state, but add info. 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kBTUpdateState[] = "update"; 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Names of possible arguments used for ui update. 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kPincodeArgName[] = "pincode"; 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kDeviceNameArgName[] = "name"; 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kLabelArgName[] = "keyboard-label"; 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Standard length of pincode for pairing BT keyboards. 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const int kPincodeLength = 6; 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeviceIsPointing(device::BluetoothDevice::DeviceType device_type) { 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return device_type == device::BluetoothDevice::DEVICE_MOUSE || 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO || 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_TABLET; 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeviceIsPointing(const device::InputServiceLinux::InputDeviceInfo& info) { 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return info.is_mouse || info.is_touchpad || info.is_touchscreen || 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) info.is_tablet; 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeviceIsKeyboard(device::BluetoothDevice::DeviceType device_type) { 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return device_type == device::BluetoothDevice::DEVICE_KEYBOARD || 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO; 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace chromeos { 68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)HIDDetectionScreenHandler::HIDDetectionScreenHandler( 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CoreOobeActor* core_oobe_actor) 71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : BaseScreenHandler(kJsScreenPath), 72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_(NULL), 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) core_oobe_actor_(core_oobe_actor), 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) show_on_init_(false), 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_(false), 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) pointing_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_(false), 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) keyboard_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch_on_adapter_when_ready_(false), 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_(this) { 81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 83a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochHIDDetectionScreenHandler::~HIDDetectionScreenHandler() { 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) adapter_initially_powered_.reset(); 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (adapter_.get()) 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->RemoveObserver(this); 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.RemoveObserver(this); 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (delegate_) 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_->OnActorDestroyed(this); 90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::OnStartDiscoverySession( 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT Discovery session started"; 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) discovery_session_ = discovery_session.Pass(); 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::SetPoweredError() { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(ERROR) << "Failed to power BT adapter"; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void HIDDetectionScreenHandler::SetPoweredOffError() { 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) LOG(ERROR) << "Failed to power off BT adapter"; 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::FindDevicesError() { 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Failed to start Bluetooth discovery."; 109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::Show() { 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!page_is_ready()) { 113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch show_on_init_ = true; 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableDemoMode)) 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch core_oobe_actor_->InitDemoModeDetection(); 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.AddObserver(this); 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateDevices(); 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int num_of_times_dialog_was_shown = local_state->GetInteger( 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefs::kTimesHIDDialogShown); 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) local_state->SetInteger(prefs::kTimesHIDDialogShown, 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) num_of_times_dialog_was_shown + 1); 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ShowScreen(OobeUI::kScreenHIDDetection, NULL); 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!pointing_device_id_.empty()) 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendPointingDeviceNotification(); 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!keyboard_device_id_.empty()) 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::Hide() { 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (adapter_.get()) 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->RemoveObserver(this); 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.RemoveObserver(this); 138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::SetDelegate(Delegate* delegate) { 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_ = delegate; 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (page_is_ready()) 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Initialize(); 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void HIDDetectionScreenHandler::CheckIsScreenRequired( 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Callback<void(bool)>& on_check_done) { 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) input_service_proxy_.GetDevices( 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesListForCheck, 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) on_check_done)); 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::DeclareLocalizedValues( 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch LocalizedValuesBuilder* builder) { 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch builder->Add("hidDetectionContinue", IDS_HID_DETECTION_CONTINUE_BUTTON); 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionInvitation", IDS_HID_DETECTION_INVITATION_TEXT); 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionPrerequisites", 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_PRECONDITION_TEXT); 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionMouseSearching", IDS_HID_DETECTION_SEARCHING_MOUSE); 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionKeyboardSearching", 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_SEARCHING_KEYBOARD); 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionUSBMouseConnected", 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_CONNECTED_USB_MOUSE); 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionUSBKeyboardConnected", 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_CONNECTED_USB_KEYBOARD); 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionBTMousePaired", 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_PAIRED_BLUETOOTH_MOUSE); 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionBTEnterKey", IDS_HID_DETECTION_BLUETOOTH_ENTER_KEY); 170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::Initialize() { 173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!page_is_ready() || !delegate_) 174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapterFactory::GetAdapter( 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::InitializeAdapter, 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (show_on_init_) { 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Show(); 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch show_on_init_ = false; 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::RegisterMessages() { 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddCallback( 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch "HIDDetectionOnContinue", &HIDDetectionScreenHandler::HandleOnContinue); 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 190a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::HandleOnContinue() { 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Continue button pressed. 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ContinueScenarioType scenario_type; 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!pointing_device_id_.empty() && !keyboard_device_id_.empty()) 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scenario_type = All_DEVICES_DETECTED; 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if (pointing_device_id_.empty()) 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scenario_type = KEYBOARD_DEVICE_ONLY_DETECTED; 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scenario_type = POINTING_DEVICE_ONLY_DETECTED; 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "HIDDetection.OOBEDevicesDetectedOnContinuePressed", 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scenario_type, 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CONTINUE_SCENARIO_TYPE_SIZE); 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Switch off BT adapter if it was off before the screen and no BT device 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // connected. 2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (adapter_ && adapter_->IsPresent() && adapter_->IsPowered() && 2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) !(pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH || 2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) && 2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) adapter_initially_powered_ && !(*adapter_initially_powered_)) { 2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) VLOG(1) << "Switching off BT adapter after HID OOBE screen as unused."; 2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) adapter_->SetPowered( 2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) false, 2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&base::DoNothing), 2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::SetPoweredOffError, 2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) core_oobe_actor_->StopDemoModeDetection(); 221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (delegate_) 222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_->OnExit(); 223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::InitializeAdapter( 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<device::BluetoothAdapter> adapter) { 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_ = adapter; 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(adapter_.get()); 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->AddObserver(this); 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::StartBTDiscoverySession() { 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->StartDiscoverySession( 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::OnStartDiscoverySession, 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::FindDevicesError, 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::RequestPinCode( 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "RequestPinCode id = " << device->GetDeviceID() 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->CancelPairing(); 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::RequestPasskey( 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "RequestPassKey id = " << device->GetDeviceID() 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->CancelPairing(); 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DisplayPinCode(device::BluetoothDevice* device, 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& pincode) { 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "DisplayPinCode id = " << device->GetDeviceID() 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue params; 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("state", kBTPairingState); 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pairing-state", kRemotePinCode); 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pincode", pincode); 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString(kDeviceNameArgName, device->GetName()); 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(¶ms); 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DisplayPasskey( 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device, uint32 passkey) { 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID() 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue params; 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("state", kBTPairingState); 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pairing-state", kRemotePasskey); 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetInteger("passkey", passkey); 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string pincode = base::UintToString(passkey); 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pincode = std::string(kPincodeLength - pincode.length(), '0').append(pincode); 278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pincode", pincode); 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString(kDeviceNameArgName, device->GetName()); 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(¶ms); 281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::KeysEntered( 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device, uint32 entered) { 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Keys entered"; 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue params; 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("state", kBTUpdateState); 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetInteger("keysEntered", entered); 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(¶ms); 290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::ConfirmPasskey( 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device, uint32 passkey) { 294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Confirm Passkey"; 295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->CancelPairing(); 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::AuthorizePairing( 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // There is never any circumstance where this will be called, since the 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // HID detection screen handler will only be used for outgoing pairing 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // requests, but play it safe. 303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Authorize pairing"; 304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->ConfirmPairing(); 305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::AdapterPresentChanged( 308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, bool present) { 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (present && switch_on_adapter_when_ready_) { 3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) VLOG(1) << "Switching on BT adapter on HID OOBE screen."; 3116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) adapter_initially_powered_.reset(new bool(adapter_->IsPowered())); 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->SetPowered( 313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true, 314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession, 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::SetPoweredError, 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::TryPairingAsPointingDevice( 322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() && 324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeviceIsPointing(device->GetDeviceType()) && 325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->IsPairable() && !device->IsPaired() && !mouse_is_pairing_) { 326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConnectBTDevice(device); 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::TryPairingAsKeyboardDevice( 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty() && 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeviceIsKeyboard(device->GetDeviceType()) && 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->IsPairable() && !device->IsPaired() && !keyboard_is_pairing_) { 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConnectBTDevice(device); 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DeviceAdded( 340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT input device added id = " << device->GetDeviceID() << 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " name = " << device->GetName(); 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsPointingDevice(device); 344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsKeyboardDevice(device); 345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DeviceChanged( 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " << 350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->GetName(); 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsPointingDevice(device); 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsKeyboardDevice(device); 353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DeviceRemoved( 356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { 357010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " << 358010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->GetName(); 359010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 361010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::OnInputDeviceAdded( 362010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const InputDeviceInfo& info) { 363010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Input device added id = " << info.id << " name = " << info.name; 364010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(merkulova): deal with all available device types, e.g. joystick. 365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!keyboard_device_id_.empty() && !pointing_device_id_.empty()) 366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 367010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() && DeviceIsPointing(info)) { 369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_id_ = info.id; 370010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_name_ = info.name; 371010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_connect_type_ = info.type; 372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendPointingDeviceNotification(); 373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty() && info.is_keyboard) { 375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_id_ = info.id; 376010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_name_ = info.name; 377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_connect_type_ = info.type; 378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 382010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::OnInputDeviceRemoved(const std::string& id) { 383010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (id == keyboard_device_id_) { 384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_id_.clear(); 385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_name_.clear(); 386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; 387010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (id == pointing_device_id_) { 390010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_id_.clear(); 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_name_.clear(); 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendPointingDeviceNotification(); 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) { 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry->RegisterIntegerPref(prefs::kTimesHIDDialogShown, 0); 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 403010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::UpdateDevices() { 404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.GetDevices( 405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesList, 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::UpdateBTDevices() { 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!adapter_ || !adapter_->IsPresent() || !adapter_->IsPowered()) 411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If no connected devices found as pointing device and keyboard, we try to 414010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // connect some type-suitable active bluetooth device. 415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices(); 416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::vector<device::BluetoothDevice*>::const_iterator it = 417010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bt_devices.begin(); 418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != bt_devices.end() && 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (keyboard_device_id_.empty() || pointing_device_id_.empty()); 420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsPointingDevice(*it); 422010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsKeyboardDevice(*it); 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::ProcessConnectedDevicesList( 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::vector<InputDeviceInfo>& devices) { 428010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin(); 429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != devices.end() && 430010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (pointing_device_id_.empty() || keyboard_device_id_.empty()); 431010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 432010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() && DeviceIsPointing(*it)) { 433010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_id_ = it->id; 434010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_name_ = it->name; 435010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_connect_type_ = it->type; 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (page_is_ready()) 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendPointingDeviceNotification(); 438010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 439010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty() && it->is_keyboard) { 440010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_id_ = it->id; 441010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_name_ = it->name; 442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_connect_type_ = it->type; 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (page_is_ready()) 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 445010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 446010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::TryInitiateBTDevicesUpdate() { 450010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((pointing_device_id_.empty() || keyboard_device_id_.empty()) && 451010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_) { 452010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!adapter_->IsPresent()) { 453010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Switch on BT adapter later when it's available. 454010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch_on_adapter_when_ready_ = true; 455010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (!adapter_->IsPowered()) { 4566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) VLOG(1) << "Switching on BT adapter on HID OOBE screen."; 4576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) adapter_initially_powered_.reset(new bool(false)); 458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->SetPowered( 459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true, 460010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession, 461010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 462010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::SetPoweredError, 463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateBTDevices(); 466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void HIDDetectionScreenHandler::OnGetInputDevicesListForCheck( 4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Callback<void(bool)>& on_check_done, 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<InputDeviceInfo>& devices) { 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessConnectedDevicesList(devices); 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Screen is not required if both devices are present. 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool all_devices_autodetected = !pointing_device_id_.empty() && 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !keyboard_device_id_.empty(); 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("HIDDetection.OOBEDialogShown", 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !all_devices_autodetected); 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) on_check_done.Run(!all_devices_autodetected); 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::OnGetInputDevicesList( 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<InputDeviceInfo>& devices) { 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessConnectedDevicesList(devices); 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TryInitiateBTDevicesUpdate(); 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 490010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::ConnectBTDevice( 491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!device->IsPairable() || device->IsPaired()) 493010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 494010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DeviceType device_type = device->GetDeviceType(); 495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 496010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (device_type == device::BluetoothDevice::DEVICE_MOUSE || 497010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_TABLET) { 498010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mouse_is_pairing_) 499010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = true; 501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (device_type == device::BluetoothDevice::DEVICE_KEYBOARD) { 502010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_is_pairing_) 503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = true; 505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (device_type == 506010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO) { 507010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mouse_is_pairing_ || keyboard_is_pairing_) 508010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 509010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = true; 510010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = true; 511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 512010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->Connect(this, 513010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::BTConnected, 514010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), device_type), 515010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::BTConnectError, 516010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 517010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->GetAddress(), device_type)); 518010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 519010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::BTConnected( 521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DeviceType device_type) { 522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (DeviceIsPointing(device_type)) 523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = false; 524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (DeviceIsKeyboard(device_type)) 525010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = false; 526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::BTConnectError( 529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& address, 530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DeviceType device_type, 531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::ConnectErrorCode error_code) { 532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(WARNING) << "BTConnectError while connecting " << address 533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " error code = " << error_code; 534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (DeviceIsPointing(device_type)) 535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = false; 536f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (DeviceIsKeyboard(device_type)) { 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = false; 538f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SendKeyboardDeviceNotification(NULL); 539f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() || keyboard_device_id_.empty()) 542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::SendPointingDeviceNotification() { 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string state; 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty()) 549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state = kSearchingState; 550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else if (pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) 551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state = kBTPairedState; 552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state = kUSBConnectedState; 554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CallJS("setPointingDeviceState", state); 555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::SendKeyboardDeviceNotification( 558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue* params) { 559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue state_info; 560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params) 561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.MergeDictionary(params); 562010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::string16 device_name; 564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!state_info.GetString(kDeviceNameArgName, &device_name)) { 565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_name = l10n_util::GetStringUTF16( 566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME); 567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty()) { 570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!state_info.HasKey("state")) { 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString("state", kSearchingState); 572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (state_info.HasKey(kPincodeArgName)) { 573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString( 574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kLabelArgName, 575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) l10n_util::GetStringFUTF16( 576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST, 577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_name)); 578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) { 580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString("state", kBTPairedState); 581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString( 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kLabelArgName, 583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) l10n_util::GetStringFUTF16( 584010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD, 585010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::UTF8ToUTF16(keyboard_device_name_))); 586010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 587010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString("state", kUSBConnectedState); 588010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 589010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CallJS("setKeyboardDeviceState", state_info); 590010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 591010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 592a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace chromeos 593