1// Copyright 2013 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/ui/android/infobars/infobar_container_android.h"
6
7#include "base/android/jni_android.h"
8#include "base/logging.h"
9#include "base/message_loop/message_loop.h"
10#include "chrome/browser/infobars/infobar_service.h"
11#include "chrome/browser/ui/android/infobars/auto_login_infobar_delegate_android.h"
12#include "chrome/browser/ui/android/infobars/infobar_android.h"
13#include "components/infobars/core/infobar.h"
14#include "components/infobars/core/infobar_delegate.h"
15#include "content/public/browser/web_contents.h"
16#include "jni/InfoBarContainer_jni.h"
17
18
19// InfoBarContainerAndroid ----------------------------------------------------
20
21InfoBarContainerAndroid::InfoBarContainerAndroid(JNIEnv* env,
22                                                 jobject obj,
23                                                 jobject auto_login_delegate)
24    : infobars::InfoBarContainer(NULL),
25      weak_java_infobar_container_(env, obj),
26      weak_java_auto_login_delegate_(env, auto_login_delegate) {}
27
28InfoBarContainerAndroid::~InfoBarContainerAndroid() {
29  RemoveAllInfoBarsForDestruction();
30}
31
32void InfoBarContainerAndroid::Destroy(JNIEnv* env, jobject obj) {
33  delete this;
34}
35
36void InfoBarContainerAndroid::PlatformSpecificAddInfoBar(
37    infobars::InfoBar* infobar,
38    size_t position) {
39  DCHECK(infobar);
40  InfoBarAndroid* android_bar = static_cast<InfoBarAndroid*>(infobar);
41  if (!android_bar) {
42    // TODO(bulach): CLANK: implement other types of InfoBars.
43    // TODO(jrg): this will always print out WARNING_TYPE as an int.
44    // Try and be more helpful.
45    NOTIMPLEMENTED() << "CLANK: infobar type "
46                     << infobar->delegate()->GetInfoBarType();
47    return;
48  }
49
50  if (infobar->delegate()->AsAutoLoginInfoBarDelegate()) {
51    AutoLoginInfoBarDelegateAndroid* auto_login_delegate =
52        static_cast<AutoLoginInfoBarDelegateAndroid*>(
53            infobar->delegate()->AsAutoLoginInfoBarDelegate());
54    if (!auto_login_delegate->AttachAccount(weak_java_auto_login_delegate_))
55      return;
56  }
57
58  AttachJavaInfoBar(android_bar);
59}
60
61void InfoBarContainerAndroid::AttachJavaInfoBar(InfoBarAndroid* android_bar) {
62  if (android_bar->HasSetJavaInfoBar())
63    return;
64  JNIEnv* env = base::android::AttachCurrentThread();
65  base::android::ScopedJavaLocalRef<jobject> java_infobar =
66      android_bar->CreateRenderInfoBar(env);
67  Java_InfoBarContainer_addInfoBar(
68      env, weak_java_infobar_container_.get(env).obj(), java_infobar.obj());
69  android_bar->set_java_infobar(java_infobar);
70}
71
72void InfoBarContainerAndroid::PlatformSpecificReplaceInfoBar(
73    infobars::InfoBar* old_infobar,
74    infobars::InfoBar* new_infobar) {
75  static_cast<InfoBarAndroid*>(new_infobar)->PassJavaInfoBar(
76      static_cast<InfoBarAndroid*>(old_infobar));
77}
78
79void InfoBarContainerAndroid::PlatformSpecificRemoveInfoBar(
80    infobars::InfoBar* infobar) {
81  InfoBarAndroid* android_infobar = static_cast<InfoBarAndroid*>(infobar);
82  android_infobar->CloseJavaInfoBar();
83}
84
85
86// Native JNI methods ---------------------------------------------------------
87
88static jlong Init(JNIEnv* env,
89                  jobject obj,
90                  jobject web_contents,
91                  jobject auto_login_delegate) {
92  InfoBarContainerAndroid* infobar_container =
93      new InfoBarContainerAndroid(env, obj, auto_login_delegate);
94  InfoBarService* infobar_service = InfoBarService::FromWebContents(
95      content::WebContents::FromJavaWebContents(web_contents));
96  infobar_container->ChangeInfoBarManager(infobar_service);
97  return reinterpret_cast<intptr_t>(infobar_container);
98}
99
100bool RegisterInfoBarContainer(JNIEnv* env) {
101  return RegisterNativesImpl(env);
102}
103