Loading core/java/android/service/autofill/Dataset.java +1 −1 Original line number Diff line number Diff line Loading @@ -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()) Loading core/java/android/widget/TimePicker.java +1 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading services/autofill/java/com/android/server/autofill/Helper.java +0 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); } Loading services/autofill/java/com/android/server/autofill/Session.java +56 −60 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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}. Loading Loading @@ -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; } } } Loading Loading @@ -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 ViewState viewState = mViewStates.get(id); if (viewState == null) { Slog.w(TAG, "showSaveLocked(): no ViewState for required " + id); continue; } final AutofillValue initialValue = node.getAutofillValue(); if (initialValue == null || initialValue.isEmpty()) { final AutofillValue currentValue = viewState.getCurrentValue(); if (currentValue == null || currentValue.isEmpty()) { if (DEBUG) { Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id ); Slog.d(TAG, "showSaveLocked(): empty value for required " + id ); } allRequiredAreNotEmpty = false; break; } } if (state.isChanged()) { final AutofillValue filledValue = findValue(mAutoFilledDataset, id); if (!state.getCurrentValue().equals(filledValue)) { final AutofillValue filledValue = viewState.getAutofilledValue(); if (!currentValue.equals(filledValue)) { if (DEBUG) { Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": " + filledValue + " => " + state.getCurrentValue()); Slog.d(TAG, "showSaveLocked(): found a change on required " + id + ": " + filledValue + " => " + currentValue); } 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 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; Loading Loading @@ -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); final AutofillValue filledValue = viewState.getAutofilledValue(); if (value.equals(filledValue)) { viewState.setCurrentValue(value); 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 { Loading Loading @@ -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); Loading @@ -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); } Loading @@ -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); } Loading Loading @@ -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 + " "; Loading services/autofill/java/com/android/server/autofill/ViewState.java +19 −11 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ final class ViewState { private FillResponse mResponse; private AutofillValue mCurrentValue; private AutofillValue mAutofilledValue; private Rect mVirtualBounds; private int mState; Loading Loading @@ -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() { Loading @@ -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.. Loading Loading @@ -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); } } No newline at end of file Loading
core/java/android/service/autofill/Dataset.java +1 −1 Original line number Diff line number Diff line Loading @@ -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()) Loading
core/java/android/widget/TimePicker.java +1 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading
services/autofill/java/com/android/server/autofill/Helper.java +0 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); } Loading
services/autofill/java/com/android/server/autofill/Session.java +56 −60 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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}. Loading Loading @@ -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; } } } Loading Loading @@ -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 ViewState viewState = mViewStates.get(id); if (viewState == null) { Slog.w(TAG, "showSaveLocked(): no ViewState for required " + id); continue; } final AutofillValue initialValue = node.getAutofillValue(); if (initialValue == null || initialValue.isEmpty()) { final AutofillValue currentValue = viewState.getCurrentValue(); if (currentValue == null || currentValue.isEmpty()) { if (DEBUG) { Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id ); Slog.d(TAG, "showSaveLocked(): empty value for required " + id ); } allRequiredAreNotEmpty = false; break; } } if (state.isChanged()) { final AutofillValue filledValue = findValue(mAutoFilledDataset, id); if (!state.getCurrentValue().equals(filledValue)) { final AutofillValue filledValue = viewState.getAutofilledValue(); if (!currentValue.equals(filledValue)) { if (DEBUG) { Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": " + filledValue + " => " + state.getCurrentValue()); Slog.d(TAG, "showSaveLocked(): found a change on required " + id + ": " + filledValue + " => " + currentValue); } 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 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; Loading Loading @@ -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); final AutofillValue filledValue = viewState.getAutofilledValue(); if (value.equals(filledValue)) { viewState.setCurrentValue(value); 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 { Loading Loading @@ -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); Loading @@ -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); } Loading @@ -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); } Loading Loading @@ -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 + " "; Loading
services/autofill/java/com/android/server/autofill/ViewState.java +19 −11 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ final class ViewState { private FillResponse mResponse; private AutofillValue mCurrentValue; private AutofillValue mAutofilledValue; private Rect mVirtualBounds; private int mState; Loading Loading @@ -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() { Loading @@ -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.. Loading Loading @@ -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); } } No newline at end of file