1 // Copyright 2020 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 COMPONENTS_ARC_ENTERPRISE_ARC_DATA_SNAPSHOTD_MANAGER_H_
6 #define COMPONENTS_ARC_ENTERPRISE_ARC_DATA_SNAPSHOTD_MANAGER_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/callback.h"
12 #include "base/memory/weak_ptr.h"
13 #include "components/session_manager/core/session_manager_observer.h"
14 
15 class PrefService;
16 
17 namespace base {
18 
19 class Value;
20 
21 }  // namespace base
22 
23 namespace arc {
24 namespace data_snapshotd {
25 
26 class ArcDataSnapshotdBridge;
27 
28 // This class manages ARC data/ directory snapshots and controls the lifetime of
29 // the arc-data-snapshotd daemon.
30 class ArcDataSnapshotdManager final
31     : public session_manager::SessionManagerObserver {
32  public:
33   // State of the flow.
34   enum class State {
35     kNone,
36     // Blocked UI mode is ON.
37     kBlockedUi,
38     // In blocked UI mode, MGS can be launched.
39     kMgsToLaunch,
40     // MGS is launched to create a snapshot.
41     kMgsLaunched,
42     // User session was restored.
43     kRestored,
44   };
45 
46   // This class operates with a snapshot related info either last or
47   // backed-up (previous): stores and keeps in sync with an appropriate
48   // preference in local state.
49   class SnapshotInfo {
50    public:
51     SnapshotInfo(const base::Value* value, bool last);
52     SnapshotInfo(const SnapshotInfo&) = delete;
53     SnapshotInfo& operator=(const SnapshotInfo&) = delete;
54     ~SnapshotInfo();
55 
56     // Creates from the passed arguments instead of constructing it from
57     // dictionary.
58     static std::unique_ptr<SnapshotInfo> CreateForTesting(
59         const std::string& os_version,
60         const std::string& creation_date,
61         bool verified,
62         bool updated,
63         bool last);
64 
65     // Syncs stored snapshot info to dictionaty |value|.
66     void Sync(base::Value* value);
67 
68     // Returns true if snapshot is expired.
69     bool IsExpired() const;
70 
71     // Returns true if OS version is updated, since the snapshot has been taken.
72     bool IsOsVersionUpdated() const;
73 
is_last()74     bool is_last() const { return is_last_; }
75 
76    private:
77     SnapshotInfo(const std::string& os_version,
78                  const std::string& creation_date,
79                  bool verified,
80                  bool updated,
81                  bool last);
82 
83     // Returns dictionary path in arc.snapshot local state preference.
84     std::string GetDictPath() const;
85 
86     bool is_last_;
87 
88     // Values should be kept in sync with values stored in arc.snapshot.last or
89     // arc.snapshot.previous preferences.
90     std::string os_version_;
91     std::string creation_date_;
92     bool verified_ = false;
93     bool updated_ = false;
94   };
95 
96   // This class operates with a snapshot related info including mode and
97   // creation flow time: stores and keeps in sync with arc.snapshot preference
98   // in local state.
99   class Snapshot {
100    public:
101     // Snapshot does not own |local_state|, it must be non nullptr and must
102     // outlive the instance.
103     explicit Snapshot(PrefService* local_state);
104 
105     Snapshot(const Snapshot&) = delete;
106     Snapshot& operator=(const Snapshot&) = delete;
107     ~Snapshot();
108 
109     // Creates an instance from the passed arguments instead of reading it from
110     // |local_state|.
111     static std::unique_ptr<Snapshot> CreateForTesting(
112         PrefService* local_state,
113         bool blocked_ui_mode,
114         bool started,
115         std::unique_ptr<SnapshotInfo> last,
116         std::unique_ptr<SnapshotInfo> previous);
117 
118     // Parses the snapshot info from arc.snapshot preference.
119     void Parse();
120     // Syncs stored snapshot info to local state.
121     void Sync();
122     // Clears snapshot related info in arc.snapshot preference either last
123     // if |last| is true or previous otherwise.
124     void ClearSnapshot(bool last);
125 
126     // Moves last snapshot to previous and updates a |start_date| to the current
127     // date.
128     void StartNewSnapshot();
129 
set_blocked_ui_mode(bool blocked_ui_mode)130     void set_blocked_ui_mode(bool blocked_ui_mode) {
131       blocked_ui_mode_ = blocked_ui_mode;
132     }
is_blocked_ui_mode()133     bool is_blocked_ui_mode() const { return blocked_ui_mode_; }
started()134     bool started() const { return started_; }
last()135     SnapshotInfo* last() { return last_.get(); }
previous()136     SnapshotInfo* previous() { return previous_.get(); }
137 
138    private:
139     Snapshot(PrefService* local_state,
140              bool blocked_ui_mode,
141              bool started,
142              std::unique_ptr<SnapshotInfo> last,
143              std::unique_ptr<SnapshotInfo> previous);
144 
145     // Unowned pointer - outlives this instance.
146     PrefService* const local_state_;
147 
148     // Values should be kept in sync with values stored in arc.snapshot
149     // preference.
150     bool blocked_ui_mode_ = false;
151     bool started_;
152     std::unique_ptr<SnapshotInfo> last_;
153     std::unique_ptr<SnapshotInfo> previous_;
154   };
155 
156   ArcDataSnapshotdManager(PrefService* local_state,
157                           base::OnceClosure attempt_user_exit_callback);
158   ArcDataSnapshotdManager(const ArcDataSnapshotdManager&) = delete;
159   ArcDataSnapshotdManager& operator=(const ArcDataSnapshotdManager&) = delete;
160   ~ArcDataSnapshotdManager() override;
161 
162   static ArcDataSnapshotdManager* Get();
163 
164   // Starts arc-data-snapshotd.
165   void EnsureDaemonStarted(base::OnceClosure callback);
166   // Stops arc-data-snapshotd.
167   void EnsureDaemonStopped(base::OnceClosure callback);
168 
169   // Returns true if autologin to public account should be performed.
170   bool IsAutoLoginConfigured();
171   // Returns true if autologin is allowed to be performed and manager is not
172   // waiting for the response from arc-data-snapshotd daemon.
173   bool IsAutoLoginAllowed();
174 
175   // session_manager::SessionManagerObserver:
176   void OnSessionStateChanged() override;
177 
178   // Get |bridge_| for testing.
bridge()179   ArcDataSnapshotdBridge* bridge() { return bridge_.get(); }
180 
state()181   State state() const { return state_; }
182 
set_reset_autologin_callback(base::OnceClosure callback)183   void set_reset_autologin_callback(base::OnceClosure callback) {
184     reset_autologin_callback_ = std::move(callback);
185   }
186 
set_snapshot_enabled_for_testing(bool enabled)187   static void set_snapshot_enabled_for_testing(bool enabled) {
188     is_snapshot_enabled_for_testing_ = enabled;
189   }
is_snapshot_enabled_for_testing()190   static bool is_snapshot_enabled_for_testing() {
191     return is_snapshot_enabled_for_testing_;
192   }
set_state_for_testing(State state)193   void set_state_for_testing(State state) { state_ = state; }
194 
195  private:
196   // Attempts to arc-data-snapshotd daemon regardless of state of the class.
197   // Runs |callback| once finished.
198   void StopDaemon(base::OnceClosure callback);
199 
200   // Attempts to clear snapshots.
201   void DoClearSnapshots();
202   // Attempts to clear the passed snapshot, calls |callback| once finished.
203   // |success| indicates a successfully or not the previous operation has been
204   // finished.
205   void DoClearSnapshot(SnapshotInfo* snapshot,
206                        base::OnceCallback<void(bool)> callback,
207                        bool success);
208 
209   // Delegates operations to |bridge_|
210   void GenerateKeyPair();
211   void ClearSnapshot(bool last, base::OnceCallback<void(bool)> callback);
212 
213   // Called once the outdated snapshots were removed or ensured that there are
214   // no outdated snapshots.
215   void OnSnapshotsCleared(bool success);
216   // Called once GenerateKeyPair is finished with a result |success|.
217   void OnKeyPairGenerated(bool success);
218   // Called once arc-data-snapshotd starting process is finished with result
219   // |success|, runs |callback| afterwards.
220   void OnDaemonStarted(base::OnceClosure callback, bool success);
221   // Called once arc-data-snapshotd stopping process is finished with result
222   // |success", runs |callback| afterwards.
223   void OnDaemonStopped(base::OnceClosure callback, bool success);
224 
225   static bool is_snapshot_enabled_for_testing_;
226   State state_ = State::kNone;
227   Snapshot snapshot_;
228 
229   std::unique_ptr<ArcDataSnapshotdBridge> bridge_;
230 
231   base::OnceClosure attempt_user_exit_callback_;
232 
233   // Callback to reset an autologin timer once userless MGS is ready to start.
234   base::OnceClosure reset_autologin_callback_;
235 
236   // Used for cancelling previously posted tasks to daemon.
237   base::WeakPtrFactory<ArcDataSnapshotdManager> daemon_weak_ptr_factory_{this};
238   // WeakPtrFactory to use for callbacks.
239   base::WeakPtrFactory<ArcDataSnapshotdManager> weak_ptr_factory_{this};
240 };
241 
242 }  // namespace data_snapshotd
243 }  // namespace arc
244 
245 #endif  // COMPONENTS_ARC_ENTERPRISE_ARC_DATA_SNAPSHOTD_MANAGER_H_
246