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/translate_infobar.h"
6
7#include "base/android/jni_android.h"
8#include "base/android/jni_array.h"
9#include "base/android/jni_weak_ref.h"
10#include "chrome/browser/translate/chrome_translate_client.h"
11#include "components/translate/core/browser/translate_infobar_delegate.h"
12#include "jni/TranslateInfoBarDelegate_jni.h"
13
14// ChromeTranslateClient
15// ----------------------------------------------------------
16
17scoped_ptr<infobars::InfoBar> ChromeTranslateClient::CreateInfoBar(
18    scoped_ptr<translate::TranslateInfoBarDelegate> delegate) const {
19  return scoped_ptr<infobars::InfoBar>(new TranslateInfoBar(delegate.Pass()));
20}
21
22
23// TranslateInfoBar -----------------------------------------------------------
24
25TranslateInfoBar::TranslateInfoBar(
26    scoped_ptr<translate::TranslateInfoBarDelegate> delegate)
27    : InfoBarAndroid(delegate.PassAs<infobars::InfoBarDelegate>()),
28      java_translate_delegate_() {
29}
30
31TranslateInfoBar::~TranslateInfoBar() {
32}
33
34ScopedJavaLocalRef<jobject> TranslateInfoBar::CreateRenderInfoBar(JNIEnv* env) {
35  java_translate_delegate_.Reset(Java_TranslateInfoBarDelegate_create(env));
36  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
37  std::vector<base::string16> languages;
38  languages.reserve(delegate->num_languages());
39  for (size_t i = 0; i < delegate->num_languages(); ++i)
40    languages.push_back(delegate->language_name_at(i));
41
42  base::android::ScopedJavaLocalRef<jobjectArray> java_languages =
43      base::android::ToJavaArrayOfStrings(env, languages);
44  return Java_TranslateInfoBarDelegate_showTranslateInfoBar(
45      env, java_translate_delegate_.obj(), reinterpret_cast<intptr_t>(this),
46      delegate->translate_step(), delegate->original_language_index(),
47      delegate->target_language_index(), delegate->ShouldAlwaysTranslate(),
48      ShouldDisplayNeverTranslateInfoBarOnCancel(),
49      delegate->triggered_from_menu(), java_languages.obj());
50}
51
52void TranslateInfoBar::ProcessButton(int action,
53                                     const std::string& action_value) {
54  if (!owner())
55    return;  // We're closing; don't call anything, it might access the owner.
56
57  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
58  if (action == InfoBarAndroid::ACTION_TRANSLATE) {
59    delegate->Translate();
60    return;
61  }
62
63  if (action == InfoBarAndroid::ACTION_CANCEL)
64    delegate->TranslationDeclined();
65  else if (action == InfoBarAndroid::ACTION_TRANSLATE_SHOW_ORIGINAL)
66    delegate->RevertTranslation();
67  else
68    DCHECK_EQ(InfoBarAndroid::ACTION_NONE, action);
69
70  RemoveSelf();
71}
72
73void TranslateInfoBar::PassJavaInfoBar(InfoBarAndroid* source) {
74  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
75  DCHECK_NE(translate::TRANSLATE_STEP_BEFORE_TRANSLATE,
76            delegate->translate_step());
77
78  // Ask the former bar to transfer ownership to us.
79  DCHECK(source != NULL);
80  static_cast<TranslateInfoBar*>(source)->TransferOwnership(
81      this, delegate->translate_step());
82}
83
84void TranslateInfoBar::ApplyTranslateOptions(JNIEnv* env,
85                                             jobject obj,
86                                             int source_language_index,
87                                             int target_language_index,
88                                             bool always_translate,
89                                             bool never_translate_language,
90                                             bool never_translate_site) {
91  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
92  delegate->UpdateOriginalLanguageIndex(source_language_index);
93  delegate->UpdateTargetLanguageIndex(target_language_index);
94
95  if (delegate->ShouldAlwaysTranslate() != always_translate)
96    delegate->ToggleAlwaysTranslate();
97
98  if (never_translate_language && delegate->IsTranslatableLanguageByPrefs())
99    delegate->ToggleTranslatableLanguageByPrefs();
100
101  if (never_translate_site && !delegate->IsSiteBlacklisted())
102    delegate->ToggleSiteBlacklist();
103}
104
105void TranslateInfoBar::TransferOwnership(TranslateInfoBar* destination,
106                                         translate::TranslateStep new_type) {
107  JNIEnv* env = base::android::AttachCurrentThread();
108  if (Java_TranslateInfoBarDelegate_changeTranslateInfoBarTypeAndPointer(
109      env, java_translate_delegate_.obj(),
110      reinterpret_cast<intptr_t>(destination), new_type)) {
111    ReassignJavaInfoBar(destination);
112    destination->SetJavaDelegate(java_translate_delegate_.Release());
113  }
114}
115
116void TranslateInfoBar::SetJavaDelegate(jobject delegate) {
117  JNIEnv* env = base::android::AttachCurrentThread();
118  java_translate_delegate_.Reset(env, delegate);
119}
120
121bool TranslateInfoBar::ShouldDisplayNeverTranslateInfoBarOnCancel() {
122  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
123  return (delegate->translate_step() ==
124          translate::TRANSLATE_STEP_BEFORE_TRANSLATE) &&
125         delegate->ShouldShowNeverTranslateShortcut();
126}
127
128translate::TranslateInfoBarDelegate* TranslateInfoBar::GetDelegate() {
129  return delegate()->AsTranslateInfoBarDelegate();
130}
131
132
133// Native JNI methods ---------------------------------------------------------
134
135bool RegisterTranslateInfoBarDelegate(JNIEnv* env) {
136  return RegisterNativesImpl(env);
137}
138