| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import './diagnose_info_view.js'; |
| |
| import {getRequiredElement} from 'chrome://resources/js/util.js'; |
| |
| import type {DiagnoseInfoViewElement} from './diagnose_info_view.js'; |
| import type {AccessPointData, GeolocationDiagnostics, GeolocationInternalsObserverInterface, NetworkLocationResponse} from './geolocation_internals.mojom-webui.js'; |
| import {GeolocationInternalsObserverReceiver, GeolocationInternalsRemote} from './geolocation_internals.mojom-webui.js'; |
| import {LocationInternalsHandler} from './location_internals.mojom-webui.js'; |
| |
| export const WATCH_BUTTON_ID = 'watch-btn'; |
| export const LOG_BUTTON_ID = 'log-btn'; |
| export const REFRESH_STATUS_ID = 'refresh-status'; |
| export const REFRESH_STATUS_SUCCESS = 'Last updated '; |
| export const REFRESH_STATUS_UNINITIALIZED = |
| `Geolocation API is not initialized. Click "Start Watching Position" to |
| begin.`; |
| export const REFRESH_FINISH_EVENT = 'refresh-finish-event'; |
| export const DIAGNOSE_INFO_VIEW_ID = 'diagnose-info-view'; |
| |
| let watchId: number = -1; |
| let geolocationInternals: GeolocationInternalsRemote|undefined; |
| let geolocationInternalsObserver: GeolocationInternalsObserverReceiver| |
| undefined; |
| const diagnoseInfoView = |
| getRequiredElement<DiagnoseInfoViewElement>(DIAGNOSE_INFO_VIEW_ID); |
| |
| class GeolocationInternalsObserver implements |
| GeolocationInternalsObserverInterface { |
| onDiagnosticsChanged(diagnostics: GeolocationDiagnostics) { |
| handleDiagnosticsChanged(diagnostics); |
| } |
| onNetworkLocationRequested(request: AccessPointData[]) { |
| handleNetworkLocationRequested(request); |
| } |
| onNetworkLocationReceived(response: NetworkLocationResponse|null) { |
| handleNetworkLocationReceived(response); |
| } |
| } |
| |
| // Initialize buttons callback |
| function initializeButtons() { |
| const watchButton = getRequiredElement<HTMLElement>(WATCH_BUTTON_ID); |
| watchButton.addEventListener('click', watchPosition); |
| const saveButton = getRequiredElement<HTMLElement>(LOG_BUTTON_ID); |
| saveButton.addEventListener('click', saveDiagnostics); |
| } |
| |
| // Initialize Mojo pipe |
| export function initializeMojo() { |
| geolocationInternals = new GeolocationInternalsRemote(); |
| LocationInternalsHandler.getRemote().bindInternalsInterface( |
| geolocationInternals.$.bindNewPipeAndPassReceiver()); |
| |
| geolocationInternalsObserver = new GeolocationInternalsObserverReceiver( |
| new GeolocationInternalsObserver()); |
| geolocationInternals |
| .addInternalsObserver( |
| geolocationInternalsObserver.$.bindNewPipeAndPassRemote()) |
| .then(data => { |
| handleDiagnosticsChanged(data.diagnostics); |
| }); |
| } |
| |
| function watchPosition() { |
| const watchButton = getRequiredElement<HTMLElement>(WATCH_BUTTON_ID); |
| if (watchId === -1) { |
| watchId = navigator.geolocation.watchPosition( |
| diagnoseInfoView.watchPositionSuccess, |
| diagnoseInfoView.watchPositionError, { |
| enableHighAccuracy: true, |
| timeout: 5000, |
| maximumAge: 0, |
| }); |
| watchButton.textContent = 'Stop Watching Position'; |
| } else { |
| navigator.geolocation.clearWatch(watchId); |
| watchId = -1; |
| watchButton.textContent = 'Start Watching Position'; |
| } |
| } |
| |
| function handleDiagnosticsChanged(diagnostics: GeolocationDiagnostics|null) { |
| const refreshStatus = getRequiredElement(REFRESH_STATUS_ID); |
| if (diagnostics) { |
| refreshStatus.textContent = |
| REFRESH_STATUS_SUCCESS + new Date().toLocaleString(); |
| diagnoseInfoView.updateDiagnosticsTables(diagnostics); |
| } else { |
| refreshStatus.textContent = REFRESH_STATUS_UNINITIALIZED; |
| } |
| window.dispatchEvent(new CustomEvent(REFRESH_FINISH_EVENT)); |
| } |
| |
| function handleNetworkLocationRequested(request: AccessPointData[]) { |
| diagnoseInfoView.updateLastNetworkRequestTable(request); |
| window.dispatchEvent(new CustomEvent(REFRESH_FINISH_EVENT)); |
| } |
| |
| function handleNetworkLocationReceived(response: NetworkLocationResponse|null) { |
| diagnoseInfoView.updateLastNetworkResponseTable(response); |
| window.dispatchEvent(new CustomEvent(REFRESH_FINISH_EVENT)); |
| } |
| |
| function saveDiagnostics() { |
| const tables = diagnoseInfoView.outputTables(); |
| const content = JSON.stringify(tables, null, 2); |
| const blob = new Blob([content], {type: 'application/json'}); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `location_internals_${new Date().toISOString()}.json`; |
| a.click(); |
| } |
| |
| document.addEventListener('DOMContentLoaded', () => { |
| initializeButtons(); |
| initializeMojo(); |
| }); |