15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/android/logo_bridge.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <jni.h>
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/android/jni_android.h"
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/android/jni_string.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/android/scoped_java_ref.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/bind.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/android/logo_service.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/profiles/profile.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/profiles/profile_android.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/search_provider_logos/logo_tracker.h"
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "jni/LogoBridge_jni.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "third_party/skia/include/core/SkBitmap.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/android/java_bitmap.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing base::android::ScopedJavaLocalRef;
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing base::android::ConvertUTF8ToJavaString;
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Converts a C++ Logo to a Java Logo.
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuScopedJavaLocalRef<jobject> ConvertLogoToJavaObject(
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    JNIEnv* env,
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const search_provider_logos::Logo* logo) {
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!logo)
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return ScopedJavaLocalRef<jobject>();
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedJavaLocalRef<jobject> j_bitmap = gfx::ConvertToJavaBitmap(&logo->image);
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedJavaLocalRef<jstring> j_on_click_url;
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!logo->metadata.on_click_url.empty())
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    j_on_click_url = ConvertUTF8ToJavaString(env, logo->metadata.on_click_url);
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedJavaLocalRef<jstring> j_alt_text;
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!logo->metadata.alt_text.empty())
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    j_alt_text = ConvertUTF8ToJavaString(env, logo->metadata.alt_text);
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return Java_LogoBridge_createLogo(
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      env, j_bitmap.obj(), j_on_click_url.obj(), j_alt_text.obj());
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass LogoObserverAndroid : public search_provider_logos::LogoObserver {
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public:
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  LogoObserverAndroid(base::WeakPtr<LogoBridge> logo_bridge,
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      JNIEnv* env,
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      jobject j_logo_observer)
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      : logo_bridge_(logo_bridge) {
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    j_logo_observer_.Reset(env, j_logo_observer);
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual ~LogoObserverAndroid() {}
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // seach_provider_logos::LogoObserver:
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void OnLogoAvailable(const search_provider_logos::Logo* logo,
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                               bool from_cache) OVERRIDE {
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!logo_bridge_)
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return;
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    JNIEnv* env = base::android::AttachCurrentThread();
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ScopedJavaLocalRef<jobject> j_logo = ConvertLogoToJavaObject(env, logo);
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Java_LogoObserver_onLogoAvailable(
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        env, j_logo_observer_.obj(), j_logo.obj(), from_cache);
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void OnObserverRemoved() OVERRIDE {
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    delete this;
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private:
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // The associated LogoBridge. We won't call back to Java if the LogoBridge has
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // been destroyed.
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::WeakPtr<LogoBridge> logo_bridge_;
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::android::ScopedJavaGlobalRef<jobject> j_logo_observer_;
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic jlong Init(JNIEnv* env, jobject obj, jobject j_profile) {
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  LogoBridge* logo_bridge = new LogoBridge(j_profile);
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return reinterpret_cast<intptr_t>(logo_bridge);
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuLogoBridge::LogoBridge(jobject j_profile) : weak_ptr_factory_(this) {
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (profile)
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    logo_service_ = LogoServiceFactory::GetForProfile(profile);
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuLogoBridge::~LogoBridge() {}
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid LogoBridge::Destroy(JNIEnv* env, jobject obj) {
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  delete this;
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid LogoBridge::GetCurrentLogo(JNIEnv* env,
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                jobject obj,
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                jobject j_logo_observer) {
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!logo_service_)
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |observer| is deleted in LogoObserverAndroid::OnObserverRemoved().
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  LogoObserverAndroid* observer = new LogoObserverAndroid(
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      weak_ptr_factory_.GetWeakPtr(), env, j_logo_observer);
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  logo_service_->GetLogo(observer);
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// static
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool RegisterLogoBridge(JNIEnv* env) {
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return RegisterNativesImpl(env);
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
117