Merge "Moar pre-partitioning refactoring." into oc-dev
am: 92f76ba958
Change-Id: Ia6c04764c0df183849abb2e95254bc38b84c1c99
This commit is contained in:
@@ -97,7 +97,7 @@ public final class Dataset implements Parcelable {
|
||||
if (!DEBUG) return super.toString();
|
||||
|
||||
return new StringBuilder("Dataset [")
|
||||
.append(", fieldIds=").append(mFieldIds)
|
||||
.append("fieldIds=").append(mFieldIds)
|
||||
.append(", fieldValues=").append(mFieldValues)
|
||||
.append(", fieldPresentations=")
|
||||
.append(mFieldPresentations == null ? 0 : mFieldPresentations.size())
|
||||
|
||||
@@ -535,6 +535,7 @@ public class TimePicker extends FrameLayout {
|
||||
|
||||
if (!value.isDate()) {
|
||||
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
|
||||
return;
|
||||
}
|
||||
|
||||
mDelegate.setDate(value.getDateValue());
|
||||
|
||||
@@ -16,13 +16,8 @@
|
||||
|
||||
package com.android.server.autofill;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Bundle;
|
||||
import android.service.autofill.Dataset;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -54,24 +49,6 @@ final class Helper {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a {@link Dataset} field by its id, or {@code null} if not found.
|
||||
*/
|
||||
@Nullable
|
||||
static AutofillValue findValue(Dataset dataset, AutofillId id) {
|
||||
if (dataset != null) {
|
||||
final ArrayList<AutofillId> ids = dataset.getFieldIds();
|
||||
final int size = ids.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (id.equals(ids.get(i))) {
|
||||
return dataset.getFieldValues().get(i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Helper() {
|
||||
throw new UnsupportedOperationException("contains static members only");
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;
|
||||
|
||||
import static com.android.server.autofill.Helper.DEBUG;
|
||||
import static com.android.server.autofill.Helper.VERBOSE;
|
||||
import static com.android.server.autofill.Helper.findValue;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -120,10 +119,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
/**
|
||||
* Used to remember which {@link Dataset} filled the session.
|
||||
*/
|
||||
// TODO(b/33197203 , b/35707731): might need more than one once it supports partitioning
|
||||
// TODO(b/33197203 , b/35707731): will be removed once it supports partitioning
|
||||
@GuardedBy("mLock")
|
||||
private Dataset mAutoFilledDataset;
|
||||
|
||||
/**
|
||||
* Dataset that when tapped launched a service authentication request.
|
||||
*/
|
||||
private Dataset mDatasetWaitingAuth;
|
||||
|
||||
/**
|
||||
* Assist structure sent by the app; it will be updated (sanitized, change values for save)
|
||||
* before sent to {@link AutofillService}.
|
||||
@@ -326,10 +330,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
processResponseLocked(mCurrentResponse);
|
||||
} else if (result instanceof Dataset) {
|
||||
final Dataset dataset = (Dataset) result;
|
||||
final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset);
|
||||
final int index = mCurrentResponse.getDatasets().indexOf(mDatasetWaitingAuth);
|
||||
if (index >= 0) {
|
||||
mCurrentResponse.getDatasets().set(index, dataset);
|
||||
autoFill(dataset);
|
||||
mDatasetWaitingAuth = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,58 +390,49 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
boolean atLeastOneChanged = false;
|
||||
for (int i = 0; i < requiredIds.length; i++) {
|
||||
final AutofillId id = requiredIds[i];
|
||||
final ViewState state = mViewStates.get(id);
|
||||
if (state == null || state.getCurrentValue() == null
|
||||
|| state.getCurrentValue().isEmpty()) {
|
||||
final ViewNode node = findViewNodeByIdLocked(id);
|
||||
if (node == null) {
|
||||
Slog.w(TAG, "Service passed invalid id on SavableInfo: " + id);
|
||||
allRequiredAreNotEmpty = false;
|
||||
break;
|
||||
}
|
||||
final AutofillValue initialValue = node.getAutofillValue();
|
||||
if (initialValue == null || initialValue.isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id );
|
||||
}
|
||||
allRequiredAreNotEmpty = false;
|
||||
break;
|
||||
}
|
||||
final ViewState viewState = mViewStates.get(id);
|
||||
if (viewState == null) {
|
||||
Slog.w(TAG, "showSaveLocked(): no ViewState for required " + id);
|
||||
continue;
|
||||
}
|
||||
if (state.isChanged()) {
|
||||
final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
|
||||
if (!state.getCurrentValue().equals(filledValue)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": "
|
||||
+ filledValue + " => " + state.getCurrentValue());
|
||||
}
|
||||
atLeastOneChanged = true;
|
||||
}
|
||||
} else {
|
||||
if (state.getCurrentValue() == null || state.getCurrentValue().isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "finishSessionLocked(): empty value for " + id + ": "
|
||||
+ state.getCurrentValue());
|
||||
}
|
||||
allRequiredAreNotEmpty = false;
|
||||
break;
|
||||
|
||||
final AutofillValue currentValue = viewState.getCurrentValue();
|
||||
if (currentValue == null || currentValue.isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "showSaveLocked(): empty value for required " + id );
|
||||
}
|
||||
allRequiredAreNotEmpty = false;
|
||||
break;
|
||||
}
|
||||
final AutofillValue filledValue = viewState.getAutofilledValue();
|
||||
|
||||
if (!currentValue.equals(filledValue)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "showSaveLocked(): found a change on required " + id + ": "
|
||||
+ filledValue + " => " + currentValue);
|
||||
}
|
||||
atLeastOneChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
final AutofillId[] optionalIds = saveInfo.getOptionalIds();
|
||||
if (allRequiredAreNotEmpty) {
|
||||
if (!atLeastOneChanged && saveInfo.getOptionalIds() != null) {
|
||||
for (int i = 0; i < saveInfo.getOptionalIds().length; i++) {
|
||||
final AutofillId id = saveInfo.getOptionalIds()[i];
|
||||
final ViewState state = mViewStates.get(id);
|
||||
if (state != null && state.getCurrentValue() != null && state.isChanged()) {
|
||||
final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
|
||||
if (!state.getCurrentValue().equals(filledValue)) {
|
||||
if (!atLeastOneChanged && optionalIds != null) {
|
||||
// No change on required ids yet, look for changes on optional ids.
|
||||
for (int i = 0; i < optionalIds.length; i++) {
|
||||
final AutofillId id = optionalIds[i];
|
||||
final ViewState viewState = mViewStates.get(id);
|
||||
if (viewState == null) {
|
||||
Slog.w(TAG, "showSaveLocked(): no ViewState for optional " + id);
|
||||
continue;
|
||||
}
|
||||
if ((viewState.getState() & ViewState.STATE_CHANGED) != 0) {
|
||||
final AutofillValue currentValue = viewState.getCurrentValue();
|
||||
final AutofillValue filledValue = viewState.getAutofilledValue();
|
||||
if (currentValue != null && !currentValue.equals(filledValue)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "finishSessionLocked(): found a change on optional "
|
||||
+ id + ": " + filledValue + " => "
|
||||
+ state.getCurrentValue());
|
||||
+ id + ": " + filledValue + " => " + currentValue);
|
||||
}
|
||||
atLeastOneChanged = true;
|
||||
break;
|
||||
@@ -523,25 +519,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
|
||||
if ((flags & FLAG_VALUE_CHANGED) != 0) {
|
||||
if (value != null && !value.equals(viewState.getCurrentValue())) {
|
||||
|
||||
// TODO(b/33197203 , b/35707731): currently resets STATE_AUTOFILLED; should check
|
||||
// first (doesn't make a difference now, but it will when it supports partitions)
|
||||
viewState.setState(ViewState.STATE_CHANGED);
|
||||
// Always update the internal state.
|
||||
viewState.setCurrentValue(value);
|
||||
|
||||
// Must check if this update was caused by autofilling the view, in which
|
||||
// case we just update the value, but not the UI.
|
||||
if (mAutoFilledDataset != null) {
|
||||
final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
|
||||
if (value.equals(filledValue)) {
|
||||
viewState.setCurrentValue(value);
|
||||
return;
|
||||
}
|
||||
final AutofillValue filledValue = viewState.getAutofilledValue();
|
||||
if (value.equals(filledValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Change value
|
||||
viewState.setCurrentValue(value);
|
||||
|
||||
// Update the chooser UI
|
||||
// Update the internal state...
|
||||
viewState.setState(ViewState.STATE_CHANGED);
|
||||
// ... and the chooser UI.
|
||||
if (value.isText()) {
|
||||
getUiForShowing().filterFillUi(value.getTextValue().toString());
|
||||
} else {
|
||||
@@ -657,6 +646,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
private void setViewStatesLocked(@Nullable FillResponse response, @NonNull Dataset dataset,
|
||||
int state) {
|
||||
final ArrayList<AutofillId> ids = dataset.getFieldIds();
|
||||
final ArrayList<AutofillValue> values = dataset.getFieldValues();
|
||||
for (int j = 0; j < ids.size(); j++) {
|
||||
final AutofillId id = ids.get(j);
|
||||
ViewState viewState = mViewStates.get(id);
|
||||
@@ -669,6 +659,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
mViewStates.put(id, viewState);
|
||||
}
|
||||
if ((state & ViewState.STATE_AUTOFILLED) != 0) {
|
||||
viewState.setAutofilledValue(values.get(j));
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
viewState.setResponse(response);
|
||||
}
|
||||
@@ -686,6 +680,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
// ...or handle authentication.
|
||||
mDatasetWaitingAuth = dataset;
|
||||
final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
|
||||
startAuthentication(dataset.getAuthentication(), fillInIntent);
|
||||
}
|
||||
@@ -721,6 +716,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
|
||||
pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse);
|
||||
pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset);
|
||||
pw.print(prefix); pw.print("mDatasetWaitingAuth: "); pw.println(mDatasetWaitingAuth);
|
||||
pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
|
||||
pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
|
||||
final String prefix2 = prefix + " ";
|
||||
|
||||
@@ -50,7 +50,7 @@ final class ViewState {
|
||||
public static final int STATE_AUTOFILLED = 0x04;
|
||||
/** View value was changed, but not by the service. */
|
||||
public static final int STATE_CHANGED = 0x08;
|
||||
/** Set only in the View that started a session . */
|
||||
/** Set only in the View that started a session. */
|
||||
public static final int STATE_STARTED_SESSION = 0x10;
|
||||
|
||||
public final AutofillId id;
|
||||
@@ -59,6 +59,7 @@ final class ViewState {
|
||||
private FillResponse mResponse;
|
||||
|
||||
private AutofillValue mCurrentValue;
|
||||
private AutofillValue mAutofilledValue;
|
||||
private Rect mVirtualBounds;
|
||||
|
||||
private int mState;
|
||||
@@ -86,20 +87,30 @@ final class ViewState {
|
||||
return mCurrentValue;
|
||||
}
|
||||
|
||||
void setResponse(FillResponse response) {
|
||||
mResponse = response;
|
||||
void setCurrentValue(AutofillValue value) {
|
||||
mCurrentValue = value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
AutofillValue getAutofilledValue() {
|
||||
return mAutofilledValue;
|
||||
}
|
||||
|
||||
void setAutofilledValue(AutofillValue value) {
|
||||
mAutofilledValue = value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
FillResponse getResponse() {
|
||||
return mResponse;
|
||||
}
|
||||
|
||||
CharSequence getServiceName() {
|
||||
return mSession.getServiceName();
|
||||
void setResponse(FillResponse response) {
|
||||
mResponse = response;
|
||||
}
|
||||
|
||||
boolean isChanged() {
|
||||
return (mState & STATE_CHANGED) != 0;
|
||||
CharSequence getServiceName() {
|
||||
return mSession.getServiceName();
|
||||
}
|
||||
|
||||
int getState() {
|
||||
@@ -110,10 +121,6 @@ final class ViewState {
|
||||
return DebugUtils.flagsToString(ViewState.class, "STATE_", mState);
|
||||
}
|
||||
|
||||
void setCurrentValue(AutofillValue value) {
|
||||
mCurrentValue = value;
|
||||
}
|
||||
|
||||
void setState(int state) {
|
||||
// TODO(b/33197203 , b/35707731): currently it's always setting one state, but once it
|
||||
// supports partitioning it will need to 'or' some of them..
|
||||
@@ -165,6 +172,7 @@ final class ViewState {
|
||||
pw.print(prefix); pw.print("state:" ); pw.println(getStateAsString());
|
||||
pw.print(prefix); pw.print("has response:" ); pw.println(mResponse != null);
|
||||
pw.print(prefix); pw.print("currentValue:" ); pw.println(mCurrentValue);
|
||||
pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue);
|
||||
pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user