#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/event_router.h"
-#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_global_error.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/extensions/api/identity.h"
#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
-#include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_function_dispatcher.h"
+#include "extensions/common/extension.h"
#include "google_apis/gaia/gaia_urls.h"
#include "url/gurl.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
#include "google_apis/gaia/gaia_constants.h"
const char kInvalidRedirect[] = "Did not redirect to the right URL.";
const char kOffTheRecord[] = "Identity API is disabled in incognito windows.";
const char kPageLoadFailure[] = "Authorization page could not be loaded.";
+const char kCanceled[] = "canceled";
const int kCachedIssueAdviceTTLSeconds = 1;
} // namespace identity_constants
static const char kChromiumDomainRedirectUrlPattern[] =
"https://%s.chromiumapp.org/";
+std::string GetPrimaryAccountId(content::BrowserContext* context) {
+ SigninManagerBase* signin_manager =
+ SigninManagerFactory::GetForProfile(Profile::FromBrowserContext(context));
+ return signin_manager->GetAuthenticatedAccountId();
+}
+
} // namespace
namespace identity = api::identity;
+IdentityTokenCacheValue::IdentityTokenCacheValue()
+ : status_(CACHE_STATUS_NOTFOUND) {}
+
+IdentityTokenCacheValue::IdentityTokenCacheValue(
+ const IssueAdviceInfo& issue_advice)
+ : status_(CACHE_STATUS_ADVICE), issue_advice_(issue_advice) {
+ expiration_time_ =
+ base::Time::Now() + base::TimeDelta::FromSeconds(
+ identity_constants::kCachedIssueAdviceTTLSeconds);
+}
+
+IdentityTokenCacheValue::IdentityTokenCacheValue(const std::string& token,
+ base::TimeDelta time_to_live)
+ : status_(CACHE_STATUS_TOKEN), token_(token) {
+ // Remove 20 minutes from the ttl so cached tokens will have some time
+ // to live any time they are returned.
+ time_to_live -= base::TimeDelta::FromMinutes(20);
+
+ base::TimeDelta zero_delta;
+ if (time_to_live < zero_delta)
+ time_to_live = zero_delta;
+
+ expiration_time_ = base::Time::Now() + time_to_live;
+}
+
+IdentityTokenCacheValue::~IdentityTokenCacheValue() {}
+
+IdentityTokenCacheValue::CacheValueStatus IdentityTokenCacheValue::status()
+ const {
+ if (is_expired())
+ return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND;
+ else
+ return status_;
+}
+
+const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const {
+ return issue_advice_;
+}
+
+const std::string& IdentityTokenCacheValue::token() const { return token_; }
+
+bool IdentityTokenCacheValue::is_expired() const {
+ return status_ == CACHE_STATUS_NOTFOUND ||
+ expiration_time_ < base::Time::Now();
+}
+
+const base::Time& IdentityTokenCacheValue::expiration_time() const {
+ return expiration_time_;
+}
+
+IdentityAPI::IdentityAPI(content::BrowserContext* context)
+ : browser_context_(context),
+ account_tracker_(Profile::FromBrowserContext(context)) {
+ account_tracker_.AddObserver(this);
+}
+
+IdentityAPI::~IdentityAPI() {}
+
+IdentityMintRequestQueue* IdentityAPI::mint_queue() { return &mint_queue_; }
+
+void IdentityAPI::SetCachedToken(const ExtensionTokenKey& key,
+ const IdentityTokenCacheValue& token_data) {
+ CachedTokens::iterator it = token_cache_.find(key);
+ if (it != token_cache_.end() && it->second.status() <= token_data.status())
+ token_cache_.erase(it);
+
+ token_cache_.insert(std::make_pair(key, token_data));
+}
+
+void IdentityAPI::EraseCachedToken(const std::string& extension_id,
+ const std::string& token) {
+ CachedTokens::iterator it;
+ for (it = token_cache_.begin(); it != token_cache_.end(); ++it) {
+ if (it->first.extension_id == extension_id &&
+ it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN &&
+ it->second.token() == token) {
+ token_cache_.erase(it);
+ break;
+ }
+ }
+}
+
+void IdentityAPI::EraseAllCachedTokens() { token_cache_.clear(); }
+
+const IdentityTokenCacheValue& IdentityAPI::GetCachedToken(
+ const ExtensionTokenKey& key) {
+ return token_cache_[key];
+}
+
+const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() {
+ return token_cache_;
+}
+
+void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) {
+ account_tracker_.ReportAuthError(GetPrimaryAccountId(browser_context_),
+ error);
+}
+
+GoogleServiceAuthError IdentityAPI::GetAuthStatusForTest() const {
+ return account_tracker_.GetAuthStatus();
+}
+
+void IdentityAPI::Shutdown() {
+ FOR_EACH_OBSERVER(ShutdownObserver, shutdown_observer_list_, OnShutdown());
+ account_tracker_.RemoveObserver(this);
+ account_tracker_.Shutdown();
+}
+
+static base::LazyInstance<BrowserContextKeyedAPIFactory<IdentityAPI> >
+ g_factory = LAZY_INSTANCE_INITIALIZER;
+
+// static
+BrowserContextKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() {
+ return g_factory.Pointer();
+}
+
+void IdentityAPI::OnAccountAdded(const AccountIds& ids) {}
+
+void IdentityAPI::OnAccountRemoved(const AccountIds& ids) {}
+
+void IdentityAPI::OnAccountSignInChanged(const AccountIds& ids,
+ bool is_signed_in) {
+ api::identity::AccountInfo account_info;
+ account_info.id = ids.gaia;
+
+ scoped_ptr<base::ListValue> args =
+ api::identity::OnSignInChanged::Create(account_info, is_signed_in);
+ scoped_ptr<Event> event(new Event(api::identity::OnSignInChanged::kEventName,
+ args.Pass(),
+ browser_context_));
+
+ EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
+}
+
+void IdentityAPI::AddShutdownObserver(ShutdownObserver* observer) {
+ shutdown_observer_list_.AddObserver(observer);
+}
+
+void IdentityAPI::RemoveShutdownObserver(ShutdownObserver* observer) {
+ shutdown_observer_list_.RemoveObserver(observer);
+}
+
+template <>
+void BrowserContextKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() {
+ DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
+ DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
+}
+
IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction()
- : should_prompt_for_scopes_(false),
+ : OAuth2TokenService::Consumer("extensions_identity_api"),
+ should_prompt_for_scopes_(false),
should_prompt_for_signin_(false) {}
IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {}
-bool IdentityGetAuthTokenFunction::RunImpl() {
+bool IdentityGetAuthTokenFunction::RunAsync() {
if (GetProfile()->IsOffTheRecord()) {
error_ = identity_constants::kOffTheRecord;
return false;
return false;
}
- // Balanced in CompleteFunctionWithResult|CompleteFunctionWithError
- AddRef();
+ std::set<std::string> scopes(oauth2_info.scopes.begin(),
+ oauth2_info.scopes.end());
+ token_key_.reset(new ExtensionTokenKey(
+ GetExtension()->id(), GetPrimaryAccountId(GetProfile()), scopes));
+
+ // From here on out, results must be returned asynchronously.
+ StartAsyncRun();
#if defined(OS_CHROMEOS)
+ policy::BrowserPolicyConnectorChromeOS* connector =
+ g_browser_process->platform_part()->browser_policy_connector_chromeos();
if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp() &&
- g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) {
+ connector->IsEnterpriseManaged()) {
StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
return true;
}
if (!HasLoginToken()) {
if (!should_prompt_for_signin_) {
- error_ = identity_constants::kUserNotSignedIn;
- Release();
- return false;
+ CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
+ return true;
}
// Display a login prompt.
StartSigninFlow();
return true;
}
+void IdentityGetAuthTokenFunction::StartAsyncRun() {
+ // Balanced in CompleteAsyncRun
+ AddRef();
+ extensions::IdentityAPI::GetFactoryInstance()
+ ->Get(GetProfile())
+ ->AddShutdownObserver(this);
+}
+
+void IdentityGetAuthTokenFunction::CompleteAsyncRun(bool success) {
+ extensions::IdentityAPI::GetFactoryInstance()
+ ->Get(GetProfile())
+ ->RemoveShutdownObserver(this);
+
+ SendResponse(success);
+ Release(); // Balanced in StartAsyncRun
+}
+
void IdentityGetAuthTokenFunction::CompleteFunctionWithResult(
const std::string& access_token) {
+
SetResult(new base::StringValue(access_token));
- SendResponse(true);
- Release(); // Balanced in RunImpl.
+ CompleteAsyncRun(true);
}
void IdentityGetAuthTokenFunction::CompleteFunctionWithError(
const std::string& error) {
error_ = error;
- SendResponse(false);
- Release(); // Balanced in RunImpl.
+ CompleteAsyncRun(false);
}
void IdentityGetAuthTokenFunction::StartSigninFlow() {
// All cached tokens are invalid because the user is not signed in.
IdentityAPI* id_api =
- extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
- GetProfile());
+ extensions::IdentityAPI::GetFactoryInstance()->Get(GetProfile());
id_api->EraseAllCachedTokens();
// Display a login prompt. If the subsequent mint fails, don't display the
// login prompt again.
// Flows are serialized to prevent excessive traffic to GAIA, and
// to consolidate UI pop-ups.
- const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
- std::set<std::string> scopes(oauth2_info.scopes.begin(),
- oauth2_info.scopes.end());
IdentityAPI* id_api =
- extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
- GetProfile());
+ extensions::IdentityAPI::GetFactoryInstance()->Get(GetProfile());
if (!should_prompt_for_scopes_) {
// Caller requested no interaction.
return;
}
if (!id_api->mint_queue()->empty(
- IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE,
- GetExtension()->id(), scopes)) {
+ IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE, *token_key_)) {
// Another call is going through a consent UI.
CompleteFunctionWithError(identity_constants::kNoGrant);
return;
}
}
- id_api->mint_queue()->RequestStart(type,
- GetExtension()->id(),
- scopes,
- this);
+ id_api->mint_queue()->RequestStart(type, *token_key_, this);
}
void IdentityGetAuthTokenFunction::CompleteMintTokenFlow() {
oauth2_info.scopes.end());
extensions::IdentityAPI::GetFactoryInstance()
- ->GetForProfile(GetProfile())
+ ->Get(GetProfile())
->mint_queue()
- ->RequestComplete(type, GetExtension()->id(), scopes, this);
+ ->RequestComplete(type, *token_key_, this);
}
void IdentityGetAuthTokenFunction::StartMintToken(
IdentityMintRequestQueue::MintType type) {
const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
- IdentityAPI* id_api =
- IdentityAPI::GetFactoryInstance()->GetForProfile(GetProfile());
- IdentityTokenCacheValue cache_entry = id_api->GetCachedToken(
- GetExtension()->id(), oauth2_info.scopes);
+ IdentityAPI* id_api = IdentityAPI::GetFactoryInstance()->Get(GetProfile());
+ IdentityTokenCacheValue cache_entry = id_api->GetCachedToken(*token_key_);
IdentityTokenCacheValue::CacheValueStatus cache_status =
cache_entry.status();
// Always force minting token for ChromeOS kiosk app.
if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
- if (g_browser_process->browser_policy_connector()->
- IsEnterpriseManaged()) {
+ policy::BrowserPolicyConnectorChromeOS* connector =
+ g_browser_process->platform_part()
+ ->browser_policy_connector_chromeos();
+ if (connector->IsEnterpriseManaged()) {
StartDeviceLoginAccessTokenRequest();
} else {
StartLoginAccessTokenRequest();
void IdentityGetAuthTokenFunction::OnMintTokenSuccess(
const std::string& access_token, int time_to_live) {
- const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
IdentityTokenCacheValue token(access_token,
base::TimeDelta::FromSeconds(time_to_live));
- IdentityAPI::GetFactoryInstance()
- ->GetForProfile(GetProfile())
- ->SetCachedToken(GetExtension()->id(), oauth2_info.scopes, token);
+ IdentityAPI::GetFactoryInstance()->Get(GetProfile())->SetCachedToken(
+ *token_key_, token);
CompleteMintTokenFlow();
CompleteFunctionWithResult(access_token);
case GoogleServiceAuthError::ACCOUNT_DELETED:
case GoogleServiceAuthError::ACCOUNT_DISABLED:
extensions::IdentityAPI::GetFactoryInstance()
- ->GetForProfile(GetProfile())
+ ->Get(GetProfile())
->ReportAuthError(error);
if (should_prompt_for_signin_) {
// Display a login prompt and try again (once).
void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess(
const IssueAdviceInfo& issue_advice) {
- const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
- IdentityAPI::GetFactoryInstance()
- ->GetForProfile(GetProfile())
- ->SetCachedToken(GetExtension()->id(),
- oauth2_info.scopes,
- IdentityTokenCacheValue(issue_advice));
+ IdentityAPI::GetFactoryInstance()->Get(GetProfile())->SetCachedToken(
+ *token_key_, IdentityTokenCacheValue(issue_advice));
CompleteMintTokenFlow();
should_prompt_for_signin_ = false;
int time_to_live;
if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) {
- const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
IdentityTokenCacheValue token_value(
access_token, base::TimeDelta::FromSeconds(time_to_live));
- IdentityAPI::GetFactoryInstance()
- ->GetForProfile(GetProfile())
- ->SetCachedToken(GetExtension()->id(), oauth2_info.scopes, token_value);
+ IdentityAPI::GetFactoryInstance()->Get(GetProfile())->SetCachedToken(
+ *token_key_, token_value);
}
CompleteMintTokenFlow();
OnGaiaFlowFailure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string());
}
-#if defined(OS_CHROMEOS)
-void IdentityGetAuthTokenFunction::StartDeviceLoginAccessTokenRequest() {
- chromeos::DeviceOAuth2TokenServiceFactory::Get(
- base::Bind(&IdentityGetAuthTokenFunction::DidGetTokenService,
- this));
+void IdentityGetAuthTokenFunction::OnShutdown() {
+ gaia_web_auth_flow_.reset();
+ signin_flow_.reset();
+ login_token_request_.reset();
+ extensions::IdentityAPI::GetFactoryInstance()
+ ->Get(GetProfile())
+ ->mint_queue()
+ ->RequestCancel(*token_key_, this);
+ CompleteFunctionWithError(identity_constants::kCanceled);
}
-void IdentityGetAuthTokenFunction::DidGetTokenService(
- chromeos::DeviceOAuth2TokenService* service) {
- if (!service) {
- CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
- return;
- }
+#if defined(OS_CHROMEOS)
+void IdentityGetAuthTokenFunction::StartDeviceLoginAccessTokenRequest() {
+ chromeos::DeviceOAuth2TokenService* service =
+ chromeos::DeviceOAuth2TokenServiceFactory::Get();
// Since robot account refresh tokens are scoped down to [any-api] only,
// request access token for [any-api] instead of login.
OAuth2TokenService::ScopeSet scopes;
void IdentityGetAuthTokenFunction::StartLoginAccessTokenRequest() {
ProfileOAuth2TokenService* service =
ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
+ const std::string primary_account_id = GetPrimaryAccountId(GetProfile());
#if defined(OS_CHROMEOS)
if (chrome::IsRunningInForcedAppMode()) {
std::string app_client_id;
if (chromeos::UserManager::Get()->GetAppModeChromeClientOAuthInfo(
&app_client_id, &app_client_secret)) {
login_token_request_ =
- service->StartRequestForClient(service->GetPrimaryAccountId(),
+ service->StartRequestForClient(primary_account_id,
app_client_id,
app_client_secret,
OAuth2TokenService::ScopeSet(),
}
#endif
login_token_request_ = service->StartRequest(
- service->GetPrimaryAccountId(), OAuth2TokenService::ScopeSet(), this);
+ primary_account_id, OAuth2TokenService::ScopeSet(), this);
}
void IdentityGetAuthTokenFunction::StartGaiaRequest(
ProfileOAuth2TokenService* token_service =
ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
return token_service->RefreshTokenIsAvailable(
- token_service->GetPrimaryAccountId());
+ GetPrimaryAccountId(GetProfile()));
}
std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription(
~IdentityRemoveCachedAuthTokenFunction() {
}
-bool IdentityRemoveCachedAuthTokenFunction::RunImpl() {
+bool IdentityRemoveCachedAuthTokenFunction::RunSync() {
if (GetProfile()->IsOffTheRecord()) {
error_ = identity_constants::kOffTheRecord;
return false;
scoped_ptr<identity::RemoveCachedAuthToken::Params> params(
identity::RemoveCachedAuthToken::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
- IdentityAPI::GetFactoryInstance()
- ->GetForProfile(GetProfile())
- ->EraseCachedToken(GetExtension()->id(), params->details.token);
+ IdentityAPI::GetFactoryInstance()->Get(GetProfile())->EraseCachedToken(
+ GetExtension()->id(), params->details.token);
return true;
}
auth_flow_.release()->DetachDelegateAndDelete();
}
-bool IdentityLaunchWebAuthFlowFunction::RunImpl() {
+bool IdentityLaunchWebAuthFlowFunction::RunAsync() {
if (GetProfile()->IsOffTheRecord()) {
error_ = identity_constants::kOffTheRecord;
return false;
break;
}
SendResponse(false);
- Release(); // Balanced in RunImpl.
+ Release(); // Balanced in RunAsync.
}
void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange(
if (redirect_url.GetWithEmptyPath() == final_url_prefix_) {
SetResult(new base::StringValue(redirect_url.spec()));
SendResponse(true);
- Release(); // Balanced in RunImpl.
+ Release(); // Balanced in RunAsync.
}
}
-IdentityTokenCacheValue::IdentityTokenCacheValue()
- : status_(CACHE_STATUS_NOTFOUND) {
-}
-
-IdentityTokenCacheValue::IdentityTokenCacheValue(
- const IssueAdviceInfo& issue_advice) : status_(CACHE_STATUS_ADVICE),
- issue_advice_(issue_advice) {
- expiration_time_ = base::Time::Now() + base::TimeDelta::FromSeconds(
- identity_constants::kCachedIssueAdviceTTLSeconds);
-}
-
-IdentityTokenCacheValue::IdentityTokenCacheValue(
- const std::string& token, base::TimeDelta time_to_live)
- : status_(CACHE_STATUS_TOKEN),
- token_(token) {
- // Remove 20 minutes from the ttl so cached tokens will have some time
- // to live any time they are returned.
- time_to_live -= base::TimeDelta::FromMinutes(20);
-
- base::TimeDelta zero_delta;
- if (time_to_live < zero_delta)
- time_to_live = zero_delta;
-
- expiration_time_ = base::Time::Now() + time_to_live;
-}
-
-IdentityTokenCacheValue::~IdentityTokenCacheValue() {
-}
-
-IdentityTokenCacheValue::CacheValueStatus
- IdentityTokenCacheValue::status() const {
- if (is_expired())
- return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND;
- else
- return status_;
-}
-
-const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const {
- return issue_advice_;
-}
-
-const std::string& IdentityTokenCacheValue::token() const {
- return token_;
-}
-
-bool IdentityTokenCacheValue::is_expired() const {
- return status_ == CACHE_STATUS_NOTFOUND ||
- expiration_time_ < base::Time::Now();
-}
-
-const base::Time& IdentityTokenCacheValue::expiration_time() const {
- return expiration_time_;
-}
-
-IdentityAPI::IdentityAPI(Profile* profile)
- : profile_(profile),
- account_tracker_(profile) {
- account_tracker_.AddObserver(this);
-}
-
-IdentityAPI::~IdentityAPI() {}
-
-IdentityMintRequestQueue* IdentityAPI::mint_queue() {
- return &mint_queue_;
-}
-
-void IdentityAPI::SetCachedToken(const std::string& extension_id,
- const std::vector<std::string> scopes,
- const IdentityTokenCacheValue& token_data) {
- std::set<std::string> scopeset(scopes.begin(), scopes.end());
- TokenCacheKey key(extension_id, scopeset);
-
- CachedTokens::iterator it = token_cache_.find(key);
- if (it != token_cache_.end() && it->second.status() <= token_data.status())
- token_cache_.erase(it);
-
- token_cache_.insert(std::make_pair(key, token_data));
-}
-
-void IdentityAPI::EraseCachedToken(const std::string& extension_id,
- const std::string& token) {
- CachedTokens::iterator it;
- for (it = token_cache_.begin(); it != token_cache_.end(); ++it) {
- if (it->first.extension_id == extension_id &&
- it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN &&
- it->second.token() == token) {
- token_cache_.erase(it);
- break;
- }
- }
-}
-
-void IdentityAPI::EraseAllCachedTokens() {
- token_cache_.clear();
-}
-
-const IdentityTokenCacheValue& IdentityAPI::GetCachedToken(
- const std::string& extension_id, const std::vector<std::string> scopes) {
- std::set<std::string> scopeset(scopes.begin(), scopes.end());
- TokenCacheKey key(extension_id, scopeset);
- return token_cache_[key];
-}
-
-const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() {
- return token_cache_;
-}
-
-void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) {
- ProfileOAuth2TokenService* token_service =
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
- account_tracker_.ReportAuthError(token_service->GetPrimaryAccountId(), error);
-}
-
-void IdentityAPI::Shutdown() {
- account_tracker_.RemoveObserver(this);
- account_tracker_.Shutdown();
-}
-
-static base::LazyInstance<ProfileKeyedAPIFactory<IdentityAPI> >
- g_factory = LAZY_INSTANCE_INITIALIZER;
-
-// static
-ProfileKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() {
- return &g_factory.Get();
-}
-
-void IdentityAPI::OnAccountAdded(const AccountIds& ids) {}
-
-void IdentityAPI::OnAccountRemoved(const AccountIds& ids) {}
-
-void IdentityAPI::OnAccountSignInChanged(const AccountIds& ids,
- bool is_signed_in) {
- api::identity::AccountInfo account_info;
- account_info.id = ids.gaia;
-
- scoped_ptr<base::ListValue> args =
- api::identity::OnSignInChanged::Create(account_info, is_signed_in);
- scoped_ptr<Event> event(new Event(
- api::identity::OnSignInChanged::kEventName, args.Pass(), profile_));
-
- ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(event.Pass());
-}
-
-template <>
-void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() {
- DependsOn(ExtensionSystemFactory::GetInstance());
- DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
-}
-
-IdentityAPI::TokenCacheKey::TokenCacheKey(const std::string& extension_id,
- const std::set<std::string> scopes)
- : extension_id(extension_id),
- scopes(scopes) {
-}
-
-IdentityAPI::TokenCacheKey::~TokenCacheKey() {
-}
-
-bool IdentityAPI::TokenCacheKey::operator<(
- const IdentityAPI::TokenCacheKey& rhs) const {
- if (extension_id < rhs.extension_id)
- return true;
- else if (rhs.extension_id < extension_id)
- return false;
-
- return scopes < rhs.scopes;
-}
-
} // namespace extensions