| Index: chrome/browser/resources/hotword/audio_client.js
|
| diff --git a/chrome/browser/resources/hotword/audio_client.js b/chrome/browser/resources/hotword/audio_client.js
|
| index 25d227a9cdb5fd46c4750c0deadfecc11f74d404..552dd49cdafff1f4ae79213fb6fd2eb50ea05188 100644
|
| --- a/chrome/browser/resources/hotword/audio_client.js
|
| +++ b/chrome/browser/resources/hotword/audio_client.js
|
| @@ -13,364 +13,363 @@
|
| */
|
|
|
| (function() {
|
| - /**
|
| - * @constructor
|
| - */
|
| - var AudioClient = function() {
|
| - /** @private {Element} */
|
| - this.speechOverlay_ = null;
|
| -
|
| - /** @private {number} */
|
| - this.checkSpeechUiRetries_ = 0;
|
| +/**
|
| + * @constructor
|
| + */
|
| +var AudioClient = function() {
|
| + /** @private {Element} */
|
| + this.speechOverlay_ = null;
|
|
|
| - /**
|
| - * Port used to communicate with the audio manager.
|
| - * @private {?Port}
|
| - */
|
| - this.port_ = null;
|
| -
|
| - /**
|
| - * Keeps track of the effects of different commands. Used to verify that
|
| - * proper UIs are shown to the user.
|
| - * @private {Object<AudioClient.CommandToPage, Object>}
|
| - */
|
| - this.uiStatus_ = null;
|
| -
|
| - /**
|
| - * Bound function used to handle commands sent from the page to this script.
|
| - * @private {Function}
|
| - */
|
| - this.handleCommandFromPageFunc_ = null;
|
| - };
|
| + /** @private {number} */
|
| + this.checkSpeechUiRetries_ = 0;
|
|
|
| /**
|
| - * Messages sent to the page to control the voice search UI.
|
| - * @enum {string}
|
| + * Port used to communicate with the audio manager.
|
| + * @private {?Port}
|
| */
|
| - AudioClient.CommandToPage = {
|
| - HOTWORD_VOICE_TRIGGER: 'vt',
|
| - HOTWORD_STARTED: 'hs',
|
| - HOTWORD_ENDED: 'hd',
|
| - HOTWORD_TIMEOUT: 'ht',
|
| - HOTWORD_ERROR: 'he'
|
| - };
|
| + this.port_ = null;
|
|
|
| /**
|
| - * Messages received from the page used to indicate voice search state.
|
| - * @enum {string}
|
| + * Keeps track of the effects of different commands. Used to verify that
|
| + * proper UIs are shown to the user.
|
| + * @private {Object<AudioClient.CommandToPage, Object>}
|
| */
|
| - AudioClient.CommandFromPage = {
|
| - SPEECH_START: 'ss',
|
| - SPEECH_END: 'se',
|
| - SPEECH_RESET: 'sr',
|
| - SHOWING_HOTWORD_START: 'shs',
|
| - SHOWING_ERROR_MESSAGE: 'sem',
|
| - SHOWING_TIMEOUT_MESSAGE: 'stm',
|
| - CLICKED_RESUME: 'hcc',
|
| - CLICKED_RESTART: 'hcr',
|
| - CLICKED_DEBUG: 'hcd'
|
| - };
|
| + this.uiStatus_ = null;
|
|
|
| /**
|
| - * Errors that are sent to the hotword extension.
|
| - * @enum {string}
|
| + * Bound function used to handle commands sent from the page to this script.
|
| + * @private {Function}
|
| */
|
| - AudioClient.Error = {
|
| - NO_SPEECH_UI: 'ac1',
|
| - NO_HOTWORD_STARTED_UI: 'ac2',
|
| - NO_HOTWORD_TIMEOUT_UI: 'ac3',
|
| - NO_HOTWORD_ERROR_UI: 'ac4'
|
| - };
|
| + this.handleCommandFromPageFunc_ = null;
|
| +};
|
|
|
| - /**
|
| - * @const {string}
|
| - * @private
|
| - */
|
| - AudioClient.HOTWORD_EXTENSION_ID_ = 'nbpagnldghgfoolbancepceaanlmhfmd';
|
| +/**
|
| + * Messages sent to the page to control the voice search UI.
|
| + * @enum {string}
|
| + */
|
| +AudioClient.CommandToPage = {
|
| + HOTWORD_VOICE_TRIGGER: 'vt',
|
| + HOTWORD_STARTED: 'hs',
|
| + HOTWORD_ENDED: 'hd',
|
| + HOTWORD_TIMEOUT: 'ht',
|
| + HOTWORD_ERROR: 'he'
|
| +};
|
|
|
| - /**
|
| - * Number of times to retry checking a transient error.
|
| - * @const {number}
|
| - * @private
|
| - */
|
| - AudioClient.MAX_RETRIES = 3;
|
| +/**
|
| + * Messages received from the page used to indicate voice search state.
|
| + * @enum {string}
|
| + */
|
| +AudioClient.CommandFromPage = {
|
| + SPEECH_START: 'ss',
|
| + SPEECH_END: 'se',
|
| + SPEECH_RESET: 'sr',
|
| + SHOWING_HOTWORD_START: 'shs',
|
| + SHOWING_ERROR_MESSAGE: 'sem',
|
| + SHOWING_TIMEOUT_MESSAGE: 'stm',
|
| + CLICKED_RESUME: 'hcc',
|
| + CLICKED_RESTART: 'hcr',
|
| + CLICKED_DEBUG: 'hcd'
|
| +};
|
|
|
| - /**
|
| - * Delay to wait in milliseconds before rechecking for any transient errors.
|
| - * @const {number}
|
| - * @private
|
| - */
|
| - AudioClient.RETRY_TIME_MS_ = 2000;
|
| +/**
|
| + * Errors that are sent to the hotword extension.
|
| + * @enum {string}
|
| + */
|
| +AudioClient.Error = {
|
| + NO_SPEECH_UI: 'ac1',
|
| + NO_HOTWORD_STARTED_UI: 'ac2',
|
| + NO_HOTWORD_TIMEOUT_UI: 'ac3',
|
| + NO_HOTWORD_ERROR_UI: 'ac4'
|
| +};
|
|
|
| - /**
|
| - * DOM ID for the speech UI overlay.
|
| - * @const {string}
|
| - * @private
|
| - */
|
| - AudioClient.SPEECH_UI_OVERLAY_ID_ = 'spch';
|
| +/**
|
| + * @const {string}
|
| + * @private
|
| + */
|
| +AudioClient.HOTWORD_EXTENSION_ID_ = 'nbpagnldghgfoolbancepceaanlmhfmd';
|
|
|
| - /**
|
| - * @const {string}
|
| - * @private
|
| - */
|
| - AudioClient.HELP_CENTER_URL_ =
|
| - 'https://support.google.com/chrome/?p=ui_hotword_search';
|
| +/**
|
| + * Number of times to retry checking a transient error.
|
| + * @const {number}
|
| + * @private
|
| + */
|
| +AudioClient.MAX_RETRIES = 3;
|
|
|
| - /**
|
| - * @const {string}
|
| - * @private
|
| - */
|
| - AudioClient.CLIENT_PORT_NAME_ = 'chwcpn';
|
| +/**
|
| + * Delay to wait in milliseconds before rechecking for any transient errors.
|
| + * @const {number}
|
| + * @private
|
| + */
|
| +AudioClient.RETRY_TIME_MS_ = 2000;
|
|
|
| - /**
|
| - * Existence of the Audio Client.
|
| - * @const {string}
|
| - * @private
|
| - */
|
| - AudioClient.EXISTS_ = 'chwace';
|
| +/**
|
| + * DOM ID for the speech UI overlay.
|
| + * @const {string}
|
| + * @private
|
| + */
|
| +AudioClient.SPEECH_UI_OVERLAY_ID_ = 'spch';
|
|
|
| - /**
|
| - * Checks for the presence of speech overlay UI DOM elements.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.checkSpeechOverlayUi_ = function() {
|
| - if (!this.speechOverlay_) {
|
| - window.setTimeout(
|
| - this.delayedCheckSpeechOverlayUi_.bind(this),
|
| - AudioClient.RETRY_TIME_MS_);
|
| - } else {
|
| - this.checkSpeechUiRetries_ = 0;
|
| - }
|
| - };
|
| +/**
|
| + * @const {string}
|
| + * @private
|
| + */
|
| +AudioClient.HELP_CENTER_URL_ =
|
| + 'https://support.google.com/chrome/?p=ui_hotword_search';
|
|
|
| - /**
|
| - * Function called to check for the speech UI overlay after some time has
|
| - * passed since an initial check. Will either retry triggering the speech
|
| - * or sends an error message depending on the number of retries.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.delayedCheckSpeechOverlayUi_ = function() {
|
| - this.speechOverlay_ =
|
| - document.getElementById(AudioClient.SPEECH_UI_OVERLAY_ID_);
|
| - if (!this.speechOverlay_) {
|
| - if (this.checkSpeechUiRetries_++ < AudioClient.MAX_RETRIES) {
|
| - this.sendCommandToPage_(AudioClient.CommandToPage.VOICE_TRIGGER);
|
| - this.checkSpeechOverlayUi_();
|
| - } else {
|
| - this.sendCommandToExtension_(AudioClient.Error.NO_SPEECH_UI);
|
| - }
|
| - } else {
|
| - this.checkSpeechUiRetries_ = 0;
|
| - }
|
| - };
|
| +/**
|
| + * @const {string}
|
| + * @private
|
| + */
|
| +AudioClient.CLIENT_PORT_NAME_ = 'chwcpn';
|
|
|
| - /**
|
| - * Checks that the triggered UI is actually displayed.
|
| - * @param {AudioClient.CommandToPage} command Command that was send.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.checkUi_ = function(command) {
|
| - this.uiStatus_[command].timeoutId = window.setTimeout(
|
| - this.failedCheckUi_.bind(this, command), AudioClient.RETRY_TIME_MS_);
|
| - };
|
| +/**
|
| + * Existence of the Audio Client.
|
| + * @const {string}
|
| + * @private
|
| + */
|
| +AudioClient.EXISTS_ = 'chwace';
|
|
|
| - /**
|
| - * Function called when the UI verification is not called in time. Will either
|
| - * retry the command or sends an error message, depending on the number of
|
| - * retries for the command.
|
| - * @param {AudioClient.CommandToPage} command Command that was sent.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.failedCheckUi_ = function(command) {
|
| - if (this.uiStatus_[command].tries++ < AudioClient.MAX_RETRIES) {
|
| - this.sendCommandToPage_(command);
|
| - this.checkUi_(command);
|
| +/**
|
| + * Checks for the presence of speech overlay UI DOM elements.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.checkSpeechOverlayUi_ = function() {
|
| + if (!this.speechOverlay_) {
|
| + window.setTimeout(
|
| + this.delayedCheckSpeechOverlayUi_.bind(this),
|
| + AudioClient.RETRY_TIME_MS_);
|
| + } else {
|
| + this.checkSpeechUiRetries_ = 0;
|
| + }
|
| +};
|
| +
|
| +/**
|
| + * Function called to check for the speech UI overlay after some time has
|
| + * passed since an initial check. Will either retry triggering the speech
|
| + * or sends an error message depending on the number of retries.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.delayedCheckSpeechOverlayUi_ = function() {
|
| + this.speechOverlay_ =
|
| + document.getElementById(AudioClient.SPEECH_UI_OVERLAY_ID_);
|
| + if (!this.speechOverlay_) {
|
| + if (this.checkSpeechUiRetries_++ < AudioClient.MAX_RETRIES) {
|
| + this.sendCommandToPage_(AudioClient.CommandToPage.VOICE_TRIGGER);
|
| + this.checkSpeechOverlayUi_();
|
| } else {
|
| - this.sendCommandToExtension_(this.uiStatus_[command].error);
|
| + this.sendCommandToExtension_(AudioClient.Error.NO_SPEECH_UI);
|
| }
|
| - };
|
| + } else {
|
| + this.checkSpeechUiRetries_ = 0;
|
| + }
|
| +};
|
|
|
| - /**
|
| - * Confirm that an UI element has been shown.
|
| - * @param {AudioClient.CommandToPage} command UI to confirm.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.verifyUi_ = function(command) {
|
| - if (this.uiStatus_[command].timeoutId) {
|
| - window.clearTimeout(this.uiStatus_[command].timeoutId);
|
| - this.uiStatus_[command].timeoutId = null;
|
| - this.uiStatus_[command].tries = 0;
|
| - }
|
| - };
|
| +/**
|
| + * Checks that the triggered UI is actually displayed.
|
| + * @param {AudioClient.CommandToPage} command Command that was send.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.checkUi_ = function(command) {
|
| + this.uiStatus_[command].timeoutId = window.setTimeout(
|
| + this.failedCheckUi_.bind(this, command), AudioClient.RETRY_TIME_MS_);
|
| +};
|
|
|
| - /**
|
| - * Sends a command to the audio manager.
|
| - * @param {string} commandStr command to send to plugin.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.sendCommandToExtension_ = function(commandStr) {
|
| - if (this.port_)
|
| - this.port_.postMessage({'cmd': commandStr});
|
| - };
|
| +/**
|
| + * Function called when the UI verification is not called in time. Will either
|
| + * retry the command or sends an error message, depending on the number of
|
| + * retries for the command.
|
| + * @param {AudioClient.CommandToPage} command Command that was sent.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.failedCheckUi_ = function(command) {
|
| + if (this.uiStatus_[command].tries++ < AudioClient.MAX_RETRIES) {
|
| + this.sendCommandToPage_(command);
|
| + this.checkUi_(command);
|
| + } else {
|
| + this.sendCommandToExtension_(this.uiStatus_[command].error);
|
| + }
|
| +};
|
|
|
| - /**
|
| - * Handles a message from the audio manager.
|
| - * @param {{cmd: string}} commandObj Command from the audio manager.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.handleCommandFromExtension_ = function(commandObj) {
|
| - var command = commandObj['cmd'];
|
| - if (command) {
|
| - switch (command) {
|
| - case AudioClient.CommandToPage.HOTWORD_VOICE_TRIGGER:
|
| - this.sendCommandToPage_(command);
|
| - this.checkSpeechOverlayUi_();
|
| - break;
|
| - case AudioClient.CommandToPage.HOTWORD_STARTED:
|
| - this.sendCommandToPage_(command);
|
| - this.checkUi_(command);
|
| - break;
|
| - case AudioClient.CommandToPage.HOTWORD_ENDED:
|
| - this.sendCommandToPage_(command);
|
| - break;
|
| - case AudioClient.CommandToPage.HOTWORD_TIMEOUT:
|
| - this.sendCommandToPage_(command);
|
| - this.checkUi_(command);
|
| - break;
|
| - case AudioClient.CommandToPage.HOTWORD_ERROR:
|
| - this.sendCommandToPage_(command);
|
| - this.checkUi_(command);
|
| - break;
|
| - }
|
| - }
|
| - };
|
| +/**
|
| + * Confirm that an UI element has been shown.
|
| + * @param {AudioClient.CommandToPage} command UI to confirm.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.verifyUi_ = function(command) {
|
| + if (this.uiStatus_[command].timeoutId) {
|
| + window.clearTimeout(this.uiStatus_[command].timeoutId);
|
| + this.uiStatus_[command].timeoutId = null;
|
| + this.uiStatus_[command].tries = 0;
|
| + }
|
| +};
|
|
|
| - /**
|
| - * @param {AudioClient.CommandToPage} commandStr Command to send.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.sendCommandToPage_ = function(commandStr) {
|
| - window.postMessage({'type': commandStr}, '*');
|
| - };
|
| +/**
|
| + * Sends a command to the audio manager.
|
| + * @param {string} commandStr command to send to plugin.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.sendCommandToExtension_ = function(commandStr) {
|
| + if (this.port_)
|
| + this.port_.postMessage({'cmd': commandStr});
|
| +};
|
|
|
| - /**
|
| - * Handles a message from the html window.
|
| - * @param {!MessageEvent} messageEvent Message event from the window.
|
| - * @private
|
| - */
|
| - AudioClient.prototype.handleCommandFromPage_ = function(messageEvent) {
|
| - if (messageEvent.source == window && messageEvent.data.type) {
|
| - var command = messageEvent.data.type;
|
| - switch (command) {
|
| - case AudioClient.CommandFromPage.SPEECH_START:
|
| - this.speechActive_ = true;
|
| - this.sendCommandToExtension_(command);
|
| - break;
|
| - case AudioClient.CommandFromPage.SPEECH_END:
|
| - this.speechActive_ = false;
|
| - this.sendCommandToExtension_(command);
|
| - break;
|
| - case AudioClient.CommandFromPage.SPEECH_RESET:
|
| - this.speechActive_ = false;
|
| - this.sendCommandToExtension_(command);
|
| - break;
|
| - case 'SPEECH_RESET': // Legacy, for embedded NTP.
|
| - this.speechActive_ = false;
|
| - this.sendCommandToExtension_(AudioClient.CommandFromPage.SPEECH_END);
|
| - break;
|
| - case AudioClient.CommandFromPage.CLICKED_RESUME:
|
| - this.sendCommandToExtension_(command);
|
| - break;
|
| - case AudioClient.CommandFromPage.CLICKED_RESTART:
|
| - this.sendCommandToExtension_(command);
|
| - break;
|
| - case AudioClient.CommandFromPage.CLICKED_DEBUG:
|
| - window.open(AudioClient.HELP_CENTER_URL_, '_blank');
|
| - break;
|
| - case AudioClient.CommandFromPage.SHOWING_HOTWORD_START:
|
| - this.verifyUi_(AudioClient.CommandToPage.HOTWORD_STARTED);
|
| - break;
|
| - case AudioClient.CommandFromPage.SHOWING_ERROR_MESSAGE:
|
| - this.verifyUi_(AudioClient.CommandToPage.HOTWORD_ERROR);
|
| - break;
|
| - case AudioClient.CommandFromPage.SHOWING_TIMEOUT_MESSAGE:
|
| - this.verifyUi_(AudioClient.CommandToPage.HOTWORD_TIMEOUT);
|
| - break;
|
| - }
|
| +/**
|
| + * Handles a message from the audio manager.
|
| + * @param {{cmd: string}} commandObj Command from the audio manager.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.handleCommandFromExtension_ = function(commandObj) {
|
| + var command = commandObj['cmd'];
|
| + if (command) {
|
| + switch (command) {
|
| + case AudioClient.CommandToPage.HOTWORD_VOICE_TRIGGER:
|
| + this.sendCommandToPage_(command);
|
| + this.checkSpeechOverlayUi_();
|
| + break;
|
| + case AudioClient.CommandToPage.HOTWORD_STARTED:
|
| + this.sendCommandToPage_(command);
|
| + this.checkUi_(command);
|
| + break;
|
| + case AudioClient.CommandToPage.HOTWORD_ENDED:
|
| + this.sendCommandToPage_(command);
|
| + break;
|
| + case AudioClient.CommandToPage.HOTWORD_TIMEOUT:
|
| + this.sendCommandToPage_(command);
|
| + this.checkUi_(command);
|
| + break;
|
| + case AudioClient.CommandToPage.HOTWORD_ERROR:
|
| + this.sendCommandToPage_(command);
|
| + this.checkUi_(command);
|
| + break;
|
| }
|
| - };
|
| + }
|
| +};
|
|
|
| - /**
|
| - * Initialize the content script.
|
| - */
|
| - AudioClient.prototype.initialize = function() {
|
| - if (AudioClient.EXISTS_ in window)
|
| - return;
|
| - window[AudioClient.EXISTS_] = true;
|
| -
|
| - // UI verification object.
|
| - this.uiStatus_ = {};
|
| - this.uiStatus_[AudioClient.CommandToPage.HOTWORD_STARTED] = {
|
| - timeoutId: null,
|
| - tries: 0,
|
| - error: AudioClient.Error.NO_HOTWORD_STARTED_UI
|
| - };
|
| - this.uiStatus_[AudioClient.CommandToPage.HOTWORD_TIMEOUT] = {
|
| - timeoutId: null,
|
| - tries: 0,
|
| - error: AudioClient.Error.NO_HOTWORD_TIMEOUT_UI
|
| - };
|
| - this.uiStatus_[AudioClient.CommandToPage.HOTWORD_ERROR] = {
|
| - timeoutId: null,
|
| - tries: 0,
|
| - error: AudioClient.Error.NO_HOTWORD_ERROR_UI
|
| - };
|
| -
|
| - this.handleCommandFromPageFunc_ = this.handleCommandFromPage_.bind(this);
|
| - window.addEventListener('message', this.handleCommandFromPageFunc_, false);
|
| - this.initPort_();
|
| - };
|
| +/**
|
| + * @param {AudioClient.CommandToPage} commandStr Command to send.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.sendCommandToPage_ = function(commandStr) {
|
| + window.postMessage({'type': commandStr}, '*');
|
| +};
|
|
|
| - /**
|
| - * Initialize the communications port with the audio manager. This
|
| - * function will be also be called again if the audio-manager
|
| - * disconnects for some reason (such as the extension
|
| - * background.html page being reloaded).
|
| - * @private
|
| - */
|
| - AudioClient.prototype.initPort_ = function() {
|
| - this.port_ = chrome.runtime.connect(
|
| - AudioClient.HOTWORD_EXTENSION_ID_,
|
| - {'name': AudioClient.CLIENT_PORT_NAME_});
|
| - // Note that this listen may have to be destroyed manually if AudioClient
|
| - // is ever destroyed on this tab.
|
| - this.port_.onDisconnect.addListener(
|
| - (function(e) {
|
| - if (this.handleCommandFromPageFunc_) {
|
| - window.removeEventListener(
|
| - 'message', this.handleCommandFromPageFunc_, false);
|
| - }
|
| - delete window[AudioClient.EXISTS_];
|
| - }).bind(this));
|
| -
|
| - // See note above.
|
| - this.port_.onMessage.addListener(
|
| - this.handleCommandFromExtension_.bind(this));
|
| -
|
| - if (this.speechActive_) {
|
| - this.sendCommandToExtension_(AudioClient.CommandFromPage.SPEECH_START);
|
| - } else {
|
| - // It's possible for this script to be injected into the page after it has
|
| - // completed loaded (i.e. when prerendering). In this case, this script
|
| - // won't receive a SPEECH_RESET from the page to forward onto the
|
| - // extension. To make up for this, always send a SPEECH_RESET. This means
|
| - // in most cases, the extension will receive SPEECH_RESET twice, one from
|
| - // this sendCommandToExtension_ and the one forwarded from the page. But
|
| - // that's OK and the extension can handle it.
|
| - this.sendCommandToExtension_(AudioClient.CommandFromPage.SPEECH_RESET);
|
| +/**
|
| + * Handles a message from the html window.
|
| + * @param {!MessageEvent} messageEvent Message event from the window.
|
| + * @private
|
| + */
|
| +AudioClient.prototype.handleCommandFromPage_ = function(messageEvent) {
|
| + if (messageEvent.source == window && messageEvent.data.type) {
|
| + var command = messageEvent.data.type;
|
| + switch (command) {
|
| + case AudioClient.CommandFromPage.SPEECH_START:
|
| + this.speechActive_ = true;
|
| + this.sendCommandToExtension_(command);
|
| + break;
|
| + case AudioClient.CommandFromPage.SPEECH_END:
|
| + this.speechActive_ = false;
|
| + this.sendCommandToExtension_(command);
|
| + break;
|
| + case AudioClient.CommandFromPage.SPEECH_RESET:
|
| + this.speechActive_ = false;
|
| + this.sendCommandToExtension_(command);
|
| + break;
|
| + case 'SPEECH_RESET': // Legacy, for embedded NTP.
|
| + this.speechActive_ = false;
|
| + this.sendCommandToExtension_(AudioClient.CommandFromPage.SPEECH_END);
|
| + break;
|
| + case AudioClient.CommandFromPage.CLICKED_RESUME:
|
| + this.sendCommandToExtension_(command);
|
| + break;
|
| + case AudioClient.CommandFromPage.CLICKED_RESTART:
|
| + this.sendCommandToExtension_(command);
|
| + break;
|
| + case AudioClient.CommandFromPage.CLICKED_DEBUG:
|
| + window.open(AudioClient.HELP_CENTER_URL_, '_blank');
|
| + break;
|
| + case AudioClient.CommandFromPage.SHOWING_HOTWORD_START:
|
| + this.verifyUi_(AudioClient.CommandToPage.HOTWORD_STARTED);
|
| + break;
|
| + case AudioClient.CommandFromPage.SHOWING_ERROR_MESSAGE:
|
| + this.verifyUi_(AudioClient.CommandToPage.HOTWORD_ERROR);
|
| + break;
|
| + case AudioClient.CommandFromPage.SHOWING_TIMEOUT_MESSAGE:
|
| + this.verifyUi_(AudioClient.CommandToPage.HOTWORD_TIMEOUT);
|
| + break;
|
| }
|
| + }
|
| +};
|
| +
|
| +/**
|
| + * Initialize the content script.
|
| + */
|
| +AudioClient.prototype.initialize = function() {
|
| + if (AudioClient.EXISTS_ in window)
|
| + return;
|
| + window[AudioClient.EXISTS_] = true;
|
| +
|
| + // UI verification object.
|
| + this.uiStatus_ = {};
|
| + this.uiStatus_[AudioClient.CommandToPage.HOTWORD_STARTED] = {
|
| + timeoutId: null,
|
| + tries: 0,
|
| + error: AudioClient.Error.NO_HOTWORD_STARTED_UI
|
| + };
|
| + this.uiStatus_[AudioClient.CommandToPage.HOTWORD_TIMEOUT] = {
|
| + timeoutId: null,
|
| + tries: 0,
|
| + error: AudioClient.Error.NO_HOTWORD_TIMEOUT_UI
|
| + };
|
| + this.uiStatus_[AudioClient.CommandToPage.HOTWORD_ERROR] = {
|
| + timeoutId: null,
|
| + tries: 0,
|
| + error: AudioClient.Error.NO_HOTWORD_ERROR_UI
|
| };
|
|
|
| - // Initializes as soon as the code is ready, do not wait for the page.
|
| - new AudioClient().initialize();
|
| + this.handleCommandFromPageFunc_ = this.handleCommandFromPage_.bind(this);
|
| + window.addEventListener('message', this.handleCommandFromPageFunc_, false);
|
| + this.initPort_();
|
| +};
|
| +
|
| +/**
|
| + * Initialize the communications port with the audio manager. This
|
| + * function will be also be called again if the audio-manager
|
| + * disconnects for some reason (such as the extension
|
| + * background.html page being reloaded).
|
| + * @private
|
| + */
|
| +AudioClient.prototype.initPort_ = function() {
|
| + this.port_ = chrome.runtime.connect(
|
| + AudioClient.HOTWORD_EXTENSION_ID_,
|
| + {'name': AudioClient.CLIENT_PORT_NAME_});
|
| + // Note that this listen may have to be destroyed manually if AudioClient
|
| + // is ever destroyed on this tab.
|
| + this.port_.onDisconnect.addListener(
|
| + (function(e) {
|
| + if (this.handleCommandFromPageFunc_) {
|
| + window.removeEventListener(
|
| + 'message', this.handleCommandFromPageFunc_, false);
|
| + }
|
| + delete window[AudioClient.EXISTS_];
|
| + }).bind(this));
|
| +
|
| + // See note above.
|
| + this.port_.onMessage.addListener(this.handleCommandFromExtension_.bind(this));
|
| +
|
| + if (this.speechActive_) {
|
| + this.sendCommandToExtension_(AudioClient.CommandFromPage.SPEECH_START);
|
| + } else {
|
| + // It's possible for this script to be injected into the page after it has
|
| + // completed loaded (i.e. when prerendering). In this case, this script
|
| + // won't receive a SPEECH_RESET from the page to forward onto the
|
| + // extension. To make up for this, always send a SPEECH_RESET. This means
|
| + // in most cases, the extension will receive SPEECH_RESET twice, one from
|
| + // this sendCommandToExtension_ and the one forwarded from the page. But
|
| + // that's OK and the extension can handle it.
|
| + this.sendCommandToExtension_(AudioClient.CommandFromPage.SPEECH_RESET);
|
| + }
|
| +};
|
| +
|
| +// Initializes as soon as the code is ready, do not wait for the page.
|
| +new AudioClient().initialize();
|
| })();
|
|
|