Chromium Code Reviews| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 'de', | 103 'de', | 
| 102 'es', | 104 'es', | 
| 103 'fr', | 105 'fr', | 
| 104 'it', | 106 'it', | 
| 105 'ru' | 107 'ru' | 
| 106 ]; | 108 ]; | 
| 107 | 109 | 
| 108 // Check for the new tab page first. | 110 // Check for the new tab page first. | 
| 109 if (this.checkUrlPathIsEligible_(url, 'chrome://newtab')) | 111 if (this.checkUrlPathIsEligible_(url, 'chrome://newtab')) | 
| 110 return true; | 112 return true; | 
| 113 if (this.checkUrlPathIsEligible_(url, 'http://kcarattini-z620.syd.corp.goo gle.com:8888/')) | |
| 
 
Anand Mistry (off Chromium)
2015/03/10 02:47:29
Remove.
 
kcarattini
2015/03/10 04:34:05
Done.
 
 | |
| 114 return true; | |
| 111 | 115 | 
| 112 // Check URLs with each type of local-based TLD. | 116 // Check URLs with each type of local-based TLD. | 
| 113 for (var i = 0; i < baseGoogleUrls.length; i++) { | 117 for (var i = 0; i < baseGoogleUrls.length; i++) { | 
| 114 for (var j = 0; j < tlds.length; j++) { | 118 for (var j = 0; j < tlds.length; j++) { | 
| 115 var base = baseGoogleUrls[i] + tlds[j]; | 119 var base = baseGoogleUrls[i] + tlds[j]; | 
| 116 if (this.checkUrlPathIsEligible_(url, base)) | 120 if (this.checkUrlPathIsEligible_(url, base)) | 
| 117 return true; | 121 return true; | 
| 118 } | 122 } | 
| 119 } | 123 } | 
| 120 return false; | 124 return false; | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 handleUpdatedTab_: function(tabId, info, tab) { | 224 handleUpdatedTab_: function(tabId, info, tab) { | 
| 221 // Chrome fires multiple update events: undefined, loading and completed. | 225 // Chrome fires multiple update events: undefined, loading and completed. | 
| 222 // We perform content injection on loading state. | 226 // We perform content injection on loading state. | 
| 223 if (info['status'] != 'loading') | 227 if (info['status'] != 'loading') | 
| 224 return; | 228 return; | 
| 225 | 229 | 
| 226 this.prepareTab_(tab); | 230 this.prepareTab_(tab); | 
| 227 }, | 231 }, | 
| 228 | 232 | 
| 229 /** | 233 /** | 
| 230 * Handles a tab that was just became active. | 234 * Handles a tab that has just become active. | 
| 231 * @param {{tabId: number}} info Information about the activated tab. | 235 * @param {{tabId: number}} info Information about the activated tab. | 
| 232 * @private | 236 * @private | 
| 233 */ | 237 */ | 
| 234 handleActivatedTab_: function(info) { | 238 handleActivatedTab_: function(info) { | 
| 235 this.updateTabState_(); | 239 this.updateTabState_(); | 
| 236 }, | 240 }, | 
| 237 | 241 | 
| 238 | 242 | 
| 239 /** | 243 /** | 
| 240 * Handles a change in Chrome windows. | 244 * Handles a change in Chrome windows. | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 this.stateManager_.startSession( | 345 this.stateManager_.startSession( | 
| 342 hotword.constants.SessionSource.NTP, | 346 hotword.constants.SessionSource.NTP, | 
| 343 function() { | 347 function() { | 
| 344 this.sendAllClients_(CommandToPage.HOTWORD_STARTED); | 348 this.sendAllClients_(CommandToPage.HOTWORD_STARTED); | 
| 345 }.bind(this), | 349 }.bind(this), | 
| 346 this.hotwordTriggered_.bind(this)); | 350 this.hotwordTriggered_.bind(this)); | 
| 347 }, | 351 }, | 
| 348 | 352 | 
| 349 /** | 353 /** | 
| 350 * Starts hotwording if the currently active tab is eligible for hotwording | 354 * Starts hotwording if the currently active tab is eligible for hotwording | 
| 351 * (i.e. google.com). | 355 * (e.g. google.com). | 
| 352 * @private | 356 * @private | 
| 353 */ | 357 */ | 
| 354 startHotwordingIfEligible_: function() { | 358 startHotwordingIfEligible_: function() { | 
| 355 this.findCurrentTab_(function(tab) { | 359 this.findCurrentTab_(function(tab) { | 
| 356 if (!tab) { | 360 if (!tab) { | 
| 357 this.stopHotwording_(); | 361 this.stopHotwording_(); | 
| 358 return; | 362 return; | 
| 359 } | 363 } | 
| 360 if (this.isEligibleUrl_(tab.url)) | 364 if (this.isEligibleUrl_(tab.url)) | 
| 361 this.startHotwording_(); | 365 this.startHotwording_(); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 case CommandFromPage.SPEECH_START: | 405 case CommandFromPage.SPEECH_START: | 
| 402 this.stopHotwording_(); | 406 this.stopHotwording_(); | 
| 403 break; | 407 break; | 
| 404 case CommandFromPage.SPEECH_END: | 408 case CommandFromPage.SPEECH_END: | 
| 405 case CommandFromPage.SPEECH_RESET: | 409 case CommandFromPage.SPEECH_RESET: | 
| 406 this.startHotwording_(); | 410 this.startHotwording_(); | 
| 407 break; | 411 break; | 
| 408 } | 412 } | 
| 409 }, | 413 }, | 
| 410 | 414 | 
| 415 | |
| 416 /** | |
| 417 * Handles a message directly from the NTP/HP/SERP. | |
| 418 * @param {!Object} request Message from the sender. | |
| 419 * @param {!MessageSender} sender Information about the sender. | |
| 420 * @param {!function(HotwordStatus)} sendResponse Callback to respond | |
| 421 * to sender. | |
| 422 * @return {boolean} Whether to maintain the port open to call sendResponse. | |
| 423 * @private | |
| 424 */ | |
| 425 handleMessageFromPage_: function(request, sender, sendResponse) { | |
| 426 switch (request.type) { | |
| 427 case CommandFromPage.PAGE_WAKEUP: | |
| 428 if ((sender.tab && this.isEligibleUrl_(sender.tab.url)) && | |
| 429 chrome.hotwordPrivate && chrome.hotwordPrivate.getStatus) { | |
| 
 
Anand Mistry (off Chromium)
2015/03/10 02:47:29
Remove these checks. We already assume that chrome
 
kcarattini
2015/03/10 04:34:05
Where do we make that assumption? I don't see it u
 
Anand Mistry (off Chromium)
2015/03/10 04:40:54
Look at other files in this directory, such as sta
 
kcarattini
2015/03/10 04:50:58
Done.
 
 | |
| 430 chrome.hotwordPrivate.getStatus( | |
| 431 this.statusDone_.bind( | |
| 432 this, | |
| 433 request.tab || sender.tab || {incognito: true}, | |
| 434 sendResponse)); | |
| 435 return true; | |
| 436 } | |
| 437 break; | |
| 438 case CommandFromPage.CLICKED_OPTIN: | |
| 439 if (chrome.hotwordPrivate && chrome.hotwordPrivate.setEnabled && | |
| 440 chrome.hotwordPrivate.getStatus) { | |
| 441 chrome.hotwordPrivate.setEnabled(true); | |
| 442 // chrome.hotwordPrivate.getStatus( | |
| 
 
Anand Mistry (off Chromium)
2015/03/10 02:47:29
Remove.
 
kcarattini
2015/03/10 04:34:05
Done.
 
 | |
| 443 // this.injectTab_.bind(this, sender.tab, sendResponse)); | |
| 444 // return true; | |
| 445 } | |
| 446 break; | |
| 447 // User has explicitly clicked 'no thanks'. | |
| 448 case CommandFromPage.CLICKED_NO_OPTIN: | |
| 449 if (chrome.hotwordPrivate && chrome.hotwordPrivate.setEnabled) { | |
| 450 chrome.hotwordPrivate.setEnabled(false); | |
| 451 } | |
| 452 break; | |
| 453 } | |
| 454 return false; | |
| 455 }, | |
| 456 | |
| 457 /** | |
| 458 * Sends the response to the tab. | |
| 459 * @param {Tab} tab The tab that the request was sent from. | |
| 460 * @param {function(HotwordStatus)} sendResponse Callback function to | |
| 461 * respond to sender. | |
| 462 * @param {HotwordStatus} hotwordStatus Status of the hotword extension. | |
| 463 * @private | |
| 464 */ | |
| 465 statusDone_: function(tab, sendResponse, hotwordStatus) { | |
| 466 var response = {'doNotShowOptinMessage': true}; | |
| 467 | |
| 468 if (!tab.incognito && hotwordStatus.available && | |
| 469 !hotwordStatus.enabledSet) { | |
| 470 response = hotwordStatus; | |
| 471 } | |
| 472 | |
| 473 try { | |
| 474 sendResponse(response); | |
| 475 } catch (err) { | |
| 476 // Suppress the exception thrown by sendResponse() when the page doesn't | |
| 477 // specify a response callback in the call to | |
| 478 // chrome.runtime.sendMessage(). | |
| 479 // Unfortunately, there doesn't appear to be a way to detect one-way | |
| 480 // messages without explicitly saying in the message itself. This | |
| 481 // message is defined as a constant in | |
| 482 // extensions/renderer/messaging_bindings.cc | |
| 483 if (err.message == 'Attempting to use a disconnected port object') | |
| 484 return; | |
| 485 throw err; | |
| 486 } | |
| 487 }, | |
| 488 | |
| 411 /** | 489 /** | 
| 412 * Set up event listeners. | 490 * Set up event listeners. | 
| 413 * @private | 491 * @private | 
| 414 */ | 492 */ | 
| 415 setupListeners_: function() { | 493 setupListeners_: function() { | 
| 416 if (chrome.runtime.onConnect.hasListener(this.connectListener_)) | 494 if (chrome.runtime.onConnect.hasListener(this.connectListener_)) | 
| 417 return; | 495 return; | 
| 418 | 496 | 
| 419 chrome.runtime.onConnect.addListener(this.connectListener_); | 497 chrome.runtime.onConnect.addListener(this.connectListener_); | 
| 420 chrome.tabs.onCreated.addListener(this.tabCreatedListener_); | 498 chrome.tabs.onCreated.addListener(this.tabCreatedListener_); | 
| 421 chrome.tabs.onUpdated.addListener(this.tabUpdatedListener_); | 499 chrome.tabs.onUpdated.addListener(this.tabUpdatedListener_); | 
| 422 chrome.tabs.onActivated.addListener(this.tabActivatedListener_); | 500 chrome.tabs.onActivated.addListener(this.tabActivatedListener_); | 
| 423 chrome.windows.onFocusChanged.addListener( | 501 chrome.windows.onFocusChanged.addListener( | 
| 424 this.windowFocusChangedListener_); | 502 this.windowFocusChangedListener_); | 
| 503 // TODO(kcarattini): Possibly remove the next line. It's probably not | |
| 504 // used, but leaving for now to be safe. We should remove it once all | |
| 505 // messsage relaying is removed from the content scripts. | |
| 506 if (chrome.runtime.onMessage.hasListener(this.messageListener_)) | |
| 507 return; | |
| 508 chrome.runtime.onMessage.addListener(this.messageListener_); | |
| 
 
Anand Mistry (off Chromium)
2015/03/10 02:47:29
Isn't this one unnecessary? If so, it should be re
 
kcarattini
2015/03/10 04:34:05
Done.
 
 | |
| 509 chrome.runtime.onMessageExternal.addListener( | |
| 510 this.messageListener_); | |
| 425 }, | 511 }, | 
| 426 | 512 | 
| 427 /** | 513 /** | 
| 428 * Remove event listeners. | 514 * Remove event listeners. | 
| 429 * @private | 515 * @private | 
| 430 */ | 516 */ | 
| 431 removeListeners_: function() { | 517 removeListeners_: function() { | 
| 432 chrome.runtime.onConnect.removeListener(this.connectListener_); | 518 chrome.runtime.onConnect.removeListener(this.connectListener_); | 
| 433 chrome.tabs.onCreated.removeListener(this.tabCreatedListener_); | 519 chrome.tabs.onCreated.removeListener(this.tabCreatedListener_); | 
| 434 chrome.tabs.onUpdated.removeListener(this.tabUpdatedListener_); | 520 chrome.tabs.onUpdated.removeListener(this.tabUpdatedListener_); | 
| 435 chrome.tabs.onActivated.removeListener(this.tabActivatedListener_); | 521 chrome.tabs.onActivated.removeListener(this.tabActivatedListener_); | 
| 436 chrome.windows.onFocusChanged.removeListener( | 522 chrome.windows.onFocusChanged.removeListener( | 
| 437 this.windowFocusChangedListener_); | 523 this.windowFocusChangedListener_); | 
| 524 // Don't remove the Message listeners, as we want them listening all | |
| 525 // the time, | |
| 438 }, | 526 }, | 
| 439 | 527 | 
| 440 /** | 528 /** | 
| 441 * Update event listeners based on the current hotwording state. | 529 * Update event listeners based on the current hotwording state. | 
| 442 * @private | 530 * @private | 
| 443 */ | 531 */ | 
| 444 updateListeners_: function() { | 532 updateListeners_: function() { | 
| 445 if (this.stateManager_.isSometimesOnEnabled()) { | 533 if (this.stateManager_.isSometimesOnEnabled()) { | 
| 446 this.setupListeners_(); | 534 this.setupListeners_(); | 
| 447 } else { | 535 } else { | 
| 448 this.removeListeners_(); | 536 this.removeListeners_(); | 
| 449 this.stopHotwording_(); | 537 this.stopHotwording_(); | 
| 450 this.disconnectAllClients_(); | 538 this.disconnectAllClients_(); | 
| 451 } | 539 } | 
| 452 } | 540 } | 
| 453 }; | 541 }; | 
| 454 | 542 | 
| 455 return { | 543 return { | 
| 456 PageAudioManager: PageAudioManager | 544 PageAudioManager: PageAudioManager | 
| 457 }; | 545 }; | 
| 458 }); | 546 }); | 
| OLD | NEW |