| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_ARC_COMMON_INTENT_HELPER_ACTIVITY_ICON_LOADER_H_ |
| #define COMPONENTS_ARC_COMMON_INTENT_HELPER_ACTIVITY_ICON_LOADER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/threading/thread_checker.h" |
| #include "build/chromeos_buildflags.h" |
| #include "ui/base/layout.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "url/gurl.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| #include "ash/components/arc/mojom/intent_helper.mojom.h" |
| #elif BUILDFLAG(IS_CHROMEOS_LACROS) |
| #include "chromeos/crosapi/mojom/arc.mojom.h" // nogncheck |
| #else |
| #error "ARC files should only be included for Ash-chrome or Lacros-chrome." |
| #endif |
| |
| namespace arc { |
| |
| class AdaptiveIconDelegate; |
| |
| namespace internal { |
| |
| // A class which retrieves an activity icon from ARC. |
| class ActivityIconLoader { |
| public: |
| struct Icons { |
| Icons(const gfx::Image& icon16, |
| const gfx::Image& icon20, |
| const scoped_refptr<base::RefCountedData<GURL>>& icon16_dataurl); |
| Icons(const Icons& other); |
| ~Icons(); |
| |
| const gfx::Image icon16; // 16 dip |
| const gfx::Image icon20; // 20 dip |
| const scoped_refptr<base::RefCountedData<GURL>> icon16_dataurl; // as URL |
| }; |
| |
| struct ActivityName { |
| ActivityName(const std::string& package_name, |
| const std::string& activity_name); |
| ~ActivityName(); |
| bool operator<(const ActivityName& other) const; |
| |
| std::string package_name; |
| // Can be empty. When |activity_name| is empty, the loader tries to fetch |
| // the package's default icon. |
| std::string activity_name; |
| }; |
| |
| enum class GetResult { |
| // Succeeded. The callback will be called asynchronously. |
| SUCCEEDED_ASYNC, |
| // Succeeded. The callback has already been called synchronously. |
| SUCCEEDED_SYNC, |
| // Failed. The intent_helper instance is not yet ready. This is a temporary |
| // error. |
| FAILED_ARC_NOT_READY, |
| // Failed. Either ARC is not supported at all or intent_helper instance |
| // version is too old. |
| FAILED_ARC_NOT_SUPPORTED, |
| }; |
| |
| // Ash uses arc::mojom interface while Lacros uses crosapi::mojom. |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| using ActivityIconPtr = mojom::ActivityIconPtr; |
| using ActivityNamePtr = mojom::ActivityNamePtr; |
| using ScaleFactor = mojom::ScaleFactor; |
| #else // BUILDFLAG(IS_CHROMEOS_LACROS) |
| using ActivityIconPtr = crosapi::mojom::ActivityIconPtr; |
| using ActivityNamePtr = crosapi::mojom::ActivityNamePtr; |
| using ScaleFactor = crosapi::mojom::ScaleFactor; |
| #endif |
| |
| using ActivityToIconsMap = std::map<ActivityName, Icons>; |
| using OnIconsReadyCallback = |
| base::OnceCallback<void(std::unique_ptr<ActivityToIconsMap>)>; |
| |
| ActivityIconLoader(); |
| ActivityIconLoader(const ActivityIconLoader&) = delete; |
| ActivityIconLoader& operator=(const ActivityIconLoader&) = delete; |
| ~ActivityIconLoader(); |
| |
| void SetAdaptiveIconDelegate(AdaptiveIconDelegate* delegate); |
| |
| // Removes icons associated with |package_name| from the cache. |
| void InvalidateIcons(const std::string& package_name); |
| |
| // Retrieves icons for the |activities| and calls |cb|. The |cb| is called |
| // back exactly once, either synchronously in the GetActivityIcons() when |
| // the result is _not_ SUCCEEDED_ASYNC (i.e. all icons are already cached |
| // locally or ARC is not ready/supported). Otherwise, the callback is run |
| // later asynchronously with icons fetched from ARC side. |
| GetResult GetActivityIcons(const std::vector<ActivityName>& activities, |
| OnIconsReadyCallback cb); |
| |
| void OnIconsResizedForTesting(OnIconsReadyCallback cb, |
| std::unique_ptr<ActivityToIconsMap> result); |
| void AddCacheEntryForTesting(const ActivityName& activity); |
| |
| void OnIconsReadyForTesting(std::unique_ptr<ActivityToIconsMap> cached_result, |
| OnIconsReadyCallback cb, |
| std::vector<ActivityIconPtr> icons); |
| |
| // Returns true if |result| indicates that the |cb| object passed to |
| // GetActivityIcons() has already called. |
| static bool HasIconsReadyCallbackRun(GetResult result); |
| |
| const ActivityToIconsMap& cached_icons_for_testing() { return cached_icons_; } |
| |
| private: |
| // A function called when the mojo IPC returns. |
| void OnIconsReady(std::unique_ptr<ActivityToIconsMap> cached_result, |
| OnIconsReadyCallback cb, |
| std::vector<ActivityIconPtr> icons); |
| |
| // A function called when the adaptive icons are generated. |
| void OnAdaptiveIconGenerated( |
| std::vector<ActivityName> actvity_names, |
| std::unique_ptr<ActivityToIconsMap> cached_result, |
| OnIconsReadyCallback cb, |
| const std::vector<gfx::ImageSkia>& adaptive_icons); |
| |
| // A function called when ResizeIcons finishes. Append items in |result| to |
| // |cached_icons_|. |
| void OnIconsResized(std::unique_ptr<ActivityToIconsMap> cached_result, |
| OnIconsReadyCallback cb, |
| std::unique_ptr<ActivityToIconsMap> result); |
| |
| // The maximum scale factor the current platform supports. |
| const ui::ResourceScaleFactor scale_factor_; |
| // A map which holds icons in a scale-factor independent form (gfx::Image). |
| ActivityToIconsMap cached_icons_; |
| |
| // A delegate which converts the icon to the adaptive icon. |
| raw_ptr<AdaptiveIconDelegate> delegate_ = nullptr; |
| |
| THREAD_CHECKER(thread_checker_); |
| |
| // This must come last to make sure weak pointers are invalidated first. |
| base::WeakPtrFactory<ActivityIconLoader> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace internal |
| } // namespace arc |
| |
| #endif // COMPONENTS_ARC_COMMON_INTENT_HELPER_ACTIVITY_ICON_LOADER_H_ |