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