blob: 615a5c6d0d982755100eca005c22613ff5a067a0 [file] [log] [blame]
// Copyright 2015 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 "chrome/browser/android/webapps/add_to_homescreen_manager.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/location.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/android/shortcut_helper.h"
#include "chrome/browser/android/webapk/webapk_install_service.h"
#include "chrome/browser/banners/app_banner_manager_android.h"
#include "chrome/browser/banners/app_banner_settings_helper.h"
#include "chrome/browser/installable/installable_manager.h"
#include "chrome/browser/installable/installable_metrics.h"
#include "components/url_formatter/elide_url.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "jni/AddToHomescreenManager_jni.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/modules/installation/installation.mojom.h"
#include "ui/gfx/android/java_bitmap.h"
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
namespace {
// The length of time to allow the add to homescreen data fetcher to run before
// timing out and generating an icon.
const int kDataTimeoutInMilliseconds = 8000;
} // namespace
jlong JNI_AddToHomescreenManager_InitializeAndStart(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jobject>& java_web_contents) {
content::WebContents* web_contents =
content::WebContents::FromJavaWebContents(java_web_contents);
AddToHomescreenManager* manager = new AddToHomescreenManager(env, obj);
manager->Start(web_contents);
return reinterpret_cast<intptr_t>(manager);
}
AddToHomescreenManager::AddToHomescreenManager(JNIEnv* env, jobject obj)
: is_webapk_compatible_(false) {
java_ref_.Reset(env, obj);
}
void AddToHomescreenManager::Destroy(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
delete this;
}
void AddToHomescreenManager::AddToHomescreen(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& j_user_title) {
content::WebContents* web_contents = data_fetcher_->web_contents();
if (!web_contents)
return;
RecordAddToHomescreen();
if (is_webapk_compatible_) {
WebApkInstallService::Get(web_contents->GetBrowserContext())
->InstallAsync(web_contents, data_fetcher_->shortcut_info(),
data_fetcher_->primary_icon(),
data_fetcher_->badge_icon(),
InstallableMetrics::GetInstallSource(
web_contents, InstallTrigger::MENU));
} else {
base::string16 user_title =
base::android::ConvertJavaStringToUTF16(env, j_user_title);
data_fetcher_->shortcut_info().user_title = user_title;
ShortcutHelper::AddToLauncherWithSkBitmap(
web_contents, data_fetcher_->shortcut_info(),
data_fetcher_->primary_icon(),
data_fetcher_->has_maskable_primary_icon());
}
// Fire the appinstalled event and do install time logging.
banners::AppBannerManagerAndroid* app_banner_manager =
banners::AppBannerManagerAndroid::FromWebContents(web_contents);
app_banner_manager->OnInstall(false /* is_native */,
data_fetcher_->shortcut_info().display);
}
void AddToHomescreenManager::Start(content::WebContents* web_contents) {
// Icon generation depends on having a valid visible URL.
DCHECK(web_contents->GetVisibleURL().is_valid());
JNIEnv* env = base::android::AttachCurrentThread();
Java_AddToHomescreenManager_showDialog(env, java_ref_);
data_fetcher_ = std::make_unique<AddToHomescreenDataFetcher>(
web_contents, kDataTimeoutInMilliseconds, this);
}
AddToHomescreenManager::~AddToHomescreenManager() {}
void AddToHomescreenManager::RecordAddToHomescreen() {
// Record that the shortcut has been added, so no banners will be shown
// for this app.
content::WebContents* web_contents = data_fetcher_->web_contents();
if (!web_contents)
return;
AppBannerSettingsHelper::RecordBannerEvent(
web_contents, web_contents->GetURL(),
data_fetcher_->shortcut_info().url.spec(),
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
base::Time::Now());
}
void AddToHomescreenManager::OnUserTitleAvailable(
const base::string16& user_title,
const GURL& url,
bool is_webapk_compatible) {
is_webapk_compatible_ = is_webapk_compatible;
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jstring> j_user_title =
base::android::ConvertUTF16ToJavaString(env, user_title);
// Trim down the app URL to the origin. Elide cryptographic schemes so HTTP
// is still shown.
ScopedJavaLocalRef<jstring> j_url = base::android::ConvertUTF16ToJavaString(
env, url_formatter::FormatUrlForSecurityDisplay(
url, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));
Java_AddToHomescreenManager_onUserTitleAvailable(
env, java_ref_, j_user_title, j_url,
is_webapk_compatible_ /* isWebapp */);
}
void AddToHomescreenManager::OnDataAvailable(const ShortcutInfo& info,
const SkBitmap& primary_icon,
const SkBitmap& badge_icon) {
ScopedJavaLocalRef<jobject> java_bitmap;
if (!primary_icon.drawsNothing())
java_bitmap = gfx::ConvertToJavaBitmap(&primary_icon);
JNIEnv* env = base::android::AttachCurrentThread();
Java_AddToHomescreenManager_onIconAvailable(
env, java_ref_, java_bitmap, data_fetcher_->has_maskable_primary_icon());
}