hid_detection_screen_handler.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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" 8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/compiler_specific.h" 9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/macros.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/histogram.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/prefs/pref_service.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string16.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/browser_process.h" 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/pref_names.h" 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h" 19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "grit/chromium_strings.h" 20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "grit/generated_resources.h" 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace { 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst char kJsScreenPath[] = "login.HIDDetectionScreen"; 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Variants of pairing state. 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kRemotePinCode[] = "bluetoothRemotePinCode"; 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kRemotePasskey[] = "bluetoothRemotePasskey"; 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Possible ui-states for device-blocks. 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kSearchingState[] = "searching"; 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kUSBConnectedState[] = "connected"; 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kBTPairedState[] = "paired"; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kBTPairingState[] = "pairing"; 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Special state for notifications that don't switch ui-state, but add info. 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kBTUpdateState[] = "update"; 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Names of possible arguments used for ui update. 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kPincodeArgName[] = "pincode"; 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kDeviceNameArgName[] = "name"; 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kLabelArgName[] = "keyboard-label"; 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Standard length of pincode for pairing BT keyboards. 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const int kPincodeLength = 6; 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeviceIsPointing(device::BluetoothDevice::DeviceType device_type) { 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return device_type == device::BluetoothDevice::DEVICE_MOUSE || 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO || 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_TABLET; 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeviceIsPointing(const device::InputServiceLinux::InputDeviceInfo& info) { 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return info.is_mouse || info.is_touchpad || info.is_touchscreen || 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) info.is_tablet; 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeviceIsKeyboard(device::BluetoothDevice::DeviceType device_type) { 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return device_type == device::BluetoothDevice::DEVICE_KEYBOARD || 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO; 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace 64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace chromeos { 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)HIDDetectionScreenHandler::HIDDetectionScreenHandler( 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CoreOobeActor* core_oobe_actor) 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : BaseScreenHandler(kJsScreenPath), 70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_(NULL), 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) core_oobe_actor_(core_oobe_actor), 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) show_on_init_(false), 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_(false), 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_(false), 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch_on_adapter_when_ready_(false), 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) first_time_screen_show_(true), 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_(this) { 78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 80a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochHIDDetectionScreenHandler::~HIDDetectionScreenHandler() { 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (adapter_.get()) 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->RemoveObserver(this); 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.RemoveObserver(this); 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (delegate_) 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_->OnActorDestroyed(this); 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::OnStartDiscoverySession( 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT Discovery session started"; 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) discovery_session_ = discovery_session.Pass(); 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::SetPoweredError() { 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(ERROR) << "Failed to power BT adapter"; 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::FindDevicesError() { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Failed to start Bluetooth discovery."; 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::Show() { 104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!page_is_ready()) { 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch show_on_init_ = true; 106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) core_oobe_actor_->InitDemoModeDetection(); 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.AddObserver(this); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) first_time_screen_show_ = true; 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetDevicesFirstTime(); 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ShowScreen(OobeUI::kScreenHIDDetection, NULL); 113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::Hide() { 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (adapter_.get()) 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->RemoveObserver(this); 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.RemoveObserver(this); 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::SetDelegate(Delegate* delegate) { 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_ = delegate; 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (page_is_ready()) 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Initialize(); 125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::DeclareLocalizedValues( 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch LocalizedValuesBuilder* builder) { 129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch builder->Add("hidDetectionContinue", IDS_HID_DETECTION_CONTINUE_BUTTON); 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionInvitation", IDS_HID_DETECTION_INVITATION_TEXT); 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionPrerequisites", 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_PRECONDITION_TEXT); 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionMouseSearching", IDS_HID_DETECTION_SEARCHING_MOUSE); 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionKeyboardSearching", 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_SEARCHING_KEYBOARD); 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionUSBMouseConnected", 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_CONNECTED_USB_MOUSE); 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionUSBKeyboardConnected", 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_CONNECTED_USB_KEYBOARD); 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionBTMousePaired", 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_PAIRED_BLUETOOTH_MOUSE); 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) builder->Add("hidDetectionBTEnterKey", IDS_HID_DETECTION_BLUETOOTH_ENTER_KEY); 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::Initialize() { 146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!page_is_ready() || !delegate_) 147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapterFactory::GetAdapter( 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::InitializeAdapter, 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (show_on_init_) { 154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Show(); 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch show_on_init_ = false; 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::RegisterMessages() { 160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddCallback( 161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch "HIDDetectionOnContinue", &HIDDetectionScreenHandler::HandleOnContinue); 162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HIDDetectionScreenHandler::HandleOnContinue() { 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!first_time_screen_show_) { 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Continue button pressed. 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ContinueScenarioType scenario_type; 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!pointing_device_id_.empty() && !keyboard_device_id_.empty()) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scenario_type = All_DEVICES_DETECTED; 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else if (pointing_device_id_.empty()) 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scenario_type = KEYBOARD_DEVICE_ONLY_DETECTED; 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scenario_type = POINTING_DEVICE_ONLY_DETECTED; 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "HIDDetection.OOBEDevicesDetectedOnContinuePressed", 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scenario_type, 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CONTINUE_SCENARIO_TYPE_SIZE); 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) core_oobe_actor_->StopDemoModeDetection(); 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (delegate_) 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch delegate_->OnExit(); 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::InitializeAdapter( 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<device::BluetoothAdapter> adapter) { 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_ = adapter; 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(adapter_.get()); 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->AddObserver(this); 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::StartBTDiscoverySession() { 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->StartDiscoverySession( 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::OnStartDiscoverySession, 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::FindDevicesError, 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::RequestPinCode( 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "RequestPinCode id = " << device->GetDeviceID() 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->CancelPairing(); 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::RequestPasskey( 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "RequestPassKey id = " << device->GetDeviceID() 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->CancelPairing(); 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DisplayPinCode(device::BluetoothDevice* device, 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& pincode) { 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "DisplayPinCode id = " << device->GetDeviceID() 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue params; 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("state", kBTPairingState); 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pairing-state", kRemotePinCode); 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pincode", pincode); 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString(kDeviceNameArgName, device->GetName()); 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(¶ms); 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DisplayPasskey( 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device, uint32 passkey) { 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID() 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " name = " << device->GetName(); 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue params; 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("state", kBTPairingState); 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pairing-state", kRemotePasskey); 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetInteger("passkey", passkey); 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string pincode = base::UintToString(passkey); 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pincode = std::string(kPincodeLength - pincode.length(), '0').append(pincode); 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("pincode", pincode); 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString(kDeviceNameArgName, device->GetName()); 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(¶ms); 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::KeysEntered( 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device, uint32 entered) { 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Keys entered"; 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue params; 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetString("state", kBTUpdateState); 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) params.SetInteger("keysEntered", entered); 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(¶ms); 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::ConfirmPasskey( 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device, uint32 passkey) { 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Confirm Passkey"; 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->CancelPairing(); 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::AuthorizePairing( 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // There is never any circumstance where this will be called, since the 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // HID detection screen handler will only be used for outgoing pairing 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // requests, but play it safe. 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Authorize pairing"; 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->ConfirmPairing(); 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::AdapterPresentChanged( 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, bool present) { 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (present && switch_on_adapter_when_ready_) { 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->SetPowered( 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true, 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession, 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::SetPoweredError, 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::TryPairingAsPointingDevice( 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() && 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeviceIsPointing(device->GetDeviceType()) && 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->IsPairable() && !device->IsPaired() && !mouse_is_pairing_) { 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConnectBTDevice(device); 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::TryPairingAsKeyboardDevice( 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty() && 291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeviceIsKeyboard(device->GetDeviceType()) && 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->IsPairable() && !device->IsPaired() && !keyboard_is_pairing_) { 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConnectBTDevice(device); 294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DeviceAdded( 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT input device added id = " << device->GetDeviceID() << 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " name = " << device->GetName(); 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsPointingDevice(device); 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsKeyboardDevice(device); 303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DeviceChanged( 306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { 307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " << 308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->GetName(); 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsPointingDevice(device); 310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsKeyboardDevice(device); 311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::DeviceRemoved( 314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " << 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->GetName(); 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::OnInputDeviceAdded( 320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const InputDeviceInfo& info) { 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VLOG(1) << "Input device added id = " << info.id << " name = " << info.name; 322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(merkulova): deal with all available device types, e.g. joystick. 323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!keyboard_device_id_.empty() && !pointing_device_id_.empty()) 324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() && DeviceIsPointing(info)) { 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_id_ = info.id; 328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_name_ = info.name; 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_connect_type_ = info.type; 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendPointingDeviceNotification(); 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty() && info.is_keyboard) { 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_id_ = info.id; 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_name_ = info.name; 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_connect_type_ = info.type; 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::OnInputDeviceRemoved(const std::string& id) { 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (id == keyboard_device_id_) { 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_id_.clear(); 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_name_.clear(); 344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; 345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (id == pointing_device_id_) { 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_id_.clear(); 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_name_.clear(); 350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendPointingDeviceNotification(); 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) { 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry->RegisterIntegerPref(prefs::kTimesHIDDialogShown, 0); 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::GetDevicesFirstTime() { 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_service_proxy_.GetDevices( 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesListFirstTime, 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 367010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::UpdateDevices() { 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_service_proxy_.GetDevices( 369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesList, 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 371010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::UpdateBTDevices() { 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!adapter_ || !adapter_->IsPresent() || !adapter_->IsPowered()) 375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 376010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If no connected devices found as pointing device and keyboard, we try to 378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // connect some type-suitable active bluetooth device. 379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices(); 380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::vector<device::BluetoothDevice*>::const_iterator it = 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bt_devices.begin(); 382010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != bt_devices.end() && 383010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (keyboard_device_id_.empty() || pointing_device_id_.empty()); 384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsPointingDevice(*it); 386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TryPairingAsKeyboardDevice(*it); 387010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::ProcessConnectedDevicesList( 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::vector<InputDeviceInfo>& devices) { 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin(); 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != devices.end() && 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (pointing_device_id_.empty() || keyboard_device_id_.empty()); 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() && DeviceIsPointing(*it)) { 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_id_ = it->id; 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_name_ = it->name; 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pointing_device_connect_type_ = it->type; 400010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendPointingDeviceNotification(); 401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty() && it->is_keyboard) { 403010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_id_ = it->id; 404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_name_ = it->name; 405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_device_connect_type_ = it->type; 406010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendKeyboardDeviceNotification(NULL); 407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::TryInitiateBTDevicesUpdate() { 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((pointing_device_id_.empty() || keyboard_device_id_.empty()) && 413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_) { 414010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!adapter_->IsPresent()) { 415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Switch on BT adapter later when it's available. 416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch_on_adapter_when_ready_ = true; 417010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (!adapter_->IsPowered()) { 418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) adapter_->SetPowered( 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true, 420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession, 421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 422010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::SetPoweredError, 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateBTDevices(); 426010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 428010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::OnGetInputDevicesListFirstTime( 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<InputDeviceInfo>& devices) { 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessConnectedDevicesList(devices); 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Skip screen if both devices are present. 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool all_devices_autodetected = !pointing_device_id_.empty() && 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !keyboard_device_id_.empty(); 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("HIDDetection.OOBEDialogShown", 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !all_devices_autodetected); 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (all_devices_autodetected) { 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HandleOnContinue(); 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int num_of_times_dialog_was_shown = local_state->GetInteger( 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefs::kTimesHIDDialogShown); 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) local_state->SetInteger(prefs::kTimesHIDDialogShown, 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) num_of_times_dialog_was_shown + 1); 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) first_time_screen_show_ = false; 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TryInitiateBTDevicesUpdate(); 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HIDDetectionScreenHandler::OnGetInputDevicesList( 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<InputDeviceInfo>& devices) { 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessConnectedDevicesList(devices); 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TryInitiateBTDevicesUpdate(); 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::ConnectBTDevice( 460010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice* device) { 461010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!device->IsPairable() || device->IsPaired()) 462010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DeviceType device_type = device->GetDeviceType(); 464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (device_type == device::BluetoothDevice::DEVICE_MOUSE || 466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_type == device::BluetoothDevice::DEVICE_TABLET) { 467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mouse_is_pairing_) 468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = true; 470010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (device_type == device::BluetoothDevice::DEVICE_KEYBOARD) { 471010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_is_pairing_) 472010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = true; 474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (device_type == 475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO) { 476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mouse_is_pairing_ || keyboard_is_pairing_) 477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = true; 479010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = true; 480010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->Connect(this, 482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::BTConnected, 483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), device_type), 484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HIDDetectionScreenHandler::BTConnectError, 485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device->GetAddress(), device_type)); 487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 488010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 489010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::BTConnected( 490010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DeviceType device_type) { 491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (DeviceIsPointing(device_type)) 492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = false; 493010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (DeviceIsKeyboard(device_type)) 494010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = false; 495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 496010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 497010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::BTConnectError( 498010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& address, 499010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::DeviceType device_type, 500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device::BluetoothDevice::ConnectErrorCode error_code) { 501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(WARNING) << "BTConnectError while connecting " << address 502010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << " error code = " << error_code; 503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (DeviceIsPointing(device_type)) 504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_is_pairing_ = false; 505f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (DeviceIsKeyboard(device_type)) { 506010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keyboard_is_pairing_ = false; 507f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SendKeyboardDeviceNotification(NULL); 508f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 509010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 510010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty() || keyboard_device_id_.empty()) 511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateDevices(); 512010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 513010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 514010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 515010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::SendPointingDeviceNotification() { 516010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string state; 517010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pointing_device_id_.empty()) 518010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state = kSearchingState; 519010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else if (pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) 520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state = kBTPairedState; 521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state = kUSBConnectedState; 523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CallJS("setPointingDeviceState", state); 524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 525010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void HIDDetectionScreenHandler::SendKeyboardDeviceNotification( 527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue* params) { 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue state_info; 529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params) 530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.MergeDictionary(params); 531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::string16 device_name; 533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!state_info.GetString(kDeviceNameArgName, &device_name)) { 534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_name = l10n_util::GetStringUTF16( 535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME); 536010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard_device_id_.empty()) { 539010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!state_info.HasKey("state")) { 540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString("state", kSearchingState); 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (state_info.HasKey(kPincodeArgName)) { 542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString( 543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kLabelArgName, 544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) l10n_util::GetStringFUTF16( 545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST, 546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) device_name)); 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) { 549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString("state", kBTPairedState); 550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString( 551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kLabelArgName, 552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) l10n_util::GetStringFUTF16( 553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD, 554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::UTF8ToUTF16(keyboard_device_name_))); 555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_info.SetString("state", kUSBConnectedState); 557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CallJS("setKeyboardDeviceState", state_info); 559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 561a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace chromeos 562