// 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. #include "chrome/browser/web_applications/preinstalled_web_app_utils.h" #include <memory> #include <string_view> #include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/types/expected_macros.h" #include "base/values.h" #include "chrome/browser/apps/user_type_filter.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/file_utils_wrapper.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/common/pref_names.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/webapps/common/constants.h" #include "components/webapps/common/web_app_id.h" #include "third_party/blink/public/common/manifest/manifest_util.h" #include "ui/events/devices/device_data_manager.h" #include "ui/gfx/codec/png_codec.h" namespace web_app { namespace { // kAppUrl is a required string specifying a URL inside the scope of the web // app that contains a link to the app manifest. constexpr char kAppUrl[] = …; // kHideFromUser is an optional boolean which controls whether we add // a shortcut to the relevant OS surface i.e. Application folder on macOS, Start // Menu on Windows and Linux, and launcher on Chrome OS. Defaults to false if // missing. If true, we also don't show the app in search or in app management // on Chrome OS. constexpr char kHideFromUser[] = …; // kOnlyForNewUsers is an optional boolean. If set and true we will not install // the app for users that have already run Chrome before. constexpr char kOnlyForNewUsers[] = …; // kOnlyIfPreviouslyPreinstalled is an optional boolean. If set and true we will // not preinstall the app for new users. constexpr char kOnlyIfPreviouslyPreinstalled[] = …; // kUserType is an allowlist of user types to install this app for. This must be // populated otherwise the app won't ever be installed. // Example: "user_type": ["unmanaged", "managed", "child"] // See apps::DetermineUserType() for relevant string constants. constexpr char kUserType[] = …; // kCreateShortcuts is an optional boolean which controls whether OS // level shortcuts are created. On Chrome OS this controls whether the app is // pinned to the shelf. // The default value of kCreateShortcuts if false. constexpr char kCreateShortcuts[] = …; // kFeatureName is an optional string parameter specifying a feature // associated with this app. The feature must be present in // |kPreinstalledAppInstallFeatures| to be applicable. // If specified: // - if the feature is enabled, the app will be installed // - if the feature is not enabled, the app will be removed. constexpr char kFeatureName[] = …; // kFeatureNameOrInstalled is an optional string parameter specifying a feature // associated with this app. The feature must be present in // |kPreinstalledAppInstallFeatures| to be applicable. // // When specified, the app will only be installed when the feature is enabled. // If the feature is disabled, existing installations will not be removed. constexpr char kFeatureNameOrInstalled[] = …; // kDisableIfArcSupported is an optional bool which specifies whether to skip // install of the app if the device supports Arc (Chrome OS only). // Defaults to false. constexpr char kDisableIfArcSupported[] = …; // kDisableIfTabletFormFactor is an optional bool which specifies whether to // skip install of the app if the device is a tablet form factor. // This is only for Chrome OS tablets, Android does not use any of this code. // Defaults to false. constexpr char kDisableIfTabletFormFactor[] = …; // kLaunchContainer is a required string which can be "window" or "tab" // and controls what sort of container the web app is launched in. constexpr char kLaunchContainer[] = …; constexpr char kLaunchContainerTab[] = …; constexpr char kLaunchContainerWindow[] = …; // kLaunchQueryParams is an optional string which specifies query parameters to // add to the start_url when launching the app. If the provided params are a // substring of start_url's existing params then it will not be added a second // time. // Note that substring matches include "param=a" matching in "some_param=abc". // Extend the implementation in WebAppRegistrar::GetAppLaunchUrl() if this edge // case needs to be handled differently. constexpr char kLaunchQueryParams[] = …; // kLoadAndAwaitServiceWorkerRegistration is an optional bool that specifies // whether to fetch the |kServiceWorkerRegistrationUrl| after installation to // allow time for the app to register its service worker. This is done as a // second pass after install in order to not block the installation of other // background installed apps. No fetch is made if the service worker has already // been registered by the |kAppUrl|. // Defaults to true. constexpr char kLoadAndAwaitServiceWorkerRegistration[] = …; // kServiceWorkerRegistrationUrl is an optional string specifying the URL to use // for the above |kLoadAndAwaitServiceWorkerRegistration|. // Defaults to the |kAppUrl|. constexpr char kServiceWorkerRegistrationUrl[] = …; // kUninstallAndReplace is an optional array of strings which specifies App IDs // which the app is replacing. This will transfer OS attributes (e.g the source // app's shelf and app list positions on ChromeOS) and then uninstall the source // app. constexpr char kUninstallAndReplace[] = …; // kOnlyUseOfflineManifest is an optional bool. // If set to true then no network install will be attempted and the app will be // installed using |kOfflineManifest| data. |kOfflineManifest| must be specified // in this case. // If set to false and |kOfflineManifest| is set then it will be used as a // fallback manifest if the network install fails. // Defaults to false. constexpr char kOnlyUseOfflineManifest[] = …; // kOfflineManifest is a dictionary of manifest field values to use as an // install to avoid the expense of fetching the install URL to download the // app's true manifest. Next time the user visits the app it will undergo a // manifest update check and correct any differences from the site (except for // name and start_url). // // Why not use blink::ManifestParser? // blink::ManifestParser depends on substantial sections of the CSS parser which // is infeasible to run outside of the renderer process. constexpr char kOfflineManifest[] = …; // "name" manifest value to use for offline install. constexpr char kOfflineManifestName[] = …; // "start_url" manifest value to use for offline install. Can be updated from a // live manifest if the manifest ID field is specified to match the offline // start_url. constexpr char kOfflineManifestStartUrl[] = …; // "scope" manifest value to use for offline install. constexpr char kOfflineManifestScope[] = …; // "display" manifest value to use for offline install. constexpr char kOfflineManifestDisplay[] = …; // List of PNG files in the default web app config directory to use as the // icons for offline install. Will be installed with purpose "any". constexpr char kOfflineManifestIconAnyPngs[] = …; // List of PNG files in the default web app config directory to use as the // icons for offline install. Will be installed with purpose "maskable". constexpr char kOfflineManifestIconMaskablePngs[] = …; // Optional 8 value ARGB hex code to use as the "theme_color" manifest value. // Example: // "theme_color_argb_hex": "FFFF0000" // is equivalent to // "theme_color": "red" constexpr char kOfflineManifestThemeColorArgbHex[] = …; // Contains numeric milestone number M like 89 (the Chrome version). The app // gets updated if browser's binary milestone number goes from <M to >=M. constexpr char kForceReinstallForMilestone[] = …; // Contains boolean indicating whether the app installation is requested by // the device OEM. constexpr char kOemInstalled[] = …; // Contains boolean indicating weather the app should only be install on devices // with a built-in touchscreen with stylus support. constexpr char kDisableIfTouchScreenWithStylusNotSupported[] = …; // Contains boolean that, if set to true, will set the app as the preferred app // for its supported links after installation. Note that this has no effect if // the app is already installed as the user may have already updated their // preference. constexpr char kIsPreferredAppForSupportedLinks[] = …; void EnsureContains(base::Value::List& list, std::string_view value) { … } } // namespace OptionsOrError ParseConfig(FileUtilsWrapper& file_utils, const base::FilePath& dir, const base::FilePath& file, const base::Value& app_config) { … } IconBitmapsOrError ParseOfflineManifestIconBitmaps( FileUtilsWrapper& file_utils, const base::FilePath& dir, const base::FilePath& manifest_file, const char* icon_key, const base::Value::List& icon_files) { … } WebAppInstallInfoFactoryOrError ParseOfflineManifest( FileUtilsWrapper& file_utils, const base::FilePath& dir, const base::FilePath& file, const base::Value& offline_manifest) { … } bool IsReinstallPastMilestoneNeeded( std::string_view last_preinstall_synchronize_milestone_str, std::string_view current_milestone_str, int force_reinstall_for_milestone) { … } bool WasAppMigratedToWebApp(Profile* profile, const std::string& app_id) { … } void MarkAppAsMigratedToWebApp(Profile* profile, const std::string& app_id, bool was_migrated) { … } bool WasMigrationRun(Profile* profile, std::string_view feature_name) { … } void SetMigrationRun(Profile* profile, std::string_view feature_name, bool was_migrated) { … } bool WasPreinstalledAppUninstalled(Profile* profile, const std::string& app_id) { … } void MarkPreinstalledAppAsUninstalled(Profile* profile, const std::string& app_id) { … } std::optional<bool> DeviceHasStylusEnabledTouchscreen() { … } } // namespace web_app