1 // Copyright (c) 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.
8 * @fileoverview This extension manages communications between Chrome,
9 * Google.com pages and the Chrome Hotword extension.
11 * This helper extension is required due to the depoyment plan for Chrome M34:
13 * - The hotword extension will be distributed as an externally loaded
14 * component extension.
15 * - Settings for enabling and disabling the hotword extension has moved to
17 * - Newtab page is served via chrome://newtab/
24 var OptInManager = function() {};
31 OptInManager.HOTWORD_EXTENSION_ID_ = 'bepbmhgboaologfdajaanbcjmnhjmhfn';
35 * Commands sent from the page to this content script.
38 OptInManager.CommandFromPage = {
39 // User has explicitly clicked 'no'.
40 CLICKED_NO_OPTIN: 'hcno',
43 // Audio logging is opted in.
44 AUDIO_LOGGING_ON: 'alon',
45 // Audio logging is opted out.
46 AUDIO_LOGGING_OFF: 'aloff',
47 // User visited an eligible page.
53 * @param {Tab} tab Tab to inject.
54 * @param {function(HotwordStatus)} sendResponse Callback function to respond
56 * @param {HotwordStatus} hotwordStatus Status of the hotword extension.
59 OptInManager.prototype.injectTab_ = function(
60 tab, sendResponse, hotwordStatus) {
61 if (!hotwordStatus.available)
63 if (hotwordStatus.enabled)
64 chrome.tabs.executeScript(tab.id, {'file': 'audio_client.js'});
65 else if (!hotwordStatus.enabledSet)
66 chrome.tabs.executeScript(tab.id, {'file': 'optin_client.js'});
67 sendResponse(hotwordStatus);
72 * Handles messages from the helper content script.
73 * @param {*} request Message from the sender.
74 * @param {MessageSender} sender Information about the sender.
75 * @param {function(HotwordStatus)} sendResponse Callback function to respond
77 * @return {boolean} Whether to maintain the port open to call sendResponse.
80 OptInManager.prototype.handleMessage_ = function(
81 request, sender, sendResponse) {
82 switch (request.type) {
83 case OptInManager.CommandFromPage.PAGE_WAKEUP:
84 if (((sender.tab && this.isEligibleUrl(sender.tab.url)) ||
85 sender.id == OptInManager.HOTWORD_EXTENSION_ID_) &&
86 chrome.hotwordPrivate && chrome.hotwordPrivate.getStatus) {
87 chrome.hotwordPrivate.getStatus(
88 this.injectTab_.bind(this, request.tab || sender.tab,
93 case OptInManager.CommandFromPage.CLICKED_OPTIN:
94 if (chrome.hotwordPrivate && chrome.hotwordPrivate.setEnabled &&
95 chrome.hotwordPrivate.getStatus) {
96 chrome.hotwordPrivate.setEnabled(true);
97 chrome.hotwordPrivate.getStatus(
98 this.injectTab_.bind(this, sender.tab, sendResponse));
102 // User has explicitly clicked 'no thanks'.
103 case OptInManager.CommandFromPage.CLICKED_NO_OPTIN:
104 if (chrome.hotwordPrivate && chrome.hotwordPrivate.setEnabled) {
105 chrome.hotwordPrivate.setEnabled(false);
108 // Information regarding the audio logging preference was sent.
109 case OptInManager.CommandFromPage.AUDIO_LOGGING_ON:
110 if (chrome.hotwordPrivate &&
111 chrome.hotwordPrivate.setAudioLoggingEnabled) {
112 chrome.hotwordPrivate.setAudioLoggingEnabled(true);
115 case OptInManager.CommandFromPage.AUDIO_LOGGING_OFF:
116 if (chrome.hotwordPrivate &&
117 chrome.hotwordPrivate.setAudioLoggingEnabled) {
118 chrome.hotwordPrivate.setAudioLoggingEnabled(false);
129 * Determines if a URL is eligible for hotwording. For now, the
130 * valid pages are the Google HP and SERP (this will include the NTP).
131 * @param {string} url Url to check.
132 * @return {boolean} True if url is eligible hotword url.
134 OptInManager.prototype.isEligibleUrl = function(url) {
139 'https://www.google.com',
141 'https://encrypted.google.com'
144 for (var i = 0; i < baseUrls.length; i++) {
145 var base = baseUrls[i];
146 if (url === base + '/' ||
147 url.indexOf(base + '/_/chrome/newtab?') === 0 || // Appcache NTP.
148 url.indexOf(base + '/?') === 0 ||
149 url.indexOf(base + '/#') === 0 ||
150 url.indexOf(base + '/webhp') === 0 ||
151 url.indexOf(base + '/search') === 0) {
160 * Initializes the extension.
162 OptInManager.prototype.initialize = function() {
163 // TODO(rlp): Possibly remove the next line. It's proably not used, but
164 // leaving for now to be safe. We should remove it once all messsage
165 // relaying is removed form the content scripts.
166 chrome.runtime.onMessage.addListener(this.handleMessage_.bind(this));
167 chrome.runtime.onMessageExternal.addListener(
168 this.handleMessage_.bind(this));
172 new OptInManager().initialize();