Chromium Code Reviews| 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 * Promise adapter for all JS promises to the task manager. | 443 * Promise adapter for all JS promises to the task manager. |
| 441 */ | 444 */ |
| 442 function registerPromiseAdapter() { | 445 function registerPromiseAdapter() { |
| 443 var originalThen = Promise.prototype.then; | 446 var originalThen = Promise.prototype.then; |
| 444 var originalCatch = Promise.prototype.catch; | 447 var originalCatch = Promise.prototype.catch; |
| 445 | 448 |
| 446 /** | 449 /** |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 612 return { | 615 return { |
| 613 handleThen: handleThen, | 616 handleThen: handleThen, |
| 614 handleCatch: handleCatch | 617 handleCatch: handleCatch |
| 615 }; | 618 }; |
| 616 } | 619 } |
| 617 } | 620 } |
| 618 | 621 |
| 619 registerPromiseAdapter(); | 622 registerPromiseAdapter(); |
| 620 | 623 |
| 621 /** | 624 /** |
| 625 * Control promise rejection. | |
| 626 * @enum {boolean} | |
| 627 */ | |
| 628 var PromiseRejection = { | |
| 629 /** Disallow promise rejection */ | |
| 630 DISALLOW: false, | |
| 631 /** Allow promise rejection */ | |
| 632 ALLOW: true | |
| 633 }; | |
| 634 | |
| 635 /** | |
| 636 * Provides the promise equivalent of instrumented.storage.local.get. | |
| 637 * @param {Object} defaultStorageObject Default storage object to fill. | |
| 638 * @param {boolean} opt_allowPromiseRejection If PromiseRejection.ALLOW, | |
|
rgustafson
2014/02/27 21:32:10
document param as optional
robliao
2014/02/27 23:52:36
Done.
| |
| 639 * allow promise rejection on errors, otherwise the default storage | |
| 640 * object is resolved. | |
| 641 * @return {Promise} A promise that fills the default storage object. On | |
| 642 * failure, if promise rejection is allowed, the promise is rejected, | |
| 643 * otherwise it is resolved to the default storage object. | |
| 644 */ | |
| 645 function fillFromChromeLocalStorage( | |
| 646 defaultStorageObject, | |
| 647 opt_allowPromiseRejection) { | |
| 648 return new Promise(function(resolve, reject) { | |
| 649 instrumented.storage.local.get(defaultStorageObject, function(items) { | |
| 650 if (items) { | |
| 651 resolve(items); | |
| 652 } else if (opt_allowPromiseRejection === PromiseRejection.ALLOW) { | |
|
vadimt
2014/02/27 20:20:36
Why not "if (opt_allowPromiseRejection)"?
robliao
2014/02/27 23:52:36
We're comparing against an enum, so we should do a
vadimt
2014/02/28 20:21:05
You don't use the fact that enum values are boolea
robliao
2014/02/28 20:39:49
We can use the number, but for enums it shouldn't
| |
| 653 reject(); | |
| 654 } else { | |
| 655 resolve(defaultStorageObject); | |
| 656 } | |
| 657 }); | |
| 658 }); | |
| 659 } | |
| 660 | |
| 661 /** | |
| 622 * Builds the object to manage tasks (mutually exclusive chains of events). | 662 * Builds the object to manage tasks (mutually exclusive chains of events). |
| 623 * @param {function(string, string): boolean} areConflicting Function that | 663 * @param {function(string, string): boolean} areConflicting Function that |
| 624 * checks if a new task can't be added to a task queue that contains an | 664 * checks if a new task can't be added to a task queue that contains an |
| 625 * existing task. | 665 * existing task. |
| 626 * @return {Object} Task manager interface. | 666 * @return {Object} Task manager interface. |
| 627 */ | 667 */ |
| 628 function buildTaskManager(areConflicting) { | 668 function buildTaskManager(areConflicting) { |
| 629 /** | 669 /** |
| 630 * Queue of scheduled tasks. The first element, if present, corresponds to the | 670 * Queue of scheduled tasks. The first element, if present, corresponds to the |
| 631 * currently running task. | 671 * currently running task. |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 chrome.alarms.clear(alarmName); | 892 chrome.alarms.clear(alarmName); |
| 853 chrome.storage.local.remove(currentDelayStorageKey); | 893 chrome.storage.local.remove(currentDelayStorageKey); |
| 854 } | 894 } |
| 855 | 895 |
| 856 /** | 896 /** |
| 857 * Plans for the next attempt. | 897 * Plans for the next attempt. |
| 858 * @param {function()} callback Completion callback. It will be invoked after | 898 * @param {function()} callback Completion callback. It will be invoked after |
| 859 * the planning is done. | 899 * the planning is done. |
| 860 */ | 900 */ |
| 861 function planForNext(callback) { | 901 function planForNext(callback) { |
| 862 instrumented.storage.local.get(currentDelayStorageKey, function(items) { | 902 var request = {}; |
| 863 if (!items) { | 903 request[currentDelayStorageKey] = maximumDelaySeconds; |
|
vadimt
2014/02/27 20:20:36
This changes the semantics. If items retrieved, bu
robliao
2014/02/27 23:52:36
Gotcha. Fixed.
On 2014/02/27 20:20:36, vadimt wrot
| |
| 864 items = {}; | 904 fillFromChromeLocalStorage(request).then(function(items) { |
| 865 items[currentDelayStorageKey] = maximumDelaySeconds; | |
| 866 } | |
| 867 console.log('planForNext-get-storage ' + JSON.stringify(items)); | 905 console.log('planForNext-get-storage ' + JSON.stringify(items)); |
| 868 scheduleNextAttempt(items[currentDelayStorageKey]); | 906 scheduleNextAttempt(items[currentDelayStorageKey]); |
| 869 callback(); | 907 callback(); |
| 870 }); | 908 }); |
| 871 } | 909 } |
| 872 | 910 |
| 873 instrumented.alarms.onAlarm.addListener(function(alarm) { | 911 instrumented.alarms.onAlarm.addListener(function(alarm) { |
| 874 if (alarm.name == alarmName) | 912 if (alarm.name == alarmName) |
| 875 isRunning(function(running) { | 913 isRunning(function(running) { |
| 876 if (running) | 914 if (running) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 function addListener(callback) { | 988 function addListener(callback) { |
| 951 listeners.push(callback); | 989 listeners.push(callback); |
| 952 } | 990 } |
| 953 | 991 |
| 954 /** | 992 /** |
| 955 * Checks if the last signed in state matches the current one. | 993 * Checks if the last signed in state matches the current one. |
| 956 * If it doesn't, it notifies the listeners of the change. | 994 * If it doesn't, it notifies the listeners of the change. |
| 957 */ | 995 */ |
| 958 function checkAndNotifyListeners() { | 996 function checkAndNotifyListeners() { |
| 959 isSignedIn().then(function(signedIn) { | 997 isSignedIn().then(function(signedIn) { |
| 960 instrumented.storage.local.get('lastSignedInState', function(items) { | 998 fillFromChromeLocalStorage({lastSignedInState: undefined}) |
| 961 items = items || {}; | 999 .then(function(items) { |
| 962 if (items.lastSignedInState != signedIn) { | 1000 if (items.lastSignedInState != signedIn) { |
| 963 chrome.storage.local.set( | 1001 chrome.storage.local.set( |
| 964 {lastSignedInState: signedIn}); | 1002 {lastSignedInState: signedIn}); |
| 965 listeners.forEach(function(callback) { | 1003 listeners.forEach(function(callback) { |
| 966 callback(); | 1004 callback(); |
| 967 }); | 1005 }); |
| 968 } | 1006 } |
| 1007 }); | |
| 969 }); | 1008 }); |
| 970 }); | |
| 971 } | 1009 } |
| 972 | 1010 |
| 973 instrumented.identity.onSignInChanged.addListener(function() { | 1011 instrumented.identity.onSignInChanged.addListener(function() { |
| 974 checkAndNotifyListeners(); | 1012 checkAndNotifyListeners(); |
| 975 }); | 1013 }); |
| 976 | 1014 |
| 977 instrumented.alarms.onAlarm.addListener(function(alarm) { | 1015 instrumented.alarms.onAlarm.addListener(function(alarm) { |
| 978 if (alarm.name == alarmName) | 1016 if (alarm.name == alarmName) |
| 979 checkAndNotifyListeners(); | 1017 checkAndNotifyListeners(); |
| 980 }); | 1018 }); |
| 981 | 1019 |
| 982 // Poll for the sign in state every hour. | 1020 // Poll for the sign in state every hour. |
| 983 // One hour is just an arbitrary amount of time chosen. | 1021 // One hour is just an arbitrary amount of time chosen. |
| 984 chrome.alarms.create(alarmName, {periodInMinutes: 60}); | 1022 chrome.alarms.create(alarmName, {periodInMinutes: 60}); |
| 985 | 1023 |
| 986 return { | 1024 return { |
| 987 addListener: addListener, | 1025 addListener: addListener, |
| 988 getAuthToken: getAuthToken, | 1026 getAuthToken: getAuthToken, |
| 989 isSignedIn: isSignedIn, | 1027 isSignedIn: isSignedIn, |
| 990 removeToken: removeToken | 1028 removeToken: removeToken |
| 991 }; | 1029 }; |
| 992 } | 1030 } |
| OLD | NEW |