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/location.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/android/shortcut_helper.h"
13 #include "chrome/browser/android/shortcut_info.h"
14 #include "chrome/browser/android/tab_android.h"
15 #include "chrome/browser/banners/app_banner_data_fetcher.h"
16 #include "chrome/browser/banners/app_banner_metrics.h"
17 #include "chrome/browser/banners/app_banner_settings_helper.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h"
21 #include "chrome/common/render_messages.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "components/rappor/rappor_utils.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/manifest.h"
28 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h"
29 #include "ui/gfx/android/java_bitmap.h"
31 using base::android::ConvertJavaStringToUTF8
;
32 using base::android::ConvertJavaStringToUTF16
;
33 using base::android::ConvertUTF8ToJavaString
;
34 using base::android::ConvertUTF16ToJavaString
;
38 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
40 const base::string16
& app_title
,
42 const content::Manifest
& web_app_data
)
43 : app_title_(app_title
),
45 event_request_id_(event_request_id
),
46 web_app_data_(web_app_data
) {
47 DCHECK(!web_app_data
.IsEmpty());
51 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
53 const base::string16
& app_title
,
55 const base::android::ScopedJavaGlobalRef
<jobject
>& native_app_data
,
56 const std::string
& native_app_package
)
57 : app_title_(app_title
),
59 event_request_id_(event_request_id
),
60 native_app_data_(native_app_data
),
61 native_app_package_(native_app_package
) {
62 DCHECK(!native_app_data_
.is_null());
66 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
67 TrackDismissEvent(DISMISS_EVENT_DISMISSED
);
68 JNIEnv
* env
= base::android::AttachCurrentThread();
69 Java_AppBannerInfoBarDelegateAndroid_destroy(env
,
70 java_delegate_
.obj());
71 java_delegate_
.Reset();
74 void AppBannerInfoBarDelegateAndroid::UpdateInstallState(JNIEnv
* env
,
76 if (native_app_data_
.is_null())
79 int newState
= Java_AppBannerInfoBarDelegateAndroid_determineInstallState(
82 native_app_data_
.obj());
83 static_cast<AppBannerInfoBarAndroid
*>(infobar())
84 ->OnInstallStateChanged(newState
);
87 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned(
90 jboolean jis_installing
) {
94 content::WebContents
* web_contents
=
95 InfoBarService::WebContentsFromInfoBar(infobar());
100 AppBannerSettingsHelper::RecordBannerEvent(
102 web_contents
->GetURL(),
104 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN
,
105 AppBannerDataFetcher::GetCurrentTime());
107 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_STARTED
);
108 rappor::SampleDomainAndRegistryFromGURL(g_browser_process
->rappor_service(),
109 "AppBanner.NativeApp.Installed",
110 web_contents
->GetURL());
113 UpdateInstallState(env
, obj
);
116 void AppBannerInfoBarDelegateAndroid::OnInstallFinished(JNIEnv
* env
,
123 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED
);
124 UpdateInstallState(env
, obj
);
125 } else if (infobar()->owner()) {
126 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT
);
127 infobar()->owner()->RemoveInfoBar(infobar());
131 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() {
132 JNIEnv
* env
= base::android::AttachCurrentThread();
133 java_delegate_
.Reset(Java_AppBannerInfoBarDelegateAndroid_create(
135 reinterpret_cast<intptr_t>(this)));
138 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted(
139 content::WebContents
* web_contents
,
140 const std::string
& platform
) {
141 web_contents
->GetMainFrame()->Send(
142 new ChromeViewMsg_AppBannerAccepted(
143 web_contents
->GetMainFrame()->GetRoutingID(),
148 gfx::Image
AppBannerInfoBarDelegateAndroid::GetIcon() const {
149 return gfx::Image::CreateFrom1xBitmap(*app_icon_
.get());
152 void AppBannerInfoBarDelegateAndroid::InfoBarDismissed() {
153 content::WebContents
* web_contents
=
154 InfoBarService::WebContentsFromInfoBar(infobar());
158 web_contents
->GetMainFrame()->Send(
159 new ChromeViewMsg_AppBannerDismissed(
160 web_contents
->GetMainFrame()->GetRoutingID(),
163 if (!native_app_data_
.is_null()) {
164 AppBannerSettingsHelper::RecordBannerDismissEvent(
165 web_contents
, native_app_package_
, AppBannerSettingsHelper::NATIVE
);
166 } else if (!web_app_data_
.IsEmpty()) {
167 AppBannerSettingsHelper::RecordBannerDismissEvent(
168 web_contents
, web_app_data_
.start_url
.spec(),
169 AppBannerSettingsHelper::WEB
);
173 base::string16
AppBannerInfoBarDelegateAndroid::GetMessageText() const {
177 int AppBannerInfoBarDelegateAndroid::GetButtons() const {
181 bool AppBannerInfoBarDelegateAndroid::Accept() {
182 content::WebContents
* web_contents
=
183 InfoBarService::WebContentsFromInfoBar(infobar());
185 TrackDismissEvent(DISMISS_EVENT_ERROR
);
189 if (!native_app_data_
.is_null()) {
190 JNIEnv
* env
= base::android::AttachCurrentThread();
192 TabAndroid
* tab
= TabAndroid::FromWebContents(web_contents
);
193 if (tab
== nullptr) {
194 TrackDismissEvent(DISMISS_EVENT_ERROR
);
198 bool was_opened
= Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp(
200 java_delegate_
.obj(),
201 tab
->GetJavaObject().obj(),
202 native_app_data_
.obj());
205 TrackDismissEvent(DISMISS_EVENT_APP_OPEN
);
207 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED
);
209 SendBannerAccepted(web_contents
, "play");
211 } else if (!web_app_data_
.IsEmpty()) {
212 AppBannerSettingsHelper::RecordBannerInstallEvent(
213 web_contents
, web_app_data_
.start_url
.spec(),
214 AppBannerSettingsHelper::WEB
);
217 info
.UpdateFromManifest(web_app_data_
);
218 info
.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER
);
219 content::BrowserThread::PostTask(
220 content::BrowserThread::IO
,
222 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap
,
226 SendBannerAccepted(web_contents
, "web");
233 bool AppBannerInfoBarDelegateAndroid::LinkClicked(
234 WindowOpenDisposition disposition
) {
235 if (native_app_data_
.is_null())
238 // Try to show the details for the native app.
239 JNIEnv
* env
= base::android::AttachCurrentThread();
241 content::WebContents
* web_contents
=
242 InfoBarService::WebContentsFromInfoBar(infobar());
243 TabAndroid
* tab
= web_contents
? TabAndroid::FromWebContents(web_contents
)
245 if (tab
== nullptr) {
246 TrackDismissEvent(DISMISS_EVENT_ERROR
);
250 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(env
,
251 java_delegate_
.obj(),
252 tab
->GetJavaObject().obj(),
253 native_app_data_
.obj());
255 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK
);
259 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv
* env
) {
260 return RegisterNativesImpl(env
);
263 } // namespace banners