1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_APP_RESTORE_FULL_RESTORE_SAVE_HANDLER_H_
#define COMPONENTS_APP_RESTORE_FULL_RESTORE_SAVE_HANDLER_H_
#include <list>
#include <map>
#include <memory>
#include <set>
#include <utility>
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "base/uuid.h"
#include "components/app_restore/app_restore_arc_info.h"
#include "components/app_restore/arc_save_handler.h"
#include "ui/aura/env.h"
#include "ui/aura/env_observer.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
namespace apps {
class AppRegistryCache;
} // namespace apps
namespace app_restore {
struct AppLaunchInfo;
class RestoreData;
struct WindowInfo;
} // namespace app_restore
namespace ash::full_restore {
class FullRestoreServiceTestHavingFullRestoreFile;
class FullRestoreAppLaunchHandlerArcAppBrowserTest;
} // namespace ash::full_restore
namespace base {
class FilePath;
class SequencedTaskRunner;
} // namespace base
namespace full_restore {
class FullRestoreFileHandler;
// FullRestoreSaveHandler is responsible for writing both the app launch
// information and the app window information to disk. FullRestoreSaveHandler
// runs on the main thread and creates FullRestoreFileHandler (which runs on a
// background task runner) for the actual writing. To minimize IO,
// FullRestoreSaveHandler starts a timer that invokes restore data saving at a
// later time.
class COMPONENT_EXPORT(APP_RESTORE) FullRestoreSaveHandler
: public aura::EnvObserver,
public aura::WindowObserver,
public app_restore::AppRestoreArcInfo::Observer {
public:
using AppLaunchInfoPtr = std::unique_ptr<app_restore::AppLaunchInfo>;
static FullRestoreSaveHandler* GetInstance();
FullRestoreSaveHandler();
FullRestoreSaveHandler(const FullRestoreSaveHandler&) = delete;
FullRestoreSaveHandler& operator=(const FullRestoreSaveHandler&) = delete;
~FullRestoreSaveHandler() override;
void InsertIgnoreApplicationId(const std::string& app_id);
void SetPrimaryProfilePath(const base::FilePath& profile_path);
void SetActiveProfilePath(const base::FilePath& profile_path);
void SetAppRegistryCache(const base::FilePath& profile_path,
apps::AppRegistryCache* app_registry_cache);
// When called, allows the Save() method to write to disk. Schedules the save
// timer to start for each monitored profile.
void AllowSave();
void SetShutDown();
// aura::EnvObserver:
void OnWindowInitialized(aura::Window* window) override;
// aura::WindowObserver:
void OnWindowDestroyed(aura::Window* window) override;
// app_restore::AppRestoreArcInfo::Observer:
void OnTaskCreated(const std::string& app_id,
int32_t task_id,
int32_t session_id) override;
void OnTaskDestroyed(int32_t task_id) override;
void OnArcConnectionChanged(bool is_connection_ready) override;
void OnArcPlayStoreEnabledChanged(bool enabled) override;
void OnTaskThemeColorUpdated(int32_t task_id,
uint32_t primary_color,
uint32_t status_bar_color) override;
// Saves |app_launch_info| to the full restore file in |profile_path|.
void SaveAppLaunchInfo(
const base::FilePath& profile_path,
std::unique_ptr<app_restore::AppLaunchInfo> app_launch_info);
// Saves |window_info| to |profile_path_to_restore_data_|.
void SaveWindowInfo(const app_restore::WindowInfo& window_info);
// Saves `removing_desk_guid` to the restore data for the currently active
// profile path.
void SaveRemovingDeskGuid(const base::Uuid& removing_desk_guid);
// Flushes the full restore file in |profile_path| with the current restore
// data.
void Flush(const base::FilePath& profile_path);
// Returns true if there is a AppRestoreData for the given `profile_path`,
// `app_id` and `window_id`. Otherwise, returns false.
bool HasAppRestoreData(const base::FilePath& profile_path,
const std::string& app_id,
int32_t window_id);
// Saves |app_launch_info| to |profile_path_to_file_handler_| for
// |profile_path| which will be written to the full restore file, if
// |app_launch_info| has a window_id.
void AddAppLaunchInfo(const base::FilePath& profile_path,
AppLaunchInfoPtr app_launch_info);
// Modify the window id for `app_id` from `old_window_id` to `new_window_id`.
void ModifyWindowId(const base::FilePath& profile_path,
const std::string& app_id,
int32_t old_window_id,
int32_t new_window_id);
// Saves |window_info| to |profile_path| for |app_id| and |window_id|.
void ModifyWindowInfo(const base::FilePath& profile_path,
const std::string& app_id,
int32_t window_id,
const app_restore::WindowInfo& window_info);
// Saves |primary_color| and |status_bar_color| to |profile_path| for |app_id|
// and |window_id|.
void ModifyThemeColor(const base::FilePath& profile_path,
const std::string& app_id,
int32_t window_id,
uint32_t primary_color,
uint32_t status_bar_color);
// Removes app launching and app windows for an app with the given |app_id|
// from |file_path_to_restore_data_| for |profile_path| .
void RemoveApp(const base::FilePath& profile_path, const std::string& app_id);
// Removes AppRestoreData from |profile_path| for |app_id| and |window_id|.
void RemoveAppRestoreData(const base::FilePath& profile_path,
const std::string& app_id,
int window_id);
// Sends the window for `profile_path` `app_id and `window_id` to background.
void SendWindowToBackground(const base::FilePath& profile_path,
const std::string& app_id,
int window_id);
// Starts the timer, and when timeout, clears restore data for |profile_path|.
void ClearRestoreData(const base::FilePath& profile_path);
// Generates the ARC session id (0 - 1,000,000,000) for ARC apps.
int32_t GetArcSessionId();
// Returns the RestoreData that associates with |profile_path|. Returns
// nullptr if there is no such RestoreData.
const app_restore::RestoreData* GetRestoreData(
const base::FilePath& profile_path);
// Returns the full restore app id for |window| that can be used to look up
// the window's associated AppRestoreData.
std::string GetAppId(aura::Window* window);
// Fetches the app launch information from `app_id_to_app_launch_infos_` for
// the given `profile_path` and `app_id`. `app_id` should be a Chrome app id.
AppLaunchInfoPtr FetchAppLaunchInfo(const base::FilePath& profile_path,
const std::string& app_id);
// Returns the window information from the restore data of `profile_path` for
// `app_id` and `window_id`.
std::unique_ptr<app_restore::WindowInfo> GetWindowInfo(
const base::FilePath& profile_path,
const std::string& app_id,
int window_id);
base::OneShotTimer* GetTimerForTesting() { return &save_timer_; }
// Since this is a singleton, tests may need to clear it between tests.
void ClearForTesting();
private:
friend class FullRestoreSaveHandlerTestApi;
friend class ash::full_restore::FullRestoreServiceTestHavingFullRestoreFile;
friend class ash::full_restore::FullRestoreAppLaunchHandlerArcAppBrowserTest;
// Map from a profile path to AppLaunchInfos.
using AppLaunchInfos =
base::flat_map<base::FilePath, std::list<AppLaunchInfoPtr>>;
// Starts the timer that invokes Save (if timer isn't already running).
void MaybeStartSaveTimer(const base::FilePath& profile_path);
// Passes |profile_path_to_restore_data_| to the backend for saving.
void Save();
// Invoked when write to file operation for |profile_path| is finished.
void OnSaveFinished(const base::FilePath& profile_path);
FullRestoreFileHandler* GetFileHandler(const base::FilePath& profile_path);
base::SequencedTaskRunner* BackendTaskRunner(
const base::FilePath& profile_path);
// Saves |window_info| to |profile_path_to_file_handler_|.
void ModifyWindowInfo(int window_id,
const app_restore::WindowInfo& window_info);
// Removes AppRestoreData for |window_id|.
void RemoveAppRestoreData(int window_id);
// Applications with their app ids in this set will not have their app launch
// infos saved.
base::flat_set<std::string> ignore_applications_ids_;
// FullRestoreSaveHandler might be called to save the help app before
// FullRestoreAppLaunchHandler reads the full restore data from the full
// restore file during the system startup phase, e.g. when a new user login.
// So call FullRestoreReadHandler to read the file before saving the new data.
// `been_read_profile_paths_` is used to save the profile paths, whose full
// restore file has been read by FullRestoreReadHandler.
std::set<base::FilePath> been_read_profile_paths_;
// Records whether there are new updates for saving between each saving delay.
// |pending_save_profile_paths_| is cleared when Save is invoked.
std::set<base::FilePath> pending_save_profile_paths_;
// The restore data for each user's profile. The key is the profile path.
std::map<base::FilePath, app_restore::RestoreData>
profile_path_to_restore_data_;
// The file handler for each user's profile to write the restore data to the
// full restore file for each user. The key is the profile path.
base::flat_map<base::FilePath, scoped_refptr<FullRestoreFileHandler>>
profile_path_to_file_handler_;
// The AppRegistryCache for each user's profile. The key is the profile path.
base::flat_map<base::FilePath,
raw_ptr<apps::AppRegistryCache, CtnExperimental>>
profile_path_to_app_registry_cache_;
// The map from the window id to the full restore file path and the app id.
// The window id is saved in the window property. This map is used to find the
// file path and the app id for browser windows and Chrome app windows only
// when save the window info. This map can't be used for ARC app windows.
std::map<int32_t, std::pair<base::FilePath, std::string>>
window_id_to_app_restore_info_;
// The map from the app id to the app launch info for each full restore file
// path.
std::map<std::string, AppLaunchInfos> app_id_to_app_launch_infos_;
// The current active user profile path.
base::FilePath active_profile_path_;
// Timer used to delay the restore data writing to the full restore file.
base::OneShotTimer save_timer_;
// During the startup phase, start `wait_timer_` to wait for the system
// finishes the startup and the restore process, to prevent the original
// restore data is overwritten if the system restarts due to fast crash or
// upgrading.
base::OneShotTimer wait_timer_;
// Records whether the saving process is running for a full restore file.
std::set<base::FilePath> save_running_;
std::unique_ptr<ArcSaveHandler> arc_save_handler_;
bool is_shut_down_ = false;
// Due to the system crash or upgrading, the system might restart or reboot
// very fast after startup. If the new window is written for the first time
// startup, after the second time reboot, the original restore data can't be
// restored. For the user, it looks like not restore. So block the save timer
// when startup until one of the below condition is matched:
// 1. restore finish if the restore setting is always, and no crash.
// 2. restore finish if there is a restore notification, and the user selects
// restore.
// 3. an app is launched by the user if there is a restore notification.
// 4. the restore notification is cancel or closed by the user if there is a
// restore notification.
// 5. the restore setting is off.
// 6. 'wait_timer_' is expired.
//
// When one of the above condition is matched, allow_save_ is set as true to
// permit `save_timer_` to start periodically triggering saving to disk.
bool allow_save_ = false;
base::ScopedObservation<aura::Env, aura::EnvObserver> env_observer_{this};
base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
observed_windows_{this};
base::ScopedObservation<app_restore::AppRestoreArcInfo,
app_restore::AppRestoreArcInfo::Observer>
arc_info_observer_{this};
base::WeakPtrFactory<FullRestoreSaveHandler> weak_factory_{this};
};
} // namespace full_restore
#endif // COMPONENTS_APP_RESTORE_FULL_RESTORE_SAVE_HANDLER_H_
|