chromium/chrome/browser/apps/app_service/publishers/arc_apps.h

// 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_APPS_APP_SERVICE_PUBLISHERS_ARC_APPS_H_
#define CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_ARC_APPS_H_

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "ash/components/arc/mojom/app_permissions.mojom.h"
#include "ash/components/arc/mojom/intent_helper.mojom-forward.h"
#include "ash/components/arc/mojom/privacy_items.mojom.h"
#include "ash/public/cpp/message_center/arc_notification_manager_base.h"
#include "ash/public/cpp/message_center/arc_notifications_host_initializer.h"
#include "base/containers/flat_set.h"
#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/apps/app_service/app_icon/app_icon_factory.h"
#include "chrome/browser/apps/app_service/app_icon/arc_activity_adaptive_icon_impl.h"
#include "chrome/browser/apps/app_service/app_notifications.h"
#include "chrome/browser/apps/app_service/app_service_proxy_forward.h"
#include "chrome/browser/apps/app_service/app_shortcut_item.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/publishers/app_publisher.h"
#include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h"
#include "chrome/browser/ash/arc/app_shortcuts/arc_app_shortcuts_request.h"
#include "chrome/browser/ash/arc/privacy_items/arc_privacy_items_bridge.h"
#include "components/arc/intent_helper/arc_intent_helper_bridge.h"
#include "components/arc/intent_helper/arc_intent_helper_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/cpp/instance_registry.h"
#include "components/services/app_service/public/cpp/intent.h"
#include "components/services/app_service/public/cpp/menu.h"
#include "components/services/app_service/public/cpp/permission.h"

class Profile;

