1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_ARC_SESSION_ARC_SESSION_MANAGER_H_ 6 #define CHROME_BROWSER_CHROMEOS_ARC_SESSION_ARC_SESSION_MANAGER_H_ 7 8 #include <memory> 9 #include <ostream> 10 #include <string> 11 #include <utility> 12 13 #include "base/macros.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/observer_list.h" 16 #include "base/optional.h" 17 #include "base/timer/timer.h" 18 #include "chrome/browser/chromeos/arc/arc_support_host.h" 19 #include "chrome/browser/chromeos/arc/session/adb_sideloading_availability_delegate_impl.h" 20 #include "chrome/browser/chromeos/arc/session/arc_app_id_provider_impl.h" 21 #include "chrome/browser/chromeos/arc/session/arc_session_manager_observer.h" 22 #include "chrome/browser/chromeos/policy/android_management_client.h" 23 #include "chromeos/dbus/concierge_client.h" 24 #include "chromeos/dbus/session_manager/session_manager_client.h" 25 #include "components/arc/mojom/auth.mojom.h" 26 #include "components/arc/session/arc_session_runner.h" 27 #include "components/arc/session/arc_stop_reason.h" 28 #include "third_party/abseil-cpp/absl/types/variant.h" 29 30 class ArcAppLauncher; 31 class PrefService; 32 class Profile; 33 34 namespace arc { 35 36 constexpr const char kGeneratedPropertyFilesPath[] = "/run/arc/host_generated"; 37 constexpr const char kGeneratedPropertyFilesPathVm[] = 38 "/run/arcvm/host_generated"; 39 40 class ArcAndroidManagementChecker; 41 class ArcDataRemover; 42 class ArcFastAppReinstallStarter; 43 class ArcPaiStarter; 44 class ArcTermsOfServiceNegotiator; 45 class ArcUiAvailabilityReporter; 46 47 enum class ProvisioningResult : int; 48 enum class ArcStopReason; 49 50 // This class is responsible for handing stages of ARC life-cycle. 51 class ArcSessionManager : public ArcSessionRunner::Observer, 52 public ArcSupportHost::ErrorDelegate, 53 public chromeos::SessionManagerClient::Observer, 54 public chromeos::ConciergeClient::VmObserver { 55 public: 56 // Represents each State of ARC session. 57 // NOT_INITIALIZED: represents the state that the Profile is not yet ready 58 // so that this service is not yet initialized, or Chrome is being shut 59 // down so that this is destroyed. 60 // STOPPED: ARC session is not running, or being terminated. 61 // NEGOTIATING_TERMS_OF_SERVICE: Negotiating Google Play Store "Terms of 62 // Service" with a user. There are several ways for the negotiation, 63 // including opt-in flow, which shows "Terms of Service" page on ARC 64 // support app, and OOBE flow, which shows "Terms of Service" page as a 65 // part of Chrome OOBE flow. 66 // If user does not accept the Terms of Service, disables Google Play 67 // Store, which triggers RequestDisable() and the state will be set to 68 // STOPPED, then. 69 // CHECKING_ANDROID_MANAGEMENT: Checking Android management status. Note that 70 // the status is checked for each ARC session starting, but this is the 71 // state only for the first boot case (= opt-in case). The second time and 72 // later the management check is running in parallel with ARC session 73 // starting, and in such a case, State is ACTIVE, instead. 74 // REMOVING_DATA_DIR: When ARC is disabled, the data directory is removed. 75 // While removing is processed, ARC cannot be started. This is the state. 76 // ACTIVE: ARC is running. 77 // STOPPING: ARC is being shut down. 78 // 79 // State transition should be as follows: 80 // 81 // NOT_INITIALIZED -> STOPPED: when the primary Profile gets ready. 82 // ...(any)... -> NOT_INITIALIZED: when the Chrome is being shutdown. 83 // ...(any)... -> STOPPED: on error. 84 // 85 // In the first boot case: 86 // STOPPED -> NEGOTIATING_TERMS_OF_SERVICE: On request to enable. 87 // NEGOTIATING_TERMS_OF_SERVICE -> CHECKING_ANDROID_MANAGEMENT: when a user 88 // accepts "Terms Of Service" 89 // CHECKING_ANDROID_MANAGEMENT -> ACTIVE: when the auth token is 90 // successfully fetched. 91 // 92 // In the second (or later) boot case: 93 // STOPPED -> ACTIVE: when arc.enabled preference is checked that it is 94 // true. Practically, this is when the primary Profile gets ready. 95 // 96 // In the disabling case: 97 // NEGOTIATING_TERMS_OF_SERVICE -> STOPPED 98 // CHECKING_ANDROID_MANAGEMENT -> STOPPED 99 // ACTIVE -> STOPPING -> (maybe REMOVING_DATA_DIR ->) STOPPED 100 // STOPPING: Eventually change the state to STOPPED. Do nothing 101 // immediately. 102 // REMOVING_DATA_DIR: Eventually state will become STOPPED. Do nothing 103 // immediately. 104 // 105 // TODO(hidehiko): Fix the state machine, and update the comment including 106 // relationship with |enable_requested_|. 107 enum class State { 108 NOT_INITIALIZED, 109 STOPPED, 110 NEGOTIATING_TERMS_OF_SERVICE, 111 CHECKING_ANDROID_MANAGEMENT, 112 REMOVING_DATA_DIR, 113 ACTIVE, 114 STOPPING, 115 }; 116 117 using ExpansionResult = std::pair<std::string /* salt on disk */, 118 bool /* expansion successful */>; 119 120 ArcSessionManager(std::unique_ptr<ArcSessionRunner> arc_session_runner, 121 std::unique_ptr<AdbSideloadingAvailabilityDelegateImpl> 122 adb_sideloading_availability_delegate); 123 ~ArcSessionManager() override; 124 125 static ArcSessionManager* Get(); 126 127 static void SetUiEnabledForTesting(bool enabled); 128 static void SetArcTermsOfServiceOobeNegotiatorEnabledForTesting(bool enabled); 129 static void EnableCheckAndroidManagementForTesting(bool enable); 130 static std::string GenerateFakeSerialNumberForTesting( 131 const std::string& chromeos_user, 132 const std::string& salt); 133 static std::string GetOrCreateSerialNumberForTesting( 134 PrefService* local_state, 135 const std::string& chromeos_user, 136 const std::string& arc_salt_on_disk); 137 static bool ReadSaltOnDiskForTesting(const base::FilePath& salt_path, 138 std::string* out_salt); 139 140 // Returns true if ARC is allowed to run for the current session. 141 // TODO(hidehiko): The name is very close to IsArcAllowedForProfile(), but 142 // has different meaning. Clean this up. 143 bool IsAllowed() const; 144 145 // Start expanding the property files. Note that these property files are 146 // needed to start the mini instance. This function also tries to read 147 // /var/lib/misc/arc_salt when ARCVM is enabled. 148 void ExpandPropertyFilesAndReadSalt(); 149 150 // Initializes ArcSessionManager. Before this runs, Profile must be set 151 // via SetProfile(). 152 void Initialize(); 153 154 void Shutdown(); 155 156 // Sets the |profile|, and sets up Profile related fields in this instance. 157 // IsArcAllowedForProfile() must return true for the given |profile|. 158 void SetProfile(Profile* profile); profile()159 Profile* profile() { return profile_; } profile()160 const Profile* profile() const { return profile_; } 161 state()162 State state() const { return state_; } 163 164 // Adds or removes observers. 165 void AddObserver(ArcSessionManagerObserver* observer); 166 void RemoveObserver(ArcSessionManagerObserver* observer); 167 168 // Notifies observers that Google Play Store enabled preference is changed. 169 // Note: ArcPlayStoreEnabledPreferenceHandler has the main responsibility to 170 // notify the event. However, due to life time, it is difficult for non-ARC 171 // services to subscribe the handler instance directly. Instead, they can 172 // subscribe to ArcSessionManager, and ArcSessionManager proxies the event. 173 void NotifyArcPlayStoreEnabledChanged(bool enabled); 174 175 // Called from ARC support platform app when user cancels signing. 176 void CancelAuthCode(); 177 178 // Requests to enable ARC session. This starts ARC instance, or maybe starts 179 // Terms Of Service negotiation if they haven't been accepted yet. 180 // If it is already requested to enable, no-op. 181 // Currently, enabled/disabled is tied to whether Google Play Store is 182 // enabled or disabled. Please see also TODO of 183 // SetArcPlayStoreEnabledForProfile(). 184 void RequestEnable(); 185 186 // Requests to disable ARC session. This stops ARC instance, or quits Terms 187 // Of Service negotiation if it is the middle of the process (e.g. closing 188 // UI for manual negotiation if it is shown). This does not remove user ARC 189 // data. 190 // If it is already requested to disable, no-op. 191 void RequestDisable(); 192 193 // Requests to remove the ARC data. 194 // If ARC is stopped, triggers to remove the data. Otherwise, queues to 195 // remove the data after ARC stops. 196 // A log statement with the removal reason must be added prior to calling 197 // this. 198 void RequestArcDataRemoval(); 199 200 // ArcSupportHost:::ErrorDelegate: 201 void OnWindowClosed() override; 202 void OnRetryClicked() override; 203 void OnSendFeedbackClicked() override; 204 205 // StopArc(), then restart. Between them data clear may happens. 206 // This is a special method to support enterprise device lost case. 207 // This can be called only when ARC is running. 208 void StopAndEnableArc(); 209 support_host()210 ArcSupportHost* support_host() { return support_host_.get(); } 211 212 // On provisioning completion (regardless of whether successfully done or 213 // not), this is called with its status. On success, called with 214 // ProvisioningResult::SUCCESS, otherwise |result| is the error reason. 215 // |error| either contains the sign-in error that came from ARC or it may 216 // indicate that ARC stopped prematurely and provisioning could not finish 217 // successfully. 218 void OnProvisioningFinished( 219 ProvisioningResult result, 220 absl::variant<mojom::ArcSignInErrorPtr, ArcStopReason> error); 221 222 // A helper function that calls ArcSessionRunner's SetUserInfo. 223 void SetUserInfo(); 224 225 // Returns the time when the sign in process started, or a null time if 226 // signing in didn't happen during this session. sign_in_start_time()227 base::TimeTicks sign_in_start_time() const { return sign_in_start_time_; } 228 229 // Returns the time when ARC was about to start, or a null time if ARC has not 230 // been started yet. arc_start_time()231 base::TimeTicks arc_start_time() const { return arc_start_time_; } 232 233 // Returns true if ARC requested to start. enable_requested()234 bool enable_requested() const { return enable_requested_; } 235 236 // Returns PAI starter that is used to start Play Auto Install flow. It is 237 // available only on initial start. pai_starter()238 ArcPaiStarter* pai_starter() { return pai_starter_.get(); } 239 240 // Returns Fast App Reinstall starter that is used to start Play Fast App 241 // Reinstall flow. It is available only on initial start. fast_app_resintall_starter()242 ArcFastAppReinstallStarter* fast_app_resintall_starter() { 243 return fast_app_reinstall_starter_.get(); 244 } 245 246 // Returns true if the current ARC run has started with skipping user ToS 247 // negotiation, because the user had accepted already or policy does not 248 // require ToS acceptance. Returns false in other cases, including one when 249 // ARC is not currently running. is_directly_started()250 bool is_directly_started() const { return directly_started_; } set_directly_started_for_testing(bool directly_started)251 void set_directly_started_for_testing(bool directly_started) { 252 directly_started_ = directly_started; 253 } 254 255 // Injectors for testing. 256 void SetArcSessionRunnerForTesting( 257 std::unique_ptr<ArcSessionRunner> arc_session_runner); 258 ArcSessionRunner* GetArcSessionRunnerForTesting(); 259 void SetAttemptUserExitCallbackForTesting( 260 const base::RepeatingClosure& callback); 261 262 // Returns whether the Play Store app is requested to be launched by this 263 // class. Should be used only for tests. 264 bool IsPlaystoreLaunchRequestedForTesting() const; 265 266 // Invoking StartArc() only for testing, e.g., to emulate accepting Terms of 267 // Service then passing Android management check successfully. StartArcForTesting()268 void StartArcForTesting() { StartArc(); } 269 270 // Invokes OnTermsOfServiceNegotiated as if negotiation is done for testing. OnTermsOfServiceNegotiatedForTesting(bool accepted)271 void OnTermsOfServiceNegotiatedForTesting(bool accepted) { 272 OnTermsOfServiceNegotiated(accepted); 273 } 274 275 // Invokes OnExpandPropertyFilesAndReadSalt as if the expansion is done. OnExpandPropertyFilesAndReadSaltForTesting(bool result)276 void OnExpandPropertyFilesAndReadSaltForTesting(bool result) { 277 OnExpandPropertyFilesAndReadSalt(ExpansionResult{{}, result}); 278 } 279 reset_property_files_expansion_result()280 void reset_property_files_expansion_result() { 281 property_files_expansion_result_.reset(); 282 } 283 set_property_files_source_dir_for_testing(const base::FilePath & property_files_source_dir)284 void set_property_files_source_dir_for_testing( 285 const base::FilePath& property_files_source_dir) { 286 property_files_source_dir_ = property_files_source_dir; 287 } 288 set_property_files_dest_dir_for_testing(const base::FilePath & property_files_dest_dir)289 void set_property_files_dest_dir_for_testing( 290 const base::FilePath& property_files_dest_dir) { 291 property_files_dest_dir_ = property_files_dest_dir; 292 } 293 294 // chromeos::ConciergeClient::VmObserver overrides. 295 void OnVmStarted( 296 const vm_tools::concierge::VmStartedSignal& vm_signal) override; 297 void OnVmStopped( 298 const vm_tools::concierge::VmStoppedSignal& vm_signal) override; 299 300 // Getter for |vm_info_|. 301 // If ARCVM is not running, return base::nullopt. 302 const base::Optional<vm_tools::concierge::VmInfo>& GetVmInfo() const; 303 304 private: 305 // Reports statuses of OptIn flow to UMA. 306 class ScopedOptInFlowTracker; 307 308 // RequestEnable() has a check in order not to trigger starting procedure 309 // twice. This method can be called to bypass that check when restarting. 310 // Returns true if ARC is started directly. 311 bool RequestEnableImpl(); 312 313 // Negotiates the terms of service to user, if necessary. 314 // Otherwise, move to StartAndroidManagementCheck(). 315 void MaybeStartTermsOfServiceNegotiation(); 316 void OnTermsOfServiceNegotiated(bool accepted); 317 318 void ShutdownSession(); 319 void ResetArcState(); 320 void OnArcSignInTimeout(); 321 322 // Starts Android management check. This is for first boot case (= Opt-in 323 // or OOBE flow case). In secondary or later ARC enabling, the check should 324 // run in background. 325 void StartAndroidManagementCheck(); 326 327 // Called when the Android management check is done in opt-in flow or 328 // OOBE flow. 329 void OnAndroidManagementChecked( 330 policy::AndroidManagementClient::Result result); 331 332 // Starts Android management check in background (in parallel with starting 333 // ARC). This is for secondary or later ARC enabling. 334 // The reason running them in parallel is for performance. The secondary or 335 // later ARC enabling is typically on "logging into Chrome" for the user who 336 // already opted in to use Google Play Store. In such a case, network is 337 // typically not yet ready. Thus, if we block ARC boot, it delays several 338 // seconds, which is not very user friendly. 339 void StartBackgroundAndroidManagementCheck(); 340 341 // Called when the background Android management check is done. It is 342 // triggered when the second or later ARC boot timing. 343 void OnBackgroundAndroidManagementChecked( 344 policy::AndroidManagementClient::Result result); 345 346 // Requests to start ARC instance. Also, updates the internal state to 347 // ACTIVE. 348 void StartArc(); 349 350 // Requests to stop ARC instance. This resets two persistent flags: 351 // kArcSignedIn and kArcTermsAccepted, so that, in next enabling, 352 // it is started from Terms of Service negotiation. 353 // TODO(hidehiko): Introduce STOPPING state, and this function should 354 // transition to it. 355 void StopArc(); 356 357 // ArcSessionRunner::Observer: 358 void OnSessionStopped(ArcStopReason reason, bool restarting) override; 359 void OnSessionRestarting() override; 360 361 // Starts to remove ARC data, if it is requested via RequestArcDataRemoval(). 362 // On completion, OnArcDataRemoved() is called. 363 // If not requested, just skipping the data removal, and moves to 364 // MaybeReenableArc() directly. 365 void MaybeStartArcDataRemoval(); 366 void OnArcDataRemoved(base::Optional<bool> success); 367 368 // On ARC session stopped and/or data removal completion, this is called 369 // so that, if necessary, ARC session is restarted. 370 // TODO(hidehiko): This can be removed after the racy state machine 371 // is fixed. 372 void MaybeReenableArc(); 373 374 // Starts a timer to check if provisioning takes too long. 375 // The timer will not be set if this device was previously provisioned 376 // successfully. 377 void MaybeStartTimer(); 378 379 // Requests the support host (if it exists) to show the error, and notifies 380 // the observers. 381 void ShowArcSupportHostError(ArcSupportHost::Error error, 382 int error_code, 383 bool should_show_send_feedback); 384 385 // chromeos::SessionManagerClient::Observer: 386 void EmitLoginPromptVisibleCalled() override; 387 388 // Called when ExpandPropertyFilesAndReadSalt is done. 389 void OnExpandPropertyFilesAndReadSalt(ExpansionResult result); 390 391 std::unique_ptr<ArcSessionRunner> arc_session_runner_; 392 std::unique_ptr<AdbSideloadingAvailabilityDelegateImpl> 393 adb_sideloading_availability_delegate_; 394 395 // Unowned pointer. Keeps current profile. 396 Profile* profile_ = nullptr; 397 398 // Whether ArcSessionManager is requested to enable (starting to run ARC 399 // instance) or not. 400 bool enable_requested_ = false; 401 402 // Internal state machine. See also State enum class. 403 State state_ = State::NOT_INITIALIZED; 404 405 base::ObserverList<ArcSessionManagerObserver>::Unchecked observer_list_; 406 std::unique_ptr<ArcAppLauncher> playstore_launcher_; 407 bool reenable_arc_ = false; 408 bool provisioning_reported_ = false; 409 bool directly_started_ = false; 410 base::OneShotTimer arc_sign_in_timer_; 411 412 std::unique_ptr<ArcSupportHost> support_host_; 413 std::unique_ptr<ArcDataRemover> data_remover_; 414 415 std::unique_ptr<ArcTermsOfServiceNegotiator> terms_of_service_negotiator_; 416 417 std::unique_ptr<ArcAndroidManagementChecker> android_management_checker_; 418 419 std::unique_ptr<ScopedOptInFlowTracker> scoped_opt_in_tracker_; 420 std::unique_ptr<ArcPaiStarter> pai_starter_; 421 std::unique_ptr<ArcFastAppReinstallStarter> fast_app_reinstall_starter_; 422 std::unique_ptr<ArcUiAvailabilityReporter> arc_ui_availability_reporter_; 423 424 // The time when the sign in process started. 425 base::TimeTicks sign_in_start_time_; 426 // The time when ARC was about to start. 427 base::TimeTicks arc_start_time_; 428 base::RepeatingClosure attempt_user_exit_callback_; 429 430 ArcAppIdProviderImpl app_id_provider_; 431 432 // The content of /var/lib/misc/arc_salt. Empty if the file doesn't exist. 433 base::Optional<std::string> arc_salt_on_disk_; 434 435 base::Optional<bool> property_files_expansion_result_; 436 base::FilePath property_files_source_dir_; 437 base::FilePath property_files_dest_dir_; 438 439 base::Optional<vm_tools::concierge::VmInfo> vm_info_; 440 441 // Must be the last member. 442 base::WeakPtrFactory<ArcSessionManager> weak_ptr_factory_{this}; 443 444 DISALLOW_COPY_AND_ASSIGN(ArcSessionManager); 445 }; 446 447 // Outputs the stringified |state| to |os|. This is only for logging purposes. 448 std::ostream& operator<<(std::ostream& os, 449 const ArcSessionManager::State& state); 450 451 } // namespace arc 452 453 #endif // CHROME_BROWSER_CHROMEOS_ARC_SESSION_ARC_SESSION_MANAGER_H_ 454