blob: 8c1469759e7f71a4f35edc00c9c9fb1cfdbec9f3 [file] [log] [blame]
// Copyright 2016 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_CHROMEOS_ARC_ARC_SESSION_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_ARC_ARC_SESSION_MANAGER_H_
#include <memory>
#include <ostream>
#include <string>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/arc/arc_support_host.h"
#include "chrome/browser/chromeos/policy/android_management_client.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync_preferences/pref_service_syncable_observer.h"
#include "components/sync_preferences/synced_pref_observer.h"
#include "mojo/public/cpp/bindings/binding.h"
class ArcAppLauncher;
class Profile;
namespace ash {
class ShelfDelegate;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace arc {
class ArcAndroidManagementChecker;
class ArcAuthCodeFetcher;
class ArcAuthContext;
class ArcTermsOfServiceNegotiator;
enum class ProvisioningResult : int;
// This class proxies the request from the client to fetch an auth code from
// LSO. It lives on the UI thread.
class ArcSessionManager : public ArcService,
public ArcBridgeService::Observer,
public ArcSupportHost::Observer,
public sync_preferences::PrefServiceSyncableObserver,
public sync_preferences::SyncedPrefObserver {
public:
// Represents each State of ARC session.
// NOT_INITIALIZED: represents the state that the Profile is not yet ready
// so that this service is not yet initialized, or Chrome is being shut
// down so that this is destroyed.
// STOPPED: ARC session is not running, or being terminated.
// SHOWING_TERMS_OF_SERVICE: "Terms Of Service" page is shown on ARC support
// Chrome app.
// CHECKING_ANDROID_MANAGEMENT: Checking Android management status. Note that
// the status is checked for each ARC session starting, but this is the
// state only for the first boot case (= opt-in case). The second time and
// later the management check is running in parallel with ARC session
// starting, and in such a case, State is ACTIVE, instead.
// FETCHING_CODE: Fetching an auth token. Similar to
// CHECKING_ANDROID_MANAGEMENT case, this is only for the first boot case.
// In re-auth flow (fetching an auth token while ARC is running), the
// State should be ACTIVE.
// TODO(hidehiko): Migrate into re-auth flow, then remove this state.
// ACTIVE: ARC is running.
//
// State transition should be as follows:
//
// NOT_INITIALIZED -> STOPPED: when the primary Profile gets ready.
// ...(any)... -> NOT_INITIALIZED: when the Chrome is being shutdown.
// ...(any)... -> STOPPED: on error.
//
// In the first boot case (no OOBE case):
// STOPPED -> SHOWING_TERMS_OF_SERVICE: when arc.enabled preference is set.
// SHOWING_TERMS_OF_SERVICE -> CHECKING_ANDROID_MANAGEMENT: when a user
// agree with "Terms Of Service"
// CHECKING_ANDROID_MANAGEMENT -> FETCHING_CODE: when Android management
// check passes.
// FETCHING_CODE -> ACTIVE: when the auth token is successfully fetched.
//
// In the first boot case (OOBE case):
// STOPPED -> FETCHING_CODE: When arc.enabled preference is set.
// FETCHING_CODE -> ACTIVE: when the auth token is successfully fetched.
//
// In the second (or later) boot case:
// STOPPED -> ACTIVE: when arc.enabled preference is checked that it is
// true. Practically, this is when the primary Profile gets ready.
enum class State {
NOT_INITIALIZED,
STOPPED,
SHOWING_TERMS_OF_SERVICE,
CHECKING_ANDROID_MANAGEMENT,
ACTIVE,
};
class Observer {
public:
virtual ~Observer() = default;
// Called to notify that ARC bridge is shut down.
virtual void OnShutdownBridge() {}
// Called to notify that ARC enabled state has been updated.
virtual void OnOptInEnabled(bool enabled) {}
// Called to notify that ARC has been initialized successfully.
virtual void OnInitialStart() {}
};
explicit ArcSessionManager(ArcBridgeService* bridge_service);
~ArcSessionManager() override;
static ArcSessionManager* Get();
// It is called from chrome/browser/prefs/browser_prefs.cc.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
static void DisableUIForTesting();
static void SetShelfDelegateForTesting(ash::ShelfDelegate* shelf_delegate);
// Checks if OptIn verification was disabled by switch in command line.
static bool IsOptInVerificationDisabled();
static void EnableCheckAndroidManagementForTesting();
// Returns true if Arc is allowed to run for the given profile.
static bool IsAllowedForProfile(const Profile* profile);
// Returns true if ARC should run under Kiosk mode.
static bool IsArcKioskMode();
// Returns true if Arc is allowed to run for the current session.
bool IsAllowed() const;
void OnPrimaryUserProfilePrepared(Profile* profile);
void Shutdown();
Profile* profile() { return profile_; }
const Profile* profile() const { return profile_; }
State state() const { return state_; }
// Adds or removes observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// ArcBridgeService::Observer:
void OnBridgeStopped(ArcBridgeService::StopReason reason) override;
// Called from Arc support platform app when user cancels signing.
void CancelAuthCode();
bool IsArcManaged() const;
bool IsArcEnabled() const;
// This requires Arc to be allowed (|IsAllowed|)for current profile.
void EnableArc();
void DisableArc();
// Called from the Chrome OS metrics provider to record Arc.State
// periodically.
void RecordArcState();
// sync_preferences::PrefServiceSyncableObserver
void OnIsSyncingChanged() override;
// sync_preferences::SyncedPrefObserver
void OnSyncedPrefChanged(const std::string& path, bool from_sync) override;
// ArcSupportHost::Observer:
void OnWindowClosed() override;
void OnTermsAgreed(bool is_metrics_enabled,
bool is_backup_and_restore_enabled,
bool is_location_service_enabled) override;
void OnRetryClicked() override;
void OnSendFeedbackClicked() override;
// Stops ARC without changing ArcEnabled preference.
void StopArc();
// StopArc(), then EnableArc(). Between them data clear may happens.
// This is a special method to support enterprise device lost case.
// This can be called only when ARC is running.
void StopAndEnableArc();
// Removes the data if ARC is stopped. Otherwise, queue to remove the data
// on ARC is stopped.
void RemoveArcData();
ArcSupportHost* support_host() { return support_host_.get(); }
// TODO(hidehiko): Get rid of the getter by migration between ArcAuthContext
// and ArcAuthCodeFetcher.
ArcAuthContext* auth_context() { return context_.get(); }
void StartArc();
void OnProvisioningFinished(ProvisioningResult result);
private:
// Negotiates the terms of service to user.
void StartTermsOfServiceNegotiation();
void OnTermsOfServiceNegotiated(bool accepted);
void SetState(State state);
void ShutdownBridge();
void OnOptInPreferenceChanged();
void OnAndroidManagementPassed();
void OnArcDataRemoved(bool success);
void OnArcSignInTimeout();
void FetchAuthCode();
void PrepareContextForAuthCodeRequest();
void StartArcAndroidManagementCheck();
// Called when the Android management check is done in opt-in flow or
// re-auth flow.
void OnAndroidManagementChecked(
policy::AndroidManagementClient::Result result);
// Called when the background Android management check is done. It is
// triggered when the second or later ARC boot timing.
void OnBackgroundAndroidManagementChecked(
policy::AndroidManagementClient::Result result);
// Unowned pointer. Keeps current profile.
Profile* profile_ = nullptr;
// Registrar used to monitor ARC enabled state.
PrefChangeRegistrar pref_change_registrar_;
State state_ = State::NOT_INITIALIZED;
base::ObserverList<Observer> observer_list_;
std::unique_ptr<ArcAppLauncher> playstore_launcher_;
bool clear_required_ = false;
bool reenable_arc_ = false;
base::OneShotTimer arc_sign_in_timer_;
std::unique_ptr<ArcSupportHost> support_host_;
std::unique_ptr<ArcTermsOfServiceNegotiator> terms_of_service_negotiator_;
std::unique_ptr<ArcAuthContext> context_;
std::unique_ptr<ArcAndroidManagementChecker> android_management_checker_;
base::Time sign_in_time_;
base::WeakPtrFactory<ArcSessionManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ArcSessionManager);
};
// Outputs the stringified |state| to |os|. This is only for logging purposes.
std::ostream& operator<<(std::ostream& os,
const ArcSessionManager::State& state);
} // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_ARC_SESSION_MANAGER_H_