1 // Copyright 2015 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.
5 #include "chrome/browser/ui/android/infobars/account_chooser_infobar.h"
7 #include "base/android/jni_string.h"
8 #include "base/android/scoped_java_ref.h"
9 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/password_manager/account_chooser_infobar_delegate_android.h"
12 #include "chrome/browser/password_manager/credential_android.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/passwords/account_avatar_fetcher.h"
15 #include "components/password_manager/core/common/credential_manager_types.h"
16 #include "jni/AccountChooserInfoBar_jni.h"
17 #include "ui/gfx/android/java_bitmap.h"
21 void AddElementsToJavaCredentialArray(
23 ScopedJavaLocalRef
<jobjectArray
> java_credentials_array
,
24 const std::vector
<const autofill::PasswordForm
*>& password_forms
,
25 password_manager::CredentialType type
,
27 int index
= indexStart
;
28 for (auto password_form
: password_forms
) {
29 ScopedJavaLocalRef
<jobject
> java_credential
= CreateNativeCredential(
30 env
, *password_form
, index
- indexStart
, static_cast<int>(type
));
31 env
->SetObjectArrayElement(java_credentials_array
.obj(), index
,
32 java_credential
.obj());
37 class AvatarFetcherAndroid
: public AccountAvatarFetcher
{
42 const base::android::ScopedJavaGlobalRef
<jobject
>& java_infobar
);
45 ~AvatarFetcherAndroid() override
= default;
46 // chrome::BitmapFetcherDelegate:
47 void OnFetchComplete(const GURL
& url
, const SkBitmap
* bitmap
) override
;
50 base::android::ScopedJavaGlobalRef
<jobject
> java_infobar_
;
52 DISALLOW_COPY_AND_ASSIGN(AvatarFetcherAndroid
);
55 AvatarFetcherAndroid::AvatarFetcherAndroid(
58 const base::android::ScopedJavaGlobalRef
<jobject
>& java_infobar
)
59 : AccountAvatarFetcher(url
, base::WeakPtr
<AccountAvatarFetcherDelegate
>()),
61 java_infobar_(java_infobar
) {
64 void AvatarFetcherAndroid::OnFetchComplete(const GURL
& url
,
65 const SkBitmap
* bitmap
) {
67 base::android::ScopedJavaLocalRef
<jobject
> java_bitmap
=
68 gfx::ConvertToJavaBitmap(bitmap
);
69 Java_AccountChooserInfoBar_imageFetchComplete(
70 base::android::AttachCurrentThread(), java_infobar_
.obj(), index_
,
77 const base::android::ScopedJavaGlobalRef
<jobject
>& java_infobar
,
78 const std::vector
<const autofill::PasswordForm
*>& password_forms
,
80 net::URLRequestContextGetter
* request_context
) {
81 for (auto password_form
: password_forms
) {
82 if (!password_form
->icon_url
.is_valid())
84 // Fetcher deletes itself once fetching is finished.
85 auto fetcher
= new AvatarFetcherAndroid(password_form
->icon_url
, index
,
87 fetcher
->Start(request_context
);
94 AccountChooserInfoBar::AccountChooserInfoBar(
95 scoped_ptr
<AccountChooserInfoBarDelegateAndroid
> delegate
)
96 : InfoBarAndroid(delegate
.Pass()) {
99 AccountChooserInfoBar::~AccountChooserInfoBar() {
102 base::android::ScopedJavaLocalRef
<jobject
>
103 AccountChooserInfoBar::CreateRenderInfoBar(JNIEnv
* env
) {
104 size_t credential_array_size
=
105 GetDelegate()->local_credentials_forms().size() +
106 GetDelegate()->federated_credentials_forms().size();
107 ScopedJavaLocalRef
<jobjectArray
> java_credentials_array
=
108 CreateNativeCredentialArray(env
, credential_array_size
);
109 AddElementsToJavaCredentialArray(
110 env
, java_credentials_array
, GetDelegate()->local_credentials_forms(),
111 password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD
);
112 AddElementsToJavaCredentialArray(
113 env
, java_credentials_array
, GetDelegate()->federated_credentials_forms(),
114 password_manager::CredentialType::CREDENTIAL_TYPE_FEDERATED
,
115 GetDelegate()->local_credentials_forms().size());
116 base::android::ScopedJavaGlobalRef
<jobject
> java_infobar_global
;
117 java_infobar_global
.Reset(Java_AccountChooserInfoBar_show(
118 env
, GetEnumeratedIconId(), java_credentials_array
.obj(),
119 base::android::ConvertUTF16ToJavaString(env
, GetDelegate()->message())
121 GetDelegate()->message_link_range().start(),
122 GetDelegate()->message_link_range().end()));
123 base::android::ScopedJavaLocalRef
<jobject
> java_infobar(java_infobar_global
);
124 content::WebContents
* web_contents
=
125 InfoBarService::WebContentsFromInfoBar(this);
126 net::URLRequestContextGetter
* request_context
=
127 Profile::FromBrowserContext(web_contents
->GetBrowserContext())
128 ->GetRequestContext();
129 FetchAvatars(java_infobar_global
, GetDelegate()->local_credentials_forms(), 0,
132 java_infobar_global
, GetDelegate()->federated_credentials_forms(),
133 GetDelegate()->local_credentials_forms().size(), request_context
);
137 void AccountChooserInfoBar::OnCredentialClicked(JNIEnv
* env
,
139 jint credential_item
,
140 jint credential_type
) {
141 GetDelegate()->ChooseCredential(
143 static_cast<password_manager::CredentialType
>(credential_type
));
147 void AccountChooserInfoBar::ProcessButton(int action
,
148 const std::string
& action_value
) {
150 return; // We're closing; don't call anything, it might access the owner.
151 GetDelegate()->ChooseCredential(
152 -1, password_manager::CredentialType::CREDENTIAL_TYPE_EMPTY
);
156 void AccountChooserInfoBar::OnLinkClicked(JNIEnv
* env
, jobject obj
) {
157 GetDelegate()->LinkClicked();
160 AccountChooserInfoBarDelegateAndroid
* AccountChooserInfoBar::GetDelegate() {
161 return static_cast<AccountChooserInfoBarDelegateAndroid
*>(delegate());
164 void AccountChooserInfoBar::SetJavaInfoBar(
165 const base::android::JavaRef
<jobject
>& java_info_bar
) {
166 InfoBarAndroid::SetJavaInfoBar(java_info_bar
);
167 JNIEnv
* env
= base::android::AttachCurrentThread();
168 Java_AccountChooserInfoBar_setNativePtr(env
, java_info_bar
.obj(),
169 reinterpret_cast<intptr_t>(this));
172 bool RegisterAccountChooserInfoBar(JNIEnv
* env
) {
173 return RegisterNativesImpl(env
);