Pass all info to  account chooser infobar.

Now account chooser infobar (which is one of the Smart Lock infobars) displaying only username. This patch adds ability to infobar to show full name and picture associated with account.

BUG=454815

Review URL: https://codereview.chromium.org/925593006

Cr-Commit-Position: refs/heads/master@{#321099}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AccountChooserInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AccountChooserInfoBar.java
index 0bf059b..0f35999e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AccountChooserInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AccountChooserInfoBar.java
@@ -18,6 +18,7 @@
 import org.chromium.base.CalledByNative;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ResourceId;
+import org.chromium.chrome.browser.password_manager.Credential;
 
 /**
  * An infobar offers the user the ability to choose credentials for
@@ -25,46 +26,32 @@
  * full name in case they are available.
  */
 public class AccountChooserInfoBar extends InfoBar {
-    private enum CredentialType {
-        EMPTY(0),
-        LOCAL(1),
-        FEDERATED(2);
-
-        private final int mType;
-        private CredentialType(int type) {
-            mType = type;
-        };
-
-        public int getValue() {
-            return mType;
-        }
-    }
-
-    private final String[] mUsernames;
+    private final Credential[] mCredentials;
 
     /**
      * Creates and shows the infobar wich allows user to choose credentials for login.
      * @param nativeInfoBar Pointer to the native infobar.
      * @param enumeratedIconId Enum ID corresponding to the icon that the infobar will show.
-     * @param usernames Usernames to display in the infobar.
+     * @param credentials Credentials to display in the infobar.
      */
     @CalledByNative
-    private static InfoBar show(long nativeInfoBar, int enumeratedIconId, String[] usernames) {
+    private static InfoBar show(
+            long nativeInfoBar, int enumeratedIconId, Credential[] credentials) {
         return new AccountChooserInfoBar(
-                nativeInfoBar, ResourceId.mapToDrawableId(enumeratedIconId), usernames);
+                nativeInfoBar, ResourceId.mapToDrawableId(enumeratedIconId), credentials);
     }
 
     /**
      * Creates and shows the infobar  which allows user to choose credentials.
      * @param nativeInfoBar Pointer to the native infobar.
      * @param iconDrawableId Drawable ID corresponding to the icon that the infobar will show.
-     * @param usernames list of usernames to display in infobar.
+     * @param credentials Credentials to display in the infobar.
      */
-    public AccountChooserInfoBar(long nativeInfoBar, int iconDrawableId, String[] usernames) {
+    public AccountChooserInfoBar(long nativeInfoBar, int iconDrawableId, Credential[] credentials) {
         super(null /* Infobar Listener */, iconDrawableId, null /* bitmap*/,
                 null /* message to show */);
         setNativeInfoBar(nativeInfoBar);
-        mUsernames = usernames.clone();
+        mCredentials = credentials.clone();
     }
 
 
@@ -89,7 +76,7 @@
     private void createAccountsView(InfoBarLayout layout) {
         ViewGroup accountsView = (ViewGroup) LayoutInflater.from(getContext()).inflate(
                 R.layout.account_chooser_infobar_list, null, false);
-        ArrayAdapter<String> adapter = generateAccountsArrayAdapter(getContext(), mUsernames);
+        ArrayAdapter<Credential> adapter = generateAccountsArrayAdapter(getContext(), mCredentials);
         ListView listView = (ListView) accountsView.findViewById(R.id.account_list);
         listView.setAdapter(adapter);
         float numVisibleItems = adapter.getCount() > 2 ? 2.5f : adapter.getCount();
@@ -100,8 +87,9 @@
         layout.setCustomContent(accountsView);
     }
 
-    private ArrayAdapter<String> generateAccountsArrayAdapter(Context context, String[] usernames) {
-        return new ArrayAdapter<String>(context, 0, usernames) {
+    private ArrayAdapter<Credential> generateAccountsArrayAdapter(
+            Context context, Credential[] credentials) {
+        return new ArrayAdapter<Credential>(context, 0, credentials) {
             @Override
             public View getView(int position, View convertView, ViewGroup parent) {
                 if (convertView == null) {
@@ -111,19 +99,19 @@
                 ImageView avatarView = (ImageView) convertView.findViewById(R.id.profile_image);
                 TextView usernameView = (TextView) convertView.findViewById(R.id.username);
                 TextView displayNameView = (TextView) convertView.findViewById(R.id.display_name);
-                String username = getItem(position);
-                usernameView.setText(username);
-                // TODO(melandory): View should show the full name. Temporarily the view shows
-                // username.
-                displayNameView.setText(username);
+                Credential credential = getItem(position);
+                usernameView.setText(credential.getUsername());
+                displayNameView.setText(credential.getDisplayName());
                 // TODO(melandory): View should show proper avatar. Temporarily the view shows
                 // blue man icon.
                 avatarView.setImageResource(R.drawable.account_management_no_picture);
-                final int currentCredentialIndex = position;
+                final int currentCredentialIndex = credential.getIndex();
+                final int credentialType = credential.getType();
                 convertView.setOnClickListener(new View.OnClickListener() {
                     @Override
                     public void onClick(View view) {
-                        passCredentialsToNative(currentCredentialIndex);
+                        nativeOnCredentialClicked(
+                                mNativeInfoBarPtr, currentCredentialIndex, credentialType);
                     }
                 });
                 return convertView;
@@ -141,14 +129,6 @@
         layout.setCustomViewInButtonRow(OverflowSelector.createOverflowSelector(getContext()));
     }
 
-    private void passCredentialsToNative(int credentialIndex) {
-        // TODO(melandory): Adding federated login support should change this
-        // code.
-        nativeOnCredentialClicked(
-                mNativeInfoBarPtr, credentialIndex, CredentialType.LOCAL.getValue());
-    }
-
-
     private native void nativeOnCredentialClicked(
             long nativeAccountChooserInfoBar, int credentialId, int credentialType);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/Credential.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/Credential.java
new file mode 100644
index 0000000..d694f0c
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/Credential.java
@@ -0,0 +1,61 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.password_manager;
+
+import org.chromium.base.CalledByNative;
+
+/**
+ * Credential type which is used to represent credential which will be shown in account chooser
+ * infobar.
+ * */
+public class Credential {
+    private final String mUsername;
+    private final String mDisplayName;
+    private final int mType;
+    private final int mIndex;
+
+    /**
+     * @param username username which is used to authenticate user.
+     *                 The value is PasswordForm::username_value.
+     * @param displayName user friendly name to show in the UI. It can be empty.
+     *                    The value is PasswordForm::display_name.
+     * @param type type which should be either local or federated. The value corresponds to a
+     *             C++ enum CredentialType.
+     * @param index position in array of credentials.
+     */
+    public Credential(String username, String displayName, int type, int index) {
+        mUsername = username;
+        mDisplayName = displayName;
+        mType = type;
+        mIndex = index;
+    }
+
+    public String getUsername() {
+        return mUsername;
+    }
+
+    public String getDisplayName() {
+        return mDisplayName;
+    }
+
+    public int getIndex() {
+        return mIndex;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    @CalledByNative
+    private static Credential createCredential(
+            String username, String displayName, int type, int index) {
+        return new Credential(username, displayName, type, index);
+    }
+
+    @CalledByNative
+    private static Credential[] createCredentialArray(int size) {
+        return new Credential[size];
+    }
+}
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index b6628a7..0f18746 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -67,6 +67,7 @@
 #include "chrome/browser/lifetime/application_lifetime_android.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h"
 #include "chrome/browser/notifications/notification_ui_manager_android.h"
+#include "chrome/browser/password_manager/credential_android.h"
 #include "chrome/browser/prerender/external_prerender_handler_android.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/search_engines/template_url_service_android.h"
@@ -165,6 +166,7 @@
     {"ContentViewUtil", RegisterContentViewUtil},
     {"ContextMenuHelper", RegisterContextMenuHelper},
     {"CookiesFetcher", RegisterCookiesFetcher},
+    {"Credential", RegisterCredential},
     {"CreditCardScanner", autofill::CreditCardScannerViewAndroid::Register},
     {"DataReductionProxyInfoBarDelegate", DataReductionProxyInfoBar::Register},
     {"DataReductionProxySettings", DataReductionProxySettingsAndroid::Register},
diff --git a/chrome/browser/password_manager/account_chooser_infobar_delegate_android.h b/chrome/browser/password_manager/account_chooser_infobar_delegate_android.h
index 3d1060de..8e6afd6 100644
--- a/chrome/browser/password_manager/account_chooser_infobar_delegate_android.h
+++ b/chrome/browser/password_manager/account_chooser_infobar_delegate_android.h
@@ -34,6 +34,11 @@
     return ui_controller_->GetCurrentForms();
   }
 
+  const std::vector<const autofill::PasswordForm*>&
+  federated_credentials_forms() const {
+    return ui_controller_->GetFederatedForms();
+  }
+
   void ChooseCredential(size_t credential_index,
                         password_manager::CredentialType credential_type);
 
diff --git a/chrome/browser/password_manager/credential_android.cc b/chrome/browser/password_manager/credential_android.cc
new file mode 100644
index 0000000..bc4ce1b0
--- /dev/null
+++ b/chrome/browser/password_manager/credential_android.cc
@@ -0,0 +1,31 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/password_manager/credential_android.h"
+
+#include "base/android/jni_string.h"
+#include "jni/Credential_jni.h"
+
+base::android::ScopedJavaLocalRef<jobject> CreateNativeCredential(
+    JNIEnv* env,
+    const autofill::PasswordForm& password_form,
+    int position,
+    int type) {
+  using base::android::ConvertUTF16ToJavaString;
+  using base::android::ConvertUTF8ToJavaString;
+  return Java_Credential_createCredential(
+      env, ConvertUTF16ToJavaString(env, password_form.username_value).obj(),
+      ConvertUTF16ToJavaString(env, password_form.display_name).obj(), type,
+      position);
+}
+
+base::android::ScopedJavaLocalRef<jobjectArray> CreateNativeCredentialArray(
+    JNIEnv* env,
+    size_t size) {
+  return Java_Credential_createCredentialArray(env, static_cast<int>(size));
+}
+
+bool RegisterCredential(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
diff --git a/chrome/browser/password_manager/credential_android.h b/chrome/browser/password_manager/credential_android.h
new file mode 100644
index 0000000..6f450e183
--- /dev/null
+++ b/chrome/browser/password_manager/credential_android.h
@@ -0,0 +1,29 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PASSWORD_MANAGER_CREDENTIAL_ANDROID_H_
+#define CHROME_BROWSER_PASSWORD_MANAGER_CREDENTIAL_ANDROID_H_
+
+#include "base/android/jni_array.h"
+#include "base/android/scoped_java_ref.h"
+#include "components/autofill/core/common/password_form.h"
+
+// Creates Java counterpart of autofill::PasswordForm, assigning it a |position|
+// in case form is part of some array of forms and |type| which should be either
+// local or federated.
+base::android::ScopedJavaLocalRef<jobject> CreateNativeCredential(
+    JNIEnv* env,
+    const autofill::PasswordForm& password_form,
+    int position,
+    int type);
+
+// Creates Java Credential[] array of size |size|.
+base::android::ScopedJavaLocalRef<jobjectArray> CreateNativeCredentialArray(
+    JNIEnv* env,
+    size_t size);
+
+// Registers the Credential native method.
+bool RegisterCredential(JNIEnv* env);
+
+#endif  // CHROME_BROWSER_PASSWORD_MANAGER_CREDENTIAL_ANDROID_H_
diff --git a/chrome/browser/ui/android/infobars/account_chooser_infobar.cc b/chrome/browser/ui/android/infobars/account_chooser_infobar.cc
index 00fa5fd..68d42e9 100644
--- a/chrome/browser/ui/android/infobars/account_chooser_infobar.cc
+++ b/chrome/browser/ui/android/infobars/account_chooser_infobar.cc
@@ -4,13 +4,32 @@
 
 #include "chrome/browser/ui/android/infobars/account_chooser_infobar.h"
 
-#include "base/android/jni_android.h"
-#include "base/android/jni_array.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/password_manager/account_chooser_infobar_delegate_android.h"
+#include "chrome/browser/password_manager/credential_android.h"
 #include "components/password_manager/content/common/credential_manager_types.h"
 #include "jni/AccountChooserInfoBar_jni.h"
 
+namespace {
+
+void AddElementsToJavaCredentialArray(
+    JNIEnv* env,
+    ScopedJavaLocalRef<jobjectArray> java_credentials_array,
+    const std::vector<const autofill::PasswordForm*>& password_forms,
+    password_manager::CredentialType type,
+    int indexStart = 0) {
+  int index = indexStart;
+  for (auto password_form : password_forms) {
+    ScopedJavaLocalRef<jobject> java_credential = CreateNativeCredential(
+        env, *password_form, index - indexStart, static_cast<int>(type));
+    env->SetObjectArrayElement(java_credentials_array.obj(), index,
+                               java_credential.obj());
+    index++;
+  }
+}
+
+};  // namespace
+
 AccountChooserInfoBar::AccountChooserInfoBar(
     scoped_ptr<AccountChooserInfoBarDelegateAndroid> delegate)
     : InfoBarAndroid(delegate.Pass()) {
@@ -21,15 +40,21 @@
 
 base::android::ScopedJavaLocalRef<jobject>
 AccountChooserInfoBar::CreateRenderInfoBar(JNIEnv* env) {
-  std::vector<base::string16> usernames;
-  // TODO(melandory): Federated credentials should be processed also.
-  for (auto password_form : GetDelegate()->local_credentials_forms())
-    usernames.push_back(password_form->username_value);
-  base::android::ScopedJavaLocalRef<jobjectArray> java_usernames =
-      base::android::ToJavaArrayOfStrings(env, usernames);
+  size_t credential_array_size =
+      GetDelegate()->local_credentials_forms().size() +
+      GetDelegate()->federated_credentials_forms().size();
+  ScopedJavaLocalRef<jobjectArray> java_credentials_array =
+      CreateNativeCredentialArray(env, credential_array_size);
+  AddElementsToJavaCredentialArray(
+      env, java_credentials_array, GetDelegate()->local_credentials_forms(),
+      password_manager::CredentialType::CREDENTIAL_TYPE_LOCAL);
+  AddElementsToJavaCredentialArray(
+      env, java_credentials_array, GetDelegate()->federated_credentials_forms(),
+      password_manager::CredentialType::CREDENTIAL_TYPE_FEDERATED,
+      GetDelegate()->local_credentials_forms().size());
   return Java_AccountChooserInfoBar_show(env, reinterpret_cast<intptr_t>(this),
                                          GetEnumeratedIconId(),
-                                         java_usernames.obj());
+                                         java_credentials_array.obj());
 }
 
 void AccountChooserInfoBar::OnCredentialClicked(JNIEnv* env,
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 5718688..f8c985e7 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -733,6 +733,8 @@
       'browser/metrics/android_metrics_provider.h',
       'browser/password_manager/account_chooser_infobar_delegate_android.cc',
       'browser/password_manager/account_chooser_infobar_delegate_android.h',
+       'browser/password_manager/credential_android.cc',
+      'browser/password_manager/credential_android.h',
       'browser/password_manager/generated_password_saved_infobar_delegate_android.cc',
       'browser/password_manager/generated_password_saved_infobar_delegate_android.h',
       'browser/sessions/in_memory_tab_restore_service.cc',
@@ -1641,6 +1643,7 @@
       'android/java/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizer.java',
       'android/java/src/org/chromium/chrome/browser/omnibox/OmniboxViewUtil.java',
       'android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java',
+      'android/java/src/org/chromium/chrome/browser/password_manager/Credential.java',
       'android/java/src/org/chromium/chrome/browser/password_manager/PasswordAuthenticationManager.java',
       'android/java/src/org/chromium/chrome/browser/PasswordUIView.java',
       'android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java',