OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * @fileoverview Utility objects and functions for Google Now extension. | 8 * @fileoverview Utility objects and functions for Google Now extension. |
9 * Most important entities here: | 9 * Most important entities here: |
10 * (1) 'wrapper' is a module used to add error handling and other services to | 10 * (1) 'wrapper' is a module used to add error handling and other services to |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 verify(!isInWrappedCallback, 'Re-entering instrumented callback'); | 316 verify(!isInWrappedCallback, 'Re-entering instrumented callback'); |
317 isInWrappedCallback = true; | 317 isInWrappedCallback = true; |
318 | 318 |
319 if (!opt_isEventListener) | 319 if (!opt_isEventListener) |
320 delete pendingCallbacks[callbackId]; | 320 delete pendingCallbacks[callbackId]; |
321 | 321 |
322 if (wrapperPluginInstance) | 322 if (wrapperPluginInstance) |
323 wrapperPluginInstance.prologue(); | 323 wrapperPluginInstance.prologue(); |
324 | 324 |
325 // Call the original callback. | 325 // Call the original callback. |
326 callback.apply(null, arguments); | 326 var returnValue = callback.apply(null, arguments); |
327 | 327 |
328 if (wrapperPluginInstance) | 328 if (wrapperPluginInstance) |
329 wrapperPluginInstance.epilogue(); | 329 wrapperPluginInstance.epilogue(); |
330 | 330 |
331 verify(isInWrappedCallback, | 331 verify(isInWrappedCallback, |
332 'Instrumented callback is not instrumented upon exit'); | 332 'Instrumented callback is not instrumented upon exit'); |
333 isInWrappedCallback = false; | 333 isInWrappedCallback = false; |
334 | |
335 return returnValue; | |
334 } catch (error) { | 336 } catch (error) { |
335 reportError(error); | 337 reportError(error); |
336 } | 338 } |
337 }; | 339 }; |
338 } | 340 } |
339 | 341 |
340 /** | 342 /** |
341 * Returns an instrumented function. | 343 * Returns an instrumented function. |
342 * @param {!Array.<string>} functionIdentifierParts Path to the chrome.* | 344 * @param {!Array.<string>} functionIdentifierParts Path to the chrome.* |
343 * function. | 345 * function. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 checkInWrappedCallback: checkInWrappedCallback, | 429 checkInWrappedCallback: checkInWrappedCallback, |
428 debugGetStateString: debugGetStateString | 430 debugGetStateString: debugGetStateString |
429 }; | 431 }; |
430 })(); | 432 })(); |
431 | 433 |
432 wrapper.instrumentChromeApiFunction('alarms.get', 1); | 434 wrapper.instrumentChromeApiFunction('alarms.get', 1); |
433 wrapper.instrumentChromeApiFunction('alarms.onAlarm.addListener', 0); | 435 wrapper.instrumentChromeApiFunction('alarms.onAlarm.addListener', 0); |
434 wrapper.instrumentChromeApiFunction('identity.getAuthToken', 1); | 436 wrapper.instrumentChromeApiFunction('identity.getAuthToken', 1); |
435 wrapper.instrumentChromeApiFunction('identity.onSignInChanged.addListener', 0); | 437 wrapper.instrumentChromeApiFunction('identity.onSignInChanged.addListener', 0); |
436 wrapper.instrumentChromeApiFunction('identity.removeCachedAuthToken', 1); | 438 wrapper.instrumentChromeApiFunction('identity.removeCachedAuthToken', 1); |
439 wrapper.instrumentChromeApiFunction('storage.local.get', 1); | |
437 wrapper.instrumentChromeApiFunction('webstorePrivate.getBrowserLogin', 0); | 440 wrapper.instrumentChromeApiFunction('webstorePrivate.getBrowserLogin', 0); |
438 | 441 |
439 /** | 442 /** |
440 * Add task tracking support to Promise.then. | 443 * Add task tracking support to Promise.then. |
441 * @override | 444 * @override |
442 */ | 445 */ |
443 Promise.prototype.then = function() { | 446 Promise.prototype.then = function() { |
444 var originalThen = Promise.prototype.then; | 447 var originalThen = Promise.prototype.then; |
445 return function(callback) { | 448 return function(callback) { |
446 return originalThen.call(this, wrapper.wrapCallback(callback, false)); | 449 return originalThen.call(this, wrapper.wrapCallback(callback, false)); |
447 } | 450 } |
448 }(); | 451 }(); |
449 | 452 |
450 /** | 453 /** |
451 * Add task tracking support to Promise.catch. | 454 * Add task tracking support to Promise.catch. |
452 * @override | 455 * @override |
453 */ | 456 */ |
454 Promise.prototype.catch = function() { | 457 Promise.prototype.catch = function() { |
455 var originalCatch = Promise.prototype.catch; | 458 var originalCatch = Promise.prototype.catch; |
456 return function(callback) { | 459 return function(callback) { |
457 return originalCatch.call(this, wrapper.wrapCallback(callback, false)); | 460 return originalCatch.call(this, wrapper.wrapCallback(callback, false)); |
458 } | 461 } |
459 }(); | 462 }(); |
460 | 463 |
464 | |
465 /* | |
skare_
2014/02/20 00:17:12
nit: /* -> /** and in :472
(sorry!)
robliao
2014/02/21 21:25:45
Done.
| |
466 * Disallow promise rejection. | |
467 * @type {boolean} | |
468 * @const | |
469 */ | |
470 var NO_PROMISE_REJECTION = false; | |
skare_
2014/02/20 00:17:12
(no action required)
this works; could make an @en
robliao
2014/02/21 21:25:45
Done.
| |
471 | |
472 /* | |
473 * Allow promise rejection. | |
474 * @type {boolean} | |
475 * @const | |
476 */ | |
477 var ALLOW_PROMISE_REJECTION = true; | |
478 | |
479 /** | |
480 * Provides the promise equivalent of instrumented.chrome.local.get. | |
skare_
2014/02/20 00:17:12
instrumented.chrome.storage.local?
robliao
2014/02/21 21:25:45
Done.
| |
481 * @param {Object} defaultStorageObject Default storage object to fill. | |
482 * @param {boolean} opt_allowPromiseRejection If ALLOW_PROMISE_REJECTION, | |
483 * allows promise rejection on errors, otherwise the default storage | |
484 * object is resolved. | |
485 * @return {Promise} A promise that fills the default storage object. On | |
skare_
2014/02/20 00:17:12
just as a first-read opinion, "fills" is slightly
robliao
2014/02/21 21:25:45
I'm open to other suggestions.
I chose fill becau
| |
486 * failure, if promise rejection is a allowed, the promise is rejected, | |
skare_
2014/02/20 00:17:12
nit: is a allowed -> is allowed
robliao
2014/02/21 21:25:45
Done.
| |
487 * otherwise it is resolved to the default storage object. | |
488 */ | |
489 function fillFromChromeLocalStorage( | |
490 defaultStorageObject, | |
491 opt_allowPromiseRejection) { | |
492 return new Promise(function(resolve, reject) { | |
493 instrumented.storage.local.get(defaultStorageObject, function(items) { | |
494 if (items) { | |
495 resolve(items); | |
496 } else if (opt_allowPromiseRejection === ALLOW_PROMISE_REJECTION) { | |
497 reject(); | |
498 } else { | |
499 resolve(defaultStorageObject); | |
500 } | |
501 }); | |
502 }); | |
503 } | |
504 | |
461 /** | 505 /** |
462 * Builds the object to manage tasks (mutually exclusive chains of events). | 506 * Builds the object to manage tasks (mutually exclusive chains of events). |
463 * @param {function(string, string): boolean} areConflicting Function that | 507 * @param {function(string, string): boolean} areConflicting Function that |
464 * checks if a new task can't be added to a task queue that contains an | 508 * checks if a new task can't be added to a task queue that contains an |
465 * existing task. | 509 * existing task. |
466 * @return {Object} Task manager interface. | 510 * @return {Object} Task manager interface. |
467 */ | 511 */ |
468 function buildTaskManager(areConflicting) { | 512 function buildTaskManager(areConflicting) { |
469 /** | 513 /** |
470 * Queue of scheduled tasks. The first element, if present, corresponds to the | 514 * Queue of scheduled tasks. The first element, if present, corresponds to the |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 chrome.alarms.clear(alarmName); | 736 chrome.alarms.clear(alarmName); |
693 chrome.storage.local.remove(currentDelayStorageKey); | 737 chrome.storage.local.remove(currentDelayStorageKey); |
694 } | 738 } |
695 | 739 |
696 /** | 740 /** |
697 * Plans for the next attempt. | 741 * Plans for the next attempt. |
698 * @param {function()} callback Completion callback. It will be invoked after | 742 * @param {function()} callback Completion callback. It will be invoked after |
699 * the planning is done. | 743 * the planning is done. |
700 */ | 744 */ |
701 function planForNext(callback) { | 745 function planForNext(callback) { |
702 instrumented.storage.local.get(currentDelayStorageKey, function(items) { | 746 var request = {}; |
703 if (!items) { | 747 request[currentDelayStorageKey] = maximumDelaySeconds; |
704 items = {}; | 748 fillFromChromeLocalStorage(request).then(function(items) { |
705 items[currentDelayStorageKey] = maximumDelaySeconds; | |
706 } | |
707 console.log('planForNext-get-storage ' + JSON.stringify(items)); | 749 console.log('planForNext-get-storage ' + JSON.stringify(items)); |
708 scheduleNextAttempt(items[currentDelayStorageKey]); | 750 scheduleNextAttempt(items[currentDelayStorageKey]); |
709 callback(); | 751 callback(); |
710 }); | 752 }); |
711 } | 753 } |
712 | 754 |
713 instrumented.alarms.onAlarm.addListener(function(alarm) { | 755 instrumented.alarms.onAlarm.addListener(function(alarm) { |
714 if (alarm.name == alarmName) | 756 if (alarm.name == alarmName) |
715 isRunning(function(running) { | 757 isRunning(function(running) { |
716 if (running) | 758 if (running) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
790 function addListener(callback) { | 832 function addListener(callback) { |
791 listeners.push(callback); | 833 listeners.push(callback); |
792 } | 834 } |
793 | 835 |
794 /** | 836 /** |
795 * Checks if the last signed in state matches the current one. | 837 * Checks if the last signed in state matches the current one. |
796 * If it doesn't, it notifies the listeners of the change. | 838 * If it doesn't, it notifies the listeners of the change. |
797 */ | 839 */ |
798 function checkAndNotifyListeners() { | 840 function checkAndNotifyListeners() { |
799 isSignedIn().then(function(signedIn) { | 841 isSignedIn().then(function(signedIn) { |
800 instrumented.storage.local.get('lastSignedInState', function(items) { | 842 fillFromChromeLocalStorage({lastSignedInState: undefined}) |
801 items = items || {}; | 843 .then(function(items) { |
802 if (items.lastSignedInState != signedIn) { | 844 if (items.lastSignedInState != signedIn) { |
803 chrome.storage.local.set( | 845 chrome.storage.local.set( |
804 {lastSignedInState: signedIn}); | 846 {lastSignedInState: signedIn}); |
805 listeners.forEach(function(callback) { | 847 listeners.forEach(function(callback) { |
806 callback(); | 848 callback(); |
807 }); | 849 }); |
808 } | 850 } |
851 }); | |
809 }); | 852 }); |
810 }); | |
811 } | 853 } |
812 | 854 |
813 instrumented.identity.onSignInChanged.addListener(function() { | 855 instrumented.identity.onSignInChanged.addListener(function() { |
814 checkAndNotifyListeners(); | 856 checkAndNotifyListeners(); |
815 }); | 857 }); |
816 | 858 |
817 instrumented.alarms.onAlarm.addListener(function(alarm) { | 859 instrumented.alarms.onAlarm.addListener(function(alarm) { |
818 if (alarm.name == alarmName) | 860 if (alarm.name == alarmName) |
819 checkAndNotifyListeners(); | 861 checkAndNotifyListeners(); |
820 }); | 862 }); |
821 | 863 |
822 // Poll for the sign in state every hour. | 864 // Poll for the sign in state every hour. |
823 // One hour is just an arbitrary amount of time chosen. | 865 // One hour is just an arbitrary amount of time chosen. |
824 chrome.alarms.create(alarmName, {periodInMinutes: 60}); | 866 chrome.alarms.create(alarmName, {periodInMinutes: 60}); |
825 | 867 |
826 return { | 868 return { |
827 addListener: addListener, | 869 addListener: addListener, |
828 getAuthToken: getAuthToken, | 870 getAuthToken: getAuthToken, |
829 isSignedIn: isSignedIn, | 871 isSignedIn: isSignedIn, |
830 removeToken: removeToken | 872 removeToken: removeToken |
831 }; | 873 }; |
832 } | 874 } |
OLD | NEW |