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