// 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.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ResourceId;
import org.chromium.components.autofill.AutofillDelegate;
import org.chromium.components.autofill.AutofillKeyboardAccessory;
import org.chromium.components.autofill.AutofillSuggestion;
import org.chromium.ui.DropdownItem;
import org.chromium.ui.base.WindowAndroid;
/**
* JNI call glue for AutofillExternalDelagate C++ and Java objects.
* This provides an alternative UI for Autofill suggestions, and replaces AutofillPopupBridge when
* --enable-autofill-keyboard-accessory-view is passed on the command line.
*/
@JNINamespace("autofill")
public class AutofillKeyboardAccessoryBridge
implements AutofillDelegate, DialogInterface.OnClickListener {
private long mNativeAutofillKeyboardAccessory;
private AutofillKeyboardAccessory mAccessoryView;
private Context mContext;
private AutofillKeyboardAccessoryBridge() {
}
@CalledByNative
private static AutofillKeyboardAccessoryBridge create() {
return new AutofillKeyboardAccessoryBridge();
}
@Override
public void dismissed() {
if (mNativeAutofillKeyboardAccessory == 0) return;
nativeViewDismissed(mNativeAutofillKeyboardAccessory);
}
@Override
public void suggestionSelected(int listIndex) {
if (mNativeAutofillKeyboardAccessory == 0) return;
nativeSuggestionSelected(mNativeAutofillKeyboardAccessory, listIndex);
}
@Override
public void deleteSuggestion(int listIndex) {
if (mNativeAutofillKeyboardAccessory == 0) return;
nativeDeletionRequested(mNativeAutofillKeyboardAccessory, listIndex);
}
@Override
public void onClick(DialogInterface dialog, int which) {
assert which == DialogInterface.BUTTON_POSITIVE;
if (mNativeAutofillKeyboardAccessory == 0) return;
nativeDeletionConfirmed(mNativeAutofillKeyboardAccessory);
}
/**
* Initializes this object.
* This function should be called at most one time.
* @param nativeAutofillKeyboardAccessory Handle to the native counterpart.
* @param windowAndroid The window on which to show the suggestions.
*/
@CalledByNative
private void init(long nativeAutofillKeyboardAccessory, WindowAndroid windowAndroid) {
if (windowAndroid == null || windowAndroid.getActivity().get() == null) {
nativeViewDismissed(nativeAutofillKeyboardAccessory);
dismissed();
return;
}
mNativeAutofillKeyboardAccessory = nativeAutofillKeyboardAccessory;
mAccessoryView = new AutofillKeyboardAccessory(windowAndroid, this);
mContext = windowAndroid.getActivity().get();
}
/**
* Clears the reference to the native view.
*/
@CalledByNative
private void resetNativeViewPointer() {
mNativeAutofillKeyboardAccessory = 0;
}
/**
* Hides the Autofill view.
*/
@CalledByNative
private void dismiss() {
if (mAccessoryView != null) mAccessoryView.dismiss();
mContext = null;
}
/**
* Shows an Autofill view with specified suggestions.
* @param suggestions Autofill suggestions to be displayed.
*/
@CalledByNative
private void show(AutofillSuggestion[] suggestions, boolean isRtl) {
if (mAccessoryView != null) mAccessoryView.showWithSuggestions(suggestions, isRtl);
}
// Helper methods for AutofillSuggestion. These are copied from AutofillPopupBridge (which
// should
// eventually disappear).
@CalledByNative
private void confirmDeletion(String title, String body) {
new AlertDialog.Builder(mContext, R.style.AlertDialogTheme)
.setTitle(title)
.setMessage(body)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok, this)
.create()
.show();
}
@CalledByNative
private static AutofillSuggestion[] createAutofillSuggestionArray(int size) {
return new AutofillSuggestion[size];
}
/**
* @param array AutofillSuggestion array that should get a new suggestion added.
* @param index Index in the array where to place a new suggestion.
* @param label Suggested text. The text that's going to be filled in the focused field, with a
* few exceptions:
* <ul>
* <li>Credit card numbers are elided, e.g. "Visa ****-1234."</li>
* <li>The text "CLEAR FORM" will clear the filled in text.</li>
* <li>Empty text can be used to display only icons, e.g. for credit card scan
* or editing autofill settings.</li>
* </ul>
* @param sublabel Hint for the suggested text. The text that's going to be filled in the
* unfocused fields of the form. If {@see label} is empty, then this must be
* empty too.
* @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon.
* @param suggestionId Identifier for the suggestion type.
*/
@CalledByNative
private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
String label, String sublabel, int iconId, int suggestionId, boolean deletable) {
int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId);
array[index] =
new AutofillSuggestion(label, sublabel, drawableId, suggestionId, deletable, false);
}
private native void nativeViewDismissed(long nativeAutofillKeyboardAccessoryView);
private native void nativeSuggestionSelected(
long nativeAutofillKeyboardAccessoryView, int listIndex);
private native void nativeDeletionRequested(
long nativeAutofillKeyboardAccessoryView, int listIndex);
private native void nativeDeletionConfirmed(long nativeAutofillKeyboardAccessoryView);
}