blob: c3aad7fcaa990ff022c38262c105ede72b25c2cf [file] [log] [blame]
// Copyright 2014 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 "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/common/pref_names.h"
#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
#include "components/policy/core/common/policy_switches.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "net/base/network_change_notifier.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace em = enterprise_management;
namespace policy {
namespace {
#if defined(OS_ANDROID)
const em::DeviceRegisterRequest::Type kCloudPolicyRegistrationType =
em::DeviceRegisterRequest::ANDROID_BROWSER;
#else
#error "This file can be built only on OS_ANDROID."
#endif
} // namespace
UserPolicySigninService::UserPolicySigninService(
Profile* profile,
PrefService* local_state,
DeviceManagementService* device_management_service,
UserCloudPolicyManager* policy_manager,
SigninManager* signin_manager,
scoped_refptr<net::URLRequestContextGetter> system_request_context,
scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory,
ProfileOAuth2TokenService* token_service)
: UserPolicySigninServiceBase(profile,
local_state,
device_management_service,
policy_manager,
signin_manager,
system_request_context,
system_url_loader_factory),
oauth2_token_service_(token_service),
profile_prefs_(profile->GetPrefs()),
weak_factory_(this) {}
UserPolicySigninService::~UserPolicySigninService() {}
void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
CancelPendingRegistration();
UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
}
void UserPolicySigninService::RegisterForPolicyWithAccountId(
const std::string& username,
const std::string& account_id,
const PolicyRegistrationCallback& callback) {
// Create a new CloudPolicyClient for fetching the DMToken.
std::unique_ptr<CloudPolicyClient> policy_client =
CreateClientForRegistrationOnly(username);
if (!policy_client) {
callback.Run(std::string(), std::string());
return;
}
CancelPendingRegistration();
// Fire off the registration process. Callback keeps the CloudPolicyClient
// alive for the length of the registration process.
registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
policy_client.get(),
kCloudPolicyRegistrationType));
// Using a raw pointer to |this| is okay, because we own the
// |registration_helper_|.
auto registration_callback = base::Bind(
&UserPolicySigninService::CallPolicyRegistrationCallback,
base::Unretained(this), base::Passed(&policy_client), callback);
registration_helper_->StartRegistration(oauth2_token_service_, account_id,
registration_callback);
}
void UserPolicySigninService::CallPolicyRegistrationCallback(
std::unique_ptr<CloudPolicyClient> client,
PolicyRegistrationCallback callback) {
registration_helper_.reset();
callback.Run(client->dm_token(), client->client_id());
}
void UserPolicySigninService::Shutdown() {
CancelPendingRegistration();
UserPolicySigninServiceBase::Shutdown();
}
void UserPolicySigninService::OnInitializationCompleted(
CloudPolicyService* service) {
UserCloudPolicyManager* manager = policy_manager();
DCHECK_EQ(service, manager->core()->service());
DCHECK(service->IsInitializationComplete());
// The service is now initialized - if the client is not yet registered, then
// it means that there is no cached policy and so we need to initiate a new
// client registration.
if (manager->IsClientRegistered()) {
DVLOG(1) << "Client already registered - not fetching DMToken";
return;
}
net::NetworkChangeNotifier::ConnectionType connection_type =
net::NetworkChangeNotifier::GetConnectionType();
base::TimeDelta retry_delay = base::TimeDelta::FromDays(3);
if (connection_type == net::NetworkChangeNotifier::CONNECTION_ETHERNET ||
connection_type == net::NetworkChangeNotifier::CONNECTION_WIFI) {
retry_delay = base::TimeDelta::FromDays(1);
}
base::Time last_check_time = base::Time::FromInternalValue(
profile_prefs_->GetInt64(prefs::kLastPolicyCheckTime));
base::Time now = base::Time::Now();
base::Time next_check_time = last_check_time + retry_delay;
// Check immediately if no check was ever done before (last_check_time == 0),
// or if the last check was in the future (?), or if we're already past the
// next check time. Otherwise, delay checking until the next check time.
base::TimeDelta try_registration_delay = base::TimeDelta::FromSeconds(5);
if (now > last_check_time && now < next_check_time)
try_registration_delay = next_check_time - now;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&UserPolicySigninService::RegisterCloudPolicyService,
weak_factory_.GetWeakPtr()),
try_registration_delay);
}
void UserPolicySigninService::RegisterCloudPolicyService() {
// If the user signed-out while this task was waiting then Shutdown() would
// have been called, which would have invalidated this task. Since we're here
// then the user must still be signed-in.
DCHECK(signin_manager()->IsAuthenticated());
DCHECK(!policy_manager()->IsClientRegistered());
DCHECK(policy_manager()->core()->client());
// Persist the current time as the last policy registration attempt time.
profile_prefs_->SetInt64(prefs::kLastPolicyCheckTime,
base::Time::Now().ToInternalValue());
registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
policy_manager()->core()->client(),
kCloudPolicyRegistrationType));
registration_helper_->StartRegistration(
oauth2_token_service_,
signin_manager()->GetAuthenticatedAccountId(),
base::Bind(&UserPolicySigninService::OnRegistrationDone,
base::Unretained(this)));
}
void UserPolicySigninService::CancelPendingRegistration() {
weak_factory_.InvalidateWeakPtrs();
registration_helper_.reset();
}
void UserPolicySigninService::OnRegistrationDone() {
registration_helper_.reset();
}
} // namespace policy