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