Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 284ad1c3 authored by Felipe Leme's avatar Felipe Leme
Browse files

Initial implementation of Augmented Autofill.

Augmented Autofill is a mechanism that will let a system-provided service
provide autofill suggestions when the stardand autofill can't.

Because the Augmented Autofill service is a system app, it has less restrictions
than the standard service; in particular, this service will be responsible for
drawing the autofill UI, although the framework will provide a mechanism to host
the window. Right now, it's creating a TYPE_APPLICATION_OVERLAY window in the
service process roughly below the focused view, but in the long-term it will
use the IME suggestion window to display it.

This CL provides the initial APIs and end-to-end workflow for the simplest
scenario, but it's still full of TODO's.

Test: atest CtsAutoFillServiceTestCases # to make sure it doesn't break it
Test: atest FrameworksCoreTests:SettingsBackupTest
Test: mmm -j150 packages/experimental/FillService &&\
  adb install -r ${OUT}/data/app/FillService/FillService.apk &&\
  adb shell settings put secure intel_service foo.bar.fill/.AiaiService &&\
  adb shell settings put global autofill_smart_suggestion_emulation_flags 2 &&\
  adb shell pm grant foo.bar.fill android.permission.SYSTEM_ALERT_WINDOW

Bug: 119638877

Change-Id: I8d59b4eab3e530cd89b81456681a72fdab532756
parent 9a72ec33
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -348,6 +348,7 @@ java_defaults {
        "core/java/android/view/accessibility/IAccessibilityManagerClient.aidl",
        "core/java/android/view/accessibility/IAccessibilityManagerClient.aidl",
        "core/java/android/view/autofill/IAutoFillManager.aidl",
        "core/java/android/view/autofill/IAutoFillManager.aidl",
        "core/java/android/view/autofill/IAutoFillManagerClient.aidl",
        "core/java/android/view/autofill/IAutoFillManagerClient.aidl",
        "core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl",
        "core/java/android/view/autofill/IAutofillWindowPresenter.aidl",
        "core/java/android/view/autofill/IAutofillWindowPresenter.aidl",
        "core/java/android/view/intelligence/IIntelligenceManager.aidl",
        "core/java/android/view/intelligence/IIntelligenceManager.aidl",
        "core/java/android/view/IApplicationToken.aidl",
        "core/java/android/view/IApplicationToken.aidl",
+52 −0
Original line number Original line Diff line number Diff line
@@ -4938,12 +4938,47 @@ package android.service.euicc {


package android.service.intelligence {
package android.service.intelligence {


  public final class FillCallback {
    method public void onSuccess(android.service.intelligence.FillResponse);
  }

  public final class FillController {
    method public void autofill(java.util.List<android.util.Pair<android.view.autofill.AutofillId, android.view.autofill.AutofillValue>>);
  }

  public final class FillRequest {
    method public android.view.autofill.AutofillId getFocusedId();
    method public android.service.intelligence.PresentationParams getPresentationParams();
    method public android.service.intelligence.InteractionSessionId getSessionId();
  }

  public final class FillResponse implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.service.intelligence.FillResponse> CREATOR;
  }

  public static class FillResponse.Builder {
    ctor public FillResponse.Builder();
    method public android.service.intelligence.FillResponse build();
    method public android.service.intelligence.FillResponse.Builder setFillWindow(android.service.intelligence.FillWindow);
    method public android.service.intelligence.FillResponse.Builder setIgnoredIds(java.util.List<android.view.autofill.AutofillId>);
  }

  public final class FillWindow {
    ctor public FillWindow();
    method public void destroy();
    method public boolean update(android.service.intelligence.PresentationParams.Area, android.view.View, long);
    field public static final long FLAG_METADATA_ADDRESS = 1L; // 0x1L
  }

  public abstract class IntelligenceService extends android.app.Service {
  public abstract class IntelligenceService extends android.app.Service {
    ctor public IntelligenceService();
    ctor public IntelligenceService();
    method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData);
    method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData);
    method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>);
    method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>);
    method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
    method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
    method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
    method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
    method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback);
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService";
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService";
  }
  }


@@ -4965,6 +5000,23 @@ package android.service.intelligence {
    field public static final android.os.Parcelable.Creator<android.service.intelligence.InteractionSessionId> CREATOR;
    field public static final android.os.Parcelable.Creator<android.service.intelligence.InteractionSessionId> CREATOR;
  }
  }


  public abstract class PresentationParams {
    method public int getFlags();
    method public android.service.intelligence.PresentationParams.Area getFullArea();
    method public android.service.intelligence.PresentationParams.Area getSuggestionArea();
    field public static final int FLAG_HINT_GRAVITY_BOTTOM = 2; // 0x2
    field public static final int FLAG_HINT_GRAVITY_LEFT = 4; // 0x4
    field public static final int FLAG_HINT_GRAVITY_RIGHT = 8; // 0x8
    field public static final int FLAG_HINT_GRAVITY_TOP = 1; // 0x1
    field public static final int FLAG_HOST_IME = 16; // 0x10
    field public static final int FLAG_HOST_SYSTEM = 32; // 0x20
  }

  public static abstract class PresentationParams.Area {
    method public android.graphics.Rect getBounds();
    method public android.service.intelligence.PresentationParams.Area getSubArea(android.graphics.Rect);
  }

  public final class SnapshotData implements android.os.Parcelable {
  public final class SnapshotData implements android.os.Parcelable {
    method public int describeContents();
    method public int describeContents();
    method public android.app.assist.AssistContent getAssistContent();
    method public android.app.assist.AssistContent getAssistContent();
+1 −0
Original line number Original line Diff line number Diff line
@@ -985,6 +985,7 @@ package android.provider {


  public static final class Settings.Global extends android.provider.Settings.NameValueTable {
  public static final class Settings.Global extends android.provider.Settings.NameValueTable {
    field public static final java.lang.String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
    field public static final java.lang.String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
    field public static final java.lang.String AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS = "autofill_smart_suggestion_emulation_flags";
    field public static final java.lang.String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
    field public static final java.lang.String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
    field public static final java.lang.String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
    field public static final java.lang.String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
    field public static final java.lang.String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
    field public static final java.lang.String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
+11 −0
Original line number Original line Diff line number Diff line
@@ -12700,6 +12700,17 @@ public final class Settings {
         */
         */
        public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
        public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
        /**
         * Used to emulate Smart Suggestion for Augmented Autofill during development
         *
         * <p>Valid values: {@code 0x1} for IME and/or {@code 0x2} for popup window.
         *
         * @hide
         */
        @TestApi
        public static final String AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS =
                "autofill_smart_suggestion_emulation_flags";
        /**
        /**
         * Exemptions to the hidden API blacklist.
         * Exemptions to the hidden API blacklist.
         *
         *
+45 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.service.intelligence;

import android.annotation.Nullable;
import android.annotation.SystemApi;

/**
 * Callback used to indicate at {@link FillRequest} has been fulfilled.
 *
 * @hide
 */
@SystemApi
public final class FillCallback {

    FillCallback() {}

    /**
     * Sets the response associated with the request.
     *
     * @param response response associated with the request, or {@code null} if the service
     * could not provide autofill for the request.
     */
    public void onSuccess(@Nullable FillResponse response) {
        final FillWindow fillWindow = response.getFillWindow();
        if (fillWindow != null) {
            fillWindow.show();
        }
        // TODO(b/111330312): properly implement on server-side by updating the Session state
        // accordingly (and adding CTS tests)
    }
}
Loading