Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / android / banners / app_banner_infobar_delegate_android.cc
blobad246a70039d0daf082d188ac825d1830b6a23cc
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/banners/app_banner_infobar_delegate_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/guid.h"
10 #include "base/location.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/android/shortcut_helper.h"
14 #include "chrome/browser/android/shortcut_info.h"
15 #include "chrome/browser/android/tab_android.h"
16 #include "chrome/browser/banners/app_banner_data_fetcher.h"
17 #include "chrome/browser/banners/app_banner_metrics.h"
18 #include "chrome/browser/banners/app_banner_settings_helper.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h"
22 #include "chrome/common/render_messages.h"
23 #include "chrome/grit/generated_resources.h"
24 #include "components/rappor/rappor_utils.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/manifest.h"
29 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h"
30 #include "ui/gfx/android/java_bitmap.h"
31 #include "url/gurl.h"
33 using base::android::ConvertJavaStringToUTF8;
34 using base::android::ConvertJavaStringToUTF16;
35 using base::android::ConvertUTF8ToJavaString;
36 using base::android::ConvertUTF16ToJavaString;
38 namespace banners {
40 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
41 int event_request_id,
42 scoped_refptr<AppBannerDataFetcherAndroid> data_fetcher,
43 const base::string16& app_title,
44 SkBitmap* app_icon,
45 const content::Manifest& web_app_data)
46 : data_fetcher_(data_fetcher),
47 app_title_(app_title),
48 app_icon_(app_icon),
49 event_request_id_(event_request_id),
50 web_app_data_(web_app_data),
51 has_user_interaction_(false) {
52 DCHECK(!web_app_data.IsEmpty());
53 CreateJavaDelegate();
56 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
57 int event_request_id,
58 const base::string16& app_title,
59 SkBitmap* app_icon,
60 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
61 const std::string& native_app_package,
62 const std::string& referrer)
63 : app_title_(app_title),
64 app_icon_(app_icon),
65 event_request_id_(event_request_id),
66 native_app_data_(native_app_data),
67 native_app_package_(native_app_package),
68 referrer_(referrer),
69 has_user_interaction_(false) {
70 DCHECK(!native_app_data_.is_null());
71 CreateJavaDelegate();
74 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
75 if (!has_user_interaction_) {
76 if (!native_app_data_.is_null())
77 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
78 else if (!web_app_data_.IsEmpty())
79 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
82 TrackDismissEvent(DISMISS_EVENT_DISMISSED);
83 JNIEnv* env = base::android::AttachCurrentThread();
84 Java_AppBannerInfoBarDelegateAndroid_destroy(env,
85 java_delegate_.obj());
86 java_delegate_.Reset();
89 void AppBannerInfoBarDelegateAndroid::UpdateInstallState(JNIEnv* env,
90 jobject obj) {
91 if (native_app_data_.is_null())
92 return;
94 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState(
95 env,
96 java_delegate_.obj(),
97 native_app_data_.obj());
98 static_cast<AppBannerInfoBarAndroid*>(infobar())
99 ->OnInstallStateChanged(newState);
102 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned(
103 JNIEnv* env,
104 jobject obj,
105 jboolean jis_installing) {
106 if (!infobar())
107 return;
109 content::WebContents* web_contents =
110 InfoBarService::WebContentsFromInfoBar(infobar());
111 if (!web_contents)
112 return;
114 if (jis_installing) {
115 AppBannerSettingsHelper::RecordBannerEvent(
116 web_contents,
117 web_contents->GetURL(),
118 native_app_package_,
119 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
120 AppBannerDataFetcher::GetCurrentTime());
122 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_STARTED);
123 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
124 "AppBanner.NativeApp.Installed",
125 web_contents->GetURL());
128 UpdateInstallState(env, obj);
131 void AppBannerInfoBarDelegateAndroid::OnInstallFinished(JNIEnv* env,
132 jobject obj,
133 jboolean success) {
134 if (!infobar())
135 return;
137 if (success) {
138 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED);
139 UpdateInstallState(env, obj);
140 } else if (infobar()->owner()) {
141 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT);
142 infobar()->owner()->RemoveInfoBar(infobar());
146 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() {
147 JNIEnv* env = base::android::AttachCurrentThread();
148 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create(
149 env,
150 reinterpret_cast<intptr_t>(this)));
153 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted(
154 content::WebContents* web_contents,
155 const std::string& platform) {
156 web_contents->GetMainFrame()->Send(
157 new ChromeViewMsg_AppBannerAccepted(
158 web_contents->GetMainFrame()->GetRoutingID(),
159 event_request_id_,
160 platform));
163 gfx::Image AppBannerInfoBarDelegateAndroid::GetIcon() const {
164 return gfx::Image::CreateFrom1xBitmap(*app_icon_.get());
167 void AppBannerInfoBarDelegateAndroid::InfoBarDismissed() {
168 has_user_interaction_ = true;
170 content::WebContents* web_contents =
171 InfoBarService::WebContentsFromInfoBar(infobar());
172 if (!web_contents)
173 return;
175 web_contents->GetMainFrame()->Send(
176 new ChromeViewMsg_AppBannerDismissed(
177 web_contents->GetMainFrame()->GetRoutingID(),
178 event_request_id_));
180 if (!native_app_data_.is_null()) {
181 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED);
182 AppBannerSettingsHelper::RecordBannerDismissEvent(
183 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE);
184 } else if (!web_app_data_.IsEmpty()) {
185 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
186 AppBannerSettingsHelper::RecordBannerDismissEvent(
187 web_contents, web_app_data_.start_url.spec(),
188 AppBannerSettingsHelper::WEB);
192 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const {
193 return app_title_;
196 int AppBannerInfoBarDelegateAndroid::GetButtons() const {
197 return BUTTON_OK;
200 bool AppBannerInfoBarDelegateAndroid::Accept() {
201 has_user_interaction_ = true;
203 content::WebContents* web_contents =
204 InfoBarService::WebContentsFromInfoBar(infobar());
205 if (!web_contents) {
206 TrackDismissEvent(DISMISS_EVENT_ERROR);
207 return true;
210 if (!native_app_data_.is_null()) {
211 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED);
212 JNIEnv* env = base::android::AttachCurrentThread();
214 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
215 if (tab == nullptr) {
216 TrackDismissEvent(DISMISS_EVENT_ERROR);
217 return true;
219 ScopedJavaLocalRef<jstring> jreferrer(
220 ConvertUTF8ToJavaString(env, referrer_));
222 bool was_opened = Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp(
223 env,
224 java_delegate_.obj(),
225 tab->GetJavaObject().obj(),
226 native_app_data_.obj(),
227 jreferrer.obj());
229 if (was_opened) {
230 TrackDismissEvent(DISMISS_EVENT_APP_OPEN);
231 } else {
232 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED);
234 SendBannerAccepted(web_contents, "play");
235 return was_opened;
236 } else if (!web_app_data_.IsEmpty()) {
237 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
239 AppBannerSettingsHelper::RecordBannerInstallEvent(
240 web_contents, web_app_data_.start_url.spec(),
241 AppBannerSettingsHelper::WEB);
243 ShortcutInfo info(GURL::EmptyGURL());
244 info.UpdateFromManifest(web_app_data_);
245 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
247 const std::string& uid = base::GenerateGUID();
248 content::BrowserThread::PostTask(
249 content::BrowserThread::IO,
250 FROM_HERE,
251 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap,
252 info,
253 uid,
254 *app_icon_.get()));
255 data_fetcher_->FetchWebappSplashScreenImage(uid);
257 SendBannerAccepted(web_contents, "web");
258 return true;
261 return true;
264 bool AppBannerInfoBarDelegateAndroid::LinkClicked(
265 WindowOpenDisposition disposition) {
266 if (native_app_data_.is_null())
267 return false;
269 // Try to show the details for the native app.
270 JNIEnv* env = base::android::AttachCurrentThread();
272 content::WebContents* web_contents =
273 InfoBarService::WebContentsFromInfoBar(infobar());
274 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents)
275 : nullptr;
276 if (tab == nullptr) {
277 TrackDismissEvent(DISMISS_EVENT_ERROR);
278 return true;
281 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(env,
282 java_delegate_.obj(),
283 tab->GetJavaObject().obj(),
284 native_app_data_.obj());
286 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
287 return true;
290 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) {
291 return RegisterNativesImpl(env);
294 } // namespace banners