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
|
// 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_
|