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