diff options
| author | 2024-11-15 00:33:21 +0000 | |
|---|---|---|
| committer | 2024-11-27 18:27:25 +0000 | |
| commit | 7726696e11b133ad7677a8d860468130f27f3b9f (patch) | |
| tree | 36a8763cf5b7f8249a4d83967088da8ca1f93cfb | |
| parent | 27764c0d29f09e1dd757f72e7a3233dace3cec1e (diff) | |
[Autofill] Add new API for getting FillEventHistory
Introduce a new callback in AutofillService that is called when the
session is finished.
Bug: 370059095
Test: android.autofillservice.cts.commontests.FillEventHistoryCommonTestCase.test_onSessionDestroyed
Flag: android.service.autofill.autofill_session_destroyed
Change-Id: I2fcb7d7a1a5c55e4afec73acd37a4bf148f3040b
6 files changed, 76 insertions, 11 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 38a0144cf6d5..d797336af549 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -40889,13 +40889,14 @@ package android.service.autofill { public abstract class AutofillService extends android.app.Service { ctor public AutofillService(); - method @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory(); + method @Deprecated @FlaggedApi("android.service.autofill.autofill_session_destroyed") @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory(); method public final android.os.IBinder onBind(android.content.Intent); method public void onConnected(); method public void onDisconnected(); method public abstract void onFillRequest(@NonNull android.service.autofill.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.FillCallback); method public abstract void onSaveRequest(@NonNull android.service.autofill.SaveRequest, @NonNull android.service.autofill.SaveCallback); method public void onSavedDatasetsInfoRequest(@NonNull android.service.autofill.SavedDatasetsInfoCallback); + method @FlaggedApi("android.service.autofill.autofill_session_destroyed") public void onSessionDestroyed(@Nullable android.service.autofill.FillEventHistory); field public static final String EXTRA_FILL_RESPONSE = "android.service.autofill.extra.FILL_RESPONSE"; field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService"; field public static final String SERVICE_META_DATA = "android.autofill"; diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java index 269839b61bef..2d922b4c09ee 100644 --- a/core/java/android/service/autofill/AutofillService.java +++ b/core/java/android/service/autofill/AutofillService.java @@ -15,9 +15,12 @@ */ package android.service.autofill; +import static android.service.autofill.Flags.FLAG_AUTOFILL_SESSION_DESTROYED; + import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.CallSuper; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; @@ -669,6 +672,14 @@ public abstract class AutofillService extends Service { AutofillService.this, new SavedDatasetsInfoCallbackImpl(receiver, SavedDatasetsInfo.TYPE_PASSWORDS))); } + + @Override + public void onSessionDestroyed(@Nullable FillEventHistory history) { + mHandler.sendMessage(obtainMessage( + AutofillService::onSessionDestroyed, + AutofillService.this, + history)); + } }; private Handler mHandler; @@ -783,26 +794,42 @@ public abstract class AutofillService extends Service { } /** - * Gets the events that happened after the last - * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} + * Called when an Autofill context has ended and the Autofill session is finished. This will be + * called as the last step of the Autofill lifecycle described in {@link AutofillManager}. + * + * <p>This will also contain the finished Session's FillEventHistory, so providers do not need + * to explicitly call {@link #getFillEventHistory()} + * + * <p>This will usually happens whenever {@link AutofillManager#commit()} or {@link + * AutofillManager#cancel()} is called. + */ + @FlaggedApi(FLAG_AUTOFILL_SESSION_DESTROYED) + public void onSessionDestroyed(@Nullable FillEventHistory history) {} + + /** + * Gets the events that happened after the last {@link + * AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} * call. * * <p>This method is typically used to keep track of previous user actions to optimize further * requests. For example, the service might return email addresses in alphabetical order by * default, but change that order based on the address the user picked on previous requests. * - * <p>The history is not persisted over reboots, and it's cleared every time the service - * replies to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling - * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} - * (if the service doesn't call any of these methods, the history will clear out after some - * pre-defined time). Hence, the service should call {@link #getFillEventHistory()} before - * finishing the {@link FillCallback}. + * <p>The history is not persisted over reboots, and it's cleared every time the service replies + * to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling {@link + * FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} (if the + * service doesn't call any of these methods, the history will clear out after some pre-defined + * time). Hence, the service should call {@link #getFillEventHistory()} before finishing the + * {@link FillCallback}. * * @return The history or {@code null} if there are no events. - * * @throws RuntimeException if the event history could not be retrieved. + * @deprecated Use {@link #onSessionDestroyed(FillEventHistory) instead} */ - @Nullable public final FillEventHistory getFillEventHistory() { + @FlaggedApi(FLAG_AUTOFILL_SESSION_DESTROYED) + @Deprecated + @Nullable + public final FillEventHistory getFillEventHistory() { final AutofillManager afm = getSystemService(AutofillManager.class); if (afm == null) { diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl index 3b64b8a0ec5e..71b75e7789c2 100644 --- a/core/java/android/service/autofill/IAutoFillService.aidl +++ b/core/java/android/service/autofill/IAutoFillService.aidl @@ -25,6 +25,8 @@ import android.service.autofill.ISaveCallback; import android.service.autofill.SaveRequest; import com.android.internal.os.IResultReceiver; +parcelable FillEventHistory; + /** * Interface from the system to an auto fill service. * @@ -38,4 +40,5 @@ oneway interface IAutoFillService { void onSaveRequest(in SaveRequest request, in ISaveCallback callback); void onSavedPasswordCountRequest(in IResultReceiver receiver); void onConvertCredentialRequest(in ConvertCredentialRequest convertCredentialRequest, in IConvertCredentialCallback convertCredentialCallback); + void onSessionDestroyed(in FillEventHistory history); } diff --git a/services/autofill/features.aconfig b/services/autofill/features.aconfig index 444844121190..80ccb0365d80 100644 --- a/services/autofill/features.aconfig +++ b/services/autofill/features.aconfig @@ -2,6 +2,13 @@ package: "android.service.autofill" container: "system" flag { + name: "autofill_session_destroyed" + namespace: "autofill" + description: "Guards against new metrics definitions introduced in W" + bug: "342676602" +} + +flag { name: "autofill_w_metrics" namespace: "autofill" description: "Guards against new metrics definitions introduced in W" diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index cd4ace2e3835..5cf96bfb2b8b 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -61,6 +61,7 @@ import android.service.autofill.FillEventHistory; import android.service.autofill.FillEventHistory.Event; import android.service.autofill.FillEventHistory.Event.NoSaveReason; import android.service.autofill.FillResponse; +import android.service.autofill.Flags; import android.service.autofill.IAutoFillService; import android.service.autofill.InlineSuggestionRenderService; import android.service.autofill.SaveInfo; @@ -100,6 +101,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Random; + /** * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the * app's {@link IAutoFillService} implementation. @@ -748,6 +750,22 @@ final class AutofillManagerServiceImpl @GuardedBy("mLock") void removeSessionLocked(int sessionId) { mSessions.remove(sessionId); + if (Flags.autofillSessionDestroyed()) { + if (sVerbose) { + Slog.v( + TAG, + "removeSessionLocked(): removed " + sessionId); + } + RemoteFillService remoteService = + new RemoteFillService( + getContext(), + mInfo.getServiceInfo().getComponentName(), + mUserId, + /* callbacks= */ null, + mMaster.isInstantServiceAllowed(), + /* credentialAutofillService= */ null); + remoteService.onSessionDestroyed(null); + } } /** diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index 07f5dcc3cb0a..f1e888400d32 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -34,6 +34,7 @@ import android.os.RemoteException; import android.service.autofill.AutofillService; import android.service.autofill.ConvertCredentialRequest; import android.service.autofill.ConvertCredentialResponse; +import android.service.autofill.FillEventHistory; import android.service.autofill.FillRequest; import android.service.autofill.FillResponse; import android.service.autofill.IAutoFillService; @@ -497,6 +498,14 @@ final class RemoteFillService extends ServiceConnector.Impl<IAutoFillService> { })); } + public void onSessionDestroyed(@Nullable FillEventHistory history) { + boolean success = run(service -> { + service.onSessionDestroyed(history); + }); + + if (sVerbose) Slog.v(TAG, "called onSessionDestroyed(): " + success); + } + void onSavedPasswordCountRequest(IResultReceiver receiver) { run(service -> service.onSavedPasswordCountRequest(receiver)); } |