Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / login / hid_detection_screen_handler.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/macros.h"
11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
18 #include "chrome/common/pref_names.h"
19 #include "chromeos/chromeos_switches.h"
20 #include "device/bluetooth/bluetooth_adapter_factory.h"
21 #include "grit/chromium_strings.h"
22 #include "grit/generated_resources.h"
23 #include "ui/base/l10n/l10n_util.h"
24
25 namespace {
26
27 const char kJsScreenPath[] = "login.HIDDetectionScreen";
28
29 // Variants of pairing state.
30 const char kRemotePinCode[] = "bluetoothRemotePinCode";
31 const char kRemotePasskey[] = "bluetoothRemotePasskey";
32
33 // Possible ui-states for device-blocks.
34 const char kSearchingState[] = "searching";
35 const char kUSBConnectedState[] = "connected";
36 const char kBTPairedState[] = "paired";
37 const char kBTPairingState[] = "pairing";
38 // Special state for notifications that don't switch ui-state, but add info.
39 const char kBTUpdateState[] = "update";
40
41 // Names of possible arguments used for ui update.
42 const char kPincodeArgName[] = "pincode";
43 const char kDeviceNameArgName[] = "name";
44 const char kLabelArgName[] = "keyboard-label";
45
46 // Standard length of pincode for pairing BT keyboards.
47 const int kPincodeLength = 6;
48
49 bool DeviceIsPointing(device::BluetoothDevice::DeviceType device_type) {
50   return device_type == device::BluetoothDevice::DEVICE_MOUSE ||
51          device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO ||
52          device_type == device::BluetoothDevice::DEVICE_TABLET;
53 }
54
55 bool DeviceIsPointing(const device::InputServiceLinux::InputDeviceInfo& info) {
56   return info.is_mouse || info.is_touchpad || info.is_touchscreen ||
57          info.is_tablet;
58 }
59
60 bool DeviceIsKeyboard(device::BluetoothDevice::DeviceType device_type) {
61   return device_type == device::BluetoothDevice::DEVICE_KEYBOARD ||
62          device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO;
63 }
64
65 }  // namespace
66
67 namespace chromeos {
68
69 HIDDetectionScreenHandler::HIDDetectionScreenHandler(
70     CoreOobeActor* core_oobe_actor)
71     : BaseScreenHandler(kJsScreenPath),
72       delegate_(NULL),
73       core_oobe_actor_(core_oobe_actor),
74       show_on_init_(false),
75       mouse_is_pairing_(false),
76       pointing_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN),
77       keyboard_is_pairing_(false),
78       keyboard_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN),
79       switch_on_adapter_when_ready_(false),
80       first_time_screen_show_(true),
81       weak_ptr_factory_(this) {
82 }
83
84 HIDDetectionScreenHandler::~HIDDetectionScreenHandler() {
85   adapter_initially_powered_.reset();
86   if (adapter_.get())
87     adapter_->RemoveObserver(this);
88   input_service_proxy_.RemoveObserver(this);
89   if (delegate_)
90     delegate_->OnActorDestroyed(this);
91 }
92
93 void HIDDetectionScreenHandler::OnStartDiscoverySession(
94     scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
95   VLOG(1) << "BT Discovery session started";
96   discovery_session_ = discovery_session.Pass();
97   UpdateDevices();
98 }
99
100 void HIDDetectionScreenHandler::SetPoweredError() {
101   LOG(ERROR) << "Failed to power BT adapter";
102 }
103
104 void HIDDetectionScreenHandler::SetPoweredOffError() {
105   LOG(ERROR) << "Failed to power off BT adapter";
106 }
107
108 void HIDDetectionScreenHandler::FindDevicesError() {
109   VLOG(1) << "Failed to start Bluetooth discovery.";
110 }
111
112 void HIDDetectionScreenHandler::Show() {
113   if (!page_is_ready()) {
114     show_on_init_ = true;
115     return;
116   }
117   if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableDemoMode))
118     core_oobe_actor_->InitDemoModeDetection();
119   input_service_proxy_.AddObserver(this);
120   first_time_screen_show_ = true;
121   GetDevicesFirstTime();
122   ShowScreen(OobeUI::kScreenHIDDetection, NULL);
123 }
124
125 void HIDDetectionScreenHandler::Hide() {
126   if (adapter_.get())
127     adapter_->RemoveObserver(this);
128   input_service_proxy_.RemoveObserver(this);
129 }
130
131 void HIDDetectionScreenHandler::SetDelegate(Delegate* delegate) {
132   delegate_ = delegate;
133   if (page_is_ready())
134     Initialize();
135 }
136
137 void HIDDetectionScreenHandler::DeclareLocalizedValues(
138     LocalizedValuesBuilder* builder) {
139   builder->Add("hidDetectionContinue", IDS_HID_DETECTION_CONTINUE_BUTTON);
140   builder->Add("hidDetectionInvitation", IDS_HID_DETECTION_INVITATION_TEXT);
141   builder->Add("hidDetectionPrerequisites",
142       IDS_HID_DETECTION_PRECONDITION_TEXT);
143   builder->Add("hidDetectionMouseSearching", IDS_HID_DETECTION_SEARCHING_MOUSE);
144   builder->Add("hidDetectionKeyboardSearching",
145       IDS_HID_DETECTION_SEARCHING_KEYBOARD);
146   builder->Add("hidDetectionUSBMouseConnected",
147       IDS_HID_DETECTION_CONNECTED_USB_MOUSE);
148   builder->Add("hidDetectionUSBKeyboardConnected",
149       IDS_HID_DETECTION_CONNECTED_USB_KEYBOARD);
150   builder->Add("hidDetectionBTMousePaired",
151       IDS_HID_DETECTION_PAIRED_BLUETOOTH_MOUSE);
152   builder->Add("hidDetectionBTEnterKey", IDS_HID_DETECTION_BLUETOOTH_ENTER_KEY);
153 }
154
155 void HIDDetectionScreenHandler::Initialize() {
156   if (!page_is_ready() || !delegate_)
157     return;
158
159   device::BluetoothAdapterFactory::GetAdapter(
160       base::Bind(&HIDDetectionScreenHandler::InitializeAdapter,
161                  weak_ptr_factory_.GetWeakPtr()));
162
163   if (show_on_init_) {
164     Show();
165     show_on_init_ = false;
166   }
167 }
168
169 void HIDDetectionScreenHandler::RegisterMessages() {
170   AddCallback(
171       "HIDDetectionOnContinue", &HIDDetectionScreenHandler::HandleOnContinue);
172 }
173
174 void HIDDetectionScreenHandler::HandleOnContinue() {
175   if (!first_time_screen_show_) {
176     // Continue button pressed.
177     ContinueScenarioType scenario_type;
178     if (!pointing_device_id_.empty() && !keyboard_device_id_.empty())
179       scenario_type = All_DEVICES_DETECTED;
180     else if (pointing_device_id_.empty())
181       scenario_type = KEYBOARD_DEVICE_ONLY_DETECTED;
182     else
183       scenario_type = POINTING_DEVICE_ONLY_DETECTED;
184
185     UMA_HISTOGRAM_ENUMERATION(
186         "HIDDetection.OOBEDevicesDetectedOnContinuePressed",
187         scenario_type,
188         CONTINUE_SCENARIO_TYPE_SIZE);
189   }
190   // Switch off BT adapter if it was off before the screen and no BT device
191   // connected.
192   if (adapter_ && adapter_->IsPresent() && adapter_->IsPowered() &&
193       !(pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH ||
194         keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) &&
195       adapter_initially_powered_ && !(*adapter_initially_powered_)) {
196     VLOG(1) << "Switching off BT adapter after HID OOBE screen as unused.";
197     adapter_->SetPowered(
198         false,
199         base::Bind(&base::DoNothing),
200         base::Bind(&HIDDetectionScreenHandler::SetPoweredOffError,
201                    weak_ptr_factory_.GetWeakPtr()));
202   }
203
204   core_oobe_actor_->StopDemoModeDetection();
205   if (delegate_)
206     delegate_->OnExit();
207 }
208
209 void HIDDetectionScreenHandler::InitializeAdapter(
210     scoped_refptr<device::BluetoothAdapter> adapter) {
211   adapter_ = adapter;
212   CHECK(adapter_.get());
213
214   adapter_->AddObserver(this);
215   UpdateDevices();
216 }
217
218 void HIDDetectionScreenHandler::StartBTDiscoverySession() {
219   adapter_->StartDiscoverySession(
220       base::Bind(&HIDDetectionScreenHandler::OnStartDiscoverySession,
221                  weak_ptr_factory_.GetWeakPtr()),
222       base::Bind(&HIDDetectionScreenHandler::FindDevicesError,
223                  weak_ptr_factory_.GetWeakPtr()));
224 }
225
226 void HIDDetectionScreenHandler::RequestPinCode(
227     device::BluetoothDevice* device) {
228   VLOG(1) << "RequestPinCode id = " << device->GetDeviceID()
229           << " name = " << device->GetName();
230   device->CancelPairing();
231 }
232
233 void HIDDetectionScreenHandler::RequestPasskey(
234     device::BluetoothDevice* device) {
235   VLOG(1) << "RequestPassKey id = " << device->GetDeviceID()
236           << " name = " << device->GetName();
237   device->CancelPairing();
238 }
239
240 void HIDDetectionScreenHandler::DisplayPinCode(device::BluetoothDevice* device,
241                                                const std::string& pincode) {
242   VLOG(1) << "DisplayPinCode id = " << device->GetDeviceID()
243           << " name = " << device->GetName();
244   base::DictionaryValue params;
245   params.SetString("state", kBTPairingState);
246   params.SetString("pairing-state", kRemotePinCode);
247   params.SetString("pincode", pincode);
248   params.SetString(kDeviceNameArgName, device->GetName());
249   SendKeyboardDeviceNotification(&params);
250 }
251
252 void HIDDetectionScreenHandler::DisplayPasskey(
253     device::BluetoothDevice* device, uint32 passkey) {
254   VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID()
255           << " name = " << device->GetName();
256   base::DictionaryValue params;
257   params.SetString("state", kBTPairingState);
258   params.SetString("pairing-state", kRemotePasskey);
259   params.SetInteger("passkey", passkey);
260   std::string pincode = base::UintToString(passkey);
261   pincode = std::string(kPincodeLength - pincode.length(), '0').append(pincode);
262   params.SetString("pincode", pincode);
263   params.SetString(kDeviceNameArgName, device->GetName());
264   SendKeyboardDeviceNotification(&params);
265 }
266
267 void HIDDetectionScreenHandler::KeysEntered(
268     device::BluetoothDevice* device, uint32 entered) {
269   VLOG(1) << "Keys entered";
270   base::DictionaryValue params;
271   params.SetString("state", kBTUpdateState);
272   params.SetInteger("keysEntered", entered);
273   SendKeyboardDeviceNotification(&params);
274 }
275
276 void HIDDetectionScreenHandler::ConfirmPasskey(
277     device::BluetoothDevice* device, uint32 passkey) {
278   VLOG(1) << "Confirm Passkey";
279   device->CancelPairing();
280 }
281
282 void HIDDetectionScreenHandler::AuthorizePairing(
283     device::BluetoothDevice* device) {
284   // There is never any circumstance where this will be called, since the
285   // HID detection screen  handler will only be used for outgoing pairing
286   // requests, but play it safe.
287   VLOG(1) << "Authorize pairing";
288   device->ConfirmPairing();
289 }
290
291 void HIDDetectionScreenHandler::AdapterPresentChanged(
292     device::BluetoothAdapter* adapter, bool present) {
293   if (present && switch_on_adapter_when_ready_) {
294     VLOG(1) << "Switching on BT adapter on HID OOBE screen.";
295     adapter_initially_powered_.reset(new bool(adapter_->IsPowered()));
296     adapter_->SetPowered(
297         true,
298         base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession,
299                    weak_ptr_factory_.GetWeakPtr()),
300         base::Bind(&HIDDetectionScreenHandler::SetPoweredError,
301                    weak_ptr_factory_.GetWeakPtr()));
302   }
303 }
304
305 void HIDDetectionScreenHandler::TryPairingAsPointingDevice(
306     device::BluetoothDevice* device) {
307   if (pointing_device_id_.empty() &&
308       DeviceIsPointing(device->GetDeviceType()) &&
309       device->IsPairable() && !device->IsPaired() && !mouse_is_pairing_) {
310     ConnectBTDevice(device);
311   }
312 }
313
314 void HIDDetectionScreenHandler::TryPairingAsKeyboardDevice(
315     device::BluetoothDevice* device) {
316   if (keyboard_device_id_.empty() &&
317       DeviceIsKeyboard(device->GetDeviceType()) &&
318       device->IsPairable() && !device->IsPaired() && !keyboard_is_pairing_) {
319     ConnectBTDevice(device);
320   }
321 }
322
323 void HIDDetectionScreenHandler::DeviceAdded(
324     device::BluetoothAdapter* adapter, device::BluetoothDevice* device) {
325   VLOG(1) << "BT input device added id = " << device->GetDeviceID() <<
326       " name = " << device->GetName();
327   TryPairingAsPointingDevice(device);
328   TryPairingAsKeyboardDevice(device);
329 }
330
331 void HIDDetectionScreenHandler::DeviceChanged(
332     device::BluetoothAdapter* adapter, device::BluetoothDevice* device) {
333   VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " <<
334       device->GetName();
335   TryPairingAsPointingDevice(device);
336   TryPairingAsKeyboardDevice(device);
337 }
338
339 void HIDDetectionScreenHandler::DeviceRemoved(
340     device::BluetoothAdapter* adapter, device::BluetoothDevice* device) {
341   VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " <<
342       device->GetName();
343 }
344
345 void HIDDetectionScreenHandler::OnInputDeviceAdded(
346     const InputDeviceInfo& info) {
347   VLOG(1) << "Input device added id = " << info.id << " name = " << info.name;
348   // TODO(merkulova): deal with all available device types, e.g. joystick.
349   if (!keyboard_device_id_.empty() && !pointing_device_id_.empty())
350     return;
351
352   if (pointing_device_id_.empty() && DeviceIsPointing(info)) {
353     pointing_device_id_ = info.id;
354     pointing_device_name_ = info.name;
355     pointing_device_connect_type_ = info.type;
356     SendPointingDeviceNotification();
357   }
358   if (keyboard_device_id_.empty() && info.is_keyboard) {
359     keyboard_device_id_ = info.id;
360     keyboard_device_name_ = info.name;
361     keyboard_device_connect_type_ = info.type;
362     SendKeyboardDeviceNotification(NULL);
363   }
364 }
365
366 void HIDDetectionScreenHandler::OnInputDeviceRemoved(const std::string& id) {
367   if (id == keyboard_device_id_) {
368     keyboard_device_id_.clear();
369     keyboard_device_name_.clear();
370     keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN;
371     SendKeyboardDeviceNotification(NULL);
372     UpdateDevices();
373   } else if (id == pointing_device_id_) {
374     pointing_device_id_.clear();
375     pointing_device_name_.clear();
376     pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN;
377     SendPointingDeviceNotification();
378     UpdateDevices();
379   }
380 }
381
382 // static
383 void HIDDetectionScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
384   registry->RegisterIntegerPref(prefs::kTimesHIDDialogShown, 0);
385 }
386
387 void HIDDetectionScreenHandler::GetDevicesFirstTime() {
388   input_service_proxy_.GetDevices(
389       base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesListFirstTime,
390                  weak_ptr_factory_.GetWeakPtr()));
391 }
392
393 void HIDDetectionScreenHandler::UpdateDevices() {
394   input_service_proxy_.GetDevices(
395       base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesList,
396                  weak_ptr_factory_.GetWeakPtr()));
397 }
398
399 void HIDDetectionScreenHandler::UpdateBTDevices() {
400   if (!adapter_ || !adapter_->IsPresent() || !adapter_->IsPowered())
401     return;
402
403   // If no connected devices found as pointing device and keyboard, we try to
404   // connect some type-suitable active bluetooth device.
405   std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices();
406   for (std::vector<device::BluetoothDevice*>::const_iterator it =
407            bt_devices.begin();
408        it != bt_devices.end() &&
409            (keyboard_device_id_.empty() || pointing_device_id_.empty());
410        ++it) {
411     TryPairingAsPointingDevice(*it);
412     TryPairingAsKeyboardDevice(*it);
413   }
414 }
415
416 void HIDDetectionScreenHandler::ProcessConnectedDevicesList(
417     const std::vector<InputDeviceInfo>& devices) {
418   for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin();
419        it != devices.end() &&
420        (pointing_device_id_.empty() || keyboard_device_id_.empty());
421        ++it) {
422     if (pointing_device_id_.empty() && DeviceIsPointing(*it)) {
423       pointing_device_id_ = it->id;
424       pointing_device_name_ = it->name;
425       pointing_device_connect_type_ = it->type;
426       SendPointingDeviceNotification();
427     }
428     if (keyboard_device_id_.empty() && it->is_keyboard) {
429       keyboard_device_id_ = it->id;
430       keyboard_device_name_ = it->name;
431       keyboard_device_connect_type_ = it->type;
432       SendKeyboardDeviceNotification(NULL);
433     }
434   }
435 }
436
437 void HIDDetectionScreenHandler::TryInitiateBTDevicesUpdate() {
438   if ((pointing_device_id_.empty() || keyboard_device_id_.empty()) &&
439       adapter_) {
440     if (!adapter_->IsPresent()) {
441       // Switch on BT adapter later when it's available.
442       switch_on_adapter_when_ready_ = true;
443     } else if (!adapter_->IsPowered()) {
444       VLOG(1) << "Switching on BT adapter on HID OOBE screen.";
445       adapter_initially_powered_.reset(new bool(false));
446       adapter_->SetPowered(
447           true,
448           base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession,
449                      weak_ptr_factory_.GetWeakPtr()),
450           base::Bind(&HIDDetectionScreenHandler::SetPoweredError,
451                      weak_ptr_factory_.GetWeakPtr()));
452     } else {
453       UpdateBTDevices();
454     }
455   }
456 }
457
458 void HIDDetectionScreenHandler::OnGetInputDevicesListFirstTime(
459     const std::vector<InputDeviceInfo>& devices) {
460   ProcessConnectedDevicesList(devices);
461
462   // Skip screen if both devices are present.
463   bool all_devices_autodetected = !pointing_device_id_.empty() &&
464                                   !keyboard_device_id_.empty();
465   UMA_HISTOGRAM_BOOLEAN("HIDDetection.OOBEDialogShown",
466                         !all_devices_autodetected);
467   if (all_devices_autodetected) {
468     HandleOnContinue();
469     return;
470   }
471   PrefService* local_state = g_browser_process->local_state();
472   int num_of_times_dialog_was_shown = local_state->GetInteger(
473       prefs::kTimesHIDDialogShown);
474   local_state->SetInteger(prefs::kTimesHIDDialogShown,
475                           num_of_times_dialog_was_shown + 1);
476   first_time_screen_show_ = false;
477
478   TryInitiateBTDevicesUpdate();
479 }
480
481 void HIDDetectionScreenHandler::OnGetInputDevicesList(
482     const std::vector<InputDeviceInfo>& devices) {
483   ProcessConnectedDevicesList(devices);
484   TryInitiateBTDevicesUpdate();
485 }
486
487 void HIDDetectionScreenHandler::ConnectBTDevice(
488     device::BluetoothDevice* device) {
489   if (!device->IsPairable() || device->IsPaired())
490     return;
491   device::BluetoothDevice::DeviceType device_type = device->GetDeviceType();
492
493   if (device_type == device::BluetoothDevice::DEVICE_MOUSE ||
494       device_type == device::BluetoothDevice::DEVICE_TABLET) {
495     if (mouse_is_pairing_)
496       return;
497     mouse_is_pairing_ = true;
498   } else if (device_type == device::BluetoothDevice::DEVICE_KEYBOARD) {
499     if (keyboard_is_pairing_)
500       return;
501     keyboard_is_pairing_ = true;
502   } else if (device_type ==
503       device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO) {
504     if (mouse_is_pairing_ || keyboard_is_pairing_)
505       return;
506     mouse_is_pairing_ = true;
507     keyboard_is_pairing_ = true;
508   }
509   device->Connect(this,
510             base::Bind(&HIDDetectionScreenHandler::BTConnected,
511                        weak_ptr_factory_.GetWeakPtr(), device_type),
512             base::Bind(&HIDDetectionScreenHandler::BTConnectError,
513                        weak_ptr_factory_.GetWeakPtr(),
514                        device->GetAddress(), device_type));
515 }
516
517 void HIDDetectionScreenHandler::BTConnected(
518     device::BluetoothDevice::DeviceType device_type) {
519   if (DeviceIsPointing(device_type))
520     mouse_is_pairing_ = false;
521   if (DeviceIsKeyboard(device_type))
522     keyboard_is_pairing_ = false;
523 }
524
525 void HIDDetectionScreenHandler::BTConnectError(
526     const std::string& address,
527     device::BluetoothDevice::DeviceType device_type,
528     device::BluetoothDevice::ConnectErrorCode error_code) {
529   LOG(WARNING) << "BTConnectError while connecting " << address
530                << " error code = " << error_code;
531   if (DeviceIsPointing(device_type))
532     mouse_is_pairing_ = false;
533   if (DeviceIsKeyboard(device_type)) {
534     keyboard_is_pairing_ = false;
535     SendKeyboardDeviceNotification(NULL);
536   }
537
538   if (pointing_device_id_.empty() || keyboard_device_id_.empty())
539     UpdateDevices();
540 }
541
542
543 void HIDDetectionScreenHandler::SendPointingDeviceNotification() {
544   std::string state;
545   if (pointing_device_id_.empty())
546     state = kSearchingState;
547   else if (pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH)
548     state = kBTPairedState;
549   else
550     state = kUSBConnectedState;
551   CallJS("setPointingDeviceState", state);
552 }
553
554 void HIDDetectionScreenHandler::SendKeyboardDeviceNotification(
555     base::DictionaryValue* params) {
556   base::DictionaryValue state_info;
557   if (params)
558     state_info.MergeDictionary(params);
559
560   base::string16 device_name;
561   if (!state_info.GetString(kDeviceNameArgName, &device_name)) {
562     device_name = l10n_util::GetStringUTF16(
563         IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME);
564   }
565
566   if (keyboard_device_id_.empty()) {
567     if (!state_info.HasKey("state")) {
568       state_info.SetString("state", kSearchingState);
569     } else if (state_info.HasKey(kPincodeArgName)) {
570       state_info.SetString(
571           kLabelArgName,
572           l10n_util::GetStringFUTF16(
573               IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST,
574               device_name));
575     }
576   } else if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) {
577     state_info.SetString("state", kBTPairedState);
578     state_info.SetString(
579         kLabelArgName,
580         l10n_util::GetStringFUTF16(
581             IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD,
582             base::UTF8ToUTF16(keyboard_device_name_)));
583   } else {
584     state_info.SetString("state", kUSBConnectedState);
585   }
586   CallJS("setKeyboardDeviceState", state_info);
587 }
588
589 }  // namespace chromeos