1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ash/components/boca/invalidations/invalidation_service_impl.h"
#include "base/time/time.h"
#include "chromeos/ash/components/boca/boca_metrics_util.h"
#include "chromeos/ash/components/boca/boca_session_manager.h"
#include "chromeos/ash/components/boca/session_api/session_client_impl.h"
#include "chromeos/ash/components/boca/session_api/upload_token_request.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/gcm_driver/instance_id/instance_id_driver.h"
namespace ash::boca {
const net::BackoffEntry::Policy kBackoffPolicy = {
0, // Number of initial errors to ignore before applying
// exponential back-off rules.
base::Seconds(2).InMilliseconds(), // Initial delay in ms.
2, // Factor by which the waiting time will be multiplied.
0.2, // Fuzzing percentage.
base::Hours(1)
.InMilliseconds(), // Maximum amount of time to delay th request in ms.
-1, // Never discard the entry.
false // Do not always use initial delay.
};
InvalidationServiceImpl::InvalidationServiceImpl(
gcm::GCMDriver* gcm_driver,
instance_id::InstanceIDDriver* instance_id_driver,
AccountId account_id,
BocaSessionManager* boca_session_manager,
SessionClientImpl* session_client_impl,
std::string base_url)
: school_tools_base_url_(std::move(base_url)),
upload_retry_backoff_{&kBackoffPolicy},
account_id_(account_id),
boca_session_manager_(boca_session_manager),
session_client_impl_(session_client_impl) {
fcm_handler_ = std::make_unique<FCMHandler>(gcm_driver, instance_id_driver,
kSenderId, kApplicationId);
// Add token refresh observer.
fcm_handler_->AddTokenObserver(this);
// Add invalidation message observer.
fcm_handler_->AddListener(this);
// Register app handler and start token fetch.
fcm_handler_->StartListening();
}
InvalidationServiceImpl::~InvalidationServiceImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
fcm_handler_->RemoveTokenObserver(this);
fcm_handler_->RemoveListener(this);
}
void InvalidationServiceImpl::OnInvalidationReceived(
const std::string& payload) {
// TODO(b/354769102): Potentially validate FCM payload before dispatching. And
// implement a thread-safe approach to skip loading when there is already
// active loading in progress.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// FCM message will be delivered even user not logged in. But
// LoadCurrentSession has a validation to skip load if the current active user
// doesn't match the profile user.
boca_session_manager_->LoadCurrentSession(/*from_polling=*/false);
}
void InvalidationServiceImpl::OnFCMRegistrationTokenChanged() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!fcm_handler_->GetFCMRegistrationToken().has_value()) {
return;
} else {
upload_retry_backoff_.Reset();
UploadToken();
}
}
void InvalidationServiceImpl::UploadToken() {
auto request = std::make_unique<UploadTokenRequest>(
session_client_impl_->sender(), school_tools_base_url_,
account_id_.GetGaiaId(), fcm_handler_->GetFCMRegistrationToken().value(),
base::BindOnce(&InvalidationServiceImpl::OnTokenUploaded,
weak_factory_.GetWeakPtr()));
session_client_impl_->UploadToken(std::move(request));
}
void InvalidationServiceImpl::OnTokenUploaded(
base::expected<bool, google_apis::ApiErrorCode> result) {
if (!result.has_value()) {
boca::RecordUploadTokenErrorCode(result.error());
LOG(WARNING) << "[Boca]Failed to upload token, retrying";
upload_retry_backoff_.InformOfRequest(/*succeeded=*/false);
base::TimeDelta backoff_delay = upload_retry_backoff_.GetTimeUntilRelease();
token_refresh_timer_.Start(
FROM_HERE, backoff_delay,
base::BindOnce(&InvalidationServiceImpl::UploadToken,
base::Unretained(this)));
return;
}
LOG(WARNING) << "[Boca]Uploaded invalidation token.";
upload_retry_backoff_.Reset();
}
void InvalidationServiceImpl::ShutDown() {
if (fcm_handler_->IsListening()) {
fcm_handler_->StopListeningPermanently();
}
}
} // namespace ash::boca
|