namespace apps {

class PublisherTest;
class WebApkManager;
struct AppLaunchParams;

// An app publisher (in the App Service sense) of ARC++ apps,
//
// See components/services/app_service/README.md.
class ArcApps : public KeyedService,
                public AppPublisher,
                public ArcAppListPrefs::Observer,
                public arc::ArcIntentHelperObserver,
                public ash::ArcNotificationManagerBase::Observer,
                public ash::ArcNotificationsHostInitializer::Observer,
                public apps::InstanceRegistry::Observer,
                public arc::ArcPrivacyItemsBridge::Observer {
 public:
  static ArcApps* Get(Profile* profile);

  explicit ArcApps(AppServiceProxy* proxy);
  ArcApps(const ArcApps&) = delete;
  ArcApps& operator=(const ArcApps&) = delete;

  ~ArcApps() override;

  WebApkManager* GetWebApkManagerForTesting() { return web_apk_manager_.get(); }

  static void SetArcVersionForTesting(int version);

 private:
  friend class ArcAppsFactory;
  friend class PublisherTest;
  FRIEND_TEST_ALL_PREFIXES(PublisherTest, ArcAppsOnApps);
  FRIEND_TEST_ALL_PREFIXES(PublisherTest, ArcApps_CapabilityAccess);

  using AppIdToTaskIds = std::map<std::string, std::set<int>>;
  using TaskIdToAppId = std::map<int, std::string>;

  void Initialize();

  // KeyedService overrides.
  void Shutdown() override;

  // apps::AppPublisher overrides.
  void GetCompressedIconData(const std::string& app_id,
                             int32_t size_in_dip,
                             ui::ResourceScaleFactor scale_factor,
                             LoadIconCallback callback) override;
  void Launch(const std::string& app_id,
              int32_t event_flags,
              LaunchSource launch_source,
              WindowInfoPtr window_info) override;
  void LaunchAppWithIntent(const std::string& app_id,
                           int32_t event_flags,
                           IntentPtr intent,
                           LaunchSource launch_source,
                           WindowInfoPtr window_info,
                           LaunchCallback callback) override;
  void LaunchAppWithParams(AppLaunchParams&& params,
                           LaunchCallback callback) override;
  void LaunchShortcut(const std::string& app_id,
                      const std::string& shortcut_id,
                      int64_t display_id) override;
  void SetPermission(const std::string& app_id,
                     PermissionPtr permission) override;
  void Uninstall(const std::string& app_id,
                 UninstallSource uninstall_source,
                 bool clear_site_data,
                 bool report_abuse) override;
  void GetMenuModel(const std::string& app_id,
                    MenuType menu_type,
                    int64_t display_id,
                    base::OnceCallback<void(MenuItems)> callback) override;
  void SetResizeLocked(const std::string& app_id, bool locked) override;
  void SetAppLocale(const std::string& app_id,
                    const std::string& locale_tag) override;

  void PauseApp(const std::string& app_id) override;
  void UnpauseApp(const std::string& app_id) override;
  void BlockApp(const std::string& app_id) override;
  void UnblockApp(const std::string& app_id) override;
  void StopApp(const std::string& app_id) override;
  void UpdateAppSize(const std::string& app_id) override;
  void ExecuteContextMenuCommand(const std::string& app_id,
                                 int command_id,
                                 const std::string& shortcut_id,
                                 int64_t display_id) override;
  void OpenNativeSettings(const std::string& app_id) override;
  void OnSupportedLinksPreferenceChanged(const std::string& app_id,
                                         bool open_in_app) override;

  // ArcAppListPrefs::Observer overrides.
  void OnAppRegistered(const std::string& app_id,
                       const ArcAppListPrefs::AppInfo& app_info) override;
  void OnAppStatesChanged(const std::string& app_id,
                          const ArcAppListPrefs::AppInfo& app_info) override;
  void OnAppRemoved(const std::string& app_id) override;
  void OnAppNameUpdated(const std::string& app_id,
                        const std::string& name) override;
  void OnAppLastLaunchTimeUpdated(const std::string& app_id) override;
  void OnPackageInstalled(
      const arc::mojom::ArcPackageInfo& package_info) override;
  void OnPackageModified(
      const arc::mojom::ArcPackageInfo& package_info) override;
  void OnPackageListInitialRefreshed() override;
  void OnTaskCreated(int32_t task_id,
                     const std::string& package_name,
                     const std::string& activity,
                     const std::string& intent,
                     int32_t session_id) override;
  void OnTaskDestroyed(int32_t task_id) override;
  void OnInstallationStarted(const std::string& package_name) override;
  void OnInstallationProgressChanged(const std::string& package_name,
                                     float progress) override;
  void OnInstallationActiveChanged(const std::string& package_name,
                                   bool active) override;
  void OnInstallationFinished(const std::string& package_name,
                              bool success,
                              bool is_launchable_app) override;
  void OnAppConnectionClosed() override;

  // arc::ArcIntentHelperObserver overrides.
  void OnIntentFiltersUpdated(
      const std::optional<std::string>& package_name) override;
  void OnArcSupportedLinksChanged(
      const std::vector<arc::mojom::SupportedLinksPackagePtr>& added,
      const std::vector<arc::mojom::SupportedLinksPackagePtr>& removed,
      arc::mojom::SupportedLinkChangeSource source) override;

  // ash::ArcNotificationsHostInitializer::Observer overrides.
  void OnSetArcNotificationsInstance(
      ash::ArcNotificationManagerBase* arc_notification_manager) override;
  void OnArcNotificationInitializerDestroyed(
      ash::ArcNotificationsHostInitializer* initializer) override;

  // ArcNotificationManagerBase::Observer overrides.
  void OnNotificationUpdated(const std::string& notification_id,
                             const std::string& app_id) override;
  void OnNotificationRemoved(const std::string& notification_id) override;
  void OnArcNotificationManagerDestroyed(
      ash::ArcNotificationManagerBase* notification_manager) override;

  // ArcPrivacyItemsBridgeObserver overrides.
  void OnPrivacyItemsChanged(
      const std::vector<arc::mojom::PrivacyItemPtr>& privacy_items) override;

  // apps::InstanceRegistry::Observer overrides.
  void OnInstanceUpdate(const apps::InstanceUpdate& update) override;
  void OnInstanceRegistryWillBeDestroyed(
      apps::InstanceRegistry* instance_registry) override;

  // Creates the App struct for `app_id` based on `app_info`. If `update_icon`
  // is true, creates a new icon key. If `raw_icon_updated` is true, sets
  // `raw_icon_updated` in the icon key as true, to remove the icon files in the
  // icon directory to get the new icon files when loading icons.
  AppPtr CreateApp(ArcAppListPrefs* prefs,
                   const std::string& app_id,
                   const ArcAppListPrefs::AppInfo& app_info,
                   bool update_icon = true,
                   bool raw_icon_updated = false);
  void ConvertAndPublishPackageApps(
      const arc::mojom::ArcPackageInfo& package_info,
      bool update_icon = true);
  IconEffects GetIconEffects(const std::string& app_id,
                             const ArcAppListPrefs::AppInfo& app_info);
  void SetIconEffect(const std::string& app_id);
  void CloseTasks(const std::string& app_id);

  void BuildMenuForShortcut(const std::string& package_name,
                            MenuItems menu_items,
                            base::OnceCallback<void(MenuItems)> callback);

  // Bound by |arc_app_shortcuts_request_|'s OnGetAppShortcutItems method.
  void OnGetAppShortcutItems(
      MenuItems menu_items,
      base::OnceCallback<void(MenuItems)> callback,
      std::unique_ptr<apps::AppShortcutItems> app_shortcut_items);

  // Observes DisabledSystemFeaturesList policy.
  void ObserveDisabledSystemFeaturesPolicy();

  // Triggered when DisabledSystemFeaturesList policy changes.
  void OnDisableListPolicyChanged();

  // Returns true if the app is suspended.
  bool IsAppSuspended(const std::string& app_id,
                      const ArcAppListPrefs::AppInfo& app_info);

  // Calculates the readiness state. Use this function for installed apps to be
  // consistent.
  Readiness GetReadiness(const std::string& app_id,
                         const ArcAppListPrefs::AppInfo& app_info);

  const raw_ptr<Profile> profile_;
  ArcActivityAdaptiveIconImpl arc_activity_adaptive_icon_impl_;

  PausedApps paused_apps_;

  AppIdToTaskIds app_id_to_task_ids_;
  TaskIdToAppId task_id_to_app_id_;

  // App id set which might be accessing camera or microphone.
  base::flat_set<std::string> accessing_apps_;

  // Handles requesting app shortcuts from Android.
  std::unique_ptr<arc::ArcAppShortcutsRequest> arc_app_shortcuts_request_;

  std::unique_ptr<apps::WebApkManager> web_apk_manager_;

  base::ScopedObservation<arc::ArcIntentHelperBridge,
                          arc::ArcIntentHelperObserver>
      arc_intent_helper_observation_{this};

  base::ScopedObservation<ash::ArcNotificationsHostInitializer,
                          ash::ArcNotificationsHostInitializer::Observer>
      notification_initializer_observation_{this};

  base::ScopedObservation<ash::ArcNotificationManagerBase,
                          ash::ArcNotificationManagerBase::Observer>
      notification_observation_{this};

  AppNotifications app_notifications_;

  base::ScopedObservation<arc::ArcPrivacyItemsBridge,
                          arc::ArcPrivacyItemsBridge::Observer>
      arc_privacy_items_bridge_observation_{this};

  base::ScopedObservation<apps::InstanceRegistry,
                          apps::InstanceRegistry::Observer>
      instance_registry_observation_{this};

  bool settings_app_is_active_ = false;

  bool settings_app_is_disabled_ = false;

  PrefChangeRegistrar local_state_pref_change_registrar_;

  std::set<std::string> blocked_app_ids_;

  base::WeakPtrFactory<ArcApps> weak_ptr_factory_{this};
};

}  // namespace apps

#endif  // CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_ARC_APPS_H_