forked from Pissandshittium/pissandshittium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ambient: Add access token controller
This patch adds an access token controller for ambient mode. It will refresh the token when entering lock screen. The following requests to backdrop server will reuse the cached token before it expires. Bug: b/148463064 Test: new unittests Change-Id: Icf882b2d0938e29e06900b4bbffea8cdc5ba1af2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2149948 Commit-Queue: Tao Wu <wutao@chromium.org> Reviewed-by: Xiyuan Xia <xiyuan@chromium.org> Reviewed-by: Xiaohui Chen <xiaohuic@chromium.org> Cr-Commit-Position: refs/heads/master@{#763547}
- Loading branch information
wutao
authored and
Commit Bot
committed
Apr 28, 2020
1 parent
e260e9e
commit 942fe1f
Showing
15 changed files
with
382 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright 2020 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "ash/ambient/ambient_access_token_controller.h" | ||
|
||
#include <algorithm> | ||
#include <utility> | ||
|
||
#include "ash/public/cpp/ambient/ambient_client.h" | ||
#include "base/rand_util.h" | ||
#include "base/time/time.h" | ||
|
||
namespace ash { | ||
|
||
namespace { | ||
|
||
constexpr base::TimeDelta kMinTokenRefreshDelay = | ||
base::TimeDelta::FromMilliseconds(1000); | ||
constexpr base::TimeDelta kMaxTokenRefreshDelay = | ||
base::TimeDelta::FromMilliseconds(60 * 1000); | ||
|
||
// The buffer time to use the access token. | ||
constexpr base::TimeDelta kTokenExpirationTimeBuffer = | ||
base::TimeDelta::FromMinutes(10); | ||
|
||
} // namespace | ||
|
||
AmbientAccessTokenController::AmbientAccessTokenController() = default; | ||
|
||
AmbientAccessTokenController::~AmbientAccessTokenController() = default; | ||
|
||
void AmbientAccessTokenController::RequestAccessToken( | ||
AccessTokenCallback callback) { | ||
// |token_refresh_timer_| may become stale during sleeping. | ||
if (token_refresh_timer_.IsRunning()) | ||
token_refresh_timer_.AbandonAndStop(); | ||
|
||
if (!access_token_.empty()) { | ||
DCHECK(!has_pending_request_); | ||
|
||
// Return the token if there is enough time to use the access token when | ||
// requested. | ||
if (expiration_time_ - base::Time::Now() > kTokenExpirationTimeBuffer) { | ||
RunCallback(std::move(callback)); | ||
return; | ||
} | ||
|
||
access_token_ = std::string(); | ||
expiration_time_ = base::Time::Now(); | ||
} | ||
|
||
callbacks_.emplace_back(std::move(callback)); | ||
|
||
if (has_pending_request_) | ||
return; | ||
|
||
RefreshAccessToken(); | ||
} | ||
|
||
void AmbientAccessTokenController::RefreshAccessToken() { | ||
DCHECK(!token_refresh_timer_.IsRunning()); | ||
|
||
has_pending_request_ = true; | ||
AmbientClient::Get()->RequestAccessToken( | ||
base::BindOnce(&AmbientAccessTokenController::AccessTokenRefreshed, | ||
weak_factory_.GetWeakPtr())); | ||
} | ||
|
||
void AmbientAccessTokenController::AccessTokenRefreshed( | ||
const std::string& gaia_id, | ||
const std::string& access_token, | ||
const base::Time& expiration_time) { | ||
has_pending_request_ = false; | ||
|
||
if (gaia_id.empty() || access_token.empty()) { | ||
RetryRefreshAccessToken(); | ||
return; | ||
} | ||
|
||
VLOG(1) << "Access token fetched."; | ||
gaia_id_ = gaia_id; | ||
access_token_ = access_token; | ||
expiration_time_ = expiration_time; | ||
NotifyAccessTokenRefreshed(); | ||
} | ||
|
||
void AmbientAccessTokenController::RetryRefreshAccessToken() { | ||
base::TimeDelta backoff_delay = | ||
std::min(kMinTokenRefreshDelay * | ||
(1 << (token_refresh_error_backoff_factor - 1)), | ||
kMaxTokenRefreshDelay) + | ||
base::RandDouble() * kMinTokenRefreshDelay; | ||
|
||
if (backoff_delay < kMaxTokenRefreshDelay) | ||
++token_refresh_error_backoff_factor; | ||
|
||
token_refresh_timer_.Start( | ||
FROM_HERE, backoff_delay, | ||
base::BindOnce(&AmbientAccessTokenController::RefreshAccessToken, | ||
base::Unretained(this))); | ||
} | ||
|
||
void AmbientAccessTokenController::NotifyAccessTokenRefreshed() { | ||
for (auto& callback : callbacks_) | ||
RunCallback(std::move(callback)); | ||
|
||
callbacks_.clear(); | ||
} | ||
|
||
void AmbientAccessTokenController::RunCallback(AccessTokenCallback callback) { | ||
DCHECK(!gaia_id_.empty()); | ||
DCHECK(!access_token_.empty()); | ||
std::move(callback).Run(gaia_id_, access_token_); | ||
} | ||
|
||
} // namespace ash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2020 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef ASH_AMBIENT_AMBIENT_ACCESS_TOKEN_CONTROLLER_H_ | ||
#define ASH_AMBIENT_AMBIENT_ACCESS_TOKEN_CONTROLLER_H_ | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "ash/ash_export.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "base/time/time.h" | ||
#include "base/timer/timer.h" | ||
|
||
namespace ash { | ||
|
||
// A class to manage the access token for ambient mode. Request will be async | ||
// and will be returned as soon as the token is refreshed. If the token has | ||
// already been refreshed, request call will be returned immediately. | ||
class ASH_EXPORT AmbientAccessTokenController { | ||
public: | ||
using AccessTokenCallback = | ||
base::OnceCallback<void(const std::string& gaia_id, | ||
const std::string& access_token)>; | ||
|
||
AmbientAccessTokenController(); | ||
AmbientAccessTokenController(const AmbientAccessTokenController&) = delete; | ||
AmbientAccessTokenController& operator=(const AmbientAccessTokenController&) = | ||
delete; | ||
~AmbientAccessTokenController(); | ||
|
||
void RequestAccessToken(AccessTokenCallback callback); | ||
|
||
private: | ||
friend class AmbientAshTestBase; | ||
|
||
void RefreshAccessToken(); | ||
void AccessTokenRefreshed(const std::string& gaia_id, | ||
const std::string& access_token, | ||
const base::Time& expiration_time); | ||
void RetryRefreshAccessToken(); | ||
void NotifyAccessTokenRefreshed(); | ||
void RunCallback(AccessTokenCallback callback); | ||
|
||
std::string gaia_id_; | ||
std::string access_token_; | ||
|
||
// The expiration time of the |access_token_|. | ||
base::Time expiration_time_; | ||
|
||
// True if has already sent access token request and waiting for result. | ||
bool has_pending_request_ = false; | ||
|
||
base::OneShotTimer token_refresh_timer_; | ||
int token_refresh_error_backoff_factor = 1; | ||
|
||
std::vector<AccessTokenCallback> callbacks_; | ||
|
||
base::WeakPtrFactory<AmbientAccessTokenController> weak_factory_{this}; | ||
}; | ||
|
||
} // namespace ash | ||
|
||
#endif // ASH_AMBIENT_AMBIENT_ACCESS_TOKEN_CONTROLLER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.