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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 checkInWrappedCallback: checkInWrappedCallback, | 388 checkInWrappedCallback: checkInWrappedCallback, |
389 debugGetStateString: debugGetStateString | 389 debugGetStateString: debugGetStateString |
390 }; | 390 }; |
391 })(); | 391 })(); |
392 | 392 |
393 wrapper.instrumentChromeApiFunction('alarms.get', 1); | 393 wrapper.instrumentChromeApiFunction('alarms.get', 1); |
394 wrapper.instrumentChromeApiFunction('alarms.onAlarm.addListener', 0); | 394 wrapper.instrumentChromeApiFunction('alarms.onAlarm.addListener', 0); |
395 wrapper.instrumentChromeApiFunction('identity.getAuthToken', 1); | 395 wrapper.instrumentChromeApiFunction('identity.getAuthToken', 1); |
396 wrapper.instrumentChromeApiFunction('identity.onSignInChanged.addListener', 0); | 396 wrapper.instrumentChromeApiFunction('identity.onSignInChanged.addListener', 0); |
397 wrapper.instrumentChromeApiFunction('identity.removeCachedAuthToken', 1); | 397 wrapper.instrumentChromeApiFunction('identity.removeCachedAuthToken', 1); |
| 398 wrapper.instrumentChromeApiFunction('webstorePrivate.getBrowserLogin', 0); |
398 | 399 |
399 /** | 400 /** |
400 * Builds the object to manage tasks (mutually exclusive chains of events). | 401 * Builds the object to manage tasks (mutually exclusive chains of events). |
401 * @param {function(string, string): boolean} areConflicting Function that | 402 * @param {function(string, string): boolean} areConflicting Function that |
402 * checks if a new task can't be added to a task queue that contains an | 403 * checks if a new task can't be added to a task queue that contains an |
403 * existing task. | 404 * existing task. |
404 * @return {Object} Task manager interface. | 405 * @return {Object} Task manager interface. |
405 */ | 406 */ |
406 function buildTaskManager(areConflicting) { | 407 function buildTaskManager(areConflicting) { |
407 /** | 408 /** |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 // TODO(robliao): Use signed-in state change watch API when it's available. | 668 // TODO(robliao): Use signed-in state change watch API when it's available. |
668 /** | 669 /** |
669 * Wraps chrome.identity to provide limited listening support for | 670 * Wraps chrome.identity to provide limited listening support for |
670 * the sign in state by polling periodically for the auth token. | 671 * the sign in state by polling periodically for the auth token. |
671 * @return {Object} The Authentication Manager interface. | 672 * @return {Object} The Authentication Manager interface. |
672 */ | 673 */ |
673 function buildAuthenticationManager() { | 674 function buildAuthenticationManager() { |
674 var alarmName = 'sign-in-alarm'; | 675 var alarmName = 'sign-in-alarm'; |
675 | 676 |
676 /** | 677 /** |
677 * Determines if the user is signed in and provides a token if signed in. | 678 * Gets an OAuth2 access token. |
678 * @param {function(string=)} callback Called on completion. | 679 * @param {function(string=)} callback Called on completion. |
679 * If the user is signed in, the string contains the token. | 680 * The string contains the token. It's undefined if there was an error. |
680 */ | 681 */ |
681 function isSignedIn(callback) { | 682 function getAuthToken(callback) { |
682 instrumented.identity.getAuthToken({interactive: false}, function(token) { | 683 instrumented.identity.getAuthToken({interactive: false}, function(token) { |
683 token = chrome.runtime.lastError ? undefined : token; | 684 token = chrome.runtime.lastError ? undefined : token; |
684 callback(token); | 685 callback(token); |
685 checkAndNotifyListeners(!!token); | |
686 }); | 686 }); |
687 } | 687 } |
688 | 688 |
| 689 /** |
| 690 * Determines whether there is an account attached to the profile. |
| 691 * @param {function(boolean)} callback Called on completion. |
| 692 */ |
| 693 function isSignedIn(callback) { |
| 694 instrumented.webstorePrivate.getBrowserLogin(function(accountInfo) { |
| 695 callback(!!accountInfo.login); |
| 696 }); |
| 697 } |
| 698 |
689 /** | 699 /** |
690 * Removes the specified cached token. | 700 * Removes the specified cached token. |
691 * @param {string} token Authentication Token to remove from the cache. | 701 * @param {string} token Authentication Token to remove from the cache. |
692 * @param {function} callback Called on completion. | 702 * @param {function} callback Called on completion. |
693 */ | 703 */ |
694 function removeToken(token, callback) { | 704 function removeToken(token, callback) { |
695 instrumented.identity.removeCachedAuthToken({token: token}, function() { | 705 instrumented.identity.removeCachedAuthToken({token: token}, function() { |
696 // Removing the token from the cache will change the sign in state. | 706 // Let Chrome now about a possible problem with the token. |
697 // Repoll now to check the state and notify listeners. | 707 getAuthToken(function() {}); |
698 // This also lets Chrome now about a possible problem with the token. | |
699 isSignedIn(function() {}); | |
700 callback(); | 708 callback(); |
701 }); | 709 }); |
702 } | 710 } |
703 | 711 |
704 var listeners = []; | 712 var listeners = []; |
705 | 713 |
706 /** | 714 /** |
707 * Registers a listener that gets called back when the signed in state | 715 * Registers a listener that gets called back when the signed in state |
708 * is found to be changed. | 716 * is found to be changed. |
709 * @param {function} callback Called when the answer to isSignedIn changes. | 717 * @param {function} callback Called when the answer to isSignedIn changes. |
710 */ | 718 */ |
711 function addListener(callback) { | 719 function addListener(callback) { |
712 listeners.push(callback); | 720 listeners.push(callback); |
713 } | 721 } |
714 | 722 |
715 /** | 723 /** |
716 * Checks if the last signed in state matches the specified one. | 724 * Checks if the last signed in state matches the current one. |
717 * If it doesn't, it notifies the listeners of the change. | 725 * If it doesn't, it notifies the listeners of the change. |
718 * @param {boolean} currentSignedInState The current signed in state. | |
719 */ | 726 */ |
720 function checkAndNotifyListeners(currentSignedInState) { | 727 function checkAndNotifyListeners() { |
721 instrumented.storage.local.get('lastSignedInState', function(items) { | 728 isSignedIn(function(signedIn) { |
722 items = items || {}; | 729 instrumented.storage.local.get('lastSignedInState', function(items) { |
723 if (items.lastSignedInState != currentSignedInState) { | 730 items = items || {}; |
724 chrome.storage.local.set( | 731 if (items.lastSignedInState != signedIn) { |
725 {lastSignedInState: currentSignedInState}); | 732 chrome.storage.local.set( |
726 if (items.lastSignedInState != undefined) { | 733 {lastSignedInState: signedIn}); |
727 listeners.forEach(function(callback) { | 734 if (items.lastSignedInState != undefined) { |
728 callback(); | 735 listeners.forEach(function(callback) { |
729 }); | 736 callback(); |
| 737 }); |
| 738 } |
730 } | 739 } |
731 } | 740 }); |
732 }); | 741 }); |
733 } | 742 } |
734 | 743 |
735 instrumented.identity.onSignInChanged.addListener(function() { | 744 instrumented.identity.onSignInChanged.addListener(function() { |
736 isSignedIn(function() {}); | 745 checkAndNotifyListeners(); |
737 }); | 746 }); |
738 | 747 |
739 instrumented.alarms.onAlarm.addListener(function(alarm) { | 748 instrumented.alarms.onAlarm.addListener(function(alarm) { |
740 if (alarm.name == alarmName) | 749 if (alarm.name == alarmName) |
741 isSignedIn(function() {}); | 750 checkAndNotifyListeners(); |
742 }); | 751 }); |
743 | 752 |
744 // Poll for the sign in state every hour. | 753 // Poll for the sign in state every hour. |
745 // One hour is just an arbitrary amount of time chosen. | 754 // One hour is just an arbitrary amount of time chosen. |
746 chrome.alarms.create(alarmName, {periodInMinutes: 60}); | 755 chrome.alarms.create(alarmName, {periodInMinutes: 60}); |
747 | 756 |
748 return { | 757 return { |
749 addListener: addListener, | 758 addListener: addListener, |
| 759 getAuthToken: getAuthToken, |
750 isSignedIn: isSignedIn, | 760 isSignedIn: isSignedIn, |
751 removeToken: removeToken | 761 removeToken: removeToken |
752 }; | 762 }; |
753 } | 763 } |
OLD | NEW |