1 // Copyright 2015 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.
5 #include "chrome/browser/android/webapps/add_to_homescreen_dialog_helper.h"
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/basictypes.h"
12 #include "base/guid.h"
13 #include "base/location.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/android/shortcut_helper.h"
17 #include "chrome/browser/banners/app_banner_settings_helper.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/manifest.h"
21 #include "jni/AddToHomescreenDialogHelper_jni.h"
22 #include "ui/gfx/android/java_bitmap.h"
23 #include "ui/gfx/color_analysis.h"
26 using content::Manifest
;
28 jlong
Initialize(JNIEnv
* env
,
29 const JavaParamRef
<jobject
>& obj
,
30 const JavaParamRef
<jobject
>& java_web_contents
,
31 jint ideal_splash_image_size_in_dp
,
32 jint ideal_icon_size_in_dp
) {
33 content::WebContents
* web_contents
=
34 content::WebContents::FromJavaWebContents(java_web_contents
);
35 AddToHomescreenDialogHelper
* add_to_homescreen_helper
=
36 new AddToHomescreenDialogHelper(env
, obj
, web_contents
,
37 ideal_splash_image_size_in_dp
, ideal_icon_size_in_dp
);
38 return reinterpret_cast<intptr_t>(add_to_homescreen_helper
);
41 AddToHomescreenDialogHelper::AddToHomescreenDialogHelper(
44 content::WebContents
* web_contents
,
45 int ideal_splash_image_size_in_dp
,
46 int ideal_icon_size_in_dp
)
47 : add_shortcut_pending_(false),
48 data_fetcher_(new AddToHomescreenDataFetcher(web_contents
,
49 ideal_splash_image_size_in_dp
,
50 ideal_icon_size_in_dp
,
52 java_ref_
.Reset(env
, obj
);
55 AddToHomescreenDialogHelper::~AddToHomescreenDialogHelper() {
56 data_fetcher_
->set_weak_observer(nullptr);
57 data_fetcher_
= nullptr;
60 void AddToHomescreenDialogHelper::OnUserTitleAvailable(
61 const base::string16
& user_title
) {
62 JNIEnv
* env
= base::android::AttachCurrentThread();
63 ScopedJavaLocalRef
<jstring
> j_user_title
=
64 base::android::ConvertUTF16ToJavaString(env
, user_title
);
65 Java_AddToHomescreenDialogHelper_onUserTitleAvailable(env
,
70 void AddToHomescreenDialogHelper::OnDataAvailable(const ShortcutInfo
& info
,
71 const SkBitmap
& icon
) {
72 JNIEnv
* env
= base::android::AttachCurrentThread();
73 ScopedJavaLocalRef
<jobject
> java_bitmap
;
75 java_bitmap
= gfx::ConvertToJavaBitmap(&icon
);
77 Java_AddToHomescreenDialogHelper_onIconAvailable(env
,
81 if (add_shortcut_pending_
)
82 AddShortcut(info
, icon
);
85 void AddToHomescreenDialogHelper::Destroy(JNIEnv
* env
, jobject obj
) {
89 SkBitmap
AddToHomescreenDialogHelper::FinalizeLauncherIcon(
90 const SkBitmap
& bitmap
,
92 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
94 // Determine a single color to use for the favicon if the favicon that is
95 // returned it is too low quality.
96 SkColor color
= color_utils::CalculateKMeanColorOfBitmap(bitmap
);
97 int dominant_red
= SkColorGetR(color
);
98 int dominant_green
= SkColorGetG(color
);
99 int dominant_blue
= SkColorGetB(color
);
101 // Make the icon acceptable for the Android launcher.
102 JNIEnv
* env
= base::android::AttachCurrentThread();
103 ScopedJavaLocalRef
<jstring
> java_url
=
104 base::android::ConvertUTF8ToJavaString(env
, url
.spec());
105 ScopedJavaLocalRef
<jobject
> java_bitmap
;
106 if (bitmap
.getSize())
107 java_bitmap
= gfx::ConvertToJavaBitmap(&bitmap
);
109 base::android::ScopedJavaLocalRef
<jobject
> ref
=
110 Java_AddToHomescreenDialogHelper_finalizeLauncherIcon(env
,
116 return gfx::CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(ref
.obj()));
119 void AddToHomescreenDialogHelper::AddShortcut(JNIEnv
* env
,
121 jstring j_user_title
) {
122 add_shortcut_pending_
= true;
124 base::string16 user_title
=
125 base::android::ConvertJavaStringToUTF16(env
, j_user_title
);
126 if (!user_title
.empty())
127 data_fetcher_
->shortcut_info().user_title
= user_title
;
129 if (data_fetcher_
->is_ready()) {
130 // If the fetcher isn't ready yet, the shortcut will be added when it is
131 // via OnDataAvailable();
132 AddShortcut(data_fetcher_
->shortcut_info(), data_fetcher_
->shortcut_icon());
136 void AddToHomescreenDialogHelper::AddShortcut(const ShortcutInfo
& info
,
137 const SkBitmap
& icon
) {
138 DCHECK(add_shortcut_pending_
);
139 if (!add_shortcut_pending_
)
141 add_shortcut_pending_
= false;
143 RecordAddToHomescreen();
145 const std::string
& uid
= base::GenerateGUID();
146 content::BrowserThread::PostTask(
147 content::BrowserThread::IO
,
149 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap
,
154 data_fetcher_
->FetchSplashScreenImage(uid
);
157 bool AddToHomescreenDialogHelper::RegisterAddToHomescreenDialogHelper(
159 return RegisterNativesImpl(env
);
162 void AddToHomescreenDialogHelper::RecordAddToHomescreen() {
163 // Record that the shortcut has been added, so no banners will be shown
165 content::WebContents
* web_contents
= data_fetcher_
->web_contents();
169 AppBannerSettingsHelper::RecordBannerEvent(
170 web_contents
, web_contents
->GetURL(),
171 data_fetcher_
->shortcut_info().url
.spec(),
172 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN
,