summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/resources/settings/bluetooth_page
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/resources/settings/bluetooth_page')
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html49
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js71
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css33
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html37
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js71
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css91
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css32
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html86
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js523
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html68
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js271
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp72
12 files changed, 1404 insertions, 0 deletions
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html
new file mode 100644
index 00000000000..c6f747c04f2
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html
@@ -0,0 +1,49 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
+
+<dom-module id="settings-bluetooth-add-device-dialog">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="bluetooth_page.css">
+ <link rel="import" type="css" href="bluetooth_dialog.css">
+ <template>
+ <div id="dialogOuterDiv" class="layout vertical flex">
+ <div id="dialogHeaderDiv" class="settings-box layout horizontal">
+ <span id="dialogTitle" class="flex"
+ i18n-content="bluetoothAddDevicePageTitle">
+ </span>
+ <paper-icon-button icon="close" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div class="settings-box flex">
+ <div id="dialogDeviceList" class="settings-box layout vertical"
+ on-device-event="onDeviceEvent_">
+ <span class="no-devices" hidden$="[[haveDevices_(deviceList)]]"
+ i18n-content="bluetoothNoDevices">
+ </span>
+ <iron-selector class="flex">
+ <template is="dom-repeat" items="[[deviceList]]"
+ filter="deviceNotPaired_" observe="paired">
+ <bluetooth-device-list-item device="[[item]]">
+ </bluetooth-device-list-item>
+ </template>
+ </iron-selector>
+ </div>
+ </div>
+ <div id="dialogFooterDiv" class="layout horizontal center">
+ <div id="scanning" class="layout horizontal center flex"
+ hidden$="[[!adapterState.discovering]]">
+ <paper-spinner active="[[adapterState.discovering]]">
+ </paper-spinner>
+ <span i18n-content="bluetoothScanning"></span>
+ </div>
+ <paper-button id="cancel" class="end-justified"
+ i18n-content="bluetoothCancel" on-tap="onCancelTap_">
+ </paper-button>
+ </div>
+ </div>
+ </template>
+ <script src="bluetooth_add_device_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js
new file mode 100644
index 00000000000..189711f310f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js
@@ -0,0 +1,71 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * 'settings-bluetooth-add-device-dialog' is the settings subpage for adding
+ * bluetooth devices.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-bluetooth-add-device-dialog
+ */
+Polymer({
+ is: 'settings-bluetooth-add-device-dialog',
+
+ properties: {
+ /**
+ * The cached bluetooth adapter state.
+ * @type {!chrome.bluetooth.AdapterState|undefined}
+ */
+ adapterState: {
+ type: Object,
+ observer: 'adapterStateChanged_',
+ },
+
+ /**
+ * The ordered list of bluetooth devices.
+ * @type {!Array<!chrome.bluetooth.Device>}
+ */
+ deviceList: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ /** @private */
+ adapterStateChanged_: function() {
+ if (!this.adapterState.powered)
+ this.fire('close-dialog');
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {boolean}
+ * @private
+ */
+ deviceNotPaired_: function(device) {
+ return !device.paired;
+ },
+
+ /**
+ * @param {!Array<!chrome.bluetooth.Device>} deviceList
+ * @return {boolean} True if deviceList contains any unpaired devices.
+ * @private
+ */
+ haveDevices_: function(deviceList) {
+ return this.deviceList.findIndex(function(d) { return !d.paired; }) != -1;
+ },
+
+ /**
+ * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e
+ * @private
+ */
+ onDeviceEvent_: function(e) {
+ this.fire('device-event', e.detail);
+ /** @type {Event} */(e).stopPropagation();
+ },
+
+ /** @private */
+ onCancelTap_: function() { this.fire('close-dialog'); },
+});
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css
new file mode 100644
index 00000000000..de43201be75
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css
@@ -0,0 +1,33 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+#outer {
+ padding: 5px 5px 5px 15px;
+}
+
+#outer:hover:not([dropdown]) {
+ background-color: #f0f0f0;
+}
+
+iron-icon {
+ -webkit-padding-start: 10px;
+ color: green;
+}
+
+paper-item:hover {
+ background-color: #f0f0f0;
+}
+
+span.name {
+ padding: 10px 0;
+}
+
+span.name[connected] {
+ font-weight: bold;
+}
+
+.dropdown-content {
+ background: white;
+ box-shadow: 0 2px 6px grey;
+}
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
new file mode 100644
index 00000000000..a868a559356
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
@@ -0,0 +1,37 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+
+<dom-module id="bluetooth-device-list-item">
+ <link rel="import" type="css" href="bluetooth_device_list_item.css">
+ <template>
+ <div id="outer" class="layout horizontal center"
+ dropdown$="[[dropdownOpened]]" on-tap="itemTapped_">
+ <span class="name" connected$="[[device.connected]]">
+ [[getDeviceName_(device)]]
+ </span>
+ <iron-icon icon="check" hidden$="[[!device.connected]]"></iron-icon>
+ <span class="flex"></span>
+ <span hidden$="[[!device.connecting]]"
+ i18n-content="bluetoothConnecting"></span>
+ <div hidden$="[[!device.paired]]" on-tap="doNothing_">
+ <paper-icon-button icon="more-vert" toggles active="{{dropdownOpened}}">
+ </paper-icon-button>
+ <iron-dropdown opened="{{dropdownOpened}}" on-tap="menuSelected_">
+ <div class="dropdown-content">
+ <paper-item id="connect" i18n-content="bluetoothConnect"
+ hidden$="[[device.connected]]"></paper-item>
+ <paper-item id="disconnect" i18n-content="bluetoothDisconnect"
+ hidden$="[[!device.connected]]"></paper-item>
+ <paper-item id="remove" i18n-content="bluetoothRemove"></paper-item>
+ </div>
+ </iron-dropdown>
+ </div>
+ </div>
+ </template>
+ <script src="bluetooth_device_list_item.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
new file mode 100644
index 00000000000..dd2378b8f11
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
@@ -0,0 +1,71 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Polymer element for displaying a bluetooth device in a list.
+ */
+
+Polymer({
+ is: 'bluetooth-device-list-item',
+
+ properties: {
+ /**
+ * The bluetooth device.
+ * @type {!chrome.bluetooth.Device}
+ */
+ device: {
+ type: Object,
+ },
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ itemTapped_: function(e) {
+ this.fire('device-event', {
+ action: 'connect',
+ device: this.device,
+ });
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ menuSelected_: function(e) {
+ e.currentTarget.opened = false;
+ this.fire('device-event', {
+ action: e.target.id,
+ device: this.device,
+ });
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ doNothing_: function(e) {
+ // Avoid triggering itemTapped_.
+ e.stopPropagation();
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {string} The text to display for |device| in the device list.
+ * @private
+ */
+ getDeviceName_: function(device) {
+ return device.name || device.address;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {boolean}
+ * @private
+ */
+ isDisconnected_: function(device) {
+ return !device.connected && !device.connecting;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css
new file mode 100644
index 00000000000..67646335f0b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css
@@ -0,0 +1,91 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+#dialogOuterDiv {
+ margin-bottom: 16px;
+}
+
+#dialogHeaderDiv {
+ height: 40px;
+ margin: 0 5px 10px;
+}
+
+#dialogFooterDiv {
+ height: 40px;
+ margin: 0 20px;
+}
+
+#dialogMessage {
+ margin-bottom: 10px;
+}
+
+#dialogTitle {
+ font-size: 125%;
+ margin: 0 10px;
+}
+
+#dialogDeviceList {
+ height: 210px;
+ margin-bottom: 20px;
+ margin-left: 4px;
+ overflow-y: auto;
+}
+
+#pairing {
+ margin-bottom: 10px;
+}
+
+#pairing paper-input {
+ text-align: center;
+}
+
+#pinDiv {
+ margin-top: 10px;
+}
+
+iron-selector {
+ width: 100%;
+}
+
+paper-spinner {
+ height: 20px;
+ margin: 0 10px;
+ width: 20px;
+}
+
+/* .display indicates a displayed pin code or passkey. */
+span.display {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-shadow: 0 0 0 1px #222;
+ color: #222;
+ font-size: 16px;
+ height: 38px;
+ line-height: 38px;
+ margin: 0 5px;
+ padding: 0 15px;
+ text-align: center;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+span.display.next {
+ background: rgb(77, 144, 254);
+ border: 2px solid rgb(77, 144, 254);
+ box-shadow: none;
+ color: #fff;
+}
+
+span.display.untyped {
+ border: 1px solid #d4d4d4;
+ box-shadow: 0 0 0 1px #888;
+ color: #666;
+}
+
+/* .confirm indicates a confirmation passkey. */
+span.confirm {
+ color: #999;
+ font-size: 20px;
+ font-weight: 600; /* semibold */
+ margin: 0 20px;
+}
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css
new file mode 100644
index 00000000000..2eb7bd8b15d
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css
@@ -0,0 +1,32 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+#addDevice {
+ color: blue;
+}
+
+#deviceList {
+ -webkit-margin-start: 15px;
+ max-height: 300px;
+ overflow-y: auto;
+}
+
+cr-expand-button {
+ -webkit-margin-end: 10px;
+}
+
+iron-icon {
+ -webkit-margin-end: 10px;
+}
+
+settings-bluetooth-add-device-dialog,
+settings-bluetooth-pair-device-dialog {
+ height: 400px;
+ padding: 0;
+ width: 500px;
+}
+
+span.no-devices {
+ margin: 10px 20px;
+}
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
new file mode 100644
index 00000000000..d6e576e17b1
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -0,0 +1,86 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
+<link rel="import" href="bluetooth_device_list_item.html">
+<link rel="import" href="bluetooth_add_device_dialog.html">
+<link rel="import" href="bluetooth_pair_device_dialog.html">
+
+<dom-module id="settings-bluetooth-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="bluetooth_page.css">
+ <template>
+ <settings-animated-pages id="pages" current-route="{{currentRoute}}"
+ section="bluetooth">
+ <neon-animatable id="main">
+ <div class="settings-box">
+ <div class="layout horizontal center">
+ <iron-icon icon="device:bluetooth"></iron-icon>
+ <span class="flex" i18n-content="bluetoothEnable"></span>
+ <cr-expand-button id="expandListButton"
+ hidden$="[[!bluetoothEnabled]]"
+ expanded="{{deviceListExpanded}}">
+ </cr-expand-button>
+ <paper-toggle-button id="enableBluetooth"
+ checked="{{bluetoothEnabled}}"
+ on-change="onBluetoothEnabledChange_">
+ </paper-toggle-button>
+ </div>
+ <iron-collapse opened="[[deviceListExpanded]]">
+ <div id="deviceList" class="layout vertical"
+ on-device-event="onDeviceEvent_">
+ <span class="no-devices"
+ hidden$="[[haveDevices_(deviceList.splices)]]"
+ i18n-content="bluetoothNoDevices">
+ </span>
+ <template is="dom-repeat" items="[[deviceList]]"
+ filter="deviceIsPairedOrConnecting_">
+ <bluetooth-device-list-item device="[[item]]">
+ </bluetooth-device-list-item>
+ </template>
+ </div>
+ <div class="settings-box" hidden$="[[!bluetoothEnabled]]">
+ <paper-button id="addDevice" i18n-content="bluetoothAddDevice"
+ on-tap="onAddDeviceTap_">
+ </paper-button>
+ </div>
+ </iron-collapse>
+ </div>
+ </neon-animatable>
+ </settings-animated-pages>
+
+ <paper-dialog modal id="deviceDialog" class="layout vertical"
+ on-iron-overlay-opened="onDialogOpened_"
+ on-iron-overlay-closed="onDialogClosed_">
+ <template is="dom-if" if="[[dialogIsVisible_(dialog, 'addDevice')]]"
+ restamp>
+ <settings-bluetooth-add-device-dialog
+ class="layout vertical flex"
+ adapter-state="[[adapterState]]"
+ device-list="[[deviceList]]"
+ on-device-event="onDeviceEvent_"
+ on-close-dialog="onCloseDialog_">
+ </settings-bluetooth-add-device-dialog>
+ </template>
+ <template is="dom-if" if="[[dialogIsVisible_(dialog, 'pairDevice')]]"
+ restamp>
+ <settings-bluetooth-pair-device-dialog
+ class="layout vertical flex"
+ pairing-device="[[pairingDevice]]"
+ pairing-event="[[pairingEvent]]"
+ on-response="onResponse_"
+ on-close-dialog="onCloseDialog_">
+ </settings-bluetooth-pair-device-dialog>
+ </template>
+ </paper-dialog>
+
+ </template>
+ <script src="bluetooth_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
new file mode 100644
index 00000000000..c8babf426cc
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
@@ -0,0 +1,523 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * 'settings-bluetooth-page' is the settings page for managing bluetooth
+ * properties and devices.
+ *
+ * Example:
+ * <core-animated-pages>
+ * <settings-bluetooth-page>
+ * </settings-bluetooth-page>
+ * ... other pages ...
+ * </core-animated-pages>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-bluetooth-page
+ */
+
+var bluetoothPage = bluetoothPage || {
+ /**
+ * Set this to provide a fake implementation for testing.
+ * @type {Bluetooth}
+ */
+ bluetoothApiForTest: null,
+
+ /**
+ * Set this to provide a fake implementation for testing.
+ * @type {BluetoothPrivate}
+ */
+ bluetoothPrivateApiForTest: null,
+};
+
+Polymer({
+ is: 'settings-bluetooth-page',
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ properties: {
+ /** The current active route. */
+ currentRoute: {
+ type: Object,
+ notify: true,
+ },
+
+ /** Whether bluetooth is enabled. */
+ bluetoothEnabled: {
+ type: Boolean,
+ value: false,
+ observer: 'bluetoothEnabledChanged_',
+ },
+
+ /** Whether the device list is expanded. */
+ deviceListExpanded: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The cached bluetooth adapter state.
+ * @type {!chrome.bluetooth.AdapterState|undefined}
+ */
+ adapterState: Object,
+
+ /**
+ * The ordered list of bluetooth devices.
+ * @type {!Array<!chrome.bluetooth.Device>}
+ */
+ deviceList: {
+ type: Array,
+ value: function() { return []; },
+ },
+
+ /**
+ * Set to the name of the dialog to show. This page uses a single
+ * paper-dialog to host one of two dialog elements, 'addDevice' or
+ * 'pairDevice'. This allows a seamless transition between adding and
+ * pairing dialogs. Note: This property should be set before opening the
+ * dialog, and setting the property will not itself cause the dialog to
+ * open.
+ */
+ dialog: String,
+
+ /**
+ * Current Pairing device.
+ * @type {?chrome.bluetooth.Device|undefined}
+ */
+ pairingDevice: Object,
+
+ /**
+ * Current Pairing event.
+ * @type {?chrome.bluetoothPrivate.PairingEvent|undefined}
+ */
+ pairingEvent: Object,
+
+ /**
+ * Interface for bluetooth calls. May be overriden by tests.
+ * @type {Bluetooth}
+ */
+ bluetooth: {
+ type: Object,
+ value: chrome.bluetooth,
+ },
+
+ /**
+ * Interface for bluetoothPrivate calls. May be overriden by tests.
+ * @type {BluetoothPrivate}
+ */
+ bluetoothPrivate: {
+ type: Object,
+ value: chrome.bluetoothPrivate,
+ },
+ },
+
+ /**
+ * Listener for chrome.bluetooth.onAdapterStateChanged events.
+ * @type {function(!chrome.bluetooth.AdapterState)|undefined}
+ * @private
+ */
+ bluetoothAdapterStateChangedListener_: undefined,
+
+ /**
+ * Listener for chrome.bluetooth.onBluetoothDeviceAdded/Changed events.
+ * @type {function(!chrome.bluetooth.Device)|undefined}
+ * @private
+ */
+ bluetoothDeviceUpdatedListener_: undefined,
+
+ /**
+ * Listener for chrome.bluetooth.onBluetoothDeviceRemoved events.
+ * @type {function(!chrome.bluetooth.Device)|undefined}
+ * @private
+ */
+ bluetoothDeviceRemovedListener_: undefined,
+
+ /**
+ * Listener for chrome.bluetoothPrivate.onPairing events.
+ * @type {function(!chrome.bluetoothPrivate.PairingEvent)|undefined}
+ * @private
+ */
+ bluetoothPrivateOnPairingListener_: undefined,
+
+ /** @override */
+ ready: function() {
+ if (bluetoothPage.bluetoothApiForTest)
+ this.bluetooth = bluetoothPage.bluetoothApiForTest;
+ if (bluetoothPage.bluetoothPrivateApiForTest)
+ this.bluetoothPrivate = bluetoothPage.bluetoothPrivateApiForTest;
+ },
+
+ /** @override */
+ attached: function() {
+ this.bluetoothAdapterStateChangedListener_ =
+ this.onBluetoothAdapterStateChanged_.bind(this);
+ this.bluetooth.onAdapterStateChanged.addListener(
+ this.bluetoothAdapterStateChangedListener_);
+
+ this.bluetoothDeviceUpdatedListener_ =
+ this.onBluetoothDeviceUpdated_.bind(this);
+ this.bluetooth.onDeviceAdded.addListener(
+ this.bluetoothDeviceUpdatedListener_);
+ this.bluetooth.onDeviceChanged.addListener(
+ this.bluetoothDeviceUpdatedListener_);
+
+ this.bluetoothDeviceRemovedListener_ =
+ this.onBluetoothDeviceRemoved_.bind(this);
+ this.bluetooth.onDeviceRemoved.addListener(
+ this.bluetoothDeviceRemovedListener_);
+
+ // Request the inital adapter state.
+ this.bluetooth.getAdapterState(
+ this.bluetoothAdapterStateChangedListener_);
+ },
+
+ /** @override */
+ detached: function() {
+ if (this.bluetoothAdapterStateChangedListener_) {
+ this.bluetooth.onAdapterStateChanged.removeListener(
+ this.bluetoothAdapterStateChangedListener_);
+ }
+ if (this.bluetoothDeviceUpdatedListener_) {
+ this.bluetooth.onDeviceAdded.removeListener(
+ this.bluetoothDeviceUpdatedListener_);
+ this.bluetooth.onDeviceChanged.removeListener(
+ this.bluetoothDeviceUpdatedListener_);
+ }
+ if (this.bluetoothDeviceRemovedListener_) {
+ this.bluetooth.onDeviceRemoved.removeListener(
+ this.bluetoothDeviceRemovedListener_);
+ }
+ },
+
+ bluetoothEnabledChanged_: function() {
+ // When bluetooth is enabled, auto-expand the device list.
+ if (this.bluetoothEnabled)
+ this.deviceListExpanded = true;
+ },
+
+ /**
+ * If bluetooth is enabled, request the complete list of devices and update
+ * |deviceList|.
+ * @private
+ */
+ updateDeviceList_: function() {
+ if (!this.bluetoothEnabled) {
+ this.deviceList = [];
+ return;
+ }
+ this.bluetooth.getDevices(function(devices) {
+ this.deviceList = devices;
+ }.bind(this));
+ },
+
+ /**
+ * Event called when a user action changes the bluetoothEnabled state.
+ * @private
+ */
+ onBluetoothEnabledChange_: function() {
+ this.bluetoothPrivate.setAdapterState(
+ {powered: this.bluetoothEnabled}, function() {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error enabling bluetooth: ' +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /**
+ * Process bluetooth.onAdapterStateChanged events.
+ * @param {!chrome.bluetooth.AdapterState} state
+ * @private
+ */
+ onBluetoothAdapterStateChanged_: function(state) {
+ this.adapterState = state;
+ this.bluetoothEnabled = state.powered;
+ this.updateDeviceList_();
+ },
+
+ /**
+ * Process bluetooth.onDeviceAdded and onDeviceChanged events.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ onBluetoothDeviceUpdated_: function(device) {
+ var address = device.address;
+ if (this.dialog && this.pairingDevice &&
+ this.pairingDevice.address == address) {
+ this.pairingDevice = device;
+ }
+ var index = this.getDeviceIndex_(address);
+ if (index >= 0) {
+ // Use splice to update the item in order to update the dom-repeat lists.
+ // See https://github.com/Polymer/polymer/issues/3254.
+ this.splice('deviceList', index, 1, device);
+ return;
+ }
+ this.push('deviceList', device);
+ },
+
+ /**
+ * Process bluetooth.onDeviceRemoved events.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ onBluetoothDeviceRemoved_: function(device) {
+ var address = device.address;
+ var index = this.getDeviceIndex_(address);
+ if (index < 0)
+ return;
+ this.splice('deviceList', index, 1);
+ },
+
+ /** @private */
+ startDiscovery_: function() {
+ if (!this.adapterState || this.adapterState.discovering)
+ return;
+
+ if (!this.bluetoothPrivateOnPairingListener_) {
+ this.bluetoothPrivateOnPairingListener_ =
+ this.onBluetoothPrivateOnPairing_.bind(this);
+ this.bluetoothPrivate.onPairing.addListener(
+ this.bluetoothPrivateOnPairingListener_);
+ }
+
+ this.bluetooth.startDiscovery(function() {
+ if (chrome.runtime.lastError) {
+ if (chrome.runtime.lastError.message == 'Failed to stop discovery') {
+ // May happen if also started elsewhere; ignore.
+ return;
+ }
+ console.error('startDsicovery Error: ' +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /** @private */
+ stopDiscovery_: function() {
+ if (!this.get('adapterState.discovering'))
+ return;
+
+ if (this.bluetoothPrivateOnPairingListener_) {
+ this.bluetoothPrivate.onPairing.removeListener(
+ this.bluetoothPrivateOnPairingListener_);
+ this.bluetoothPrivateOnPairingListener_ = undefined;
+ }
+
+ this.bluetooth.stopDiscovery(function() {
+ if (chrome.runtime.lastError) {
+ console.error('Error stopping bluetooth discovery: ' +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /**
+ * Process bluetoothPrivate.onPairing events.
+ * @param {!chrome.bluetoothPrivate.PairingEvent} e
+ * @private
+ */
+ onBluetoothPrivateOnPairing_: function(e) {
+ if (!this.dialog || !this.pairingDevice ||
+ e.device.address != this.pairingDevice.address) {
+ return;
+ }
+ if (e.pairing == chrome.bluetoothPrivate.PairingEventType.KEYS_ENTERED &&
+ e.passkey === undefined && this.pairingEvent) {
+ // 'keysEntered' event might not include the updated passkey so preserve
+ // the current one.
+ e.passkey = this.pairingEvent.passkey;
+ }
+ this.pairingEvent = e;
+ },
+
+ /** @private */
+ onAddDeviceTap_: function() { this.openDialog_('addDevice'); },
+
+ /**
+ * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e
+ * @private
+ */
+ onDeviceEvent_: function(e) {
+ var action = e.detail.action;
+ var device = e.detail.device;
+ if (action == 'connect')
+ this.connectDevice_(device);
+ else if (action == 'disconnect')
+ this.disconnectDevice_(device);
+ else if (action == 'remove')
+ this.forgetDevice_(device);
+ else
+ console.error('Unexected action: ' + action);
+ },
+
+ /**
+ * Handle a response sent from the pairing dialog and pass it to the
+ * bluetoothPrivate API.
+ * @param {Event} e
+ * @private
+ */
+ onResponse_: function(e) {
+ var options =
+ /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ (
+ e.detail);
+ this.bluetoothPrivate.setPairingResponse(options, function() {
+ if (chrome.runtime.lastError) {
+ // TODO(stevenjb): Show error.
+ console.error(
+ 'Error setting pairing response: ' + options.device.name +
+ ': Response: ' + options.response + ': Error: ' +
+ chrome.runtime.lastError.message);
+ }
+ this.closeDialog_();
+ }.bind(this));
+ },
+
+ /**
+ * @param {string} address
+ * @return {number} The index of the device associated with |address| or -1.
+ * @private
+ */
+ getDeviceIndex_: function(address) {
+ var len = this.deviceList.length;
+ for (var i = 0; i < len; ++i) {
+ if (this.deviceList[i].address == address)
+ return i;
+ }
+ return -1;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {string} The text to display for |device| in the device list.
+ * @private
+ */
+ getDeviceName_: function(device) {
+ return device.name || device.address;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {boolean}
+ * @private
+ */
+ deviceIsPairedOrConnecting_: function(device) {
+ return !!device.paired || !!device.connecting;
+ },
+
+ /**
+ * @param {Object} deviceListChanges Changes to the deviceList Array.
+ * @return {boolean} True if deviceList contains any paired devices.
+ * @private
+ */
+ haveDevices_: function(deviceListChanges) {
+ return this.deviceList.findIndex(function(d) { return d.paired; }) != -1;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ connectDevice_: function(device) {
+ // If the device is not paired, show the pairing dialog.
+ if (!device.paired) {
+ // Set the pairing device and clear any pairing event.
+ this.pairingDevice = device;
+ this.pairingEvent = null;
+
+ this.openDialog_('pairDevice');
+ }
+
+ this.bluetoothPrivate.connect(device.address, function(result) {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error connecting: ' + device.address +
+ chrome.runtime.lastError.message);
+ // TODO(stevenjb): Show error message insead.
+ this.closeDialog_();
+ }
+ }.bind(this));
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ disconnectDevice_: function(device) {
+ this.bluetoothPrivate.disconnectAll(device.address, function() {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error disconnecting: ' + device.address +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ forgetDevice_: function(device) {
+ this.bluetoothPrivate.forgetDevice(device.address, function() {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error forgetting: ' + device.name + ': ' +
+ chrome.runtime.lastError.message);
+ }
+ this.updateDeviceList_();
+ }.bind(this));
+ },
+
+ /**
+ * @param {string} dialog
+ * @param {string} dialogToShow The name of the dialog.
+ * @return {boolean}
+ * @private
+ */
+ dialogIsVisible_(dialog, dialogToShow) {
+ return dialogToShow == dialog;
+ },
+
+ /**
+ * @param {string} dialogId
+ * @private
+ */
+ openDialog_: function(dialogId) {
+ if (this.dialog) {
+ // Dialog already opened, just update the contents.
+ this.dialog = dialogId;
+ return;
+ }
+ this.dialog = dialogId;
+ // Call flush so that the dialog gets sized correctly before it is opened.
+ Polymer.dom.flush();
+ var dialog = this.$$('#deviceDialog');
+ dialog.open();
+ dialog.focus();
+ },
+
+ /** @private */
+ closeDialog_: function() {
+ if (!this.dialog)
+ return;
+ var dialog = this.$$('#deviceDialog');
+ dialog.close();
+ this.dialog = '';
+ this.pairingDevice = null;
+ this.pairingEvent = null;
+ },
+
+ /** @private */
+ onCloseDialog_: function(event) { this.closeDialog_(); },
+
+ /** @private */
+ onDialogOpened_: function() { this.startDiscovery_(); },
+
+ /** @private */
+ onDialogClosed_: function() { this.stopDiscovery_(); },
+});
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html
new file mode 100644
index 00000000000..05ed236ecd1
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html
@@ -0,0 +1,68 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+
+<dom-module id="settings-bluetooth-pair-device-dialog">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="bluetooth_page.css">
+ <link rel="import" type="css" href="bluetooth_dialog.css">
+ <template>
+ <div id="dialogOuterDiv" class="layout vertical flex">
+ <div id="dialogHeaderDiv" class="settings-box layout horizontal center">
+ <span id="dialogTitle" class="flex"
+ i18n-content="bluetoothPairDevicePageTitle">
+ </span>
+ <paper-icon-button icon="close" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div id="pairing"
+ class="settings-blox layout vertical center center-justified flex">
+ <div id="dialogMessage">
+ [[getMessage_(pairingDevice, pairingEvent)]]
+ </div>
+ <div hidden$="[[!showEnterPincode_(pairingEvent)]]">
+ <paper-input id="pincode" minlength="1" maxlength="16" type="text">
+ </div>
+ <div hidden$="[[!showEnterPasskey_(pairingEvent)]]">
+ <paper-input id="passkey" minlength="6" maxlength="6" type="text">
+ </div>
+ <div id="pinDiv" class="layout horizontal center center-justified"
+ hidden="[[!showDisplayPassOrPin_(pairingEvent)]]">
+ <template is="dom-repeat" items="[[digits]]">
+ <span class$="[[getPinClass_(pairingEvent, index)]]">
+ [[getPinDigit_(pairingEvent, index)]]
+ </span>
+ </template>
+ <span class$="[[getPinClass_(pairingEvent, -1)]]"
+ hidden="[[showAcceptReject_(pairingEvent)]]">
+ [[i18n('bluetoothEnterKey')]]
+ </span>
+ </div>
+ </div>
+ <div id="dialogFooterDiv" class="layout horizontal center end-justified">
+ <paper-button i18n-content="bluetoothAccept"
+ hidden$="[[!showAcceptReject_(pairingEvent)]]"
+ on-tap="onAcceptTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothReject"
+ hidden$="[[!showAcceptReject_(pairingEvent)]]"
+ on-tap="onRejectTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothConnect"
+ hidden$="[[!showConnect_(pairingEvent)]]"
+ on-tap="onConnectTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothDismiss"
+ hidden$="[[!showDismiss_(pairingDevice, pairingEvent)]]"
+ on-tap="onDismissTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothCancel" on-tap="onCancelTap_"
+ hidden$="[[showDismiss_(pairingDevice, pairingEvent)]]"
+ </paper-button>
+ </div>
+ </div>
+ </template>
+ <script src="bluetooth_pair_device_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js
new file mode 100644
index 00000000000..fe286744b2b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js
@@ -0,0 +1,271 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * 'settings-bluetooth-pair-device-dialog' is the settings dialog for pairing
+ * a bluetooth device.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-bluetooth-pair-device-dialog
+ */
+
+(function() {
+
+var PairingEventType = chrome.bluetoothPrivate.PairingEventType;
+
+Polymer({
+ is: 'settings-bluetooth-pair-device-dialog',
+
+ behaviors: [I18nBehavior],
+
+ properties: {
+ /**
+ * Current Pairing device.
+ * @type {?chrome.bluetooth.Device|undefined}
+ */
+ pairingDevice: Object,
+
+ /**
+ * Current Pairing event.
+ * @type {?chrome.bluetoothPrivate.PairingEvent|undefined}
+ */
+ pairingEvent: Object,
+
+ /**
+ * @const
+ * @type {!Array<number>}
+ */
+ digits: {
+ type: Array,
+ readonly: true,
+ value: [0, 1, 2, 3, 4, 5],
+ },
+ },
+
+ observers: [
+ 'pairingChanged_(pairingDevice, pairingEvent)',
+ ],
+
+ /**
+ * @param {?chrome.bluetooth.Device} pairingDevice
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @private
+ */
+ pairingChanged_: function(pairingDevice, pairingEvent) {
+ // Auto-close the dialog when pairing completes.
+ if (pairingDevice && pairingDevice.connected) {
+ this.fire('close-dialog', '');
+ return;
+ }
+ },
+
+ /**
+ * @param {?chrome.bluetooth.Device} device
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {string}
+ * @private
+ */
+ getMessage_: function(device, pairingEvent) {
+ if (!device)
+ return '';
+ var message;
+ if (!pairingEvent)
+ message = 'bluetoothStartConnecting';
+ else
+ message = this.getEventDesc_(pairingEvent.pairing);
+ return this.i18n(message, device.name);
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showEnterPincode_: function(pairingEvent) {
+ return !!pairingEvent &&
+ pairingEvent.pairing == PairingEventType.REQUEST_PINCODE;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showEnterPasskey_: function(pairingEvent) {
+ return !!pairingEvent &&
+ pairingEvent.pairing == PairingEventType.REQUEST_PASSKEY;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showDisplayPassOrPin_: function(pairingEvent) {
+ if (!pairingEvent)
+ return false;
+ var pairing = pairingEvent.pairing;
+ return (
+ pairing == PairingEventType.DISPLAY_PINCODE ||
+ pairing == PairingEventType.DISPLAY_PASSKEY ||
+ pairing == PairingEventType.CONFIRM_PASSKEY ||
+ pairing == PairingEventType.KEYS_ENTERED);
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showAcceptReject_: function(pairingEvent) {
+ return !!pairingEvent &&
+ pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showConnect_: function(pairingEvent) {
+ if (!pairingEvent)
+ return false;
+ var pairing = pairingEvent.pairing;
+ if (pairing == PairingEventType.REQUEST_PINCODE) {
+ var pincode = /** @type {{invalid: boolean}} */(this.$.pincode);
+ return !pincode.invalid;
+ } else if (pairing == PairingEventType.REQUEST_PASSKEY) {
+ var passkey = /** @type {{invalid: boolean}} */(this.$.passkey);
+ return !passkey.invalid;
+ }
+ return false;
+ },
+
+ /**
+ * @param {?chrome.bluetooth.Device} device
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showDismiss_: function(device, pairingEvent) {
+ return (!!device && device.paired) ||
+ (!!pairingEvent && pairingEvent.pairing == PairingEventType.COMPLETE);
+ },
+
+ /** @private */
+ onAcceptTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM);
+ },
+
+ /** @private */
+ onConnectTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM);
+ },
+
+ /** @private */
+ onRejectTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.REJECT);
+ },
+
+ /** @private */
+ onCancelTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL);
+ // Close the dialog immediately.
+ this.fire('close-dialog', '');
+ },
+
+ /** @private */
+ onDismissTap_: function() { this.fire('close-dialog', ''); },
+
+ /** @private */
+ sendResponse_: function(response) {
+ if (!this.pairingDevice)
+ return;
+ var options =
+ /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ {
+ device: this.pairingDevice,
+ response: response
+ };
+ if (response == chrome.bluetoothPrivate.PairingResponse.CONFIRM) {
+ var pairing = this.pairingEvent.pairing;
+ if (pairing == PairingEventType.REQUEST_PINCODE)
+ options.pincode = this.$.pincode.value;
+ else if (pairing == PairingEventType.REQUEST_PASSKEY)
+ options.passkey = parseInt(this.$.passkey.value, 10);
+ }
+ this.fire('response', options);
+ },
+
+ /**
+ * @param {!PairingEventType} eventType
+ * @return {string}
+ * @private
+ */
+ getEventDesc_: function(eventType) {
+ assert(eventType);
+ if (eventType == PairingEventType.COMPLETE ||
+ eventType == PairingEventType.KEYS_ENTERED ||
+ eventType == PairingEventType.REQUEST_AUTHORIZATION) {
+ return 'bluetoothStartConnecting';
+ }
+ return 'bluetooth_' + /** @type {string} */(eventType);
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @param {number} index
+ * @return {string}
+ * @private
+ */
+ getPinDigit_: function(pairingEvent, index) {
+ if (!pairingEvent)
+ return '';
+ var digit = '0';
+ var pairing = pairingEvent.pairing;
+ if (pairing == PairingEventType.DISPLAY_PINCODE && pairingEvent.pincode &&
+ index < pairingEvent.pincode.length) {
+ digit = pairingEvent.pincode[index];
+ } else if (pairingEvent.passkey &&
+ (pairing == PairingEventType.DISPLAY_PASSKEY ||
+ pairing == PairingEventType.KEYS_ENTERED ||
+ pairing == PairingEventType.CONFIRM_PASSKEY)) {
+ var passkeyString = String(pairingEvent.passkey);
+ if (index < passkeyString.length)
+ digit = passkeyString[index];
+ }
+ return digit;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @param {number} index
+ * @return {string}
+ * @private
+ */
+ getPinClass_: function(pairingEvent, index) {
+ if (!pairingEvent)
+ return '';
+ if (pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY)
+ return 'confirm';
+ var cssClass = 'display';
+ if (pairingEvent.pairing == PairingEventType.DISPLAY_PASSKEY) {
+ if (index == 0)
+ cssClass += ' next';
+ else
+ cssClass += ' untyped';
+ } else if (
+ pairingEvent.pairing == PairingEventType.KEYS_ENTERED &&
+ pairingEvent.enteredKey) {
+ var enteredKey = pairingEvent.enteredKey; // 1-7
+ var lastKey = this.digits.length; // 6
+ if ((index == -1 && enteredKey > lastKey) || (index + 1 == enteredKey))
+ cssClass += ' next';
+ else if (index > enteredKey)
+ cssClass += ' untyped';
+ }
+ return cssClass;
+ },
+});
+})();
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp
new file mode 100644
index 00000000000..17032053dd6
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp
@@ -0,0 +1,72 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+ 'targets': [
+ {
+ 'target_name': 'bluetooth_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth_interface.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private_interface.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../settings_page/settings_animated_pages.js'
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'bluetooth_device_list_item',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'bluetooth_add_device_dialog',
+ 'variables': {
+ 'depends': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth_interface.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private_interface.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'bluetooth_pair_device_dialog',
+ 'variables': {
+ 'depends': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth_interface.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private_interface.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}