| OLD | NEW | 
|    1 // Copyright 2014 The Chromium Authors. All rights reserved. |    1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 cr.define('hotword', function() { |    5 cr.define('hotword', function() { | 
|    6   'use strict'; |    6   'use strict'; | 
|    7  |    7  | 
|    8   /** |    8   /** | 
|    9    * Class used to manage the interaction between hotwording and the |    9    * Class used to manage the interaction between hotwording and the | 
|   10    * NTP/google.com. Injects a content script to interact with NTP/google.com |   10    * NTP/google.com. Injects a content script to interact with NTP/google.com | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|   29  |   29  | 
|   30     /** |   30     /** | 
|   31      * Chrome event listeners. Saved so that they can be de-registered when |   31      * Chrome event listeners. Saved so that they can be de-registered when | 
|   32      * hotwording is disabled. |   32      * hotwording is disabled. | 
|   33      */ |   33      */ | 
|   34     this.connectListener_ = this.handleConnect_.bind(this); |   34     this.connectListener_ = this.handleConnect_.bind(this); | 
|   35     this.tabCreatedListener_ = this.handleCreatedTab_.bind(this); |   35     this.tabCreatedListener_ = this.handleCreatedTab_.bind(this); | 
|   36     this.tabUpdatedListener_ = this.handleUpdatedTab_.bind(this); |   36     this.tabUpdatedListener_ = this.handleUpdatedTab_.bind(this); | 
|   37     this.tabActivatedListener_ = this.handleActivatedTab_.bind(this); |   37     this.tabActivatedListener_ = this.handleActivatedTab_.bind(this); | 
|   38     this.windowFocusChangedListener_ = this.handleChangedWindow_.bind(this); |   38     this.windowFocusChangedListener_ = this.handleChangedWindow_.bind(this); | 
 |   39     this.messageListener_ = this.handleMessageFromPage_.bind(this); | 
