Chromium Code Reviews| Index: chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc |
| diff --git a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc |
| index a2a26b51c9d388b45c3dc5e02a6d186914254b25..1220a77aef67fd85bbb08532282a88ac72b7eab3 100644 |
| --- a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc |
| +++ b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc |
| @@ -4,16 +4,51 @@ |
| #include "chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h" |
| +#include "base/bind.h" |
| #include "base/compiler_specific.h" |
| #include "base/macros.h" |
| +#include "base/strings/utf_string_conversions.h" |
| +#include "chrome/browser/chromeos/device/input_service_proxy.h" |
|
ygorshenin1
2014/04/24 11:30:24
Not needed here.
merkulova
2014/04/24 12:49:46
Done.
|
| #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" |
| +#include "device/bluetooth/bluetooth_adapter.h" |
|
ygorshenin1
2014/04/24 11:30:24
Not needed here.
merkulova
2014/04/24 12:49:46
Done.
|
| +#include "device/bluetooth/bluetooth_adapter_factory.h" |
| +#include "device/bluetooth/bluetooth_device.h" |
|
ygorshenin1
2014/04/24 11:30:24
Not needed here.
merkulova
2014/04/24 12:49:46
Done.
|
| #include "grit/chromium_strings.h" |
| #include "grit/generated_resources.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| namespace { |
| const char kJsScreenPath[] = "login.HIDDetectionScreen"; |
| +// |UpdateDeviceCallback| takes a variable length list as an argument. The |
| +// value stored in each list element is indicated by the following constants. |
| +const int kUpdateDeviceAddressIndex = 0; |
| +const int kUpdateDeviceCommandIndex = 1; |
| +const int kUpdateDeviceAuthTokenIndex = 2; |
| + |
| +// |UpdateDeviceCallback| provides a command value of one of the following |
| +// constants that indicates what update it is providing to us. |
| +const char kConnectCommand[] = "connect"; |
| +const char kCancelCommand[] = "cancel"; |
| +const char kAcceptCommand[] = "accept"; |
| +const char kRejectCommand[] = "reject"; |
| +const char kDisconnectCommand[] = "disconnect"; |
| +const char kForgetCommand[] = "forget"; |
| + |
| +// |SendDeviceNotification| may include a pairing parameter whose value |
| +// is one of the following constants instructing the UI to perform a certain |
| +// action. |
| +const char kStartConnecting[] = "bluetoothStartConnecting"; |
| +const char kEnterPinCode[] = "bluetoothEnterPinCode"; |
| +const char kEnterPasskey[] = "bluetoothEnterPasskey"; |
| +const char kRemotePinCode[] = "bluetoothRemotePinCode"; |
| +const char kRemotePasskey[] = "bluetoothRemotePasskey"; |
| +const char kConfirmPasskey[] = "bluetoothConfirmPasskey"; |
| + |
| +// An invalid |entered| value to represent the "undefined" value. |
| +const int kInvalidEntered = 0xFFFF; |
| + |
| } // namespace |
| namespace chromeos { |
| @@ -21,15 +56,35 @@ namespace chromeos { |
| HIDDetectionScreenHandler::HIDDetectionScreenHandler() |
| : BaseScreenHandler(kJsScreenPath), |
| delegate_(NULL), |
| - show_on_init_(false) { |
| + show_on_init_(false), |
| + adapter_(NULL), |
|
ygorshenin1
2014/04/24 11:30:24
scoped_refptr is initialized to nullptr automatica
merkulova
2014/04/24 12:49:46
Done.
|
| + pairing_device_passkey_(1000000), |
|
ygorshenin1
2014/04/24 11:30:24
Where this field is used?
merkulova
2014/04/24 12:49:46
Removed
|
| + pairing_device_entered_(kInvalidEntered), |
|
ygorshenin1
2014/04/24 11:30:24
Where this field is used?
merkulova
2014/04/24 12:49:46
Removed
|
| + keyboard_is_connecting_(false), |
| + weak_ptr_factory_(this) { |
| + pointing_device_id_.clear(); |
| + keyboard_device_id_.clear(); |
| } |
| HIDDetectionScreenHandler::~HIDDetectionScreenHandler() { |
| + if (adapter_.get()) |
| + adapter_->RemoveObserver(this); |
| + input_service_proxy_.RemoveObserver(this); |
| if (delegate_) |
| delegate_->OnActorDestroyed(this); |
| } |
| -void HIDDetectionScreenHandler::PrepareToShow() { |
| +void HIDDetectionScreenHandler::PrepareToShow() {} |
| + |
| +void HIDDetectionScreenHandler::OnStartDiscoverySession( |
| + scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { |
| + VLOG(1) << "BT Discovery session started"; |
| + discovery_session_ = discovery_session.Pass(); |
| + UpdateDevices(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::FindDevicesError() { |
| + VLOG(1) << "Failed to start Bluetooth discovery."; |
| } |
| void HIDDetectionScreenHandler::Show() { |
| @@ -37,10 +92,15 @@ void HIDDetectionScreenHandler::Show() { |
| show_on_init_ = true; |
| return; |
| } |
| + input_service_proxy_.AddObserver(this); |
| + UpdateDevices(/*true*/false /*skip screen if devices present*/); |
|
Nikita (slow)
2014/04/24 12:22:45
Debug code?
merkulova
2014/04/24 12:49:46
Removed
|
| ShowScreen(OobeUI::kScreenHIDDetection, NULL); |
| } |
| void HIDDetectionScreenHandler::Hide() { |
| + if (adapter_.get()) |
| + adapter_->RemoveObserver(this); |
| + input_service_proxy_.RemoveObserver(this); |
| } |
| void HIDDetectionScreenHandler::SetDelegate(Delegate* delegate) { |
| @@ -52,12 +112,31 @@ void HIDDetectionScreenHandler::SetDelegate(Delegate* delegate) { |
| void HIDDetectionScreenHandler::DeclareLocalizedValues( |
| LocalizedValuesBuilder* builder) { |
| builder->Add("hidDetectionContinue", IDS_HID_DETECTION_CONTINUE_BUTTON); |
| + builder->Add("hidDetectionInvitation", IDS_HID_DETECTION_INVITATION_TEXT); |
| + builder->Add("hidDetectionPrerequisites", |
| + IDS_HID_DETECTION_PRECONDITION_TEXT); |
| + builder->Add("hidDetectionMouseSearching", IDS_HID_DETECTION_SEARCHING_MOUSE); |
| + builder->Add("hidDetectionKeyboardSearching", |
| + IDS_HID_DETECTION_SEARCHING_KEYBOARD); |
| + builder->Add("hidDetectionUSBMouseConnected", |
| + IDS_HID_DETECTION_CONNECTED_USB_MOUSE); |
| + builder->Add("hidDetectionUSBKeyboardConnected", |
| + IDS_HID_DETECTION_CONNECTED_USB_KEYBOARD); |
| + builder->Add("hidDetectionBTMousePaired", |
| + IDS_HID_DETECTION_PAIRED_BLUETOOTH_MOUSE); |
| + builder->Add("hidDetectionBTKeyboardPaired", |
| + IDS_HID_DETECTION_PAIRED_BLUETOOTH_MOUSE); |
| + builder->Add("hidDetectionBTEnterKey", IDS_HID_DETECTION_BLUETOOTH_ENTER_KEY); |
| } |
| void HIDDetectionScreenHandler::Initialize() { |
| if (!page_is_ready() || !delegate_) |
| return; |
| + device::BluetoothAdapterFactory::GetAdapter( |
| + base::Bind(&HIDDetectionScreenHandler::InitializeAdapter, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + |
| if (show_on_init_) { |
| Show(); |
| show_on_init_ = false; |
| @@ -74,4 +153,265 @@ void HIDDetectionScreenHandler::HandleOnContinue() { |
| delegate_->OnExit(); |
| } |
| +void HIDDetectionScreenHandler::InitializeAdapter( |
| + scoped_refptr<device::BluetoothAdapter> adapter) { |
| + adapter_ = adapter; |
| + CHECK(adapter_.get()); |
| + adapter_->SetPowered( |
| + true, |
| + base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession, |
| + weak_ptr_factory_.GetWeakPtr()), |
| + base::Bind(&HIDDetectionScreenHandler::FindDevicesError, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + |
| + adapter_->AddObserver(this); |
| +} |
| + |
| +void HIDDetectionScreenHandler::StartBTDiscoverySession() { |
| + adapter_->StartDiscoverySession( |
| + base::Bind(&HIDDetectionScreenHandler::OnStartDiscoverySession, |
| + weak_ptr_factory_.GetWeakPtr()), |
| + base::Bind(&HIDDetectionScreenHandler::FindDevicesError, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + |
| +} |
| + |
| +void HIDDetectionScreenHandler::RequestPinCode( |
| + device::BluetoothDevice* device) { |
| + VLOG(1) << "RequestPinCode id = " << device->GetDeviceID() << " name = " << |
|
Nikita (slow)
2014/04/24 12:22:45
nit: More readable:
VLOG(1) << "RequestPinCode i
merkulova
2014/04/24 12:49:46
Done.
|
| + device->GetName(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::RequestPasskey( |
| + device::BluetoothDevice* device) { |
| + VLOG(1) << "RequestPassKey id = " << device->GetDeviceID() << " name = " << |
| + device->GetName(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::DisplayPinCode(device::BluetoothDevice* device, |
| + const std::string& pincode) { |
| + VLOG(1) << "DisplayPinCode id = " << device->GetDeviceID() << " name = " << |
| + device->GetName(); |
| + base::DictionaryValue params; |
| + params.SetString("pairing", kRemotePinCode); |
|
Nikita (slow)
2014/04/24 12:22:45
nit: Extract string constants into unnamed namespa
merkulova
2014/04/24 12:49:46
Done.
|
| + params.SetString("pincode", pincode); |
| + SendKeyboardDeviceNotification(¶ms); |
| +} |
| + |
| +void HIDDetectionScreenHandler::DisplayPasskey( |
| + device::BluetoothDevice* device, uint32 passkey) { |
| + VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID() << " name = " << |
|
ygorshenin1
2014/04/24 11:30:24
Add "// TODO" comment + NOTIMPLEMENTED() to all me
merkulova
2014/04/24 12:49:46
Done.
|
| + device->GetName(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::KeysEntered( |
| + device::BluetoothDevice* device, uint32 entered) { |
| + VLOG(1) << "Keys entered"; |
| +} |
| + |
| +void HIDDetectionScreenHandler::ConfirmPasskey( |
| + device::BluetoothDevice* device, uint32 passkey) { |
| + VLOG(1) << "Confirm Passkey"; |
| +} |
| + |
| +void HIDDetectionScreenHandler::AuthorizePairing( |
| + device::BluetoothDevice* device) { |
| + // There is never any circumstance where this will be called, since the |
| + // HID detection screen handler will only be used for outgoing pairing |
| + // requests, but play it safe. |
| + VLOG(1) << "Authorize pairing"; |
| + device->ConfirmPairing(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::DeviceAdded( |
| + device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { |
| + VLOG(1) << "BT input device added id = " << device->GetDeviceID() << |
| + " name = " << device->GetName(); |
| + if (pointing_device_id_.empty() && |
| + device->GetDeviceType() == device::BluetoothDevice::DEVICE_MOUSE) { |
| + ConnectBTDevice(device); |
| + } |
| + if (keyboard_device_id_.empty() && |
| + device->GetDeviceType() == device::BluetoothDevice::DEVICE_KEYBOARD) { |
| + ConnectBTDevice(device); |
| + } |
| +} |
| + |
| +void HIDDetectionScreenHandler::DeviceChanged( |
| + device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { |
| + VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " << |
| + device->GetName(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::DeviceRemoved( |
| + device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { |
| + VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " << |
| + device->GetName(); |
| +} |
| + |
| +void HIDDetectionScreenHandler::OnInputDeviceAdded( |
| + const InputDeviceInfo& info) { |
| + VLOG(1) << "Input device added id = " << info.id << " name = " << info.name; |
| + // TODO(merkulova): deal with all available device types. |
| + if (!keyboard_device_id_.empty() && !pointing_device_id_.empty()) |
| + return; |
| + |
| + if (pointing_device_id_.empty() && (info.is_mouse || info.is_touchpad)) { |
| + pointing_device_id_ = info.id; |
| + pointing_device_name_ = info.name; |
| + pointing_device_connect_type_ = info.type; |
| + SendPointingDeviceNotification(); |
| + } else if (keyboard_device_id_.empty() && info.is_keyboard) { |
| + keyboard_device_id_ = info.id; |
| + keyboard_device_name_ = info.name; |
| + keyboard_device_connect_type_ = info.type; |
| + SendKeyboardDeviceNotification(NULL); |
| + } |
| +} |
| + |
| +void HIDDetectionScreenHandler::OnInputDeviceRemoved(const std::string& id) { |
| + if (id == keyboard_device_id_) { |
| + keyboard_device_id_.clear(); |
| + keyboard_device_name_.clear(); |
| + keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; |
| + SendKeyboardDeviceNotification(NULL); |
| + UpdateDevices(); |
| + } else if (id == pointing_device_id_) { |
| + pointing_device_id_.clear(); |
| + pointing_device_name_.clear(); |
| + pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN; |
| + SendPointingDeviceNotification(); |
| + UpdateDevices(); |
| + } |
| +} |
| + |
| +void HIDDetectionScreenHandler::UpdateDevices(bool skipScreenIfDevicesPresent) { |
|
ygorshenin1
2014/04/24 11:30:24
Use unix_hacker_style instead of camelCaseStyle fo
merkulova
2014/04/24 12:49:46
Done.
|
| + input_service_proxy_.GetDevices( |
| + base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesList, |
| + base::Unretained(this), |
| + skipScreenIfDevicesPresent)); |
| +} |
| + |
| +void HIDDetectionScreenHandler::OnGetInputDevicesList( |
| + bool skipScreenIfDevicesPresent, |
| + const std::vector<InputDeviceInfo>& devices) { |
| + |
|
Nikita (slow)
2014/04/24 12:22:45
nit: Drop empty line.
merkulova
2014/04/24 12:49:46
Done.
|
| + for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin(); |
| + it != devices.end() && |
| + (pointing_device_id_.empty() || keyboard_device_id_.empty()); |
| + it++) { |
|
ygorshenin1
2014/04/24 11:30:24
nit: use ++it when |it| is an iterator.
merkulova
2014/04/24 12:49:46
Done.
|
| + if (pointing_device_id_.empty() && (it->is_mouse || it->is_touchpad)) { |
| + pointing_device_id_ = it->id; |
| + pointing_device_name_ = it->name; |
| + pointing_device_connect_type_ = it->type; |
| + SendPointingDeviceNotification(); |
| + } |
| + if (keyboard_device_id_.empty() && it->is_keyboard) { |
| + keyboard_device_id_ = it->id; |
| + keyboard_device_name_ = it->name; |
| + keyboard_device_connect_type_ = it->type; |
| + SendKeyboardDeviceNotification(NULL); |
| + } |
| + } |
| + if (adapter_ && |
|
Nikita (slow)
2014/04/24 12:22:45
nit: Add short comment for this block.
merkulova
2014/04/24 12:49:46
Done.
|
| + (pointing_device_id_.empty() || keyboard_device_id_.empty())) { |
| + std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices(); |
| + for (std::vector<device::BluetoothDevice*>::const_iterator it = |
| + bt_devices.begin(); |
| + it != bt_devices.end() && |
| + (keyboard_device_id_.empty() || pointing_device_id_.empty()); |
| + it++) { |
| + if (keyboard_device_id_.empty() && |
| + (*it)->GetDeviceType() == device::BluetoothDevice::DEVICE_KEYBOARD && |
| + !keyboard_is_connecting_) { |
| + keyboard_is_connecting_ = true; |
| + ConnectBTDevice(*it); |
| + break; |
| + } |
| + if (pointing_device_id_.empty() && |
| + (*it)->GetDeviceType() == device::BluetoothDevice::DEVICE_MOUSE) { |
| + ConnectBTDevice((*it)); |
| + } |
| + } |
| + } |
| + // Skip screen if both devices are present and skip was requested. |
| + if (!pointing_device_id_.empty() && |
| + !keyboard_device_id_.empty() && |
| + skipScreenIfDevicesPresent) { |
| + HandleOnContinue(); |
| + } |
| + |
|
ygorshenin1
2014/04/24 11:30:24
nit: delete blank line.
merkulova
2014/04/24 12:49:46
Done.
|
| +} |
| + |
| +void HIDDetectionScreenHandler::ConnectBTDevice( |
| + device::BluetoothDevice* device) { |
| + if (!device->IsPairable()) |
| + return; |
| + device->Connect(this, |
| + base::Bind(&HIDDetectionScreenHandler::BTConnected, |
| + weak_ptr_factory_.GetWeakPtr()), |
| + base::Bind(&HIDDetectionScreenHandler::BTConnectError, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + device->GetAddress())); |
| +} |
| + |
| +void HIDDetectionScreenHandler::BTConnected() { |
| + keyboard_is_connecting_ = false; |
| +} |
| + |
| +void HIDDetectionScreenHandler::BTConnectError( |
| + const std::string& address, |
| + device::BluetoothDevice::ConnectErrorCode error_code) { |
| + LOG(WARNING) << "BTConnectError"; |
| + keyboard_is_connecting_ = false; |
| + UpdateDevices(); |
| +} |
| + |
| + |
| +void HIDDetectionScreenHandler::SendPointingDeviceNotification() { |
| + base::DictionaryValue js_properties; |
| + if (pointing_device_id_.empty()) { |
| + js_properties.SetBoolean("searching", true); |
| + } else if (pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) { |
| + js_properties.SetBoolean("BTPaired", true); |
| + } else { |
| + js_properties.SetBoolean("USBConnected", true); |
| + } |
| + web_ui()->CallJavascriptFunction( |
|
ygorshenin1
2014/04/24 11:30:24
Use CallJS when it's possible.
merkulova
2014/04/24 12:49:46
Done.
|
| + "login.HIDDetectionScreen.setPointingDeviceState", |
| + js_properties); |
| +} |
| + |
| +void HIDDetectionScreenHandler::SendKeyboardDeviceNotification( |
| + base::DictionaryValue* params) { |
| + base::DictionaryValue js_properties; |
|
Nikita (slow)
2014/04/24 12:22:45
nit: Use more descriptive name like |state| instea
merkulova
2014/04/24 12:49:46
Done.
|
| + if (params) |
| + js_properties.MergeDictionary(params); |
| + |
| + if (keyboard_device_id_.empty()) { |
| + std::string pairing; |
| + if (!js_properties.GetString("pairing", &pairing)) { |
| + js_properties.SetBoolean("searching", true); |
| + } else if (js_properties.HasKey("pincode")) { |
| + std::string device_name; |
| + if (!js_properties.GetString("name", &device_name)) { |
| + device_name = base::UTF16ToASCII( |
| + l10n_util::GetStringUTF16(IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME)); |
| + } |
| + js_properties.SetString( |
| + "keyboard-label", |
| + l10n_util::GetStringFUTF16( |
| + IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST, |
| + base::ASCIIToUTF16(device_name))); |
| + } |
| + } else if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) { |
| + js_properties.SetBoolean("BTPaired", true); |
| + } else { |
| + js_properties.SetBoolean("USBConnected", true); |
| + } |
| + web_ui()->CallJavascriptFunction( |
| + "login.HIDDetectionScreen.setKeyboardDeviceState", |
| + js_properties); |
| +} |
| + |
| } // namespace chromeos |