Home | History | Annotate | Download | only in banners
      1 // Copyright 2014 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/banners/app_banner_manager.h"
      6 
      7 #include "base/android/jni_android.h"
      8 #include "base/android/jni_string.h"
      9 #include "base/command_line.h"
     10 #include "base/metrics/histogram.h"
     11 #include "chrome/browser/android/banners/app_banner_metrics_ids.h"
     12 #include "chrome/browser/android/banners/app_banner_settings_helper.h"
     13 #include "chrome/browser/android/banners/app_banner_utilities.h"
     14 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chrome/common/chrome_switches.h"
     17 #include "content/public/browser/android/content_view_core.h"
     18 #include "content/public/browser/navigation_details.h"
     19 #include "content/public/browser/web_contents.h"
     20 #include "content/public/common/frame_navigate_params.h"
     21 #include "jni/AppBannerManager_jni.h"
     22 #include "net/base/load_flags.h"
     23 #include "ui/gfx/android/java_bitmap.h"
     24 
     25 using base::android::ConvertJavaStringToUTF8;
     26 using base::android::ConvertUTF8ToJavaString;
     27 
     28 namespace {
     29 const char kBannerTag[] = "google-play-id";
     30 }
     31 
     32 namespace banners {
     33 
     34 AppBannerManager::AppBannerManager(JNIEnv* env, jobject obj)
     35     : MetaTagObserver(kBannerTag),
     36       weak_java_banner_view_manager_(env, obj) {}
     37 
     38 AppBannerManager::~AppBannerManager() {
     39 }
     40 
     41 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) {
     42   delete this;
     43 }
     44 
     45 void AppBannerManager::BlockBanner(JNIEnv* env,
     46                                    jobject obj,
     47                                    jstring jurl,
     48                                    jstring jpackage) {
     49   if (!web_contents())
     50     return;
     51 
     52   GURL url(ConvertJavaStringToUTF8(env, jurl));
     53   std::string package_name = ConvertJavaStringToUTF8(env, jpackage);
     54   AppBannerSettingsHelper::Block(web_contents(), url, package_name);
     55 }
     56 
     57 void AppBannerManager::ReplaceWebContents(JNIEnv* env,
     58                                           jobject obj,
     59                                           jobject jweb_contents) {
     60   content::WebContents* web_contents =
     61       content::WebContents::FromJavaWebContents(jweb_contents);
     62   Observe(web_contents);
     63 }
     64 
     65 void AppBannerManager::DidNavigateMainFrame(
     66     const content::LoadCommittedDetails& details,
     67     const content::FrameNavigateParams& params) {
     68   // Get rid of the current banner.
     69   JNIEnv* env = base::android::AttachCurrentThread();
     70   ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env);
     71   if (jobj.is_null())
     72     return;
     73   Java_AppBannerManager_dismissCurrentBanner(env, jobj.obj(), DISMISS_NAVIGATE);
     74 }
     75 
     76 void AppBannerManager::OnFetchComplete(const GURL url, const SkBitmap* bitmap) {
     77   if (bitmap) {
     78     JNIEnv* env = base::android::AttachCurrentThread();
     79 
     80     ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env);
     81     if (jobj.is_null())
     82       return;
     83 
     84     ScopedJavaLocalRef<jstring> jimage_url(
     85         ConvertUTF8ToJavaString(env, url.spec()));
     86     ScopedJavaLocalRef<jobject> jimage = gfx::ConvertToJavaBitmap(bitmap);
     87     bool displayed = Java_AppBannerManager_createBanner(env,
     88                                                         jobj.obj(),
     89                                                         jimage_url.obj(),
     90                                                         jimage.obj());
     91     if (displayed)
     92       banners::TrackDisplayEvent(DISPLAY_CREATED);
     93   } else {
     94     DVLOG(1) << "Failed to retrieve image: " << url;
     95   }
     96 
     97   fetcher_.reset();
     98 }
     99 
    100 void AppBannerManager::HandleMetaTagContent(const std::string& tag_content,
    101                                             const GURL& expected_url) {
    102   DCHECK(web_contents());
    103   banners::TrackDisplayEvent(DISPLAY_BANNER_REQUESTED);
    104 
    105   if (!AppBannerSettingsHelper::IsAllowed(web_contents(),
    106                                           expected_url,
    107                                           tag_content)) {
    108     return;
    109   }
    110 
    111   // Send the info to the Java side to get info about the app.
    112   JNIEnv* env = base::android::AttachCurrentThread();
    113   ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env);
    114   if (jobj.is_null())
    115     return;
    116 
    117   ScopedJavaLocalRef<jstring> jurl(
    118       ConvertUTF8ToJavaString(env, expected_url.spec()));
    119   ScopedJavaLocalRef<jstring> jpackage(
    120       ConvertUTF8ToJavaString(env, tag_content));
    121   Java_AppBannerManager_prepareBanner(env,
    122                                       jobj.obj(),
    123                                       jurl.obj(),
    124                                       jpackage.obj());
    125 }
    126 
    127 bool AppBannerManager::FetchIcon(JNIEnv* env,
    128                                  jobject obj,
    129                                  jstring jimage_url) {
    130   std::string image_url = ConvertJavaStringToUTF8(env, jimage_url);
    131   if (!web_contents())
    132     return false;
    133 
    134   // Begin asynchronously fetching the app icon.
    135   Profile* profile =
    136       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
    137   fetcher_.reset(new chrome::BitmapFetcher(GURL(image_url), this));
    138   fetcher_.get()->Start(
    139       profile->GetRequestContext(),
    140       std::string(),
    141       net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
    142       net::LOAD_NORMAL);
    143   return true;
    144 }
    145 
    146 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) {
    147   banners::TrackDismissEvent(metric);
    148 }
    149 
    150 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) {
    151   banners::TrackInstallEvent(metric);
    152 }
    153 
    154 jlong Init(JNIEnv* env, jobject obj) {
    155   AppBannerManager* manager = new AppBannerManager(env, obj);
    156   return reinterpret_cast<intptr_t>(manager);
    157 }
    158 
    159 jboolean IsEnabled(JNIEnv* env, jclass clazz) {
    160   return base::CommandLine::ForCurrentProcess()->HasSwitch(
    161       switches::kEnableAppInstallAlerts);
    162 }
    163 
    164 // Register native methods
    165 bool RegisterAppBannerManager(JNIEnv* env) {
    166   return RegisterNativesImpl(env);
    167 }
    168 
    169 }  // namespace banners
    170