blob: b182fac07452afe2b2b62805569f76ea3773ced5 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "components/arc/arc_service.h"
#include "components/arc/common/intent_helper.mojom.h"
#include "ui/base/layout.h"
#include "ui/gfx/image/image.h"
#include "url/gurl.h"
namespace arc {
namespace internal {
// A class which retrieves an activity icon from ARC.
class ActivityIconLoader {
struct Icons {
Icons(const gfx::Image& icon16, const gfx::Image& icon20,
const scoped_refptr<base::RefCountedData<GURL>>& icon16_dataurl);
Icons(const Icons& other);
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);
bool operator<(const ActivityName& other) const;
// TODO(yusukes): Add const to these variables later. At this point,
// doing so seems to confuse g++ 4.6 on builders.
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. The callback has already been called synchronously.
// Failed. The intent_helper instance is not yet ready. This is a temporary
// error.
// Failed. Either ARC is not supported at all or intent_helper instance
// version is too old.
using ActivityToIconsMap = std::map<ActivityName, Icons>;
using OnIconsReadyCallback =
// 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,
const OnIconsReadyCallback& cb);
void OnIconsResizedForTesting(const OnIconsReadyCallback& cb,
std::unique_ptr<ActivityToIconsMap> result);
void AddCacheEntryForTesting(const ActivityName& activity);
// 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_; }
// A function called when the mojo IPC returns.
void OnIconsReady(std::unique_ptr<ActivityToIconsMap> cached_result,
const OnIconsReadyCallback& cb,
std::vector<mojom::ActivityIconPtr> icons);
// A function called when ResizeIcons finishes. Append items in |result| to
// |cached_icons_|.
void OnIconsResized(std::unique_ptr<ActivityToIconsMap> cached_result,
const OnIconsReadyCallback& cb,
std::unique_ptr<ActivityToIconsMap> result);
// The maximum scale factor the current platform supports.
const ui::ScaleFactor scale_factor_;
// A map which holds icons in a scale-factor independent form (gfx::Image).
ActivityToIconsMap cached_icons_;
base::ThreadChecker thread_checker_;
// This must come last to make sure weak pointers are invalidated first.
base::WeakPtrFactory<ActivityIconLoader> weak_ptr_factory_;
} // namespace internal
} // namespace arc