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 package org.chromium.ui.autofill; 6 7 import android.content.Context; 8 import android.view.View; 9 import android.widget.AdapterView; 10 11 import org.chromium.ui.DropdownAdapter; 12 import org.chromium.ui.DropdownItem; 13 import org.chromium.ui.DropdownPopupWindow; 14 import org.chromium.ui.base.ViewAndroidDelegate; 15 16 import java.util.ArrayList; 17 import java.util.Arrays; 18 import java.util.HashSet; 19 import java.util.List; 20 21 /** 22 * The Autofill suggestion popup that lists relevant suggestions. 23 */ 24 public class AutofillPopup extends DropdownPopupWindow implements AdapterView.OnItemClickListener { 25 26 /** 27 * Constants defining types of Autofill suggestion entries. 28 * Has to be kept in sync with enum in WebAutofillClient.h 29 * 30 * Not supported: MenuItemIDWarningMessage, MenuItemIDClearForm, and 31 * MenuItemIDAutofillOptions. 32 */ 33 private static final int ITEM_ID_AUTOCOMPLETE_ENTRY = 0; 34 private static final int ITEM_ID_PASSWORD_ENTRY = -2; 35 private static final int ITEM_ID_SEPARATOR_ENTRY = -3; 36 private static final int ITEM_ID_DATA_LIST_ENTRY = -6; 37 38 private final Context mContext; 39 private final AutofillPopupDelegate mAutofillCallback; 40 private List<AutofillSuggestion> mSuggestions; 41 42 43 /** 44 * An interface to handle the touch interaction with an AutofillPopup object. 45 */ 46 public interface AutofillPopupDelegate { 47 /** 48 * Requests the controller to hide AutofillPopup. 49 */ requestHide()50 public void requestHide(); 51 52 /** 53 * Handles the selection of an Autofill suggestion from an AutofillPopup. 54 * @param listIndex The index of the selected Autofill suggestion. 55 */ suggestionSelected(int listIndex)56 public void suggestionSelected(int listIndex); 57 } 58 59 /** 60 * Creates an AutofillWindow with specified parameters. 61 * @param context Application context. 62 * @param viewAndroidDelegate View delegate used to add and remove views. 63 * @param autofillCallback A object that handles the calls to the native AutofillPopupView. 64 */ AutofillPopup(Context context, ViewAndroidDelegate viewAndroidDelegate, AutofillPopupDelegate autofillCallback)65 public AutofillPopup(Context context, ViewAndroidDelegate viewAndroidDelegate, 66 AutofillPopupDelegate autofillCallback) { 67 super(context, viewAndroidDelegate); 68 mContext = context; 69 mAutofillCallback = autofillCallback; 70 71 setOnItemClickListener(this); 72 } 73 74 /** 75 * Filters the Autofill suggestions to the ones that we support and shows the popup. 76 * @param suggestions Autofill suggestion data. 77 */ filterAndShow(AutofillSuggestion[] suggestions)78 public void filterAndShow(AutofillSuggestion[] suggestions) { 79 mSuggestions = new ArrayList<AutofillSuggestion>(Arrays.asList(suggestions)); 80 // Remove the AutofillSuggestions with IDs that are not supported by Android 81 ArrayList<DropdownItem> cleanedData = new ArrayList<DropdownItem>(); 82 HashSet<Integer> separators = new HashSet<Integer>(); 83 for (int i = 0; i < suggestions.length; i++) { 84 int itemId = suggestions[i].mUniqueId; 85 if (itemId > 0 || itemId == ITEM_ID_AUTOCOMPLETE_ENTRY || 86 itemId == ITEM_ID_PASSWORD_ENTRY || itemId == ITEM_ID_DATA_LIST_ENTRY) { 87 cleanedData.add(suggestions[i]); 88 } else if (itemId == ITEM_ID_SEPARATOR_ENTRY) { 89 separators.add(cleanedData.size()); 90 } 91 } 92 setAdapter(new DropdownAdapter(mContext, cleanedData, separators)); 93 show(); 94 } 95 96 /** 97 * Overrides the default dismiss behavior to request the controller to dismiss the view. 98 */ 99 @Override dismiss()100 public void dismiss() { 101 mAutofillCallback.requestHide(); 102 } 103 104 /** 105 * Hides the popup. 106 */ hide()107 public void hide() { 108 super.dismiss(); 109 } 110 111 @Override onItemClick(AdapterView<?> parent, View view, int position, long id)112 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 113 DropdownAdapter adapter = (DropdownAdapter) parent.getAdapter(); 114 int listIndex = mSuggestions.indexOf(adapter.getItem(position)); 115 assert listIndex > -1; 116 mAutofillCallback.suggestionSelected(listIndex); 117 } 118 } 119