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 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
|
// Copyright 2021 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_APPS_APP_SERVICE_APP_SERVICE_PROXY_ASH_H_
#define CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_ASH_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/one_shot_event.h"
#include "base/scoped_observation.h"
#include "chrome/browser/apps/app_service/app_icon/app_icon_reader.h"
#include "chrome/browser/apps/app_service/app_icon/app_icon_writer.h"
#include "chrome/browser/apps/app_service/app_service_proxy_base.h"
#include "chrome/browser/apps/app_service/launch_result_type.h"
#include "chrome/browser/apps/app_service/paused_apps.h"
#include "chrome/browser/apps/app_service/publisher_host.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/cpp/icon_types.h"
#include "components/services/app_service/public/cpp/instance_registry.h"
#include "components/services/app_service/public/cpp/package_id.h"
#include "components/services/app_service/public/cpp/preferred_app.h"
#include "ui/gfx/native_widget_types.h"
// Avoid including this header file directly or referring directly to
// AppServiceProxyAsh as a type. Instead:
// - for forward declarations, use app_service_proxy_forward.h
// - for the full header, use app_service_proxy.h, which aliases correctly
// based on the platform
class Profile;
namespace gfx {
class ImageSkia;
} // namespace gfx
namespace apps {
class AppInstallService;
class AppPlatformMetrics;
class AppPlatformMetricsService;
class InstanceRegistryUpdater;
class BrowserAppInstanceRegistry;
class BrowserAppInstanceTracker;
class PackageId;
class PromiseAppRegistryCache;
class PromiseAppService;
class UninstallDialog;
struct PromiseApp;
using PromiseAppPtr = std::unique_ptr<PromiseApp>;
struct PauseData {
int hours = 0;
int minutes = 0;
bool should_show_pause_dialog = false;
};
// Singleton (per Profile) proxy and cache of an App Service's apps on Chrome
// OS.
//
// See components/services/app_service/README.md.
class AppServiceProxyAsh : public AppServiceProxyBase,
public apps::AppRegistryCache::Observer,
public apps::InstanceRegistry::Observer {
public:
using OnPauseDialogClosedCallback = base::OnceCallback<void()>;
using OnUninstallForTestingCallback = base::OnceCallback<void(bool)>;
explicit AppServiceProxyAsh(Profile* profile);
AppServiceProxyAsh(const AppServiceProxyAsh&) = delete;
AppServiceProxyAsh& operator=(const AppServiceProxyAsh&) = delete;
~AppServiceProxyAsh() override;
apps::InstanceRegistry& InstanceRegistry();
apps::AppPlatformMetrics* AppPlatformMetrics();
apps::AppPlatformMetricsService* AppPlatformMetricsService();
// TODO(373972275): Remove BrowserAppInstanceTracker,
// BrowserAppInstanceRegistry and InstanceRegistryUpdater.
apps::BrowserAppInstanceTracker* BrowserAppInstanceTracker();
apps::BrowserAppInstanceRegistry* BrowserAppInstanceRegistry();
// Sets the publisher for `app_type` is unavailable, to allow
// AppService to remove apps for `app_type`, and clean up launch requests,
// etc. This is used when the app platform is unavailable, e.g. GuestOS
// disabled, ARC disabled, etc.
//
// All apps for `app_type` will be deleted from AppRegistryCache. So this
// function should not be called for the normal shutdown process.
void SetPublisherUnavailable(AppType app_type);
apps::AppInstallService& AppInstallService();
// apps::AppServiceProxyBase overrides:
void OnApps(std::vector<AppPtr> deltas,
AppType app_type,
bool should_notify_initialized) override;
// Uninstalls an app for the given |app_id|. If |parent_window| is specified,
// the uninstall dialog will be created as a modal dialog anchored at
// |parent_window|. Otherwise, the browser window will be used as the anchor.
void Uninstall(const std::string& app_id,
UninstallSource uninstall_source,
gfx::NativeWindow parent_window);
// Pauses apps. |pause_data|'s key is the app_id. |pause_data|'s PauseData
// is the time limit setting for the app, which is shown in the pause app
// dialog. AppService sets the paused status directly. If the app is running,
// AppService shows the pause app dialog. Otherwise, AppService applies the
// paused app icon effect directly.
void PauseApps(const std::map<std::string, PauseData>& pause_data);
// Unpauses the apps from the paused status. AppService sets the paused status
// as false directly and removes the paused app icon effect.
void UnpauseApps(const std::set<std::string>& app_ids);
// Mark apps as blocked by local settings. Show local block dialog if
// `show_block_dialog` is true.
void BlockApps(const std::set<std::string>& app_ids,
bool show_block_dialog = false);
// Remove the local settings block adedd by `BlockApps`.
void UnblockApps(const std::set<std::string>& app_ids);
// Set whether resize lock is enabled for the app identified by |app_id|.
void SetResizeLocked(const std::string& app_id, bool locked);
// Inform |publisher_host_| that ARC is active.
void SetArcIsRegistered();
// apps::AppServiceProxyBase overrides:
void LaunchAppWithIntent(const std::string& app_id,
int32_t event_flags,
IntentPtr intent,
LaunchSource launch_source,
WindowInfoPtr window_info,
LaunchCallback callback) override;
base::WeakPtr<AppServiceProxyAsh> GetWeakPtr();
void ReInitializeCrostiniForTesting();
void SetDialogCreatedCallbackForTesting(base::OnceClosure callback);
void UninstallForTesting(const std::string& app_id,
gfx::NativeWindow parent_window,
OnUninstallForTestingCallback callback);
void SetAppPlatformMetricsServiceForTesting(
std::unique_ptr<apps::AppPlatformMetricsService>
app_platform_metrics_service);
void RegisterPublishersForTesting();
void ReadIconsForTesting(AppType app_type,
const std::string& app_id,
int32_t size_in_dip,
const IconKey& icon_key,
IconType icon_type,
LoadIconCallback callback);
// Get pointer to the Promise App Registry Cache which holds all promise
// apps. May return a nullptr.
apps::PromiseAppRegistryCache* PromiseAppRegistryCache();
// Get pointer to the Promise App Service which manages all promise apps.
// May return a nullptr.
apps::PromiseAppService* PromiseAppService();
// Add or update a promise app in the Promise App Registry Cache.
void OnPromiseApp(PromiseAppPtr delta);
// Retrieves the icon for a promise app and applies any specified effects.
void LoadPromiseIcon(const PackageId& package_id,
int32_t size_hint_in_dip,
IconEffects icon_effects,
apps::LoadIconCallback callback);
// Load the default icon for a particular app platform. E.g. load a default
// icon for guest os app that is not registered in app service.
void LoadDefaultIcon(AppType app_type,
int32_t size_in_dip,
IconEffects icon_effects,
IconType icon_type,
LoadIconCallback callback);
// Sets app locale for an app with the given `app_id`. Empty |locale_tag|
// indicates system language being chosen.
void SetAppLocale(const std::string& app_id, const std::string& locale_tag);
private:
// OnAppsRequest is used to save the parameters of the OnApps calling.
struct OnAppsRequest {
OnAppsRequest(std::vector<AppPtr> deltas,
AppType app_type,
bool should_notify_initialized);
OnAppsRequest(const OnAppsRequest&) = delete;
OnAppsRequest& operator=(const OnAppsRequest&) = delete;
~OnAppsRequest();
std::vector<AppPtr> deltas_;
AppType app_type_;
bool should_notify_initialized_;
};
// For access to Initialize.
friend class AppServiceProxyFactory;
friend class AppServiceProxyTest;
FRIEND_TEST_ALL_PREFIXES(AppServiceProxyTest, LaunchCallback);
using UninstallDialogs =
base::flat_map<std::string, std::unique_ptr<apps::UninstallDialog>>;
bool IsValidProfile() override;
void Initialize() override;
// KeyedService overrides.
void Shutdown() override;
static void CreateBlockDialog(const std::string& app_name,
const gfx::ImageSkia& image,
Profile* profile);
static void CreateLocalBlockDialog(const std::string& app_name);
static void CreatePauseDialog(apps::AppType app_type,
const std::string& app_name,
const gfx::ImageSkia& image,
const PauseData& pause_data,
OnPauseDialogClosedCallback pause_callback);
void UninstallImpl(const std::string& app_id,
UninstallSource uninstall_source,
gfx::NativeWindow parent_window,
OnUninstallForTestingCallback callback);
// Invoked when the uninstall dialog is closed. The app for the given
// |app_type| and |app_id| will be uninstalled directly if |uninstall| is
// true. |clear_site_data| is available for bookmark apps only. If true, any
// site data associated with the app will be removed. |report_abuse| is
// available for Chrome Apps only. If true, the app will be reported for abuse
// to the Web Store. |uninstall_dialog| will be removed from
// |uninstall_dialogs_|.
void OnUninstallDialogClosed(apps::AppType app_type,
const std::string& app_id,
UninstallSource uninstall_source,
bool uninstall,
bool clear_site_data,
bool report_abuse,
UninstallDialog* uninstall_dialog);
// apps::AppServiceProxyBase overrides:
bool MaybeShowLaunchPreventionDialog(const apps::AppUpdate& update) override;
void OnLaunched(LaunchCallback callback,
LaunchResult&& launch_result) override;
// Loads the icon for the app block dialog or the app pause dialog.
void LoadIconForDialog(const apps::AppUpdate& update,
apps::LoadIconCallback callback);
// Callback invoked when the icon is loaded for the block app dialog.
void OnLoadIconForBlockDialog(const std::string& app_name,
IconValuePtr icon_value);
// Callback invoked when the icon is loaded for the pause app dialog.
void OnLoadIconForPauseDialog(apps::AppType app_type,
const std::string& app_id,
const std::string& app_name,
const PauseData& pause_data,
IconValuePtr icon_value);
// Invoked when the user clicks the 'OK' button of the pause app dialog.
// AppService stops the running app and applies the paused app icon effect.
void OnPauseDialogClosed(apps::AppType app_type, const std::string& app_id);
bool ShouldExcludeBrowserTabApps(bool exclude_browser_tab_apps,
WindowMode window_mode) override;
// apps::AppRegistryCache::Observer overrides:
void OnAppUpdate(const apps::AppUpdate& update) override;
void OnAppRegistryCacheWillBeDestroyed(
apps::AppRegistryCache* cache) override;
void PerformPostLaunchTasks(apps::LaunchSource launch_source) override;
void RecordAppPlatformMetrics(Profile* profile,
const apps::AppUpdate& update,
apps::LaunchSource launch_source,
apps::LaunchContainer container) override;
void InitAppPlatformMetrics();
void PerformPostUninstallTasks(apps::AppType app_type,
const std::string& app_id,
UninstallSource uninstall_source) override;
// apps::InstanceRegistry::Observer overrides.
void OnInstanceUpdate(const apps::InstanceUpdate& update) override;
void OnInstanceRegistryWillBeDestroyed(
apps::InstanceRegistry* cache) override;
// Checks if all instance IDs correspond to existing windows.
bool CanRunLaunchCallback(
const std::vector<base::UnguessableToken>& instance_ids);
// Launches the app if `is_allowed` is set true.
void LaunchAppWithIntentIfAllowed(const std::string& app_id,
int32_t event_flags,
IntentPtr intent,
LaunchSource launch_source,
WindowInfoPtr window_info,
LaunchCallback callback,
bool is_allowed);
bool ShouldReadIcons(AppType app_type) override;
// Reads icon image files from the local app_service icon directory on disk.
void ReadIcons(AppType app_type,
const std::string& app_id,
int32_t size_in_dip,
std::unique_ptr<IconKey> icon_key,
IconType icon_type,
LoadIconCallback callback) override;
// Invoked after reading icon image files from the local disk. If failed
// reading the icon data, calls 'icon_writer' to fetch the icon data.
void OnIconRead(AppType app_type,
const std::string& app_id,
int32_t size_in_dip,
IconEffects icon_effects,
IconType icon_type,
LoadIconCallback callback,
IconValuePtr iv);
// Invoked after writing icon image files to the local disk.
void OnIconInstalled(AppType app_type,
const std::string& app_id,
int32_t size_in_dip,
IconEffects icon_effects,
IconType icon_type,
int default_icon_resource_id,
LoadIconCallback callback,
bool install_success);
// Invoked when the icon folders for `ids` has being deleted. The saved
// `ReadIcons` requests in `pending_read_icon_requests_` are run to request
// the new raw icon from the app platforms, then load icons for `ids`.
void PostIconFoldersDeletion(const std::vector<std::string>& ids);
// Returns an instance of `IntentLaunchInfo` created based on `intent`,
// `filter`, and `update`.
IntentLaunchInfo CreateIntentLaunchInfo(
const apps::IntentPtr& intent,
const apps::IntentFilterPtr& filter,
const apps::AppUpdate& update) override;
std::unique_ptr<PublisherHost> publisher_host_;
AppIconReader icon_reader_;
AppIconWriter icon_writer_;
bool arc_is_registered_ = false;
apps::InstanceRegistry instance_registry_;
std::unique_ptr<apps::PromiseAppService> promise_app_service_;
// When PauseApps is called, the app is added to |pending_pause_requests|.
// When the user clicks the OK from the pause app dialog, the pause status is
// updated in AppRegistryCache by the publisher, then the app is removed from
// |pending_pause_requests|. If the app status is paused in AppRegistryCache
// or pending_pause_requests, the app can't be launched.
PausedApps pending_pause_requests_;
UninstallDialogs uninstall_dialogs_;
// When the icon folder is being deleted, the `ReadIcons` request is added to
// `pending_read_icon_requests_` to wait for the deletion. When the icon
// folder has being deleted, the saved `ReadIcons` requests in
// `pending_read_icon_requests_` are run to get the new raw icon from the
// app platforms, then load icons.
std::map<std::string, std::vector<base::OnceCallback<void()>>>
pending_read_icon_requests_;
std::unique_ptr<apps::AppPlatformMetricsService>
app_platform_metrics_service_;
base::ScopedObservation<apps::InstanceRegistry,
apps::InstanceRegistry::Observer>
instance_registry_observer_{this};
base::ScopedObservation<apps::AppRegistryCache,
apps::AppRegistryCache::Observer>
app_registry_cache_observer_{this};
// A list to record outstanding launch callbacks. When the first member
// returns true, the second member should be run and the pair can be removed
// from the outstanding callback queue.
std::list<std::pair<base::RepeatingCallback<bool(void)>, base::OnceClosure>>
callback_list_;
std::unique_ptr<apps::AppInstallService> app_install_service_;
base::WeakPtrFactory<AppServiceProxyAsh> weak_ptr_factory_{this};
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_ASH_H_
|