1 // Copyright 2018 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_WEB_APPLICATIONS_SYSTEM_WEB_APP_MANAGER_H_ 6 #define CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APP_MANAGER_H_ 7 8 #include <map> 9 #include <memory> 10 #include <set> 11 #include <string> 12 #include <vector> 13 14 #include "base/callback_forward.h" 15 #include "base/containers/flat_map.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/one_shot_event.h" 18 #include "chrome/browser/web_applications/components/pending_app_manager.h" 19 #include "chrome/browser/web_applications/components/web_application_info.h" 20 #include "components/prefs/pref_change_registrar.h" 21 #include "ui/gfx/geometry/size.h" 22 #include "url/gurl.h" 23 #include "url/origin.h" 24 25 namespace base { 26 class Version; 27 } 28 29 namespace content { 30 class NavigationHandle; 31 } 32 33 namespace user_prefs { 34 class PrefRegistrySyncable; 35 } 36 37 class PrefService; 38 class Profile; 39 40 namespace web_app { 41 42 class WebAppUiManager; 43 class OsIntegrationManager; 44 class AppRegistryController; 45 46 // An enum that lists the different System Apps that exist. Can be used to 47 // retrieve the App ID from the underlying Web App system. 48 enum class SystemAppType { 49 SETTINGS, 50 CAMERA, 51 TERMINAL, 52 MEDIA, 53 HELP, 54 PRINT_MANAGEMENT, 55 SCANNING, 56 DIAGNOSTICS, 57 CONNECTIVITY_DIAGNOSTICS, 58 #if !defined(OFFICIAL_BUILD) 59 FILE_MANAGER, 60 TELEMETRY, 61 SAMPLE, 62 #endif // !defined(OFFICIAL_BUILD) 63 64 // When adding a new System App, add a corresponding histogram suffix in 65 // WebAppSystemAppInternalName (histograms.xml). The suffix name should match 66 // the App's |internal_name|. This is for reporting per-app install results. 67 }; 68 69 using OriginTrialsMap = std::map<url::Origin, std::vector<std::string>>; 70 using WebApplicationInfoFactory = 71 base::RepeatingCallback<std::unique_ptr<WebApplicationInfo>()>; 72 73 // The configuration options for a System App. 74 struct SystemAppInfo { 75 SystemAppInfo(const std::string& internal_name, const GURL& install_url); 76 // When installing via a WebApplicationInfo, the url is never loaded. It's 77 // needed only for various legacy reasons, maps for tracking state, and 78 // generating the AppId and things of that nature. 79 SystemAppInfo(const std::string& internal_name, 80 const GURL& install_url, 81 const WebApplicationInfoFactory& info_factory); 82 SystemAppInfo(const SystemAppInfo& other); 83 ~SystemAppInfo(); 84 85 // A developer-friendly name for, among other things, reporting metrics and 86 // interacting with tast tests. It should follow PascalCase convention, and 87 // have a corresponding entry in WebAppSystemAppInternalName histogram 88 // suffixes. The internal name shouldn't be changed afterwards. 89 std::string internal_name; 90 91 // The URL that the System App will be installed from. 92 GURL install_url; 93 94 // If specified, the apps in |uninstall_and_replace| will have their data 95 // migrated to this System App. 96 std::vector<AppId> uninstall_and_replace; 97 98 // Minimum window size in DIPs. Empty if the app does not have a minimum. 99 // TODO(https://github.com/w3c/manifest/issues/436): Replace with PWA manifest 100 // properties for window size. 101 gfx::Size minimum_window_size; 102 103 // If set, we allow only a single window for this app. 104 bool single_window = true; 105 106 // If set, when the app is launched through the File Handling Web API, we will 107 // include the file's directory in window.launchQueue as the first value. 108 bool include_launch_directory = false; 109 110 // Map from origin to enabled origin trial names for this app. For example, 111 // "chrome://sample-web-app/" to ["Frobulate"]. If set, we will enable the 112 // given origin trials when the corresponding origin is loaded in the app. 113 OriginTrialsMap enabled_origin_trials; 114 115 // Resource Ids for additional search terms. 116 std::vector<int> additional_search_terms; 117 118 // If set to false, this app will be hidden from the Chrome OS app launcher. 119 bool show_in_launcher = true; 120 121 // If set to false, this app will be hidden from the Chrome OS search. 122 bool show_in_search = true; 123 124 // If set to true, navigations (e.g. Omnibox URL, anchor link) to this app 125 // will open in the app's window instead of the navigation's context (e.g. 126 // browser tab). 127 bool capture_navigations = false; 128 129 WebApplicationInfoFactory app_info_factory; 130 }; 131 132 // Installs, uninstalls, and updates System Web Apps. 133 // System Web Apps are built-in, highly-privileged Web Apps for Chrome OS. They 134 // have access to more APIs and are part of the Chrome OS image. 135 class SystemWebAppManager { 136 public: 137 // Policy for when the SystemWebAppManager will update apps/install new apps. 138 enum class UpdatePolicy { 139 // Update every system start. 140 kAlwaysUpdate, 141 // Update when the Chrome version number changes. 142 kOnVersionChange, 143 }; 144 145 static constexpr char kInstallResultHistogramName[] = 146 "Webapp.InstallResult.System"; 147 static constexpr char kInstallDurationHistogramName[] = 148 "Webapp.SystemApps.FreshInstallDuration"; 149 150 // Returns whether the given app type is enabled. 151 static bool IsAppEnabled(SystemAppType type); 152 153 explicit SystemWebAppManager(Profile* profile); 154 SystemWebAppManager(const SystemWebAppManager&) = delete; 155 SystemWebAppManager& operator=(const SystemWebAppManager&) = delete; 156 virtual ~SystemWebAppManager(); 157 158 void SetSubsystems(PendingAppManager* pending_app_manager, 159 AppRegistrar* registrar, 160 AppRegistryController* registry_controller, 161 WebAppUiManager* ui_manager, 162 OsIntegrationManager* os_integration_manager); 163 164 void Start(); 165 166 // The SystemWebAppManager is disabled in browser tests by default because it 167 // pollutes the startup state (several tests expect the Extensions state to be 168 // clean). 169 // 170 // Call this to install apps for SystemWebApp specific tests, e.g if a test 171 // needs to open OS Settings. 172 // 173 // This can also be called multiple times to simulate reinstallation from 174 // system restart, e.g. 175 void InstallSystemAppsForTesting(); 176 177 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 178 179 // Returns the app id for the given System App |type|. 180 base::Optional<AppId> GetAppIdForSystemApp(SystemAppType type) const; 181 182 // Returns the System App Type for the given |app_id|. 183 base::Optional<SystemAppType> GetSystemAppTypeForAppId(AppId app_id) const; 184 185 // Returns the App Ids for all installed System Web Apps. 186 std::vector<AppId> GetAppIds() const; 187 188 // Returns whether |app_id| points to an installed System App. 189 bool IsSystemWebApp(const AppId& app_id) const; 190 191 // Returns whether the given System App |type| should use a single window. 192 bool IsSingleWindow(SystemAppType type) const; 193 194 // Returns whether the given System App |type| should get launch directory in 195 // launch parameter. 196 bool AppShouldReceiveLaunchDirectory(SystemAppType type) const; 197 198 // Perform tab-specific setup when a navigation in a System Web App is about 199 // to be committed. 200 void OnReadyToCommitNavigation(const AppId& app_id, 201 content::NavigationHandle* navigation_handle); 202 203 // Returns terms to be used when searching for the app. 204 std::vector<std::string> GetAdditionalSearchTerms(SystemAppType type) const; 205 206 // Returns whether the app should be shown in the launcher. 207 bool ShouldShowInLauncher(SystemAppType type) const; 208 209 // Returns whether the app should be shown in search. 210 bool ShouldShowInSearch(SystemAppType type) const; 211 212 // Returns the SystemAppType that should capture the navigation to |url|. 213 base::Optional<SystemAppType> GetCapturingSystemAppForURL( 214 const GURL& url) const; 215 216 // Returns the minimum window size for |app_id| or an empty size if the app 217 // doesn't specify a minimum. 218 gfx::Size GetMinimumWindowSize(const AppId& app_id) const; 219 220 // Returns a map of registered system app types and infos, these apps will be 221 // installed on the system. 222 const base::flat_map<SystemAppType, SystemAppInfo>& 223 GetRegisteredSystemAppsForTesting() const; 224 on_apps_synchronized()225 const base::OneShotEvent& on_apps_synchronized() const { 226 return *on_apps_synchronized_; 227 } 228 229 // This call will override default System Apps configuration. You should call 230 // Start() after this call to install |system_apps|. 231 void SetSystemAppsForTesting( 232 base::flat_map<SystemAppType, SystemAppInfo> system_apps); 233 234 // Overrides the update policy. If AlwaysReinstallSystemWebApps feature is 235 // enabled, this method does nothing, and system apps will be reinstalled. 236 void SetUpdatePolicyForTesting(UpdatePolicy policy); 237 238 void ResetOnAppsSynchronizedForTesting(); 239 240 // Updates each system app either disabled/not disabled. 241 void OnAppsPolicyChanged(); 242 243 void Shutdown(); 244 245 protected: 246 virtual const base::Version& CurrentVersion() const; 247 virtual const std::string& CurrentLocale() const; 248 249 private: 250 // Returns the list of origin trials to enable for |url| loaded in System App 251 // |type|. Returns nullptr if the App does not specify origin trials for 252 // |url|. 253 const std::vector<std::string>* GetEnabledOriginTrials(SystemAppType type, 254 const GURL& url); 255 256 bool AppHasFileHandlingOriginTrial(SystemAppType type); 257 258 void OnAppsSynchronized(bool did_force_install_apps, 259 const base::TimeTicks& install_start_time, 260 std::map<GURL, InstallResultCode> install_results, 261 std::map<GURL, bool> uninstall_results); 262 bool ShouldForceInstallApps() const; 263 void UpdateLastAttemptedInfo(); 264 // Returns if we have exceeded the number of retry attempts allowed for this 265 // version. 266 bool CheckAndIncrementRetryAttempts(); 267 268 void RecordSystemWebAppInstallResults( 269 const std::map<GURL, InstallResultCode>& install_results) const; 270 271 void RecordSystemWebAppInstallDuration( 272 const base::TimeDelta& time_duration) const; 273 274 Profile* profile_; 275 276 std::unique_ptr<base::OneShotEvent> on_apps_synchronized_; 277 278 bool shutting_down_ = false; 279 280 std::string install_result_per_profile_histogram_name_; 281 282 UpdatePolicy update_policy_; 283 284 base::flat_map<SystemAppType, SystemAppInfo> system_app_infos_; 285 286 base::flat_map<AppId, SystemAppType> app_id_to_app_type_; 287 288 PrefService* const pref_service_; 289 290 // Used to install, uninstall, and update apps. Should outlive this class. 291 PendingAppManager* pending_app_manager_ = nullptr; 292 293 AppRegistrar* registrar_ = nullptr; 294 295 AppRegistryController* registry_controller_ = nullptr; 296 297 WebAppUiManager* ui_manager_ = nullptr; 298 299 OsIntegrationManager* os_integration_manager_ = nullptr; 300 301 PrefChangeRegistrar local_state_pref_change_registrar_; 302 303 base::WeakPtrFactory<SystemWebAppManager> weak_ptr_factory_{this}; 304 305 }; 306 307 } // namespace web_app 308 309 #endif // CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APP_MANAGER_H_ 310