blob: fc46ef7806a72f2641b340c311679f0ad4ede12b [file] [log] [blame]
[email protected]51208252013-08-19 21:05:301// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/android/shortcut_helper.h"
6
7#include <jni.h>
8
9#include "base/android/jni_android.h"
10#include "base/android/jni_string.h"
11#include "base/basictypes.h"
12#include "base/location.h"
13#include "base/strings/string16.h"
mlamouric679bbf2014-09-24 21:24:4914#include "base/strings/utf_string_conversions.h"
benwells840ae902015-02-17 21:13:2815#include "chrome/browser/banners/app_banner_settings_helper.h"
dfalcantaraaec56da2015-05-06 03:33:5616#include "content/public/browser/browser_thread.h"
[email protected]51208252013-08-19 21:05:3017#include "content/public/browser/web_contents.h"
mlamourib225ae562014-09-17 11:51:3718#include "content/public/common/manifest.h"
[email protected]51208252013-08-19 21:05:3019#include "jni/ShortcutHelper_jni.h"
20#include "ui/gfx/android/java_bitmap.h"
[email protected]51208252013-08-19 21:05:3021#include "ui/gfx/color_analysis.h"
22#include "url/gurl.h"
23
mlamouric679bbf2014-09-24 21:24:4924using content::Manifest;
25
yfriedman4846e392015-02-19 19:12:1026jlong Initialize(JNIEnv* env, jobject obj, jobject java_web_contents) {
27 content::WebContents* web_contents =
28 content::WebContents::FromJavaWebContents(java_web_contents);
29 ShortcutHelper* shortcut_helper = new ShortcutHelper(env, obj, web_contents);
mlamouriecb9b4082014-09-12 13:04:1530 return reinterpret_cast<intptr_t>(shortcut_helper);
31}
32
33ShortcutHelper::ShortcutHelper(JNIEnv* env,
34 jobject obj,
35 content::WebContents* web_contents)
dfalcantaraaec56da2015-05-06 03:33:5636 : add_shortcut_pending_(false),
37 data_fetcher_(new ShortcutDataFetcher(web_contents, this)) {
38 java_ref_.Reset(env, obj);
[email protected]51208252013-08-19 21:05:3039}
40
mlamouriecb9b4082014-09-12 13:04:1541ShortcutHelper::~ShortcutHelper() {
dfalcantaraaec56da2015-05-06 03:33:5642 data_fetcher_->set_weak_observer(nullptr);
43 data_fetcher_ = nullptr;
mlamouriecb9b4082014-09-12 13:04:1544}
45
dfalcantaraaec56da2015-05-06 03:33:5646void ShortcutHelper::OnTitleAvailable(const base::string16& title) {
mlamouriecb9b4082014-09-12 13:04:1547 JNIEnv* env = base::android::AttachCurrentThread();
mlamouriecb9b4082014-09-12 13:04:1548 ScopedJavaLocalRef<jstring> j_title =
dfalcantaraaec56da2015-05-06 03:33:5649 base::android::ConvertUTF16ToJavaString(env, title);
50 Java_ShortcutHelper_onTitleAvailable(env,
51 java_ref_.obj(),
52 j_title.obj());
mlamouriecb9b4082014-09-12 13:04:1553}
54
dfalcantaraaec56da2015-05-06 03:33:5655void ShortcutHelper::OnDataAvailable(const ShortcutInfo& info,
56 const SkBitmap& icon) {
57 JNIEnv* env = base::android::AttachCurrentThread();
58 ScopedJavaLocalRef<jobject> java_bitmap;
59 if (icon.getSize())
60 java_bitmap = gfx::ConvertToJavaBitmap(&icon);
mlamouric679bbf2014-09-24 21:24:4961
dfalcantaraaec56da2015-05-06 03:33:5662 Java_ShortcutHelper_onIconAvailable(env,
63 java_ref_.obj(),
64 java_bitmap.obj());
mlamouric679bbf2014-09-24 21:24:4965
dfalcantaraaec56da2015-05-06 03:33:5666 if (add_shortcut_pending_)
67 AddShortcut(info, icon);
mlamouric679bbf2014-09-24 21:24:4968}
69
dfalcantaraaec56da2015-05-06 03:33:5670void ShortcutHelper::Destroy(JNIEnv* env, jobject obj) {
mlamouriecb9b4082014-09-12 13:04:1571 delete this;
72}
73
dfalcantaraaec56da2015-05-06 03:33:5674SkBitmap ShortcutHelper::FinalizeLauncherIcon(const SkBitmap& bitmap,
75 const GURL& url) {
76 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
77
78 // Determine a single color to use for the favicon if the favicon that is
79 // returned it is too low quality.
80 SkColor color = color_utils::CalculateKMeanColorOfBitmap(bitmap);
81 int dominant_red = SkColorGetR(color);
82 int dominant_green = SkColorGetG(color);
83 int dominant_blue = SkColorGetB(color);
84
85 // Make the icon acceptable for the Android launcher.
86 JNIEnv* env = base::android::AttachCurrentThread();
87 ScopedJavaLocalRef<jstring> java_url =
88 base::android::ConvertUTF8ToJavaString(env, url.spec());
89 ScopedJavaLocalRef<jobject> java_bitmap;
90 if (bitmap.getSize())
91 java_bitmap = gfx::ConvertToJavaBitmap(&bitmap);
92
93 base::android::ScopedJavaLocalRef<jobject> ref =
94 Java_ShortcutHelper_finalizeLauncherIcon(env,
95 java_url.obj(),
96 java_bitmap.obj(),
97 dominant_red,
98 dominant_green,
99 dominant_blue);
100 return gfx::CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(ref.obj()));
101}
102
103void ShortcutHelper::AddShortcut(JNIEnv* env, jobject obj, jstring jtitle) {
104 add_shortcut_pending_ = true;
mlamouric679bbf2014-09-24 21:24:49105
mlamouriecb9b4082014-09-12 13:04:15106 base::string16 title = base::android::ConvertJavaStringToUTF16(env, jtitle);
107 if (!title.empty())
dfalcantaraaec56da2015-05-06 03:33:56108 data_fetcher_->shortcut_info().title = title;
mlamouriecb9b4082014-09-12 13:04:15109
dfalcantaraaec56da2015-05-06 03:33:56110 if (data_fetcher_->is_ready()) {
111 // If the fetcher isn't ready yet, the shortcut will be added when it is
112 // via OnDataAvailable();
113 AddShortcut(data_fetcher_->shortcut_info(), data_fetcher_->shortcut_icon());
mlamouric679bbf2014-09-24 21:24:49114 }
115}
116
dfalcantaraaec56da2015-05-06 03:33:56117void ShortcutHelper::AddShortcut(const ShortcutInfo& info,
118 const SkBitmap& icon) {
119 DCHECK(add_shortcut_pending_);
120 if (!add_shortcut_pending_)
121 return;
122 add_shortcut_pending_ = false;
123
dfalcantara307280152015-02-19 18:27:48124 RecordAddToHomescreen();
125
dfalcantaraaec56da2015-05-06 03:33:56126 content::BrowserThread::PostTask(
127 content::BrowserThread::IO,
mlamouric679bbf2014-09-24 21:24:49128 FROM_HERE,
129 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap,
dfalcantaraaec56da2015-05-06 03:33:56130 info,
131 icon));
[email protected]5820d32c2013-08-28 10:03:50132}
133
[email protected]51208252013-08-19 21:05:30134bool ShortcutHelper::RegisterShortcutHelper(JNIEnv* env) {
135 return RegisterNativesImpl(env);
136}
137
dfalcantaraaec56da2015-05-06 03:33:56138// static
mlamouric679bbf2014-09-24 21:24:49139void ShortcutHelper::AddShortcutInBackgroundWithSkBitmap(
dfalcantara16e84de2015-02-03 22:07:40140 const ShortcutInfo& info,
dfalcantaraaec56da2015-05-06 03:33:56141 const SkBitmap& icon_bitmap) {
142 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
[email protected]51208252013-08-19 21:05:30143
144 // Send the data to the Java side to create the shortcut.
145 JNIEnv* env = base::android::AttachCurrentThread();
146 ScopedJavaLocalRef<jstring> java_url =
dfalcantara16e84de2015-02-03 22:07:40147 base::android::ConvertUTF8ToJavaString(env, info.url.spec());
[email protected]51208252013-08-19 21:05:30148 ScopedJavaLocalRef<jstring> java_title =
dfalcantara16e84de2015-02-03 22:07:40149 base::android::ConvertUTF16ToJavaString(env, info.title);
[email protected]51208252013-08-19 21:05:30150 ScopedJavaLocalRef<jobject> java_bitmap;
mlamouric679bbf2014-09-24 21:24:49151 if (icon_bitmap.getSize())
152 java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap);
[email protected]51208252013-08-19 21:05:30153
mlamouri89ccc632014-09-16 19:29:58154 Java_ShortcutHelper_addShortcut(
155 env,
156 base::android::GetApplicationContext(),
157 java_url.obj(),
158 java_title.obj(),
159 java_bitmap.obj(),
dfalcantara16e84de2015-02-03 22:07:40160 info.display == content::Manifest::DISPLAY_MODE_STANDALONE,
dfalcantaraaec56da2015-05-06 03:33:56161 info.orientation);
[email protected]51208252013-08-19 21:05:30162}
benwells840ae902015-02-17 21:13:28163
164void ShortcutHelper::RecordAddToHomescreen() {
165 // Record that the shortcut has been added, so no banners will be shown
166 // for this app.
dfalcantaraaec56da2015-05-06 03:33:56167 content::WebContents* web_contents = data_fetcher_->web_contents();
168 if (!web_contents)
169 return;
170
benwells840ae902015-02-17 21:13:28171 AppBannerSettingsHelper::RecordBannerEvent(
dfalcantaraaec56da2015-05-06 03:33:56172 web_contents, web_contents->GetURL(),
173 data_fetcher_->shortcut_info().url.spec(),
benwells840ae902015-02-17 21:13:28174 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
175 base::Time::Now());
176}