| // Copyright 2014 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.autofill; |
| |
| import android.content.Context; |
| import android.os.Handler; |
| import android.view.View; |
| import android.widget.AdapterView; |
| import android.widget.PopupWindow; |
| |
| import org.chromium.base.annotations.CalledByNative; |
| import org.chromium.base.annotations.JNINamespace; |
| import org.chromium.chrome.R; |
| import org.chromium.ui.DropdownPopupWindow; |
| import org.chromium.ui.base.WindowAndroid; |
| |
| /** |
| * JNI call glue for password generation between native and Java objects. |
| */ |
| @JNINamespace("autofill") |
| public class PasswordGenerationPopupBridge |
| implements AdapterView.OnItemClickListener, PopupWindow.OnDismissListener, |
| PasswordGenerationAdapter.Delegate { |
| private final long mNativePasswordGenerationPopupViewAndroid; |
| private final Context mContext; |
| private final DropdownPopupWindow mPopup; |
| private final View mAnchorView; |
| /** |
| * A convenience method for the constructor to be invoked from the native counterpart. |
| * @param anchorView View anchored for popup. |
| * @param nativePopup The pointer to the native counterpart. |
| * @param windowAndroid The browser window. |
| */ |
| @CalledByNative |
| private static PasswordGenerationPopupBridge create(View anchorView, long nativePopup, |
| WindowAndroid windowAndroid) { |
| return new PasswordGenerationPopupBridge(anchorView, nativePopup, windowAndroid); |
| } |
| |
| /** |
| * Builds the bridge between native and Java objects. |
| * @param anchorView View anchored for popup. |
| * @param nativePopup The pointer to the native counterpart. |
| * @param windowAndroid The browser window. |
| */ |
| public PasswordGenerationPopupBridge(View anchorView, long nativePopup, |
| WindowAndroid windowAndroid) { |
| mNativePasswordGenerationPopupViewAndroid = nativePopup; |
| mContext = windowAndroid.getActivity().get(); |
| mAnchorView = anchorView; |
| // mContext could've been garbage collected. |
| if (mContext == null) { |
| mPopup = null; |
| // Prevent destroying the native counterpart when it's about to derefence its own |
| // members in UpdateBoundsAndRedrawPopup(). |
| new Handler().post(this::onDismiss); |
| } else { |
| mPopup = new DropdownPopupWindow(mContext, anchorView); |
| mPopup.setOnItemClickListener(this); |
| mPopup.setOnDismissListener(this); |
| mPopup.disableHideOnOutsideTap(); |
| mPopup.setContentDescriptionForAccessibility( |
| mContext.getString(R.string.password_generation_popup_content_description)); |
| } |
| } |
| |
| /** |
| * Handles clicks on popup list elements. Only suggestion element is enabled. Clicking on the |
| * suggestion element notifies the native counterpart that the suggested password was selected. |
| * @param parent The parent view where the click happened. |
| * @param view The view that was provided by the adapter that was clicked. |
| * @param position The position of the view in the adapter. |
| * @param id The row id of the clicked element. |
| */ |
| @Override |
| public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
| nativePasswordSelected(mNativePasswordGenerationPopupViewAndroid); |
| } |
| |
| private native void nativePasswordSelected(long nativePasswordGenerationPopupViewAndroid); |
| |
| /** |
| * Handles dismissing the popup window. The native counterpart is notified to destroy the |
| * controller. |
| */ |
| @Override |
| public void onDismiss() { |
| nativeDismissed(mNativePasswordGenerationPopupViewAndroid); |
| } |
| |
| private native void nativeDismissed(long nativePasswordGenerationPopupViewAndroid); |
| |
| /** |
| * Shows a password generation popup with specified data. Should be called after |
| * setAnchorRect(). |
| * @param isRtl True if the popup should be RTL. |
| * @param passwordDisplayed Whether the generated password should be displayed. |
| * @param password The auto-generated password to suggest. |
| * @param suggestionTitle The translated title of the suggestion part of the popup. |
| * @param explanationText The translated text that explains the popup. |
| * @param explanationTextLinkRangeStart The start of the range in the explanation text that |
| * should be a link to the saved passwords. |
| * @param explanationTextLinkRangeEnd The end of the range in the explanation text that should |
| * be a link to the saved passwords. |
| */ |
| @CalledByNative |
| private void show(boolean isRtl, boolean passwordDisplayed, String password, |
| String suggestionTitle, String explanationText, int explanationTextLinkRangeStart, |
| int explanationTextLinkRangeEnd) { |
| if (mPopup != null) { |
| float anchorWidth = mAnchorView.getLayoutParams().width; |
| assert anchorWidth > 0; |
| PasswordGenerationAdapter adapter = new PasswordGenerationAdapter(mContext, this, |
| passwordDisplayed, password, suggestionTitle, explanationText, |
| explanationTextLinkRangeStart, explanationTextLinkRangeEnd, anchorWidth); |
| mPopup.setAdapter(adapter); |
| mPopup.setRtl(isRtl); |
| mPopup.show(); |
| } |
| } |
| |
| /** |
| * Called from adapter when the "saved passwords" link is clicked. |
| */ |
| @Override |
| public void onSavedPasswordsLinkClicked() { |
| nativeSavedPasswordsLinkClicked(mNativePasswordGenerationPopupViewAndroid); |
| } |
| |
| private native void nativeSavedPasswordsLinkClicked( |
| long nativePasswordGenerationPopupViewAndroid); |
| |
| /** |
| * Hides the password generation popup. |
| */ |
| @CalledByNative |
| private void hide() { |
| if (mPopup != null) mPopup.dismiss(); |
| } |
| } |