diff --git a/api/current.txt b/api/current.txt index c1188dcd330b3..93b6b424458f9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -37499,6 +37499,7 @@ package android.service.autofill { public final class SaveCallback { method public void onFailure(java.lang.CharSequence); method public void onSuccess(); + method public void onSuccess(android.content.IntentSender); } public final class SaveInfo implements android.os.Parcelable { diff --git a/core/java/android/service/autofill/ISaveCallback.aidl b/core/java/android/service/autofill/ISaveCallback.aidl index e260c7375cc57..a9364fe5ccba3 100644 --- a/core/java/android/service/autofill/ISaveCallback.aidl +++ b/core/java/android/service/autofill/ISaveCallback.aidl @@ -16,12 +16,14 @@ package android.service.autofill; +import android.content.IntentSender; + /** * Interface to receive the result of a save request. * * @hide */ interface ISaveCallback { - void onSuccess(); + void onSuccess(in IntentSender intentSender); void onFailure(CharSequence message); } diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java index 7207f1df3ee56..855981a544fd7 100644 --- a/core/java/android/service/autofill/SaveCallback.java +++ b/core/java/android/service/autofill/SaveCallback.java @@ -16,9 +16,14 @@ package android.service.autofill; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.Activity; +import android.content.IntentSender; import android.os.RemoteException; +import com.android.internal.util.Preconditions; + /** * Handles save requests from the {@link AutofillService} into the {@link Activity} being * autofilled. @@ -36,18 +41,33 @@ public final class SaveCallback { * Notifies the Android System that an * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} was successfully handled * by the service. - * - *

If the service could not handle the request right away—for example, because it must - * launch an activity asking the user to authenticate first or because the network is - * down—it should still call {@link #onSuccess()}. - * - * @throws RuntimeException if an error occurred while calling the Android System. */ public void onSuccess() { + onSuccessInternal(null); + } + + /** + * Notifies the Android System that an + * {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} was successfully handled + * by the service. + * + *

This method is useful when the service requires extra work—for example, launching an + * activity asking the user to authenticate first —before it can process the request, + * as the intent will be launched from the context of the activity being autofilled and hence + * will be part of that activity's stack. + * + * @param intentSender intent that will be launched from the context of activity being + * autofilled. + */ + public void onSuccess(@NonNull IntentSender intentSender) { + onSuccessInternal(Preconditions.checkNotNull(intentSender)); + } + + private void onSuccessInternal(@Nullable IntentSender intentSender) { assertNotCalled(); mCalled = true; try { - mCallback.onSuccess(); + mCallback.onSuccess(intentSender); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } @@ -63,11 +83,10 @@ public final class SaveCallback { * the {@link SaveRequest} and call {@link #onSuccess()} instead. * *

Note: The Android System displays an UI with the supplied error message; if - * you prefer to show your own message, call {@link #onSuccess()} instead. + * you prefer to show your own message, call {@link #onSuccess()} or + * {@link #onSuccess(IntentSender)} instead. * * @param message error message to be displayed to the user. - * - * @throws RuntimeException if an error occurred while calling the Android System. */ public void onFailure(CharSequence message) { assertNotCalled(); diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 19178470e7fa8..32af29d24aa24 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4010,7 +4010,8 @@ message MetricsEvent { FIELD_AUTOFILL_NUM_IDS = 917; // ACTION: An autofill service was reqiested to save data - // Type TYPE_SUCCESS: The request succeeded + // Type TYPE_SUCCESS: The request succeeded right away + // Type TYPE_OPEN: The request succeeded but the service launched an IntentSender // Type TYPE_FAILURE: The request failed // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index af55807ff1f04..831c488e95b27 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -26,6 +26,7 @@ import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentSender; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; @@ -100,7 +101,8 @@ final class RemoteFillService implements DeathRecipient { @NonNull String servicePackageName); void onFillRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName); - void onSaveRequestSuccess(@NonNull String servicePackageName); + void onSaveRequestSuccess(@NonNull String servicePackageName, + @Nullable IntentSender intentSender); void onSaveRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName); void onServiceDied(RemoteFillService service); @@ -308,10 +310,11 @@ final class RemoteFillService implements DeathRecipient { }); } - private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest) { + private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest, + IntentSender intentSender) { mHandler.getHandler().post(() -> { if (handleResponseCallbackCommon(pendingRequest)) { - mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName()); + mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName(), intentSender); } }); } @@ -624,12 +627,13 @@ final class RemoteFillService implements DeathRecipient { mCallback = new ISaveCallback.Stub() { @Override - public void onSuccess() { + public void onSuccess(IntentSender intentSender) { if (!finish()) return; final RemoteFillService remoteService = getService(); if (remoteService != null) { - remoteService.dispatchOnSaveRequestSuccess(PendingSaveRequest.this); + remoteService.dispatchOnSaveRequestSuccess(PendingSaveRequest.this, + intentSender); } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 974148623b003..99b92b9c9cd46 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -561,7 +561,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // FillServiceCallbacks @Override - public void onSaveRequestSuccess(@NonNull String servicePackageName) { + public void onSaveRequestSuccess(@NonNull String servicePackageName, + @Nullable IntentSender intentSender) { synchronized (mLock) { mIsSaving = false; @@ -572,8 +573,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_SUCCESS); + .setType(intentSender == null ? MetricsEvent.TYPE_SUCCESS : MetricsEvent.TYPE_OPEN); mMetricsLogger.write(log); + if (intentSender != null) { + if (sDebug) Slog.d(TAG, "Starting intent sender on save()"); + startIntentSender(intentSender); + } // Nothing left to do... removeSelf();