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_manager_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/command_line.h"
10 #include "base/metrics/field_trial.h"
11 #include "chrome/browser/android/banners/app_banner_data_fetcher_android.h"
12 #include "chrome/browser/banners/app_banner_metrics.h"
13 #include "chrome/common/chrome_constants.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/frame_navigate_params.h"
16 #include "jni/AppBannerManager_jni.h"
18 using base::android::ConvertJavaStringToUTF8
;
19 using base::android::ConvertJavaStringToUTF16
;
20 using base::android::ConvertUTF8ToJavaString
;
21 using base::android::ConvertUTF16ToJavaString
;
25 const char kPlayPlatform
[] = "play";
26 const char kReferrerName
[] = "referrer";
27 const char kIdName
[] = "id";
28 const char kPlayInlineReferrer
[] = "playinline=chrome_inline";
30 } // anonymous namespace
34 AppBannerManagerAndroid::AppBannerManagerAndroid(
37 int ideal_splash_image_size_in_dp
,
38 int ideal_icon_size_in_dp
)
39 : AppBannerManager(ideal_icon_size_in_dp
),
40 ideal_splash_image_size_in_dp_(ideal_splash_image_size_in_dp
),
41 weak_java_banner_view_manager_(env
, obj
) {
44 AppBannerManagerAndroid::~AppBannerManagerAndroid() {
47 void AppBannerManagerAndroid::Destroy(JNIEnv
* env
, jobject obj
) {
51 void AppBannerManagerAndroid::ReplaceWebContents(JNIEnv
* env
,
53 jobject jweb_contents
) {
54 content::WebContents
* web_contents
=
55 content::WebContents::FromJavaWebContents(jweb_contents
);
56 AppBannerManager::ReplaceWebContents(web_contents
);
59 bool AppBannerManagerAndroid::HandleNonWebApp(const std::string
& platform
,
61 const std::string
& id
) {
62 if (!CheckPlatformAndId(platform
, id
))
65 banners::TrackDisplayEvent(DISPLAY_EVENT_NATIVE_APP_BANNER_REQUESTED
);
67 // Send the info to the Java side to get info about the app.
68 JNIEnv
* env
= base::android::AttachCurrentThread();
69 ScopedJavaLocalRef
<jobject
> jobj
= weak_java_banner_view_manager_
.get(env
);
73 std::string id_from_app_url
= ExtractQueryValueForName(url
, kIdName
);
74 if (id_from_app_url
.size() && id
!= id_from_app_url
) {
75 banners::OutputDeveloperDebugMessage(web_contents(),
76 banners::kIgnoredIdsDoNotMatch
);
80 std::string referrer
=
81 ExtractQueryValueForName(url
, kReferrerName
);
83 // Attach the chrome_inline referrer value, prefixed with "&" if the referrer
86 referrer
= kPlayInlineReferrer
;
88 referrer
.append("&").append(kPlayInlineReferrer
);
90 ScopedJavaLocalRef
<jstring
> jurl(
91 ConvertUTF8ToJavaString(env
, data_fetcher()->validated_url().spec()));
92 ScopedJavaLocalRef
<jstring
> jpackage(
93 ConvertUTF8ToJavaString(env
, id
));
94 ScopedJavaLocalRef
<jstring
> jreferrer(
95 ConvertUTF8ToJavaString(env
, referrer
));
96 Java_AppBannerManager_fetchAppDetails(env
, jobj
.obj(), jurl
.obj(),
97 jpackage
.obj(), jreferrer
.obj(),
98 ideal_icon_size_in_dp());
102 bool AppBannerManagerAndroid::CheckPlatformAndId(const std::string
& platform
,
103 const std::string
& id
) {
104 if (platform
!= kPlayPlatform
) {
105 banners::OutputDeveloperDebugMessage(
106 web_contents(), platform
+ banners::kIgnoredNotSupportedOnAndroid
);
110 banners::OutputDeveloperDebugMessage(web_contents(), banners::kIgnoredNoId
);
116 bool AppBannerManagerAndroid::CheckFetcherMatchesContents() {
120 if (!data_fetcher() ||
121 data_fetcher()->validated_url() != web_contents()->GetURL()) {
122 banners::OutputDeveloperNotShownMessage(
123 web_contents(), banners::kUserNavigatedBeforeBannerShown
);
129 std::string
AppBannerManagerAndroid::ExtractQueryValueForName(
131 const std::string
& name
) {
132 url::Component query
= url
.parsed_for_possibly_invalid_spec().query
;
133 url::Component key
, value
;
134 const char* url_spec
= url
.spec().c_str();
136 while (url::ExtractQueryKeyValue(url_spec
, &query
, &key
, &value
)) {
137 std::string
key_str(url_spec
, key
.begin
, key
.len
);
138 std::string
value_str(url_spec
, value
.begin
, value
.len
);
145 AppBannerDataFetcher
* AppBannerManagerAndroid::CreateAppBannerDataFetcher(
146 base::WeakPtr
<Delegate
> weak_delegate
,
147 const int ideal_icon_size_in_dp
) {
148 return new AppBannerDataFetcherAndroid(web_contents(), weak_delegate
,
149 ideal_splash_image_size_in_dp_
,
150 ideal_icon_size_in_dp
);
153 bool AppBannerManagerAndroid::OnAppDetailsRetrieved(JNIEnv
* env
,
157 jstring japp_package
,
159 if (!CheckFetcherMatchesContents())
162 base::android::ScopedJavaLocalRef
<jobject
> native_app_data
;
163 native_app_data
.Reset(env
, japp_data
);
164 GURL image_url
= GURL(ConvertJavaStringToUTF8(env
, jicon_url
));
166 AppBannerDataFetcherAndroid
* android_fetcher
=
167 static_cast<AppBannerDataFetcherAndroid
*>(data_fetcher().get());
168 return android_fetcher
->ContinueFetching(
169 ConvertJavaStringToUTF16(env
, japp_title
),
170 ConvertJavaStringToUTF8(env
, japp_package
),
171 native_app_data
, image_url
);
174 bool AppBannerManagerAndroid::IsFetcherActive(JNIEnv
* env
, jobject obj
) {
175 return AppBannerManager::IsFetcherActive();
179 bool AppBannerManagerAndroid::Register(JNIEnv
* env
) {
180 return RegisterNativesImpl(env
);
183 jlong
Init(JNIEnv
* env
,
184 const JavaParamRef
<jobject
>& obj
,
185 jint ideal_splash_image_size_in_dp
,
186 jint ideal_icon_size_in_dp
) {
187 AppBannerManagerAndroid
* manager
=
188 new AppBannerManagerAndroid(env
, obj
,
189 ideal_splash_image_size_in_dp
, ideal_icon_size_in_dp
);
190 return reinterpret_cast<intptr_t>(manager
);
193 void SetTimeDeltaForTesting(JNIEnv
* env
,
194 const JavaParamRef
<jclass
>& clazz
,
196 AppBannerDataFetcher::SetTimeDeltaForTesting(days
);
199 void DisableSecureSchemeCheckForTesting(JNIEnv
* env
,
200 const JavaParamRef
<jclass
>& clazz
) {
201 AppBannerManager::DisableSecureSchemeCheckForTesting();
204 void SetEngagementWeights(JNIEnv
* env
,
205 const JavaParamRef
<jclass
>& clazz
,
206 jdouble direct_engagement
,
207 jdouble indirect_engagement
) {
208 AppBannerManager::SetEngagementWeights(direct_engagement
,
209 indirect_engagement
);
212 jboolean
IsEnabled(JNIEnv
* env
, const JavaParamRef
<jclass
>& clazz
) {
213 return base::FieldTrialList::FindFullName("AppBanners") == "Enabled";
216 } // namespace banners