chromium/components/webapps/browser/installable/installable_icon_fetcher.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/webapps/browser/installable/installable_icon_fetcher.h"

#include "base/check_is_test.h"
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "build/android_buildflags.h"
#include "components/favicon/content/large_icon_service_getter.h"
#include "components/favicon/core/large_icon_service.h"
#include "components/favicon_base/favicon_types.h"
#include "components/webapps/browser/features.h"
#include "components/webapps/browser/installable/installable_evaluator.h"
#include "content/public/browser/manifest_icon_downloader.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/common/manifest/manifest_icon_selector.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_ANDROID)
#include "components/webapps/browser/android/webapps_icon_utils.h"
#endif

namespace webapps {

namespace {

// This constant is the smallest possible adaptive launcher icon size for any
// device density.
// The ideal icon size is 83dp (see documentation for
// R.dimen.webapk_adaptive_icon_size for discussion of maskable icon size). For
// a manifest to be valid, we do NOT need an maskable icon to be 83dp for the
// device's screen density. Instead, we only need the maskable icon be larger
// than (or equal to) 83dp in the smallest screen density (that is the mdpi
// screen density). For mdpi devices, 1dp is 1px. Therefore, we have 83px here.
// Requiring the minimum icon size (in pixel) independent of the device's screen
// density is because we use mipmap-anydpi-v26 to specify adaptive launcher
// icon, and it will make the icon adaptive as long as there is one usable
// maskable icon (if that icon is of wrong size, it'll be automatically
// resized).
const int kMinimumPrimaryAdaptiveLauncherIconSizeInPx =;

IconPurpose;

int GetIdealPrimaryIconSizeInPx(IconPurpose purpose) {}

int GetMinimumPrimaryIconSizeInPx(IconPurpose purpose) {}

// On Android, |LargeIconWorker::GetLargeIconRawBitmap| will try to find the
// largest icon that is also larger than the minimum size from database, and
// scale to the ideal size. However it doesn't work on desktop as Chrome stores
// icons scaled to 16x16 and 32x32 in the database. We need to find other way to
// fetch favicon on desktop.
int GetMinimumFaviconForPrimaryIconSizeInPx() {}

void ProcessFaviconInBackground(
    const favicon_base::FaviconRawBitmapResult& bitmap_result,
    scoped_refptr<base::SequencedTaskRunner> ui_thread_task_runner,
    base::OnceCallback<void(const SkBitmap&)> success_callback,
    base::OnceCallback<void(InstallableStatusCode)> failed_callback) {}

#if BUILDFLAG(IS_DESKTOP_ANDROID)
// Generates a homescreen icon for `page_url` and posts a task to invoke
// `callback` on `ui_thread_task_runner.`
void GenerateHomeScreenIconInBackground(
    const GURL& page_url,
    scoped_refptr<base::SequencedTaskRunner> ui_thread_task_runner,
    base::OnceCallback<void(const GURL& url, const SkBitmap&)> callback) {
  SkBitmap bitmap =
      WebappsIconUtils::GenerateHomeScreenIconInBackground(page_url);
  ui_thread_task_runner->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), page_url, bitmap));
}
#endif  // BUILDFLAG(IS_DESKTOP_ANDROID)

}  // namespace

namespace test {
int g_minimum_favicon_size_for_testing =;
}

InstallableIconFetcher::InstallableIconFetcher(
    content::WebContents* web_contents,
    InstallablePageData& data,
    const std::vector<blink::Manifest::ImageResource>& manifest_icons,
    bool prefer_maskable,
    bool fetch_favicon,
    base::OnceCallback<void(InstallableStatusCode)> finish_callback)
    :{}

InstallableIconFetcher::~InstallableIconFetcher() = default;

void InstallableIconFetcher::TryFetchingNextIcon() {}

void InstallableIconFetcher::OnManifestIconFetched(const GURL& icon_url,
                                                   const IconPurpose purpose,
                                                   const SkBitmap& bitmap) {}

void InstallableIconFetcher::FetchFavicon() {}

void InstallableIconFetcher::OnFaviconFetched(
    const favicon_base::LargeIconResult& result) {}

void InstallableIconFetcher::OnIconFetched(const GURL& icon_url,
                                           const IconPurpose purpose,
                                           const SkBitmap& bitmap) {}

void InstallableIconFetcher::MaybeEndWithError(InstallableStatusCode code) {}

void InstallableIconFetcher::EndWithError(InstallableStatusCode code) {}

#if BUILDFLAG(IS_DESKTOP_ANDROID)
void InstallableIconFetcher::OnHomeScreenIconGenerated(const GURL& page_url,
                                                       const SkBitmap& bitmap) {
  if (bitmap.drawsNothing()) {
    EndWithError(InstallableStatusCode::NO_ACCEPTABLE_ICON);
    return;
  }
  OnIconFetched(page_url, IconPurpose::ANY, bitmap);
}
#endif

}  // namespace webapps