blob: db8509c1eab0d9881daa931d667984d6a7fc3858 [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.
#ifndef CHROME_BROWSER_SUPERVISED_USER_CHILD_ACCOUNTS_CHILD_ACCOUNT_SERVICE_H_
#define CHROME_BROWSER_SUPERVISED_USER_CHILD_ACCOUNTS_CHILD_ACCOUNT_SERVICE_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/callback_list.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/supervised_user/child_accounts/family_info_fetcher.h"
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "net/base/backoff_entry.h"
namespace user_prefs {
class PrefRegistrySyncable;
}
class Profile;
// This class handles detection of child accounts (on sign-in as well as on
// browser restart), and triggers the appropriate behavior (e.g. enable the
// supervised user experience, fetch information about the parent(s)).
class ChildAccountService : public KeyedService,
public FamilyInfoFetcher::Consumer,
public signin::IdentityManager::Observer,
public SupervisedUserService::Delegate {
public:
enum class AuthState { AUTHENTICATED, NOT_AUTHENTICATED, PENDING };
~ChildAccountService() override;
static bool IsChildAccountDetectionEnabled();
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
void Init();
// Responds whether at least one request for child status was successful.
// And we got answer whether the profile belongs to a child account or not.
bool IsChildAccountStatusKnown();
// KeyedService:
void Shutdown() override;
void AddChildStatusReceivedCallback(base::OnceClosure callback);
// Returns whether or not the user is authenticated on Google web properties
// based on the state of the cookie jar. Returns AuthState::PENDING if
// authentication state can't be determined at the moment.
AuthState GetGoogleAuthState();
// Subscribes to changes to the Google authentication state
// (see IsGoogleAuthenticated()). Can send a notification even if the
// authentication state has not changed.
base::CallbackListSubscription ObserveGoogleAuthState(
const base::RepeatingCallback<void()>& callback);
private:
friend class ChildAccountServiceFactory;
// Use |ChildAccountServiceFactory::GetForProfile(...)| to get an instance of
// this service.
explicit ChildAccountService(Profile* profile);
// SupervisedUserService::Delegate implementation.
bool SetActive(bool active) override;
// Sets whether the signed-in account is a child account.
void SetIsChildAccount(bool is_child_account);
// signin::IdentityManager::Observer implementation.
void OnPrimaryAccountChanged(
const signin::PrimaryAccountChangeEvent& event_details) override;
void OnExtendedAccountInfoUpdated(const AccountInfo& info) override;
void OnExtendedAccountInfoRemoved(const AccountInfo& info) override;
// FamilyInfoFetcher::Consumer implementation.
void OnGetFamilyMembersSuccess(
const std::vector<FamilyInfoFetcher::FamilyMember>& members) override;
void OnFailure(FamilyInfoFetcher::ErrorCode error) override;
// IdentityManager::Observer implementation.
void OnAccountsInCookieUpdated(
const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override;
void StartFetchingFamilyInfo();
void CancelFetchingFamilyInfo();
void ScheduleNextFamilyInfoUpdate(base::TimeDelta delay);
void PropagateChildStatusToUser(bool is_child);
void SetFirstCustodianPrefs(const FamilyInfoFetcher::FamilyMember& custodian);
void SetSecondCustodianPrefs(
const FamilyInfoFetcher::FamilyMember& custodian);
void ClearFirstCustodianPrefs();
void ClearSecondCustodianPrefs();
// Owns us via the KeyedService mechanism.
Profile* profile_;
bool active_;
std::unique_ptr<FamilyInfoFetcher> family_fetcher_;
// If fetching the family info fails, retry with exponential backoff.
base::OneShotTimer family_fetch_timer_;
net::BackoffEntry family_fetch_backoff_;
signin::IdentityManager* identity_manager_;
base::RepeatingClosureList google_auth_state_observers_;
// Callbacks to run when the user status becomes known.
std::vector<base::OnceClosure> status_received_callback_list_;
base::WeakPtrFactory<ChildAccountService> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ChildAccountService);
};
#endif // CHROME_BROWSER_SUPERVISED_USER_CHILD_ACCOUNTS_CHILD_ACCOUNT_SERVICE_H_