| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_ASH_APPS_APK_WEB_APP_SERVICE_H_ |
| #define CHROME_BROWSER_ASH_APPS_APK_WEB_APP_SERVICE_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/functional/callback.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h" |
| #include "chrome/browser/ash/apps/apk_web_app_installer.h" |
| #include "chromeos/ash/experiences/arc/mojom/app.mojom-forward.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/services/app_service/public/cpp/app_registry_cache.h" |
| #include "components/webapps/browser/uninstall_result_code.h" |
| #include "components/webapps/common/web_app_id.h" |
| |
| class ArcAppListPrefs; |
| class Profile; |
| class GURL; |
| |
| namespace user_prefs { |
| class PrefRegistrySyncable; |
| } // namespace user_prefs |
| |
| namespace webapps { |
| enum class InstallResultCode; |
| enum class UninstallResultCode; |
| } // namespace webapps |
| |
| namespace apps { |
| class PromiseAppServiceTest; |
| } |
| |
| namespace ash { |
| |
| // Service which manages integration of ARC packages containing web apps. |
| // Watches for installation of APK web app packages and installs the |
| // corresponding web app, and responds to events from both ARC and web apps to |
| // keep these packages in sync. |
| class ApkWebAppService : public KeyedService, |
| public ApkWebAppInstaller::Owner, |
| public ArcAppListPrefs::Observer, |
| public apps::AppRegistryCache::Observer { |
| public: |
| // Handles app install/uninstall operations to external processes (ARC) to |
| // stub out in tests. |
| class Delegate { |
| public: |
| using WebAppInstallCallback = base::OnceCallback<void( |
| const webapps::AppId& web_app_id, |
| bool is_web_only_twa, |
| const std::optional<std::string> sha256_fingerprint, |
| webapps::InstallResultCode code)>; |
| |
| using WebAppUninstallCallback = |
| base::OnceCallback<void(webapps::UninstallResultCode code)>; |
| |
| virtual ~Delegate(); |
| |
| // Tells ARC to uninstall a package identified by |package_name|. Returns |
| // true if the call to ARC was successful, false if ARC is not running. |
| virtual void MaybeUninstallPackageInArc( |
| const std::string& package_name) = 0; |
| }; |
| |
| static ApkWebAppService* Get(Profile* profile); |
| static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); |
| |
| explicit ApkWebAppService(Profile* profile, Delegate* test_delegate); |
| |
| ApkWebAppService(const ApkWebAppService&) = delete; |
| ApkWebAppService& operator=(const ApkWebAppService&) = delete; |
| |
| ~ApkWebAppService() override; |
| |
| bool IsWebOnlyTwa(const webapps::AppId& app_id); |
| |
| bool IsWebAppInstalledFromArc(const webapps::AppId& web_app_id); |
| |
| bool IsWebAppShellPackage(const std::string& package_name); |
| |
| std::optional<std::string> GetPackageNameForWebApp( |
| const webapps::AppId& app_id, |
| bool include_installing_apks = false); |
| |
| std::optional<std::string> GetPackageNameForWebApp(const GURL& url); |
| |
| std::optional<std::string> GetWebAppIdForPackageName( |
| const std::string& package_name); |
| |
| std::optional<std::string> GetCertificateSha256Fingerprint( |
| const webapps::AppId& app_id); |
| |
| // Save a mapping of the web app ID to the package name for a web-only TWA |
| // that is currently installing. |
| void AddInstallingWebApkPackageName(const std::string& app_id, |
| const std::string& package_name); |
| |
| using WebAppCallbackForTesting = |
| base::OnceCallback<void(const std::string& package_name, |
| const webapps::AppId& web_app_id)>; |
| void SetWebAppInstalledCallbackForTesting( |
| WebAppCallbackForTesting web_app_installed_callback); |
| void SetWebAppUninstalledCallbackForTesting( |
| WebAppCallbackForTesting web_app_uninstalled_callback); |
| |
| private: |
| friend class apps::PromiseAppServiceTest; |
| |
| Delegate& GetDelegate() { |
| return test_delegate_ ? *test_delegate_ : *real_delegate_; |
| } |
| |
| // Starts installation of a web app with the given `web_app_info`. Will first |
| // load an icon from the ARC app with the given `package_name`. Does nothing |
| // if ARC is not started. |
| void MaybeInstallWebApp(const std::string& package_name, |
| arc::mojom::WebAppInfoPtr web_app_info); |
| |
| // Removes the ARC install source from the web app with the given |
| // `web_app_id`. If there are no other sources left, the web app will be |
| // uninstalled. |
| void MaybeUninstallWebApp(const webapps::AppId& web_app_id); |
| |
| // Uninstalls the ARC package with the given `package_name`. Does nothing if |
| // ARC is not started. |
| void MaybeUninstallArcPackage(const std::string& package_name); |
| |
| // If the app has updated from a web app to Android app or vice-versa, |
| // this function pins the new app in the old app's place on the shelf if it |
| // was pinned prior to the update. |
| void UpdateShelfPin(const std::string& package_name, |
| const arc::mojom::WebAppInfoPtr& web_app_info); |
| |
| // KeyedService: |
| void Shutdown() override; |
| |
| // ArcAppListPrefs::Observer: |
| void OnPackageInstalled( |
| const arc::mojom::ArcPackageInfo& package_info) override; |
| void OnPackageRemoved(const std::string& package_name, |
| bool uninstalled) override; |
| void OnPackageListInitialRefreshed() override; |
| void OnArcAppListPrefsDestroyed() override; |
| |
| // apps::AppRegistryCache::Observer overrides: |
| void OnAppUpdate(const apps::AppUpdate& update) override; |
| void OnAppTypeInitialized(apps::AppType app_type) override; |
| void OnAppRegistryCacheWillBeDestroyed( |
| apps::AppRegistryCache* cache) override; |
| |
| void MaybeRemoveArcPackageForWebApp(const webapps::AppId& web_app_id); |
| void OnDidGetWebAppIcon(const std::string& package_name, |
| arc::mojom::WebAppInfoPtr web_app_info, |
| arc::mojom::RawIconPngDataPtr icon); |
| void OnDidFinishInstall(const std::string& package_name, |
| const webapps::AppId& web_app_id, |
| bool is_web_only_twa, |
| const std::optional<std::string> sha256_fingerprint, |
| webapps::InstallResultCode code); |
| void OnDidRemoveInstallSource(const webapps::AppId& app_id, |
| webapps::UninstallResultCode code); |
| void UpdatePackageInfo(const std::string& app_id, |
| const arc::mojom::WebAppInfoPtr& web_app_info); |
| const base::Value::Dict& WebAppToApks() const; |
| void SyncArcAndWebApps(); |
| |
| void RemoveObsoletePrefValues(const webapps::AppId& web_app_id); |
| |
| // Remove the app ID from the map of currently installing APKs. |
| void RemoveInstallingWebApkPackageName(const std::string& app_id); |
| |
| WebAppCallbackForTesting web_app_installed_callback_; |
| WebAppCallbackForTesting web_app_uninstalled_callback_; |
| |
| raw_ptr<Profile> profile_; |
| raw_ptr<ArcAppListPrefs, DanglingUntriaged> arc_app_list_prefs_; |
| |
| // Delegate implementation used in production. |
| std::unique_ptr<Delegate> real_delegate_; |
| // And override delegate implementation for tests. See |GetDelegate()|. |
| raw_ptr<Delegate> test_delegate_; |
| |
| // True when ARC is fully initialized, after ArcAppLauncher has sent the |
| // initial package list. |
| bool arc_initialized_ = false; |
| |
| // Maps the app IDs of any currently installing web app apks to their ARC |
| // package names. This allows us to track the web app apks that are currently |
| // installing. |
| std::map<std::string, std::string> currently_installing_apks_; |
| |
| base::ScopedObservation<apps::AppRegistryCache, |
| apps::AppRegistryCache::Observer> |
| app_registry_cache_observer_{this}; |
| |
| base::ScopedObservation<ArcAppListPrefs, ArcAppListPrefs::Observer> |
| arc_app_list_prefs_observer_{this}; |
| |
| // Must go last. |
| base::WeakPtrFactory<ApkWebAppService> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace ash |
| |
| #endif // CHROME_BROWSER_ASH_APPS_APK_WEB_APP_SERVICE_H_ |