|   39  |   40  | 
|   40     // Need to setup listeners on startup, otherwise events that caused the |   41     // Need to setup listeners on startup, otherwise events that caused the | 
|   41     // event page to start up, will be lost. |   42     // event page to start up, will be lost. | 
|   42     this.setupListeners_(); |   43     this.setupListeners_(); | 
|   43  |   44  | 
|   44     this.stateManager_.onStatusChanged.addListener(function() { |   45     this.stateManager_.onStatusChanged.addListener(function() { | 
|   45       this.updateListeners_(); |   46       this.updateListeners_(); | 
 |   47       this.updateTabState_(); | 
|   46     }.bind(this)); |   48     }.bind(this)); | 
|   47   }; |   49   }; | 
|   48  |   50  | 
|   49   var CommandToPage = hotword.constants.CommandToPage; |   51   var CommandToPage = hotword.constants.CommandToPage; | 
|   50   var CommandFromPage = hotword.constants.CommandFromPage; |   52   var CommandFromPage = hotword.constants.CommandFromPage; | 
|   51  |   53  | 
|   52   PageAudioManager.prototype = { |   54   PageAudioManager.prototype = { | 
|   53     /** |   55     /** | 
|   54      * Helper function to test if a URL path is eligible for hotwording. |   56      * Helper function to test if a URL path is eligible for hotwording. | 
|   55      * @param {!string} url URL to check. |   57      * @param {!string} url URL to check. | 
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  220     handleUpdatedTab_: function(tabId, info, tab) { |  222     handleUpdatedTab_: function(tabId, info, tab) { | 
|  221       // Chrome fires multiple update events: undefined, loading and completed. |  223       // Chrome fires multiple update events: undefined, loading and completed. | 
|  222       // We perform content injection on loading state. |  224       // We perform content injection on loading state. | 
|  223       if (info['status'] != 'loading') |  225       if (info['status'] != 'loading') | 
|  224         return; |  226         return; | 
|  225  |  227  | 
|  226       this.prepareTab_(tab); |  228       this.prepareTab_(tab); | 
|  227     }, |  229     }, | 
|  228  |  230  | 
|  229     /** |  231     /** | 
|  230      * Handles a tab that was just became active. |  232      * Handles a tab that has just become active. | 
|  231      * @param {{tabId: number}} info Information about the activated tab. |  233      * @param {{tabId: number}} info Information about the activated tab. | 
|  232      * @private |  234      * @private | 
|  233      */ |  235      */ | 
|  234     handleActivatedTab_: function(info) { |  236     handleActivatedTab_: function(info) { | 
|  235       this.updateTabState_(); |  237       this.updateTabState_(); | 
|  236     }, |  238     }, | 
|  237  |  239  | 
|  238  |  240  | 
|  239     /** |  241     /** | 
|  240      * Handles a change in Chrome windows. |  242      * Handles a change in Chrome windows. | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  341       this.stateManager_.startSession( |  343       this.stateManager_.startSession( | 
|  342           hotword.constants.SessionSource.NTP, |  344           hotword.constants.SessionSource.NTP, | 
|  343           function() { |  345           function() { | 
|  344             this.sendAllClients_(CommandToPage.HOTWORD_STARTED); |  346             this.sendAllClients_(CommandToPage.HOTWORD_STARTED); | 
|  345           }.bind(this), |  347           }.bind(this), | 
|  346           this.hotwordTriggered_.bind(this)); |  348           this.hotwordTriggered_.bind(this)); | 
|  347     }, |  349     }, | 
|  348  |  350  | 
|  349     /** |  351     /** | 
|  350      * Starts hotwording if the currently active tab is eligible for hotwording |  352      * Starts hotwording if the currently active tab is eligible for hotwording | 
|  351      * (i.e. google.com). |  353      * (e.g. google.com). | 
|  352      * @private |  354      * @private | 
|  353      */ |  355      */ | 
|  354     startHotwordingIfEligible_: function() { |  356     startHotwordingIfEligible_: function() { | 
|  355       this.findCurrentTab_(function(tab) { |  357       this.findCurrentTab_(function(tab) { | 
|  356         if (!tab) { |  358         if (!tab) { | 
|  357           this.stopHotwording_(); |  359           this.stopHotwording_(); | 
|  358           return; |  360           return; | 
|  359         } |  361         } | 
|  360         if (this.isEligibleUrl_(tab.url)) |  362         if (this.isEligibleUrl_(tab.url)) | 
|  361           this.startHotwording_(); |  363           this.startHotwording_(); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  401         case CommandFromPage.SPEECH_START: |  403         case CommandFromPage.SPEECH_START: | 
|  402           this.stopHotwording_(); |  404           this.stopHotwording_(); | 
|  403           break; |  405           break; | 
|  404         case CommandFromPage.SPEECH_END: |  406         case CommandFromPage.SPEECH_END: | 
|  405         case CommandFromPage.SPEECH_RESET: |  407         case CommandFromPage.SPEECH_RESET: | 
|  406           this.startHotwording_(); |  408           this.startHotwording_(); | 
|  407           break; |  409           break; | 
|  408       } |  410       } | 
|  409     }, |  411     }, | 
|  410  |  412  | 
 |  413  | 
 |  414     /** | 
 |  415      * Handles a message directly from the NTP/HP/SERP. | 
 |  416      * @param {!Object} request Message from the sender. | 
 |  417      * @param {!MessageSender} sender Information about the sender. | 
 |  418      * @param {!function(HotwordStatus)} sendResponse Callback to respond | 
 |  419      *     to sender. | 
 |  420      * @return {boolean} Whether to maintain the port open to call sendResponse. | 
 |  421      * @private | 
 |  422      */ | 
 |  423     handleMessageFromPage_: function(request, sender, sendResponse) { | 
 |  424       switch (request.type) { | 
 |  425         case CommandFromPage.PAGE_WAKEUP: | 
 |  426           if (sender.tab && this.isEligibleUrl_(sender.tab.url)) { | 
 |  427             chrome.hotwordPrivate.getStatus( | 
 |  428                 this.statusDone_.bind( | 
 |  429                     this, | 
 |  430                     request.tab || sender.tab || {incognito: true}, | 
 |  431                     sendResponse)); | 
 |  432             return true; | 
 |  433           } | 
 |  434           break; | 
 |  435         case CommandFromPage.CLICKED_OPTIN: | 
 |  436           chrome.hotwordPrivate.setEnabled(true); | 
 |  437           break; | 
 |  438         // User has explicitly clicked 'no thanks'. | 
 |  439         case CommandFromPage.CLICKED_NO_OPTIN: | 
 |  440           chrome.hotwordPrivate.setEnabled(false); | 
 |  441           break; | 
 |  442       } | 
 |  443       return false; | 
 |  444     }, | 
 |  445  | 
 |  446     /** | 
 |  447      * Sends the response to the tab. | 
 |  448      * @param {Tab} tab The tab that the request was sent from. | 
 |  449      * @param {function(HotwordStatus)} sendResponse Callback function to | 
 |  450      *     respond to sender. | 
 |  451      * @param {HotwordStatus} hotwordStatus Status of the hotword extension. | 
 |  452      * @private | 
 |  453      */ | 
 |  454     statusDone_: function(tab, sendResponse, hotwordStatus) { | 
 |  455       var response = {'doNotShowOptinMessage': true}; | 
 |  456  | 
 |  457       if (!tab.incognito && hotwordStatus.available && | 
 |  458           !hotwordStatus.enabledSet) { | 
 |  459         response = hotwordStatus; | 
 |  460       } | 
 |  461  | 
 |  462       try { | 
 |  463         sendResponse(response); | 
 |  464       } catch (err) { | 
 |  465         // Suppress the exception thrown by sendResponse() when the page doesn't | 
 |  466         // specify a response callback in the call to | 
 |  467         // chrome.runtime.sendMessage(). | 
 |  468         // Unfortunately, there doesn't appear to be a way to detect one-way | 
 |  469         // messages without explicitly saying in the message itself. This | 
 |  470         // message is defined as a constant in | 
 |  471         // extensions/renderer/messaging_bindings.cc | 
 |  472         if (err.message == 'Attempting to use a disconnected port object') | 
 |  473           return; | 
 |  474         throw err; | 
 |  475       } | 
 |  476     }, | 
 |  477  | 
|  411     /** |  478     /** | 
|  412      * Set up event listeners. |  479      * Set up event listeners. | 
|  413      * @private |  480      * @private | 
|  414      */ |  481      */ | 
|  415     setupListeners_: function() { |  482     setupListeners_: function() { | 
|  416       if (chrome.runtime.onConnect.hasListener(this.connectListener_)) |  483       if (chrome.runtime.onConnect.hasListener(this.connectListener_)) | 
|  417         return; |  484         return; | 
|  418  |  485  | 
|  419       chrome.runtime.onConnect.addListener(this.connectListener_); |  486       chrome.runtime.onConnect.addListener(this.connectListener_); | 
|  420       chrome.tabs.onCreated.addListener(this.tabCreatedListener_); |  487       chrome.tabs.onCreated.addListener(this.tabCreatedListener_); | 
|  421       chrome.tabs.onUpdated.addListener(this.tabUpdatedListener_); |  488       chrome.tabs.onUpdated.addListener(this.tabUpdatedListener_); | 
|  422       chrome.tabs.onActivated.addListener(this.tabActivatedListener_); |  489       chrome.tabs.onActivated.addListener(this.tabActivatedListener_); | 
|  423       chrome.windows.onFocusChanged.addListener( |  490       chrome.windows.onFocusChanged.addListener( | 
|  424           this.windowFocusChangedListener_); |  491           this.windowFocusChangedListener_); | 
 |  492       if (chrome.runtime.onMessage.hasListener(this.messageListener_)) | 
 |  493         return; | 
 |  494       chrome.runtime.onMessageExternal.addListener( | 
 |  495           this.messageListener_); | 
|  425     }, |  496     }, | 
|  426  |  497  | 
|  427     /** |  498     /** | 
|  428      * Remove event listeners. |  499      * Remove event listeners. | 
|  429      * @private |  500      * @private | 
|  430      */ |  501      */ | 
|  431     removeListeners_: function() { |  502     removeListeners_: function() { | 
|  432       chrome.runtime.onConnect.removeListener(this.connectListener_); |  503       chrome.runtime.onConnect.removeListener(this.connectListener_); | 
|  433       chrome.tabs.onCreated.removeListener(this.tabCreatedListener_); |  504       chrome.tabs.onCreated.removeListener(this.tabCreatedListener_); | 
|  434       chrome.tabs.onUpdated.removeListener(this.tabUpdatedListener_); |  505       chrome.tabs.onUpdated.removeListener(this.tabUpdatedListener_); | 
|  435       chrome.tabs.onActivated.removeListener(this.tabActivatedListener_); |  506       chrome.tabs.onActivated.removeListener(this.tabActivatedListener_); | 
|  436       chrome.windows.onFocusChanged.removeListener( |  507       chrome.windows.onFocusChanged.removeListener( | 
|  437           this.windowFocusChangedListener_); |  508           this.windowFocusChangedListener_); | 
 |  509       // Don't remove the Message listener, as we want them listening all | 
 |  510       // the time, | 
|  438     }, |  511     }, | 
|  439  |  512  | 
|  440     /** |  513     /** | 
|  441      * Update event listeners based on the current hotwording state. |  514      * Update event listeners based on the current hotwording state. | 
|  442      * @private |  515      * @private | 
|  443      */ |  516      */ | 
|  444     updateListeners_: function() { |  517     updateListeners_: function() { | 
|  445       if (this.stateManager_.isSometimesOnEnabled()) { |  518       if (this.stateManager_.isSometimesOnEnabled()) { | 
|  446         this.setupListeners_(); |  519         this.setupListeners_(); | 
|  447       } else { |  520       } else { | 
|  448         this.removeListeners_(); |  521         this.removeListeners_(); | 
|  449         this.stopHotwording_(); |  522         this.stopHotwording_(); | 
|  450         this.disconnectAllClients_(); |  523         this.disconnectAllClients_(); | 
|  451       } |  524       } | 
|  452     } |  525     } | 
|  453   }; |  526   }; | 
|  454  |  527  | 
|  455   return { |  528   return { | 
|  456     PageAudioManager: PageAudioManager |  529     PageAudioManager: PageAudioManager | 
|  457   }; |  530   }; | 
|  458 }); |  531 }); | 
| OLD | NEW |