Merge "Recover dataset picker when view fail to autofill." into pi-dev

This commit is contained in:
TreeHugger Robot
2018-03-27 19:48:44 +00:00
committed by Android (Google) Code Review
6 changed files with 82 additions and 1 deletions

View File

@@ -1819,13 +1819,22 @@ public final class AutofillManager {
final View[] views = client.autofillClientFindViewsByAutofillIdTraversal(
Helper.toArray(ids));
ArrayList<AutofillId> failedIds = null;
for (int i = 0; i < itemCount; i++) {
final AutofillId id = ids.get(i);
final AutofillValue value = values.get(i);
final int viewId = id.getViewId();
final View view = views[i];
if (view == null) {
Log.w(TAG, "autofill(): no View with id " + viewId);
// Most likely view has been removed after the initial request was sent to the
// the service; this is fine, but we need to update the view status in the
// server side so it can be triggered again.
Log.d(TAG, "autofill(): no View with id " + id);
if (failedIds == null) {
failedIds = new ArrayList<>();
}
failedIds.add(id);
continue;
}
if (id.isVirtual()) {
@@ -1859,12 +1868,28 @@ public final class AutofillManager {
}
}
if (failedIds != null) {
if (sVerbose) {
Log.v(TAG, "autofill(): total failed views: " + failedIds);
}
try {
mService.setAutofillFailure(mSessionId, failedIds, mContext.getUserId());
} catch (RemoteException e) {
// In theory, we could ignore this error since it's not a big deal, but
// in reality, we rather crash the app anyways, as the failure could be
// a consequence of something going wrong on the server side...
e.rethrowFromSystemServer();
}
}
if (virtualValues != null) {
for (int i = 0; i < virtualValues.size(); i++) {
final View parent = virtualValues.keyAt(i);
final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
parent.autofill(childrenValues);
numApplied += childrenValues.size();
// TODO: we should provide a callback so the parent can call failures; something
// like notifyAutofillFailed(View view, int[] childrenIds);
}
}

View File

@@ -16,6 +16,8 @@
package android.view.autofill;
import java.util.List;
import android.content.ComponentName;
import android.graphics.Rect;
import android.os.Bundle;
@@ -47,6 +49,7 @@ interface IAutoFillManager {
in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
boolean hasCallback, int flags, in ComponentName componentName, int sessionId,
int action, boolean compatMode);
void setAutofillFailure(int sessionId, in List<AutofillId> ids, int userId);
void finishSession(int sessionId, int userId);
void cancelSession(int sessionId, int userId);
void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId);

View File

@@ -1035,6 +1035,18 @@ public final class AutofillManagerService extends SystemService {
return sessionId;
}
@Override
public void setAutofillFailure(int sessionId, @NonNull List<AutofillId> ids, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
service.setAutofillFailureLocked(sessionId, getCallingUid(), ids);
} else if (sVerbose) {
Slog.v(TAG, "setAutofillFailure(): no service for " + userId);
}
}
}
@Override
public void finishSession(int sessionId, int userId) {
synchronized (mLock) {

View File

@@ -403,6 +403,19 @@ final class AutofillManagerServiceImpl {
}
}
@GuardedBy("mLock")
void setAutofillFailureLocked(int sessionId, int uid, @NonNull List<AutofillId> ids) {
if (!isEnabledLocked()) {
return;
}
final Session session = mSessions.get(sessionId);
if (session == null || uid != session.uid) {
Slog.v(TAG, "setAutofillFailure(): no session for " + sessionId + "(" + uid + ")");
return;
}
session.setAutofillFailureLocked(ids);
}
@GuardedBy("mLock")
void finishSessionLocked(int sessionId, int uid) {
if (!isEnabledLocked()) {

View File

@@ -1827,6 +1827,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
viewState.setState(ViewState.STATE_STARTED_PARTITION);
requestNewFillResponseLocked(flags);
} else {
if (sVerbose) {
Slog.v(TAG, "Not starting new partition for view " + id + ": "
+ viewState.getStateAsString());
}
}
}
@@ -2194,6 +2199,27 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
}
/**
* Sets the state of views that failed to autofill.
*/
@GuardedBy("mLock")
void setAutofillFailureLocked(@NonNull List<AutofillId> ids) {
for (int i = 0; i < ids.size(); i++) {
final AutofillId id = ids.get(i);
final ViewState viewState = mViewStates.get(id);
if (viewState == null) {
Slog.w(TAG, "setAutofillFailure(): no view for id " + id);
continue;
}
viewState.resetState(ViewState.STATE_AUTOFILLED);
final int state = viewState.getState();
viewState.setState(state | ViewState.STATE_AUTOFILL_FAILED);
if (sVerbose) {
Slog.v(TAG, "Changed state of " + id + " to " + viewState.getStateAsString());
}
}
}
@GuardedBy("mLock")
private void replaceResponseLocked(@NonNull FillResponse oldResponse,
@NonNull FillResponse newResponse, @Nullable Bundle newClientState) {

View File

@@ -69,6 +69,8 @@ final class ViewState {
public static final int STATE_RESTARTED_SESSION = 0x100;
/** View is the URL bar of a package on compat mode. */
public static final int STATE_URL_BAR = 0x200;
/** View was asked to autofil but failed to do so. */
public static final int STATE_AUTOFILL_FAILED = 0x400;
public final AutofillId id;