Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_ | 5 #ifndef CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_ |
| 6 #define CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_ | 6 #define CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/gtest_prod_util.h" | |
| 13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/memory/weak_ptr.h" | 16 #include "base/memory/weak_ptr.h" |
| 16 #include "base/observer_list.h" | 17 #include "base/observer_list.h" |
| 17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 19 #include "base/timer/timer.h" | |
| 18 #include "google_apis/gaia/google_service_auth_error.h" | 20 #include "google_apis/gaia/google_service_auth_error.h" |
| 21 #include "google_apis/gaia/oauth2_access_token_consumer.h" | |
| 22 #include "google_apis/gaia/oauth2_access_token_fetcher.h" | |
| 19 | 23 |
| 20 namespace base { | 24 namespace base { |
| 21 class Time; | 25 class Time; |
| 22 } | 26 } |
| 23 | 27 |
| 24 namespace net { | 28 namespace net { |
| 25 class URLRequestContextGetter; | 29 class URLRequestContextGetter; |
| 26 } | 30 } |
| 27 | 31 |
| 28 class GoogleServiceAuthError; | 32 class GoogleServiceAuthError; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 // a request for an OAuth2 access token using the OAuth2 refresh token | 116 // a request for an OAuth2 access token using the OAuth2 refresh token |
| 113 // maintained by this instance. The caller owns the returned Request. | 117 // maintained by this instance. The caller owns the returned Request. |
| 114 // |scopes| is the set of scopes to get an access token for, |consumer| is | 118 // |scopes| is the set of scopes to get an access token for, |consumer| is |
| 115 // the object that will be called back with results if the returned request | 119 // the object that will be called back with results if the returned request |
| 116 // is not deleted. | 120 // is not deleted. |
| 117 virtual scoped_ptr<Request> StartRequest(const ScopeSet& scopes, | 121 virtual scoped_ptr<Request> StartRequest(const ScopeSet& scopes, |
| 118 Consumer* consumer); | 122 Consumer* consumer); |
| 119 | 123 |
| 120 // This method does the same as |StartRequest| except it uses |client_id| and | 124 // This method does the same as |StartRequest| except it uses |client_id| and |
| 121 // |client_secret| to identify OAuth client app instead of using | 125 // |client_secret| to identify OAuth client app instead of using |
| 122 // Chrome's default values. | 126 // Chrome's default values. |request_origin| is used to differentiate where |
| 127 // request originates from. It's expected to be empty for requests from | |
| 128 // the internal chrome services while we will use webapp id for their | |
|
Andrew T Wilson (Slow)
2013/08/19 14:04:19
So, one thing this CL (and the associated bug) is
| |
| 129 // requests. | |
| 123 virtual scoped_ptr<Request> StartRequestForClient( | 130 virtual scoped_ptr<Request> StartRequestForClient( |
| 131 const std::string& request_origin, | |
| 124 const std::string& client_id, | 132 const std::string& client_id, |
| 125 const std::string& client_secret, | 133 const std::string& client_secret, |
| 126 const ScopeSet& scopes, | 134 const ScopeSet& scopes, |
| 127 Consumer* consumer); | 135 Consumer* consumer); |
| 128 | 136 |
| 129 // This method does the same as |StartRequest| except it uses the request | 137 // This method does the same as |StartRequest| except it uses the request |
| 130 // context given by |getter| instead of using the one returned by | 138 // context given by |getter| instead of using the one returned by |
| 131 // |GetRequestContext| implemented by derived classes. | 139 // |GetRequestContext| implemented by derived classes. |
| 132 virtual scoped_ptr<Request> StartRequestWithContext( | 140 virtual scoped_ptr<Request> StartRequestWithContext( |
| 133 net::URLRequestContextGetter* getter, | 141 net::URLRequestContextGetter* getter, |
| 134 const ScopeSet& scopes, | 142 const ScopeSet& scopes, |
| 135 Consumer* consumer); | 143 Consumer* consumer); |
| 136 | 144 |
| 137 // Returns true if a refresh token exists. If false, calls to | 145 // Returns true if a refresh token exists. If false, calls to |
| 138 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback. | 146 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback. |
| 139 virtual bool RefreshTokenIsAvailable(); | 147 virtual bool RefreshTokenIsAvailable(); |
| 140 | 148 |
| 141 // Mark an OAuth2 access token as invalid. This should be done if the token | 149 // Mark an OAuth2 access token as invalid. This should be done if the token |
| 142 // was received from this class, but was not accepted by the server (e.g., | 150 // was received from this class, but was not accepted by the server (e.g., |
| 143 // the server returned 401 Unauthorized). The token will be removed from the | 151 // the server returned 401 Unauthorized). The token will be removed from the |
| 144 // cache for the given scopes. | 152 // cache for the given scopes. |
| 145 virtual void InvalidateToken(const ScopeSet& scopes, | 153 virtual void InvalidateToken(const ScopeSet& scopes, |
| 146 const std::string& invalid_token); | 154 const std::string& invalid_token); |
| 147 | 155 |
| 148 // Return the current number of entries in the cache. | 156 // Return the current number of entries in the cache. |
| 149 int cache_size_for_testing() const; | 157 int cache_size_for_testing() const; |
| 150 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); | 158 void set_max_authorization_token_fetch_retries_for_testing(int max_retries); |
| 151 | 159 |
| 152 protected: | 160 protected: |
| 161 struct ClientScopeSet { | |
| 162 ClientScopeSet(const std::string& request_origin, | |
| 163 const std::string& client_id, | |
| 164 const ScopeSet& scopes); | |
| 165 bool operator<(const ClientScopeSet& set) const; | |
| 166 | |
| 167 std::string request_origin; | |
| 168 std::string client_id; | |
| 169 ScopeSet scopes; | |
| 170 }; | |
| 171 | |
| 153 // Implements a cancelable |OAuth2TokenService::Request|, which should be | 172 // Implements a cancelable |OAuth2TokenService::Request|, which should be |
| 154 // operated on the UI thread. | 173 // operated on the UI thread. |
| 155 // TODO(davidroche): move this out of header file. | 174 // TODO(davidroche): move this out of header file. |
| 156 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, | 175 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>, |
| 157 public Request { | 176 public Request { |
| 158 public: | 177 public: |
| 159 // |consumer| is required to outlive this. | 178 // |consumer| is required to outlive this. |
| 160 explicit RequestImpl(Consumer* consumer); | 179 explicit RequestImpl(Consumer* consumer); |
| 161 virtual ~RequestImpl(); | 180 virtual ~RequestImpl(); |
| 162 | 181 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 173 // Subclasses should return the refresh token maintained. | 192 // Subclasses should return the refresh token maintained. |
| 174 // If no token is available, return an empty string. | 193 // If no token is available, return an empty string. |
| 175 virtual std::string GetRefreshToken() = 0; | 194 virtual std::string GetRefreshToken() = 0; |
| 176 | 195 |
| 177 // Subclasses can override if they want to report errors to the user. | 196 // Subclasses can override if they want to report errors to the user. |
| 178 virtual void UpdateAuthError(const GoogleServiceAuthError& error); | 197 virtual void UpdateAuthError(const GoogleServiceAuthError& error); |
| 179 | 198 |
| 180 // Add a new entry to the cache. | 199 // Add a new entry to the cache. |
| 181 // Subclasses can override if there are implementation-specific reasons | 200 // Subclasses can override if there are implementation-specific reasons |
| 182 // that an access token should ever not be cached. | 201 // that an access token should ever not be cached. |
| 183 virtual void RegisterCacheEntry(const std::string& refresh_token, | 202 virtual void RegisterCacheEntry(const std::string& request_origin, |
| 203 const std::string& client_id, | |
| 204 const std::string& refresh_token, | |
| 184 const ScopeSet& scopes, | 205 const ScopeSet& scopes, |
| 185 const std::string& access_token, | 206 const std::string& access_token, |
| 186 const base::Time& expiration_date); | 207 const base::Time& expiration_date); |
| 187 | 208 |
| 188 // Returns true if GetCacheEntry would return a valid cache entry for the | 209 // Returns true if GetCacheEntry would return a valid cache entry for the |
| 189 // given scopes. | 210 // given scopes. |
| 190 bool HasCacheEntry(const ScopeSet& scopes); | 211 bool HasCacheEntry(const ClientScopeSet& client_scopes); |
| 191 | 212 |
| 192 // Posts a task to fire the Consumer callback with the cached token. Must | 213 // Posts a task to fire the Consumer callback with the cached token. Must |
| 193 // Must only be called if HasCacheEntry() returns true. | 214 // Must only be called if HasCacheEntry() returns true. |
| 194 scoped_ptr<Request> StartCacheLookupRequest(const ScopeSet& scopes, | 215 scoped_ptr<Request> StartCacheLookupRequest( |
| 195 Consumer* consumer); | 216 const ClientScopeSet& client_scopes, |
| 217 Consumer* consumer); | |
| 196 | 218 |
| 197 // Clears the internal token cache. | 219 // Clears the internal token cache. |
| 198 void ClearCache(); | 220 void ClearCache(); |
| 199 | 221 |
| 200 // Cancels all requests that are currently in progress. | 222 // Cancels all requests that are currently in progress. |
| 201 void CancelAllRequests(); | 223 void CancelAllRequests(); |
| 202 | 224 |
| 203 // Cancels all requests related to a given refresh token. | 225 // Cancels all requests related to a given refresh token. |
| 204 void CancelRequestsForToken(const std::string& refresh_token); | 226 void CancelRequestsForToken(const std::string& refresh_token); |
| 205 | 227 |
| 206 // Called by subclasses to notify observers. | 228 // Called by subclasses to notify observers. |
| 207 void FireRefreshTokenAvailable(const std::string& account_id); | 229 void FireRefreshTokenAvailable(const std::string& account_id); |
| 208 void FireRefreshTokenRevoked(const std::string& account_id, | 230 void FireRefreshTokenRevoked(const std::string& account_id, |
| 209 const GoogleServiceAuthError& error); | 231 const GoogleServiceAuthError& error); |
| 210 void FireRefreshTokensLoaded(); | 232 void FireRefreshTokensLoaded(); |
| 211 void FireRefreshTokensCleared(); | 233 void FireRefreshTokensCleared(); |
| 212 | 234 |
| 213 private: | 235 private: |
| 236 // Class that fetches an OAuth2 access token for a given set of scopes and | |
|
Andrew T Wilson (Slow)
2013/08/19 14:04:19
I don't really like the fact that we're exposing t
| |
| 237 // OAuth2 refresh token. | |
| 238 | |
| 239 // Class that fetches OAuth2 access tokens for given scopes and refresh token. | |
| 240 // | |
| 241 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry | |
| 242 // mechanism is used to handle failures. | |
| 243 // | |
| 244 // To use this class, call CreateAndStart() to create and start a Fetcher. | |
| 245 // | |
| 246 // The Fetcher will call back the service by calling | |
| 247 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is | |
| 248 // not destructed before it completes fetching; if the Fetcher is destructed | |
| 249 // before it completes fetching, the service will never be called back. The | |
| 250 // Fetcher destructs itself after calling back the service when finishes | |
| 251 // fetching. | |
| 252 // | |
| 253 // Requests that are waiting for the fetching results of this Fetcher can be | |
| 254 // added to the Fetcher by calling | |
| 255 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher | |
| 256 // completes fetching. | |
| 257 // | |
| 258 // The waiting requests are taken as weak pointers and they can be deleted. | |
| 259 // The waiting requests will be called back with fetching results if they are | |
| 260 // not deleted | |
| 261 // - when the Fetcher completes fetching, if the Fetcher is not destructed | |
| 262 // before it completes fetching, or | |
| 263 // - when the Fetcher is destructed if the Fetcher is destructed before it | |
| 264 // completes fetching (in this case, the waiting requests will be called | |
| 265 // back with error). | |
| 266 class Fetcher : public OAuth2AccessTokenConsumer { | |
| 267 public: | |
| 268 // Creates a Fetcher and starts fetching an OAuth2 access token for | |
| 269 // |refresh_token| and |scopes| in the request context obtained by |getter|. | |
| 270 // The given |oauth2_token_service| will be informed when fetching is done. | |
| 271 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, | |
| 272 net::URLRequestContextGetter* getter, | |
| 273 const std::string& request_origin, | |
| 274 const std::string& client_id, | |
| 275 const std::string& client_secret, | |
| 276 const std::string& refresh_token, | |
| 277 const ScopeSet& scopes, | |
| 278 base::WeakPtr<RequestImpl> waiting_request); | |
| 279 virtual ~Fetcher(); | |
| 280 | |
| 281 // Add a request that is waiting for the result of this Fetcher. | |
| 282 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); | |
| 283 | |
| 284 // Returns count of waiting requests. | |
| 285 size_t GetWaitingRequestCount() const; | |
| 286 | |
| 287 void Cancel(); | |
| 288 | |
| 289 const ScopeSet& GetScopeSet() const; | |
| 290 const std::string& GetRefreshToken() const; | |
| 291 const std::string& GetClientId() const; | |
| 292 const std::string& GetRequestOrigin() const; | |
| 293 | |
| 294 // The error result from this fetcher. | |
| 295 const GoogleServiceAuthError& error() const { return error_; } | |
| 296 | |
| 297 protected: | |
| 298 // OAuth2AccessTokenConsumer | |
| 299 virtual void OnGetTokenSuccess(const std::string& access_token, | |
| 300 const base::Time& expiration_date) OVERRIDE; | |
| 301 virtual void OnGetTokenFailure( | |
| 302 const GoogleServiceAuthError& error) OVERRIDE; | |
| 303 | |
| 304 private: | |
| 305 Fetcher(OAuth2TokenService* oauth2_token_service, | |
| 306 net::URLRequestContextGetter* getter, | |
| 307 const std::string& request_origin, | |
| 308 const std::string& client_id, | |
| 309 const std::string& client_secret, | |
| 310 const std::string& refresh_token, | |
| 311 const OAuth2TokenService::ScopeSet& scopes, | |
| 312 base::WeakPtr<RequestImpl> waiting_request); | |
| 313 void Start(); | |
| 314 void InformWaitingRequests(); | |
| 315 void InformWaitingRequestsAndDelete(); | |
| 316 static bool ShouldRetry(const GoogleServiceAuthError& error); | |
| 317 int64 ComputeExponentialBackOffMilliseconds(int retry_num); | |
| 318 | |
| 319 // |oauth2_token_service_| remains valid for the life of this Fetcher, since | |
| 320 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is | |
| 321 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess | |
| 322 // (whichever comes first). | |
| 323 OAuth2TokenService* const oauth2_token_service_; | |
| 324 scoped_refptr<net::URLRequestContextGetter> getter_; | |
| 325 const std::string refresh_token_; | |
| 326 const ScopeSet scopes_; | |
| 327 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; | |
| 328 | |
| 329 int retry_number_; | |
| 330 base::OneShotTimer<Fetcher> retry_timer_; | |
| 331 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; | |
| 332 | |
| 333 // Variables that store fetch results. | |
| 334 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle | |
| 335 // destruction. | |
| 336 GoogleServiceAuthError error_; | |
| 337 std::string access_token_; | |
| 338 base::Time expiration_date_; | |
| 339 | |
| 340 // Token fetch request origin identifier. | |
| 341 std::string request_origin_; | |
| 342 | |
| 343 // OAuth2 client id and secret. | |
| 344 std::string client_id_; | |
| 345 std::string client_secret_; | |
| 346 | |
| 347 DISALLOW_COPY_AND_ASSIGN(Fetcher); | |
| 348 }; | |
| 349 | |
| 350 friend class Fetcher; | |
| 351 | |
| 352 // The parameters used to fetch an OAuth2 access token. | |
| 353 struct FetchParameters { | |
| 354 FetchParameters(const std::string& request_origin, | |
| 355 const std::string& client_id, | |
| 356 const std::string& refresh_token, | |
| 357 const ScopeSet& scopes); | |
| 358 bool operator<(const FetchParameters& params) const; | |
| 359 | |
| 360 // Request origin identifier. It's empty for internal chrome services | |
| 361 // requests but the requests originating from webapps should be identified | |
| 362 // by their originating extension_id. | |
| 363 std::string request_origin; | |
| 364 // OAuth2 client id. | |
| 365 std::string client_id; | |
| 366 // Refresh token used for minting access tokens within this request. | |
| 367 std::string refresh_token; | |
| 368 // URL scopes for the requested access token. | |
| 369 ScopeSet scopes; | |
| 370 }; | |
| 371 | |
| 372 typedef std::map<FetchParameters, Fetcher*> PendingFetcherMap; | |
| 373 | |
| 374 const PendingFetcherMap& GetPendingFetchersForTesting() const { | |
| 375 return pending_fetchers_; | |
| 376 } | |
| 377 | |
| 214 // Derived classes must provide a request context used for fetching access | 378 // Derived classes must provide a request context used for fetching access |
| 215 // tokens with the |StartRequest| method. | 379 // tokens with the |StartRequest| method. |
| 216 virtual net::URLRequestContextGetter* GetRequestContext() = 0; | 380 virtual net::URLRequestContextGetter* GetRequestContext() = 0; |
| 217 | 381 |
| 218 // Class that fetches an OAuth2 access token for a given set of scopes and | |
| 219 // OAuth2 refresh token. | |
| 220 class Fetcher; | |
| 221 friend class Fetcher; | |
| 222 | |
| 223 // Struct that contains the information of an OAuth2 access token. | 382 // Struct that contains the information of an OAuth2 access token. |
| 224 struct CacheEntry { | 383 struct CacheEntry { |
| 225 std::string access_token; | 384 std::string access_token; |
| 226 base::Time expiration_date; | 385 base::Time expiration_date; |
| 227 }; | 386 }; |
| 228 | 387 |
| 229 // This method does the same as |StartRequestWithContext| except it | 388 // This method does the same as |StartRequestWithContext| except it |
| 230 // uses |client_id| and |client_secret| to identify OAuth | 389 // uses |client_id| and |client_secret| to identify OAuth |
| 231 // client app instead of using Chrome's default values. | 390 // client app instead of using Chrome's default values. |
| 232 scoped_ptr<Request> StartRequestForClientWithContext( | 391 scoped_ptr<Request> StartRequestForClientWithContext( |
| 233 net::URLRequestContextGetter* getter, | 392 net::URLRequestContextGetter* getter, |
| 393 const std::string& request_origin, | |
| 234 const std::string& client_id, | 394 const std::string& client_id, |
| 235 const std::string& client_secret, | 395 const std::string& client_secret, |
| 236 const ScopeSet& scopes, | 396 const ScopeSet& scopes, |
| 237 Consumer* consumer); | 397 Consumer* consumer); |
| 238 | 398 |
| 239 // Returns a currently valid OAuth2 access token for the given set of scopes, | 399 // Returns a currently valid OAuth2 access token for the given set of scopes, |
| 240 // or NULL if none have been cached. Note the user of this method should | 400 // or NULL if none have been cached. Note the user of this method should |
| 241 // ensure no entry with the same |scopes| is added before the usage of the | 401 // ensure no entry with the same |client_scopes| is added before the usage of |
| 242 // returned entry is done. | 402 // the returned entry is done. |
| 243 const CacheEntry* GetCacheEntry(const ScopeSet& scopes); | 403 const CacheEntry* GetCacheEntry(const ClientScopeSet& client_scopes); |
| 244 | 404 |
| 245 | 405 |
| 246 // Removes an access token for the given set of scopes from the cache. | 406 // Removes an access token for the given set of scopes from the cache. |
| 247 // Returns true if the entry was removed, otherwise false. | 407 // Returns true if the entry was removed, otherwise false. |
| 248 bool RemoveCacheEntry(const OAuth2TokenService::ScopeSet& scopes, | 408 bool RemoveCacheEntry(const ClientScopeSet& client_scopes, |
| 249 const std::string& token_to_remove); | 409 const std::string& token_to_remove); |
| 250 | 410 |
| 251 | 411 |
| 252 // Called when |fetcher| finishes fetching. | 412 // Called when |fetcher| finishes fetching. |
| 253 void OnFetchComplete(Fetcher* fetcher); | 413 void OnFetchComplete(Fetcher* fetcher); |
| 254 | 414 |
| 255 // Called when a number of fetchers need to be canceled. | 415 // Called when a number of fetchers need to be canceled. |
| 256 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); | 416 void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); |
| 257 | 417 |
| 258 // The cache of currently valid tokens. | 418 // The cache of currently valid tokens. |
| 259 typedef std::map<ScopeSet, CacheEntry> TokenCache; | 419 typedef std::map<ClientScopeSet, CacheEntry> TokenCache; |
| 260 TokenCache token_cache_; | 420 TokenCache token_cache_; |
| 261 | 421 |
| 262 // The parameters (refresh token and scope set) used to fetch an OAuth2 access | |
| 263 // token. | |
| 264 typedef std::pair<std::string, ScopeSet> FetchParameters; | |
| 265 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access | 422 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access |
| 266 // token using these parameters. | 423 // token using these parameters. |
| 267 std::map<FetchParameters, Fetcher*> pending_fetchers_; | 424 PendingFetcherMap pending_fetchers_; |
| 268 | 425 |
| 269 // List of observers to notify when token availiability changes. | 426 // List of observers to notify when token availiability changes. |
| 270 // Makes sure list is empty on destruction. | 427 // Makes sure list is empty on destruction. |
| 271 ObserverList<Observer, true> observer_list_; | 428 ObserverList<Observer, true> observer_list_; |
| 272 | 429 |
| 273 // Maximum number of retries in fetching an OAuth2 access token. | 430 // Maximum number of retries in fetching an OAuth2 access token. |
| 274 static int max_fetch_retry_num_; | 431 static int max_fetch_retry_num_; |
| 275 | 432 |
| 433 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, ClientScopeSetOrderTest); | |
| 434 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, FetchParametersOrderTest); | |
| 435 FRIEND_TEST_ALL_PREFIXES(OAuth2TokenServiceTest, | |
| 436 SameScopesRequestedForDifferentClients); | |
| 437 | |
| 276 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); | 438 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService); |
| 277 }; | 439 }; |
| 278 | 440 |
| 279 #endif // CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_ | 441 #endif // CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_ |
| OLD | NEW |