Home | History | Annotate | Download | only in android
      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/logo_bridge.h"
      6 
      7 #include <jni.h>
      8 
      9 #include "base/android/jni_android.h"
     10 #include "base/android/jni_string.h"
     11 #include "base/android/scoped_java_ref.h"
     12 #include "base/bind.h"
     13 #include "chrome/browser/android/logo_service.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "chrome/browser/profiles/profile_android.h"
     16 #include "components/search_provider_logos/logo_tracker.h"
     17 #include "jni/LogoBridge_jni.h"
     18 #include "third_party/skia/include/core/SkBitmap.h"
     19 #include "ui/gfx/android/java_bitmap.h"
     20 
     21 using base::android::ScopedJavaLocalRef;
     22 using base::android::ConvertUTF8ToJavaString;
     23 
     24 namespace {
     25 
     26 // Converts a C++ Logo to a Java Logo.
     27 ScopedJavaLocalRef<jobject> ConvertLogoToJavaObject(
     28     JNIEnv* env,
     29     const search_provider_logos::Logo* logo) {
     30   if (!logo)
     31     return ScopedJavaLocalRef<jobject>();
     32 
     33   ScopedJavaLocalRef<jobject> j_bitmap = gfx::ConvertToJavaBitmap(&logo->image);
     34 
     35   ScopedJavaLocalRef<jstring> j_on_click_url;
     36   if (!logo->metadata.on_click_url.empty())
     37     j_on_click_url = ConvertUTF8ToJavaString(env, logo->metadata.on_click_url);
     38 
     39   ScopedJavaLocalRef<jstring> j_alt_text;
     40   if (!logo->metadata.alt_text.empty())
     41     j_alt_text = ConvertUTF8ToJavaString(env, logo->metadata.alt_text);
     42 
     43   return Java_LogoBridge_createLogo(
     44       env, j_bitmap.obj(), j_on_click_url.obj(), j_alt_text.obj());
     45 }
     46 
     47 class LogoObserverAndroid : public search_provider_logos::LogoObserver {
     48  public:
     49   LogoObserverAndroid(base::WeakPtr<LogoBridge> logo_bridge,
     50                       JNIEnv* env,
     51                       jobject j_logo_observer)
     52       : logo_bridge_(logo_bridge) {
     53     j_logo_observer_.Reset(env, j_logo_observer);
     54   }
     55 
     56   virtual ~LogoObserverAndroid() {}
     57 
     58   // seach_provider_logos::LogoObserver:
     59   virtual void OnLogoAvailable(const search_provider_logos::Logo* logo,
     60                                bool from_cache) OVERRIDE {
     61     if (!logo_bridge_)
     62       return;
     63 
     64     JNIEnv* env = base::android::AttachCurrentThread();
     65     ScopedJavaLocalRef<jobject> j_logo = ConvertLogoToJavaObject(env, logo);
     66     Java_LogoObserver_onLogoAvailable(
     67         env, j_logo_observer_.obj(), j_logo.obj(), from_cache);
     68   }
     69 
     70   virtual void OnObserverRemoved() OVERRIDE {
     71     delete this;
     72   }
     73 
     74  private:
     75   // The associated LogoBridge. We won't call back to Java if the LogoBridge has
     76   // been destroyed.
     77   base::WeakPtr<LogoBridge> logo_bridge_;
     78 
     79   base::android::ScopedJavaGlobalRef<jobject> j_logo_observer_;
     80 };
     81 
     82 }  // namespace
     83 
     84 static jlong Init(JNIEnv* env, jobject obj, jobject j_profile) {
     85   LogoBridge* logo_bridge = new LogoBridge(j_profile);
     86   return reinterpret_cast<intptr_t>(logo_bridge);
     87 }
     88 
     89 LogoBridge::LogoBridge(jobject j_profile) : weak_ptr_factory_(this) {
     90   Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
     91   if (profile)
     92     logo_service_ = LogoServiceFactory::GetForProfile(profile);
     93 }
     94 
     95 LogoBridge::~LogoBridge() {}
     96 
     97 void LogoBridge::Destroy(JNIEnv* env, jobject obj) {
     98   delete this;
     99 }
    100 
    101 void LogoBridge::GetCurrentLogo(JNIEnv* env,
    102                                 jobject obj,
    103                                 jobject j_logo_observer) {
    104   if (!logo_service_)
    105     return;
    106 
    107   // |observer| is deleted in LogoObserverAndroid::OnObserverRemoved().
    108   LogoObserverAndroid* observer = new LogoObserverAndroid(
    109       weak_ptr_factory_.GetWeakPtr(), env, j_logo_observer);
    110   logo_service_->GetLogo(observer);
    111 }
    112 
    113 // static
    114 bool RegisterLogoBridge(JNIEnv* env) {
    115   return RegisterNativesImpl(env);
    116 }
    117