| Index: chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
|
| diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
|
| index 9f1c578f878d9ab392bb5215378309d1d0b4be4b..e46d742cf6c1be2d5ba3aea1950fb77ced07ea55 100644
|
| --- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
|
| +++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
|
| @@ -8,17 +8,34 @@
|
| */
|
|
|
| // Expose for testing.
|
| +/** @type {adapter_broker.AdapterBroker} */
|
| var adapterBroker = null;
|
| +/** @type {device_collection.DeviceCollection} */
|
| var devices = null;
|
| +/** @type {sidebar.Sidebar} */
|
| var sidebarObj = null;
|
|
|
| cr.define('bluetooth_internals', function() {
|
| /** @const */ var AdapterPage = adapter_page.AdapterPage;
|
| + /** @const */ var DeviceDetailsPage = device_details_page.DeviceDetailsPage;
|
| /** @const */ var DevicesPage = devices_page.DevicesPage;
|
| /** @const */ var PageManager = cr.ui.pageManager.PageManager;
|
| /** @const */ var Snackbar = snackbar.Snackbar;
|
| /** @const */ var SnackbarType = snackbar.SnackbarType;
|
|
|
| + devices = new device_collection.DeviceCollection([]);
|
| +
|
| + /** @type {adapter_page.AdapterPage} */
|
| + var adapterPage = null;
|
| + /** @type {devices_page.DevicesPage} */
|
| + var devicesPage = null;
|
| +
|
| + /** @type {interfaces.BluetoothAdapter.DiscoverySession.ptrClass} */
|
| + var discoverySession = null;
|
| +
|
| + /** @type {boolean} */
|
| + var userRequestedScanStop = false;
|
| +
|
| /**
|
| * Observer for page changes. Used to update page title header.
|
| * @extends {cr.ui.pageManager.PageManager.Observer}
|
| @@ -42,79 +59,87 @@ cr.define('bluetooth_internals', function() {
|
| },
|
| };
|
|
|
| - /** @type {!Map<string, !interfaces.BluetoothDevice.DevicePtr>} */
|
| - var deviceAddressToProxy = new Map();
|
| + /**
|
| + * Removes DeviceDetailsPage with matching device |address|. The associated
|
| + * sidebar item is also removed.
|
| + * @param {string} address
|
| + */
|
| + function removeDeviceDetailsPage(address) {
|
| + var id = 'devices/' + address.toLowerCase();
|
| + sidebarObj.removeItem(id);
|
|
|
| - /** @type {!device_collection.DeviceCollection} */
|
| - devices = new device_collection.DeviceCollection([]);
|
| + var deviceDetailsPage = PageManager.registeredPages[id];
|
| + assert(deviceDetailsPage, 'Device Details page must exist');
|
|
|
| - /** @type {adapter_page.AdapterPage} */
|
| - var adapterPage = null;
|
| - /** @type {devices_page.DevicesPage} */
|
| - var devicesPage = null;
|
| + deviceDetailsPage.disconnect();
|
| + deviceDetailsPage.pageDiv.parentNode.removeChild(deviceDetailsPage.pageDiv);
|
|
|
| - /** @type {interfaces.BluetoothAdapter.DiscoverySession.ptrClass} */
|
| - var discoverySession = null;
|
| + // Inform the devices page that the user is inspecting this device.
|
| + // This will update the links in the device table.
|
| + devicesPage.setInspecting(
|
| + deviceDetailsPage.deviceInfo, false /* isInspecting */);
|
|
|
| - /** @type {boolean} */
|
| - var userRequestedScanStop = false;
|
| -
|
| - function handleInspect(event) {
|
| - // TODO(crbug.com/663470): Move connection logic to DeviceDetailsView
|
| - // when it's added in chrome://bluetooth-internals.
|
| - var address = event.detail.address;
|
| - var proxy = deviceAddressToProxy.get(address);
|
| -
|
| - if (proxy) {
|
| - // Device is already connected, so disconnect.
|
| - proxy.disconnect();
|
| - deviceAddressToProxy.delete(address);
|
| - devices.updateConnectionStatus(
|
| - address, device_collection.ConnectionStatus.DISCONNECTED);
|
| - return;
|
| - }
|
| + PageManager.unregister(deviceDetailsPage);
|
| + }
|
|
|
| - devices.updateConnectionStatus(
|
| - address, device_collection.ConnectionStatus.CONNECTING);
|
| + /**
|
| + * Creates a DeviceDetailsPage with the given |deviceInfo|, appends it to
|
| + * '#page-container', and adds a sidebar item to show the new page. If a
|
| + * page exists that matches |deviceInfo.address|, nothing is created and the
|
| + * existing page is returned.
|
| + * @param {!interfaces.BluetoothDevice.Device} deviceInfo
|
| + * @return {!device_details_page.DeviceDetailsPage}
|
| + */
|
| + function makeDeviceDetailsPage(deviceInfo) {
|
| + var deviceDetailsPageId = 'devices/' + deviceInfo.address.toLowerCase();
|
| + var deviceDetailsPage = PageManager.registeredPages[deviceDetailsPageId];
|
| + if (deviceDetailsPage) return deviceDetailsPage;
|
| +
|
| + var pageSection = document.createElement('section');
|
| + pageSection.hidden = true;
|
| + pageSection.id = deviceDetailsPageId;
|
| + $('page-container').appendChild(pageSection);
|
| +
|
| + deviceDetailsPage = new DeviceDetailsPage(deviceDetailsPageId, deviceInfo);
|
| + deviceDetailsPage.pageDiv.addEventListener('connectionchanged',
|
| + function(event) {
|
| + devices.updateConnectionStatus(
|
| + event.detail.address, event.detail.status);
|
| + });
|
|
|
| - adapterBroker.connectToDevice(address).then(function(deviceProxy) {
|
| - var deviceInfo = devices.getByAddress(address);
|
| - if (!deviceInfo) {
|
| - // Device no longer in list, so drop the connection.
|
| - deviceProxy.disconnect();
|
| - return;
|
| - }
|
| + deviceDetailsPage.pageDiv.addEventListener('infochanged', function(event) {
|
| + devices.addOrUpdate(event.detail.info);
|
| + });
|
|
|
| - deviceAddressToProxy.set(address, deviceProxy);
|
| - devices.updateConnectionStatus(
|
| - address, device_collection.ConnectionStatus.CONNECTED);
|
| - Snackbar.show(deviceInfo.name_for_display + ': Connected',
|
| - SnackbarType.SUCCESS);
|
| -
|
| - // Fetch services asynchronously.
|
| - return deviceProxy.getServices();
|
| - }).then(function(response) {
|
| - if (!response) return;
|
| -
|
| - var deviceInfo = devices.getByAddress(address);
|
| - deviceInfo.services = response.services;
|
| - devices.addOrUpdate(deviceInfo);
|
| - }).catch(function(error) {
|
| - // If a connection error occurs while fetching the services, the proxy
|
| - // reference must be removed.
|
| - var proxy = deviceAddressToProxy.get(address);
|
| - if (proxy) {
|
| - proxy.disconnect();
|
| - deviceAddressToProxy.delete(address);
|
| - }
|
| + deviceDetailsPage.pageDiv.addEventListener('forgetpressed',
|
| + function(event) {
|
| + PageManager.showPageByName(devicesPage.name);
|
| + removeDeviceDetailsPage(event.detail.address);
|
| + });
|
|
|
| - devices.updateConnectionStatus(
|
| - address, device_collection.ConnectionStatus.DISCONNECTED);
|
| + // Inform the devices page that the user is inspecting this device.
|
| + // This will update the links in the device table.
|
| + devicesPage.setInspecting(deviceInfo, true /* isInspecting */);
|
| + PageManager.register(deviceDetailsPage);
|
|
|
| - var deviceInfo = devices.getByAddress(address);
|
| - Snackbar.show(deviceInfo.name_for_display + ': ' + error.message,
|
| - SnackbarType.ERROR, 'Retry', function() { handleInspect(event); });
|
| + sidebarObj.addItem({
|
| + pageName: deviceDetailsPageId,
|
| + text: deviceInfo.name_for_display,
|
| });
|
| +
|
| + deviceDetailsPage.connect();
|
| + return deviceDetailsPage;
|
| + }
|
| +
|
| + /**
|
| + * Updates the DeviceDetailsPage with the matching device |address| and
|
| + * redraws it.
|
| + * @param {string} address
|
| + */
|
| + function updateDeviceDetailsPage(address) {
|
| + var detailPageId = 'devices/' + address.toLowerCase();
|
| + var page = PageManager.registeredPages[detailPageId];
|
| + if (page) page.redraw();
|
| }
|
|
|
| function updateStoppedDiscoverySession() {
|
| @@ -150,18 +175,31 @@ cr.define('bluetooth_internals', function() {
|
| // Hook up device collection events.
|
| adapterBroker.addEventListener('deviceadded', function(event) {
|
| devices.addOrUpdate(event.detail.deviceInfo);
|
| + updateDeviceDetailsPage(event.detail.deviceInfo.address);
|
| });
|
| adapterBroker.addEventListener('devicechanged', function(event) {
|
| devices.addOrUpdate(event.detail.deviceInfo);
|
| + updateDeviceDetailsPage(event.detail.deviceInfo.address);
|
| });
|
| adapterBroker.addEventListener('deviceremoved', function(event) {
|
| devices.remove(event.detail.deviceInfo);
|
| + updateDeviceDetailsPage(event.detail.deviceInfo.address);
|
| });
|
|
|
| response.devices.forEach(devices.addOrUpdate, devices /* this */);
|
|
|
| devicesPage.setDevices(devices);
|
| - devicesPage.pageDiv.addEventListener('inspectpressed', handleInspect);
|
| +
|
| + devicesPage.pageDiv.addEventListener('inspectpressed', function(event) {
|
| + var detailsPage = makeDeviceDetailsPage(
|
| + devices.getByAddress(event.detail.address));
|
| + PageManager.showPageByName(detailsPage.name);
|
| + });
|
| +
|
| + devicesPage.pageDiv.addEventListener('forgetpressed', function(event) {
|
| + PageManager.showPageByName(devicesPage.name);
|
| + removeDeviceDetailsPage(event.detail.address);
|
| + });
|
|
|
| devicesPage.pageDiv.addEventListener('scanpressed', function(event) {
|
| if (discoverySession && discoverySession.ptr.isBound()) {
|
| @@ -215,7 +253,10 @@ cr.define('bluetooth_internals', function() {
|
|
|
| // Set up hash-based navigation.
|
| window.addEventListener('hashchange', function() {
|
| - PageManager.showPageByName(window.location.hash.substr(1));
|
| + // If a user navigates and the page doesn't exist, do nothing.
|
| + var pageName = window.location.hash.substr(1);
|
| + if ($(pageName))
|
| + PageManager.showPageByName(pageName);
|
| });
|
|
|
| if (!window.location.hash) {
|
| @@ -223,7 +264,8 @@ cr.define('bluetooth_internals', function() {
|
| return;
|
| }
|
|
|
| - PageManager.showPageByName(window.location.hash.substr(1));
|
| + // Only the root pages are available on page load.
|
| + PageManager.showPageByName(window.location.hash.split('/')[0].substr(1));
|
| }
|
|
|
| function initializeViews() {
|
| @@ -242,7 +284,7 @@ cr.define('bluetooth_internals', function() {
|
| }
|
|
|
| return {
|
| - initializeViews: initializeViews
|
| + initializeViews: initializeViews,
|
| };
|
| });
|
|
|
|
|