Refactor auto-fill

* Fix a layering issue where auto-fill manager which is in view
  depended on activity which is in app

* Moved auto-fill classes to view or service based on their
  purpose and removed dependecy on the classes in view to the
  classes in service

* Push state to local auto-fill manager whether auto-fill is
  enabled to avoid making IPC for every focus transition if
  the user did not enable the feature

* Remove unnecessary offload to messages when handling calls
  to auto-fill manager service as these are made over a oneway
  interface and in general they do almost no work and typically
  we do these on the binder thread

* Removed id from data set and fill response as the provider
  can embed everything it needs to id them in the auth pending
  intent

* Enforce the auth UI to be only an activity as this will work
  with multi-window, recents, and back and also does not require
  draw on top of other app special permission

* Authentication also no longer requires passing a remotable
  callback to the auth activity but the activity handles the
  request as if called for a result

* Handling stopping of a user to clean up in-memory state as
  well as handling when a user gets unlocked as a provider may
  be non-direct boot aware

* User the correct context when creating an auto-fill manager

* Move the receiver that listens for requests to hide system
  windows to the manager service as the UI is a singleton and
  no need every per-user state to register its own

* Removed extras from dataset as the only case a provider needs
  to associate state with a dataset is for auth and the provider
  can embed this data in the auth pending intent

Test: manual and CTS

Change-Id: I4bc54c13cf779d7f6fdb3ab894637f9fac73f603
diff --git a/Android.mk b/Android.mk
index 9ebc276..28adbca 100644
--- a/Android.mk
+++ b/Android.mk
@@ -264,8 +264,6 @@
 	core/java/android/os/storage/IObbActionListener.aidl \
 	core/java/android/security/IKeystoreService.aidl \
 	core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
-	core/java/android/service/autofill/IAutoFillAppCallback.aidl \
-	core/java/android/service/autofill/IAutoFillManagerService.aidl \
 	core/java/android/service/autofill/IAutoFillService.aidl \
 	core/java/android/service/autofill/IFillCallback.aidl \
 	core/java/android/service/autofill/ISaveCallback.aidl \
@@ -318,6 +316,8 @@
 	core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\
 	core/java/android/view/accessibility/IAccessibilityManager.aidl \
 	core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \
+	core/java/android/view/autofill/IAutoFillManager.aidl \
+	core/java/android/view/autofill/IAutoFillManagerClient.aidl \
 	core/java/android/view/IApplicationToken.aidl \
 	core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl \
 	core/java/android/view/IDockedStackListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index e0d895e..6f9cb13 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9181,10 +9181,6 @@
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
-    field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
-    field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
-    field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
-    field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -36199,12 +36195,37 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
 
-  public final class FillCallback implements android.os.Parcelable {
+  public final class Dataset implements android.os.Parcelable {
     method public int describeContents();
-    method public void onFailure(java.lang.CharSequence);
-    method public void onSuccess(android.view.autofill.FillResponse);
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.service.autofill.Dataset> CREATOR;
+  }
+
+  public static final class Dataset.Builder {
+    ctor public Dataset.Builder(java.lang.CharSequence);
+    method public android.service.autofill.Dataset build();
+    method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
+  }
+
+  public final class FillCallback {
+    method public void onFailure(java.lang.CharSequence);
+    method public void onSuccess(android.service.autofill.FillResponse);
+  }
+
+  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.autofill.FillResponse> CREATOR;
+  }
+
+  public static final class FillResponse.Builder {
+    ctor public FillResponse.Builder();
+    method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
+    method public android.service.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
+    method public android.service.autofill.FillResponse build();
+    method public android.service.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
   }
 
   public final class SaveCallback {
@@ -46838,6 +46859,8 @@
     method public void valueChanged(android.view.View);
     method public void virtualFocusChanged(android.view.View, int, android.graphics.Rect, boolean);
     method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
+    field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
+    field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
 
   public final class AutoFillType implements android.os.Parcelable {
@@ -46865,35 +46888,6 @@
     field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillValue> CREATOR;
   }
 
-  public final class Dataset 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.view.autofill.Dataset> CREATOR;
-  }
-
-  public static final class Dataset.Builder {
-    ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
-    method public android.view.autofill.Dataset build();
-    method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
-    method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
-    method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
-  }
-
-  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.view.autofill.FillResponse> CREATOR;
-  }
-
-  public static final class FillResponse.Builder {
-    ctor public FillResponse.Builder(java.lang.String);
-    method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
-    method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
-    method public android.view.autofill.FillResponse build();
-    method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
-    method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
-  }
-
 }
 
 package android.view.inputmethod {
diff --git a/api/system-current.txt b/api/system-current.txt
index a5f3081..9095322 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9619,10 +9619,6 @@
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
-    field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
-    field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
-    field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
-    field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -39265,12 +39261,37 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
 
-  public final class FillCallback implements android.os.Parcelable {
+  public final class Dataset implements android.os.Parcelable {
     method public int describeContents();
-    method public void onFailure(java.lang.CharSequence);
-    method public void onSuccess(android.view.autofill.FillResponse);
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.service.autofill.Dataset> CREATOR;
+  }
+
+  public static final class Dataset.Builder {
+    ctor public Dataset.Builder(java.lang.CharSequence);
+    method public android.service.autofill.Dataset build();
+    method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
+  }
+
+  public final class FillCallback {
+    method public void onFailure(java.lang.CharSequence);
+    method public void onSuccess(android.service.autofill.FillResponse);
+  }
+
+  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.autofill.FillResponse> CREATOR;
+  }
+
+  public static final class FillResponse.Builder {
+    ctor public FillResponse.Builder();
+    method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
+    method public android.service.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
+    method public android.service.autofill.FillResponse build();
+    method public android.service.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
   }
 
   public final class SaveCallback {
@@ -50277,6 +50298,8 @@
     method public void valueChanged(android.view.View);
     method public void virtualFocusChanged(android.view.View, int, android.graphics.Rect, boolean);
     method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
+    field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
+    field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
 
   public final class AutoFillType implements android.os.Parcelable {
@@ -50304,35 +50327,6 @@
     field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillValue> CREATOR;
   }
 
-  public final class Dataset 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.view.autofill.Dataset> CREATOR;
-  }
-
-  public static final class Dataset.Builder {
-    ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
-    method public android.view.autofill.Dataset build();
-    method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
-    method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
-    method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
-  }
-
-  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.view.autofill.FillResponse> CREATOR;
-  }
-
-  public static final class FillResponse.Builder {
-    ctor public FillResponse.Builder(java.lang.String);
-    method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
-    method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
-    method public android.view.autofill.FillResponse build();
-    method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
-    method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
-  }
-
 }
 
 package android.view.inputmethod {
diff --git a/api/test-current.txt b/api/test-current.txt
index a983cf5..b414d95e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -9207,10 +9207,6 @@
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
-    field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
-    field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
-    field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
-    field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -36334,12 +36330,37 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
 
-  public final class FillCallback implements android.os.Parcelable {
+  public final class Dataset implements android.os.Parcelable {
     method public int describeContents();
-    method public void onFailure(java.lang.CharSequence);
-    method public void onSuccess(android.view.autofill.FillResponse);
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.service.autofill.Dataset> CREATOR;
+  }
+
+  public static final class Dataset.Builder {
+    ctor public Dataset.Builder(java.lang.CharSequence);
+    method public android.service.autofill.Dataset build();
+    method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
+  }
+
+  public final class FillCallback {
+    method public void onFailure(java.lang.CharSequence);
+    method public void onSuccess(android.service.autofill.FillResponse);
+  }
+
+  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.autofill.FillResponse> CREATOR;
+  }
+
+  public static final class FillResponse.Builder {
+    ctor public FillResponse.Builder();
+    method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
+    method public android.service.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
+    method public android.service.autofill.FillResponse build();
+    method public android.service.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
   }
 
   public final class SaveCallback {
@@ -47151,6 +47172,8 @@
     method public void valueChanged(android.view.View);
     method public void virtualFocusChanged(android.view.View, int, android.graphics.Rect, boolean);
     method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
+    field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
+    field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
 
   public final class AutoFillType implements android.os.Parcelable {
@@ -47178,35 +47201,6 @@
     field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillValue> CREATOR;
   }
 
-  public final class Dataset 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.view.autofill.Dataset> CREATOR;
-  }
-
-  public static final class Dataset.Builder {
-    ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
-    method public android.view.autofill.Dataset build();
-    method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
-    method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
-    method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
-  }
-
-  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.view.autofill.FillResponse> CREATOR;
-  }
-
-  public static final class FillResponse.Builder {
-    ctor public FillResponse.Builder(java.lang.String);
-    method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
-    method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
-    method public android.view.autofill.FillResponse build();
-    method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
-    method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
-  }
-
 }
 
 package android.view.inputmethod {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index edf60b4..4449454 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillManager;
+import android.view.autofill.AutoFillValue;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ToolbarActionBar;
@@ -113,8 +116,6 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillSession;
 import android.widget.AdapterView;
 import android.widget.Toast;
 import android.widget.Toolbar;
@@ -688,7 +689,8 @@
         implements LayoutInflater.Factory2,
         Window.Callback, KeyEvent.Callback,
         OnCreateContextMenuListener, ComponentCallbacks2,
-        Window.OnWindowDismissedCallback, WindowControllerCallback {
+        Window.OnWindowDismissedCallback, WindowControllerCallback,
+        AutoFillManager.AutoFillClient {
     private static final String TAG = "Activity";
     private static final boolean DEBUG_LIFECYCLE = false;
 
@@ -726,6 +728,7 @@
             "android:hasCurrentPermissionsRequest";
 
     private static final String REQUEST_PERMISSIONS_WHO_PREFIX = "@android:requestPermissions:";
+    private static final String AUTO_FILL_AUTH_WHO_PREFIX = "@android:autoFillAuth:";
 
     private static final String KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME = "com.android.systemui";
 
@@ -841,9 +844,6 @@
 
     private boolean mHasCurrentPermissionsRequest;
 
-    @GuardedBy("this")
-    private AutoFillSession mAutoFillSession;
-
     private static native String getDlWarning();
 
     /** Return the intent that started this activity. */
@@ -1695,25 +1695,6 @@
     }
 
     /**
-     * Lazily attachs the activity to the current {@link AutoFillSession} (if any).
-     */
-    void attachToAutoFillSession() {
-        synchronized (this) {
-            if (mAutoFillSession == null) {
-                final AutoFillManager afm = getSystemService(AutoFillManager.class);
-                if (afm != null) {
-                    mAutoFillSession = afm.getSession();
-                    if (mAutoFillSession != null) {
-                        mAutoFillSession.attachActivity(this);
-                    } else {
-                        Log.w(TAG, "attachToAutoFillSession(): not in a session");
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Request the Keyboard Shortcuts screen to show up. This will trigger
      * {@link #onProvideKeyboardShortcuts} to retrieve the shortcuts for the foreground activity.
      */
@@ -1799,9 +1780,8 @@
         getApplication().dispatchActivityStopped(this);
         mTranslucentCallback = null;
         mCalled = true;
-        if (mAutoFillSession != null && isFinishing()) {
-            mAutoFillSession.finishSession();
-            mAutoFillSession = null;
+        if (isFinishing() && AutoFillManager.isClientActive(getActivityToken())) {
+            getSystemService(AutoFillManager.class).reset();
         }
     }
 
@@ -6021,11 +6001,6 @@
             getWindow().peekDecorView().getViewRootImpl().dump(prefix, fd, writer, args);
         }
 
-        if (mAutoFillSession!= null) {
-            writer.print(prefix); writer.print("mAutoFillSession: " );
-                    writer.println(mAutoFillSession);
-        }
-
         mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix);
     }
 
@@ -6748,6 +6723,8 @@
         mCurrentConfig = config;
 
         mWindow.setColorMode(info.colorMode);
+
+        AutoFillManager.addClient(token, this);
     }
 
     /** @hide */
@@ -7038,6 +7015,8 @@
                     return;
                 }
             }
+        } else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
+            getSystemService(AutoFillManager.class).onAuthenticationResult(data);
         } else {
             Fragment frag = mFragments.findFragmentByWho(who);
             if (frag != null) {
@@ -7178,6 +7157,39 @@
         fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
     }
 
+    /** @hide */
+    @Override
+    public void autoFill(List<AutoFillId> ids, List<AutoFillValue> values) {
+        final View root = getWindow().getDecorView();
+        final int itemCount = ids.size();
+        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 = root.findViewByAccessibilityIdTraversal(viewId);
+            if (view == null) {
+                Log.w(TAG, "autoFill(): no View with id " + viewId);
+                continue;
+            }
+            if (id.isVirtual()) {
+                view.autoFillVirtual(id.getVirtualChildId(), value);
+            } else {
+                view.autoFill(value);
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void authenticate(IntentSender intent, Intent fillInIntent) {
+        try {
+            startIntentSenderForResultInner(intent, AUTO_FILL_AUTH_WHO_PREFIX,
+                    0, fillInIntent, 0, 0, null);
+        } catch (IntentSender.SendIntentException e) {
+            Log.e(TAG, "authenticate() failed for intent:" + intent, e);
+        }
+    }
+
     class HostCallbacks extends FragmentHostCallback<Activity> {
         public HostCallbacks() {
             super(Activity.this /*activity*/);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index dffd81f..23f0b09 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -89,8 +89,6 @@
 import android.provider.Settings;
 import android.security.NetworkSecurityPolicy;
 import android.security.net.config.NetworkSecurityConfigProvider;
-import android.service.autofill.AutoFillService;
-import android.service.autofill.IAutoFillAppCallback;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
@@ -2931,16 +2929,13 @@
             if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutoFill) {
                 structure = new AssistStructure(r.activity, forAutoFill);
                 Intent activityIntent = r.activity.getIntent();
-                boolean attachToSession = false;
                 // TODO(b/33197203): re-evaluate conditions below for auto-fill. In particular,
                 // FLAG_SECURE might be allowed on AUTO_FILL but not on AUTO_FILL_SAVE)
                 boolean notSecure = r.window == null ||
                         (r.window.getAttributes().flags
                                 & WindowManager.LayoutParams.FLAG_SECURE) == 0;
                 if (activityIntent != null && notSecure) {
-                    if (forAutoFill) {
-                        attachToSession = true;
-                    } else {
+                    if (!forAutoFill) {
                         Intent intent = new Intent(activityIntent);
                         intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
@@ -2950,16 +2945,10 @@
                 } else {
                     if (!forAutoFill) {
                         content.setDefaultIntent(new Intent());
-                    } else {
-                        // activityIntent is unlikely to be null, but if it is, we should still
-                        // set the auto-fill callback.
-                        attachToSession = notSecure;
                     }
                 }
                 if (!forAutoFill) {
                     r.activity.onProvideAssistContent(content);
-                } else if (attachToSession) {
-                    r.activity.attachToAutoFillSession();
                 }
             }
         }
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 44db326..f330a4b 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -114,7 +114,8 @@
 import android.os.storage.StorageManager;
 import android.print.IPrintManager;
 import android.print.PrintManager;
-import android.service.autofill.IAutoFillManagerService;
+import android.view.autofill.AutoFillManager;
+import android.view.autofill.IAutoFillManager;
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
 import android.service.vr.IVrManager;
@@ -130,7 +131,6 @@
 import android.view.WindowManagerImpl;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.CaptioningManager;
-import android.view.autofill.AutoFillManager;
 import android.view.inputmethod.InputMethodManager;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textservice.TextServicesManager;
@@ -826,8 +826,8 @@
             @Override
             public AutoFillManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                 IBinder b = ServiceManager.getServiceOrThrow(Context.AUTO_FILL_MANAGER_SERVICE);
-                IAutoFillManagerService service = IAutoFillManagerService.Stub.asInterface(b);
-                return new AutoFillManager(ctx, service);
+                IAutoFillManager service = IAutoFillManager.Stub.asInterface(b);
+                return new AutoFillManager(ctx.getOuterContext(), service);
             }});
 
         registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5f4c36c..028a7bcf 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1806,41 +1806,6 @@
     @SystemApi
     public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
 
-    /**
-     * Intent extra: An id if an autofill item ({@link
-     * android.view.autofill.Dataset} or {@link android.view.autofill.FillResponse}).
-     * <p>
-     * Type: String
-     * </p>
-     */
-    public static final String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
-
-    /**
-     * Intent extra: The assist structure which captures the filled screen.
-     * <p>
-     * Type: {@link android.app.assist.AssistStructure}
-     * </p>
-     */
-    public static final String EXTRA_AUTO_FILL_ASSIST_STRUCTURE =
-            "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
-
-    /**
-     * Intent extra: The metadata associated with the authenticated entity ({@link
-     * android.view.autofill.Dataset} or {@link android.view.autofill.FillResponse}).
-     * <p>
-     * Type: {@link android.os.Bundle}
-     * </p>
-     */
-    public static final String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
-
-    /**
-     * Intent extra: A callback to report an authentication result.
-     * <p>
-     * Type: {@link android.view.autofill.FillResponse}
-     * </p>
-     */
-    public static final String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
-
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent broadcast actions (see action variable).
diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java
index 6da6a39..4099f59 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -30,7 +30,6 @@
 import android.os.ICancellationSignal;
 import android.os.Looper;
 import android.util.Log;
-import android.view.autofill.FillResponse;
 
 import com.android.internal.os.SomeArgs;
 
@@ -70,7 +69,7 @@
     // Internal extras
     /** @hide */
     public static final String EXTRA_ACTIVITY_TOKEN =
-            "android.service.autofill.EXTRA_ACTIVITY_TOKEN";
+            "android.service.autofill.extra.ACTIVITY_TOKEN";
 
     // Handler messages.
     private static final int MSG_CONNECT = 1;
@@ -180,15 +179,16 @@
      * service.
      *
      * <p>Service must call one of the {@link FillCallback} methods (like
-     * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)})
+     * {@link FillCallback#onSuccess(FillResponse)}
+     * or {@link FillCallback#onFailure(CharSequence)})
      * to notify the result of the request.
      *
      * @param structure {@link Activity}'s view structure.
      * @param data bundle containing data passed by the service on previous calls to fill.
      *     This bundle allows your service to keep state between fill and save requests
      *     as well as when filling different sections of the UI as the system will try to
-     *     aggressively unbind from the service to conserve resources. See {@link FillResponse}
-     *     Javadoc for examples of multiple-sections requests.
+     *     aggressively unbind from the service to conserve resources. See {@link
+     *     FillResponse} Javadoc for examples of multiple-sections requests.
      * @param cancellationSignal signal for observing cancellation requests. The system will use
      *     this to notify you that the fill result is no longer needed and you should stop
      *     handling this fill request in order to save resources.
@@ -208,8 +208,8 @@
      * @param data bundle containing data passed by the service on previous calls to fill.
      *     This bundle allows your service to keep state between fill and save requests
      *     as well as when filling different sections of the UI as the system will try to
-     *     aggressively unbind from the service to conserve resources. See {@link FillResponse}
-     *     Javadoc for examples of multiple-sections requests.
+     *     aggressively unbind from the service to conserve resources. See {@link
+     *     FillResponse} Javadoc for examples of multiple-sections requests.
      * @param callback object used to notify the result of the request.
      */
     public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
diff --git a/core/java/android/view/autofill/Dataset.aidl b/core/java/android/service/autofill/Dataset.aidl
similarity index 94%
rename from core/java/android/view/autofill/Dataset.aidl
rename to core/java/android/service/autofill/Dataset.aidl
index 2a8e67c..2342c5f 100644
--- a/core/java/android/view/autofill/Dataset.aidl
+++ b/core/java/android/service/autofill/Dataset.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.view.autofill;
+package android.service.autofill;
 
-parcelable Dataset;
\ No newline at end of file
+parcelable Dataset;
diff --git a/core/java/android/view/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
similarity index 60%
rename from core/java/android/view/autofill/Dataset.java
rename to core/java/android/service/autofill/Dataset.java
index 2708358..bd38c7f 100644
--- a/core/java/android/view/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -14,59 +14,48 @@
  * limitations under the License.
  */
 
-package android.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
+package android.service.autofill;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.assist.AssistStructure.ViewNode;
 import android.content.IntentSender;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-
+import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillValue;
 import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 
 /**
- * A set of data that can be used to auto-fill an {@link Activity}.
+ * A set of data that can be used to auto-fill an {@link android.app.Activity}.
  *
  * <p>It contains:
  *
  * <ol>
  *   <li>A name used to identify the dataset in the UI.
  *   <li>A list of id/value pairs for the fields that can be auto-filled.
- *   <li>An optional {@link Bundle} with extras (used only by the service creating it).
+ *   <li>A list of savable ids in addition to the ones with a provided value.
  * </ol>
  *
- * @see FillResponse for examples.
+ * @see android.service.autofill.FillResponse for examples.
  */
 public final class Dataset implements Parcelable {
-    private final String mId;
+    private static final boolean DEBUG = false;
+
     private final CharSequence mName;
     private final ArrayList<AutoFillId> mFieldIds;
     private final ArrayList<AutoFillValue> mFieldValues;
-    private final Bundle mExtras;
     private final IntentSender mAuthentication;
 
     private Dataset(Builder builder) {
-        mId = builder.mId;
         mName = builder.mName;
         mFieldIds = builder.mFieldIds;
         mFieldValues = builder.mFieldValues;
-        mExtras = builder.mExtras;
         mAuthentication = builder.mAuthentication;
     }
 
     /** @hide */
-    public @NonNull String getId() {
-        return mId;
-    }
-
-    /** @hide */
     public @NonNull CharSequence getName() {
         return mName;
     }
@@ -82,11 +71,6 @@
     }
 
     /** @hide */
-    public @Nullable Bundle getExtras() {
-        return mExtras;
-    }
-
-    /** @hide */
     public @Nullable IntentSender getAuthentication() {
         return mAuthentication;
     }
@@ -100,71 +84,32 @@
     public String toString() {
         if (!DEBUG) return super.toString();
 
-        final StringBuilder builder = new StringBuilder("Dataset [id=").append(mId)
-                .append(", name=").append(mName)
+        final StringBuilder builder = new StringBuilder("Dataset [name=").append(mName)
                 .append(", fieldIds=").append(mFieldIds)
                 .append(", fieldValues=").append(mFieldValues)
-                .append(", hasAuthentication=").append(mAuthentication != null)
-                .append(", hasExtras=").append(mExtras != null);
+                .append(", hasAuthentication=").append(mAuthentication != null);
         return builder.append(']').toString();
     }
 
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Dataset other = (Dataset) obj;
-        if (mId == null) {
-            if (other.mId != null) {
-                return false;
-            }
-        } else if (!mId.equals(other.mId)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return mId != null ? mId.hashCode() : 0;
-    }
-
     /**
      * A builder for {@link Dataset} objects. You must to provide at least
      * one value for a field or set an authentication intent.
      */
     public static final class Builder {
-        private String mId;
         private CharSequence mName;
         private ArrayList<AutoFillId> mFieldIds;
         private ArrayList<AutoFillValue> mFieldValues;
-        private Bundle mExtras;
         private IntentSender mAuthentication;
         private boolean mDestroyed;
 
-        /** @hide */
-        // TODO(b/33197203): Remove once GCore migrates
-        public Builder(@NonNull CharSequence name) {
-            this(String.valueOf(System.currentTimeMillis()), name);
-        }
-
         /**
          * Creates a new builder.
          *
-         * @param id A required id to identify this dataset for future interactions related to it.
          * @param name Name used to identify the dataset in the UI. Typically it's the same value as
          * the first field in the dataset (like username or email address) or a user-provided name
          * (like "My Work Address").
          */
-        public Builder(@NonNull String id, @NonNull CharSequence name) {
-            mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty or null");
+        public Builder(@NonNull CharSequence name) {
             mName = Preconditions.checkStringNotEmpty(name, "name cannot be empty or null");
         }
 
@@ -172,50 +117,36 @@
          * Requires a dataset authentication before auto-filling the activity with this dataset.
          *
          * <p>This method is called when you need to provide an authentication
-         * UI for the dataset. For example, when a dataset contains credit card information
+         * UI for the data set. For example, when a data set contains credit card information
          * (such as number, expiration date, and verification code), you can display UI
          * asking for the verification code to before filing in the data). Even if the
-         * dataset is completely populated the system will launch the specified authentication
-         * intent and will need your approval to fill it in. Since the dataset is "locked"
-         * until the user authenticates it, typically this dataset name is masked
-         * (for example, "VISA....1234"). Typically you would want to store the dataset
-         * labels non-encypted and the actual sensitive data encrypted and not in memory.
+         * data set is completely populated the system will launch the specified authentication
+         * intent and will need your approval to fill it in. Since the data set is "locked"
+         * until the user authenticates it, typically this data set name is masked
+         * (for example, "VISA....1234"). Typically you would want to store the data set
+         * labels non-encrypted and the actual sensitive data encrypted and not in memory.
          * This allows showing the labels in the UI while involving the user if one of
          * the items with these labels is chosen. Note that if you use sensitive data as
-         * a label, for example an email address, then it should also be encrypted.
-         *</p>
+         * a label, for example an email address, then it should also be encrypted.</p>
          *
-         * <p>When a user selects this dataset, the system triggers the provided intent
-         * whose extras will have the {@link android.content.Intent#EXTRA_AUTO_FILL_ITEM_ID id}
-         * of the {@link android.view.autofill.Dataset dataset} to authenticate, the {@link
-         * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} associated with this
-         * dataset, and a {@link android.content.Intent#EXTRA_AUTO_FILL_CALLBACK callback}
-         * to dispatch the authentication result.</p>
+         * <p>When a user triggers auto-fill, the system launches the provided intent
+         * whose extras will have the {@link
+         * android.view.autofill.AutoFillManager#EXTRA_ASSIST_STRUCTURE screen content}. Once
+         * you complete your authentication flow you should set the activity result to {@link
+         * android.app.Activity#RESULT_OK} and provide the fully populated {@link Dataset
+         * dataset} by setting it to the {@link
+         * android.view.autofill.AutoFillManager#EXTRA_AUTHENTICATION_RESULT} extra. For example,
+         * if you provided an credit card information without the CVV for the data set in the
+         * {@link FillResponse response} then the returned data set should contain the
+         * CVV entry.</p>
          *
-         * <p>Once you complete your authentication flow you should use the provided callback
-         * to notify for a failure or a success. In case of a success you need to provide
-         * only the fully populated dataset that is being authenticated. For example, if you
-         * provided a {@link FillResponse} with two {@link Dataset}s and marked that
-         * only the first dataset needs an authentication then in the provided response
-         * you need to provide only the fully populated dataset being authenticated instead
-         * of both of them.
-         * </p>
-         *
-         * <p>The indent sender mechanism allows you to have your authentication UI
-         * implemented as an activity or a service or a receiver. However, the recommended
-         * way is to do this is with an activity which the system will start in the
-         * filled activity's task meaning it will properly work with back, recent apps, and
-         * free-form multi-window, while avoiding the need for the "draw on top of other"
-         * apps special permission. You can still theme your authentication activity's
-         * UI to look like a dialog if desired.</p>
-         *
-         * <p></><strong>Note:</strong> Do not make the provided intent sender
+         * <p></><strong>Note:</strong> Do not make the provided pending intent
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
          * platform needs to fill in the authentication arguments.</p>
          *
-         * @param authentication Intent to trigger your authentication flow.
+         * @param authentication Intent to an activity with your authentication flow.
          *
-         * @see android.app.PendingIntent#getIntentSender()
+         * @see android.app.PendingIntent
          */
         public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
             throwIfDestroyed();
@@ -226,7 +157,8 @@
         /**
          * Sets the value of a field.
          *
-         * @param id id returned by {@link ViewNode#getAutoFillId()}.
+         * @param id id returned by {@link
+         *         android.app.assist.AssistStructure.ViewNode#getAutoFillId()}.
          * @param value value to be auto filled.
          */
         public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
@@ -249,18 +181,6 @@
         }
 
         /**
-         * Sets a {@link Bundle} that will be passed to subsequent APIs that
-         * manipulate this dataset. For example, they are passed in as {@link
-         * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} to your
-         * authentication flow.
-         */
-        public @NonNull Builder setExtras(@Nullable Bundle extras) {
-            throwIfDestroyed();
-            mExtras = extras;
-            return this;
-        }
-
-        /**
          * Creates a new {@link Dataset} instance. You should not interact
          * with this builder once this method is called.
          */
@@ -292,21 +212,19 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeString(mId);
         parcel.writeCharSequence(mName);
         parcel.writeTypedArrayList(mFieldIds, 0);
         parcel.writeTypedArrayList(mFieldValues, 0);
-        parcel.writeBundle(mExtras);
         parcel.writeParcelable(mAuthentication, flags);
     }
 
-    public static final Parcelable.Creator<Dataset> CREATOR = new Parcelable.Creator<Dataset>() {
+    public static final Creator<Dataset> CREATOR = new Creator<Dataset>() {
         @Override
         public Dataset createFromParcel(Parcel parcel) {
             // Always go through the builder to ensure the data ingested by
             // the system obeys the contract of the builder to avoid attacks
             // using specially crafted parcels.
-            final Builder builder = new Builder(parcel.readString(), parcel.readCharSequence());
+            final Builder builder = new Builder(parcel.readCharSequence());
             final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null);
             final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null);
             final int idCount = (ids != null) ? ids.size() : 0;
@@ -316,7 +234,6 @@
                 AutoFillValue value = (valueCount > i) ? values.get(i) : null;
                 builder.setValue(id, value);
             }
-            builder.setExtras(parcel.readBundle());
             builder.setAuthentication(parcel.readParcelable(null));
             return builder.build();
         }
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index a306809..69c9904 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -19,16 +19,13 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.RemoteException;
-import android.view.autofill.FillResponse;
 
 /**
  * Handles auto-fill requests from the {@link AutoFillService} into the {@link Activity} being
  * auto-filled.
  */
-public final class FillCallback implements Parcelable {
+public final class FillCallback {
     private final IFillCallback mCallback;
     private boolean mCalled;
 
@@ -37,11 +34,6 @@
         mCallback = callback;
     }
 
-    /** @hide */
-    private FillCallback(Parcel parcel) {
-        mCallback = IFillCallback.Stub.asInterface(parcel.readStrongBinder());
-    }
-
     /**
      * Notifies the Android System that an
      * {@link AutoFillService#onFillRequest(android.app.assist.AssistStructure, Bundle,
@@ -79,33 +71,9 @@
         }
     }
 
-    /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeStrongBinder(mCallback.asBinder());
-    }
-
     private void assertNotCalled() {
         if (mCalled) {
             throw new IllegalStateException("Already called");
         }
     }
-
-    public static final Creator<FillCallback> CREATOR = new Creator<FillCallback>() {
-        @Override
-        public FillCallback createFromParcel(Parcel parcel) {
-            return new FillCallback(parcel);
-        }
-
-        @Override
-        public FillCallback[] newArray(int size) {
-            return new FillCallback[size];
-        }
-    };
 }
diff --git a/core/java/android/view/autofill/FillResponse.aidl b/core/java/android/service/autofill/FillResponse.aidl
similarity index 94%
rename from core/java/android/view/autofill/FillResponse.aidl
rename to core/java/android/service/autofill/FillResponse.aidl
index b018f15..e9c2d21 100644
--- a/core/java/android/view/autofill/FillResponse.aidl
+++ b/core/java/android/service/autofill/FillResponse.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.view.autofill;
+package android.service.autofill;
 
-parcelable FillResponse;
\ No newline at end of file
+parcelable FillResponse;
diff --git a/core/java/android/view/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
similarity index 73%
rename from core/java/android/view/autofill/FillResponse.java
rename to core/java/android/service/autofill/FillResponse.java
index 596a06c..ea36e64 100644
--- a/core/java/android/view/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -13,30 +13,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
+package android.service.autofill;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.Activity;
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArraySet;
-
-import com.android.internal.util.Preconditions;
+import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillManager;
 
 /**
  * Response for a {@link
- * android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
- * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)} and
+ * AutoFillService#onFillRequest(android.app.assist.AssistStructure,
+ * Bundle, android.os.CancellationSignal, FillCallback)} and
  * authentication requests.
  *
  * <p>The response typically contains one or more {@link Dataset}s, each representing a set of
  * fields that can be auto-filled together, and the Android system displays a dataset picker UI
- * affordance that the user must use before the {@link Activity} is filled with the dataset.
+ * affordance that the user must use before the {@link android.app.Activity} is filled with
+ * the dataset.
  *
  * <p>For example, for a login page with username/password where the user only has one account in
  * the response could be:
@@ -65,9 +63,9 @@
  *      .build();
  * </pre>
  *
- * <p>If the user does not have any data associated with this {@link Activity} but the service wants
- * to offer the user the option to save the data that was entered, then the service could populate
- * the response with {@code savableIds} instead of {@link Dataset}s:
+ * <p>If the user does not have any data associated with this {@link android.app.Activity} but
+ * the service wants to offer the user the option to save the data that was entered, then the
+ * service could populate the response with {@code savableIds} instead of {@link Dataset}s:
  *
  * <pre class="prettyprint">
  *  new FillResponse.Builder()
@@ -142,7 +140,7 @@
  * #setAuthentication(IntentSender)} and {@link Dataset.Builder#setAuthentication(IntentSender)}.
  * It is recommended that you encrypt only the sensitive data but leave the labels unencrypted
  * which would allow you to provide the dataset names to the user and if they choose one
- * them challenge the user to authenticate. For example, if the user has a home and a work
+ * them challenge the user to onAuthenticate. For example, if the user has a home and a work
  * address the Home and Work labels could be stored unencrypted as they don't have any sensitive
  * data while the address data is in an encrypted storage. If the user chooses Home, then the
  * platform will start your authentication flow. If you encrypt all data and require auth
@@ -152,20 +150,16 @@
  * Work options where they can pick one. Hence, you have flexibility how to implement your
  * auth while storing labels non-encrypted and data encrypted provides a better user
  * experience.</p>
- *
- * <p>Finally, the service can use {@link Dataset.Builder#setExtras(Bundle)} methods
- * to pass {@link Bundle extras} provided to all future calls related to a dataset,
- * for example during authentication and saving.</p>
  */
 public final class FillResponse implements Parcelable {
-    private final String mId;
+    private static final boolean DEBUG = false;
+
     private final ArraySet<Dataset> mDatasets;
     private final ArraySet<AutoFillId> mSavableIds;
     private final Bundle mExtras;
     private final IntentSender mAuthentication;
 
     private FillResponse(@NonNull Builder builder) {
-        mId = builder.mId;
         mDatasets = builder.mDatasets;
         mSavableIds = builder.mSavableIds;
         mExtras = builder.mExtras;
@@ -173,11 +167,6 @@
     }
 
     /** @hide */
-    public @NonNull String getId() {
-        return mId;
-    }
-
-    /** @hide */
     public @Nullable Bundle getExtras() {
         return mExtras;
     }
@@ -202,71 +191,49 @@
      * one dataset or set an authentication intent.
      */
     public static final class Builder {
-        private final String mId;
         private ArraySet<Dataset> mDatasets;
         private ArraySet<AutoFillId> mSavableIds;
         private Bundle mExtras;
         private IntentSender mAuthentication;
         private boolean mDestroyed;
 
-        /** @hide */
-        // TODO(b/33197203): Remove once GCore migrates
-        public Builder() {
-            this(String.valueOf(System.currentTimeMillis()));
-        }
-
         /**
          * Creates a new {@link FillResponse} builder.
-         *
-         * @param id A required id to identify this dataset for future interactions related to it.
          */
-        public Builder(@NonNull String id) {
-            mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty or null");
+        public Builder() {
+
         }
 
         /**
          * Requires a fill response authentication before auto-filling the activity with
-         * any dataset in this response. This is typically useful when a user interaction
-         * is required to unlock their data vault if you encrypt the dataset labels and
-         * dataset data. It is recommended to encrypt only the sensitive data and not the
-         * dataset labels which would allow auth on the dataset level leading to a better
-         * user experience. Note that if you use sensitive data as a label, for example an
-         * email address, then it should also be encrypted.
+         * any data set in this response.
          *
-         * <p>This method is called when you need to provide an authentication
-         * UI for the fill response. For example, when the user's data is stored
-         * encrypted and needs a user interaction to decrypt before offering fill
-         * suggestions.</p>
+         * <p>This is typically useful when a user interaction is required to unlock their
+         * data vault if you encrypt the data set labels and data set data. It is recommended
+         * to encrypt only the sensitive data and not the data set labels which would allow
+         * auth on the data set level leading to a better user experience. Note that if you
+         * use sensitive data as a label, for example an email address, then it should also
+         * be encrypted. The provided {@link android.app.PendingIntent intent} must be an
+         * activity which implements your authentication flow.</p>
          *
-         * <p>When a user initiates an auto fill, the system triggers the provided
-         * intent whose extras will have the {@link android.content.Intent
-         * #EXTRA_AUTO_FILL_ITEM_ID id} of the {@link android.view.autofill.FillResponse})
-         * to authenticate, the {@link android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras}
-         * associated with this response, and a {@link android.content.Intent
-         * #EXTRA_AUTO_FILL_CALLBACK callback} to dispatch the authentication result.</p>
+         * <p>When a user triggers auto-fill, the system launches the provided intent
+         * whose extras will have the {@link
+         * AutoFillManager#EXTRA_ASSIST_STRUCTURE screen
+         * content}. Once you complete your authentication flow you should set the activity
+         * result to {@link android.app.Activity#RESULT_OK} and provide the fully populated {@link
+         * FillResponse response} by setting it to the {@link
+         * AutoFillManager#EXTRA_AUTHENTICATION_RESULT} extra.
+         * For example, if you provided an empty {@link FillResponse resppnse} because the
+         * user's data was locked and marked that the response needs an authentication then
+         * in the response returned if authentication succeeds you need to provide all
+         * available data sets some of which may need to be further authenticated, for
+         * example a credit card whose CVV needs to be entered.</p>
          *
-         * <p>Once you complete your authentication flow you should use the provided callback
-         * to notify for a failure or a success. In case of a success you need to provide
-         * the fully populated response that is being authenticated. For example, if you
-         * provided an empty {@link FillResponse} because the user's data was locked and
-         * marked that the response needs an authentication then in the response returned
-         * if authentication succeeds you need to provide all available datasets some of
-         * which may need to be further authenticated, for example a credit card whose
-         * CVV needs to be entered.</p>
-         *
-         * <p>The indent sender mechanism allows you to have your authentication UI
-         * implemented as an activity or a service or a receiver. However, the recommended
-         * way is to do this is with an activity which the system will start in the
-         * filled activity's task meaning it will properly work with back, recent apps, and
-         * free-form multi-window, while avoiding the need for the "draw on top of other"
-         * apps special permission. You can still theme your authentication activity's
-         * UI to look like a dialog if desired.</p>
-         *
-         * <p></><strong>Note:</strong> Do not make the provided intent sender
+         * <p></><strong>Note:</strong> Do not make the provided pending intent
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
          * platform needs to fill in the authentication arguments.</p>
          *
-         * @param authentication Intent to trigger your authentication flow.
+         * @param authentication Intent to an activity with your authentication flow.
          *
          * @see android.app.PendingIntent#getIntentSender()
          */
@@ -313,8 +280,8 @@
 
         /**
          * Adds ids of additional fields that the service would be interested to save (through
-         * {@link android.service.autofill.AutoFillService#onSaveRequest(
-         * android.app.assist.AssistStructure, Bundle, android.service.autofill.SaveCallback)})
+         * {@link AutoFillService#onSaveRequest(
+         * android.app.assist.AssistStructure, Bundle, SaveCallback)})
          * but were not indirectly set through {@link #addDataset(Dataset)}.
          *
          * <p>See {@link FillResponse} for examples.
@@ -335,15 +302,13 @@
 
         /**
          * Sets a {@link Bundle} that will be passed to subsequent APIs that
-         * manipulate this response. For example, they are passed in as {@link
-         * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} to your
-         * authentication flow and to subsequent calls to {@link
-         * android.service.autofill.AutoFillService#onFillRequest(
+         * manipulate this response. For example, they are passed to subsequent
+         * calls to {@link AutoFillService#onFillRequest(
          * android.app.assist.AssistStructure, Bundle, android.os.CancellationSignal,
-         * android.service.autofill.FillCallback)} and {@link
-         * android.service.autofill.AutoFillService#onSaveRequest(
+         * FillCallback)} and {@link
+         * AutoFillService#onSaveRequest(
          * android.app.assist.AssistStructure, Bundle,
-         * android.service.autofill.SaveCallback)}.
+         * SaveCallback)}.
          */
         public Builder setExtras(Bundle extras) {
             throwIfDestroyed();
@@ -374,8 +339,7 @@
     public String toString() {
         if (!DEBUG) return super.toString();
         final StringBuilder builder = new StringBuilder(
-                "FillResponse: [id=").append(mId)
-                .append(", datasets=").append(mDatasets)
+                "FillResponse: [datasets=").append(mDatasets)
                 .append(", savableIds=").append(mSavableIds)
                 .append(", hasExtras=").append(mExtras != null)
                 .append(", hasAuthentication=").append(mAuthentication != null);
@@ -393,7 +357,6 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeString(mId);
         parcel.writeTypedArraySet(mDatasets, 0);
         parcel.writeTypedArraySet(mSavableIds, 0);
         parcel.writeParcelable(mExtras, 0);
@@ -407,7 +370,7 @@
             // Always go through the builder to ensure the data ingested by
             // the system obeys the contract of the builder to avoid attacks
             // using specially crafted parcels.
-            final Builder builder = new Builder(parcel.readString());
+            final Builder builder = new Builder();
             final ArraySet<Dataset> datasets = parcel.readTypedArraySet(null);
             final int datasetCount = (datasets != null) ? datasets.size() : 0;
             for (int i = 0; i < datasetCount; i++) {
diff --git a/core/java/android/service/autofill/IAuthenticationCallback.aidl b/core/java/android/service/autofill/IAuthenticationCallback.aidl
new file mode 100644
index 0000000..36b989d
--- /dev/null
+++ b/core/java/android/service/autofill/IAuthenticationCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.view.autofill;
+
+import android.view.autofill.Dataset;
+import android.service.autofill.FillResponse;
+
+/**
+ * Callback for delivering authentication result.
+ *
+ * {@hide}
+ */
+interface IAutoFillAuthCallback {
+    void onSuccessForDataset(in Dataset dataset);
+    void onSuccessForFillResponse(in FillResponse response);
+    void onFailure(CharSequence message);
+}
diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl
deleted file mode 100644
index 6cdb516..0000000
--- a/core/java/android/service/autofill/IAutoFillManagerService.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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.autofill;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
-
-/**
- * Mediator between apps being auto-filled and auto-fill service implementations.
- *
- * {@hide}
- */
-oneway interface IAutoFillManagerService {
-    // Methods called by AutoFillManager
-    void startSession(in IBinder activityToken, in IBinder appCallback, in AutoFillId autoFillId,
-                      in Rect bounds, in AutoFillValue value);
-    void updateSession(in IBinder activityToken, in AutoFillId id, in Rect bounds,
-                       in AutoFillValue value, int flags);
-    void finishSession(in IBinder activityToken);
-}
diff --git a/core/java/android/service/autofill/IFillCallback.aidl b/core/java/android/service/autofill/IFillCallback.aidl
index 537403e..2bb3e9a 100644
--- a/core/java/android/service/autofill/IFillCallback.aidl
+++ b/core/java/android/service/autofill/IFillCallback.aidl
@@ -18,7 +18,7 @@
 
 import android.os.ICancellationSignal;
 
-import android.view.autofill.FillResponse;
+import android.service.autofill.FillResponse;
 
 /**
  * Interface to receive the result of a save request.
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index 46b3072..c6dd1df 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -23,8 +23,6 @@
 /**
  * Handles save requests from the {@link AutoFillService} into the {@link Activity} being
  * auto-filled.
- *
- * <p>This class is thread safe.
  */
 public final class SaveCallback {
     private final ISaveCallback mCallback;
diff --git a/core/java/android/view/autofill/AutoFillManager.java b/core/java/android/view/autofill/AutoFillManager.java
index 58607ba..f7a1b61 100644
--- a/core/java/android/view/autofill/AutoFillManager.java
+++ b/core/java/android/view/autofill/AutoFillManager.java
@@ -16,40 +16,101 @@
 
 package android.view.autofill;
 
-import static android.view.autofill.Helper.VERBOSE;
-
-import android.annotation.Nullable;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.IBinder;
+import android.os.Parcelable;
 import android.os.RemoteException;
-import android.service.autofill.IAutoFillManagerService;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.View;
 
+import java.lang.ref.WeakReference;
+import java.util.List;
+
 /**
  * App entry point to the AutoFill Framework.
  */
 // TODO(b/33197203): improve this javadoc
 //TODO(b/33197203): restrict manager calls to activity
 public final class AutoFillManager {
+    private static final boolean DEBUG = false;
 
     private static final String TAG = "AutoFillManager";
 
+    /**
+     * Intent extra: The assist structure which captures the filled screen.
+     * <p>
+     * Type: {@link android.app.assist.AssistStructure}
+     * </p>
+     */
+    public static final String EXTRA_ASSIST_STRUCTURE =
+            "android.view.autofill.extra.ASSIST_STRUCTURE";
+
+    /**
+     * Intent extra: The result of an authentication operation. It is
+     * either a fully populated {@link android.service.autofill.FillResponse}
+     * or a fully populated {@link android.service.autofill.Dataset} if
+     * a response or a dataset is being authenticated respectively.
+     *
+     * <p>
+     * Type: {@link android.service.autofill.FillResponse} or a
+     * {@link android.service.autofill.Dataset}
+     * </p>
+     */
+    public static final String EXTRA_AUTHENTICATION_RESULT =
+            "android.view.autofill.extra.AUTHENTICATION_RESULT";
+
     /** @hide */ public static final int FLAG_START_SESSION = 0x1;
     /** @hide */ public static final int FLAG_FOCUS_GAINED = 0x2;
     /** @hide */ public static final int FLAG_FOCUS_LOST = 0x4;
     /** @hide */ public static final int FLAG_VALUE_CHANGED = 0x8;
 
-    private final IAutoFillManagerService mService;
-    private final Context mContext;
+    // These are activities that may have auto-fill UI which are keyed off their tokens.
+    // This is done instead of the activity setting the client in the auto-fill manager
+    // to avoid unnecessary instantiation of the manager and do this only if there is an
+    // auto-fillable focused. This has only the cost of loading the class vs creating an
+    // auto-fill manager for every activity even one that cannot be filled.
+    private static final ArrayMap<IBinder, AutoFillClient> sPendingClients = new ArrayMap<>();
 
-    private AutoFillSession mSession;
+    private final Rect mTempRect = new Rect();
+
+    private final IAutoFillManager mService;
+    private IAutoFillManagerClient mServiceClient;
+
+    private Context mContext;
+
+    private AutoFillClient mClient;
+
+    private boolean mHasSession;
+    private boolean mEnabled;
+
+    /** @hide */
+    public interface AutoFillClient {
+        /**
+         * Asks the client to perform an auto-fill.
+         *
+         * @param ids The values to auto-fill
+         * @param values The values to auto-fill
+         */
+        void autoFill(List<AutoFillId> ids, List<AutoFillValue> values);
+
+        /**
+         * Asks the client to start an authentication flow.
+         *
+         * @param intent The authentication intent.
+         * @param fillInIntent The authentication fill-in intent.
+         */
+        void authenticate(IntentSender intent, Intent fillInIntent);
+    }
 
     /**
      * @hide
      */
-    public AutoFillManager(Context context, IAutoFillManagerService service) {
+    public AutoFillManager(Context context, IAutoFillManager service) {
         mContext = context;
         mService = service;
     }
@@ -61,27 +122,26 @@
      * @param gainFocus whether focus was gained or lost.
      */
     public void focusChanged(View view, boolean gainFocus) {
-        if (mSession == null) {
-            // Starts new session.
-            final Rect bounds = new Rect();
-            view.getBoundsOnScreen(bounds);
-            final AutoFillId id = getAutoFillId(view);
-            final AutoFillValue value = view.getAutoFillValue();
-            startSession(id, bounds, value);
+        ensureServiceClientAddedIfNeeded();
+
+        if (!mEnabled) {
             return;
         }
 
-        if (!mSession.isEnabled()) {
-            // Auto-fill is disabled for this session.
-            return;
-        }
-
-        // Update focus on existing session.
-        final Rect bounds = new Rect();
+        final Rect bounds = mTempRect;
         view.getBoundsOnScreen(bounds);
         final AutoFillId id = getAutoFillId(view);
         final AutoFillValue value = view.getAutoFillValue();
-        updateSession(id, bounds, value, gainFocus ? FLAG_FOCUS_GAINED : FLAG_FOCUS_LOST);
+
+        if (!mHasSession) {
+            if (gainFocus) {
+                // Starts new session.
+                startSession(id, bounds, value);
+            }
+        } else {
+            // Update focus on existing session.
+            updateSession(id, bounds, value, gainFocus ? FLAG_FOCUS_GAINED : FLAG_FOCUS_LOST);
+        }
     }
 
     /**
@@ -93,21 +153,23 @@
      * @param gainFocus whether focus was gained or lost.
      */
     public void virtualFocusChanged(View parent, int childId, Rect bounds, boolean gainFocus) {
-        if (mSession == null) {
-            // Starts new session.
-            final AutoFillId id = getAutoFillId(parent, childId);
-            startSession(id, bounds, null);
+        ensureServiceClientAddedIfNeeded();
+
+        if (!mEnabled) {
             return;
         }
 
-        if (!mSession.isEnabled()) {
-            // Auto-fill is disabled for this session.
-            return;
-        }
-
-        // Update focus on existing session.
         final AutoFillId id = getAutoFillId(parent, childId);
-        updateSession(id, bounds, null, gainFocus ? FLAG_FOCUS_GAINED : FLAG_FOCUS_LOST);
+
+        if (!mHasSession) {
+            if (gainFocus) {
+                // Starts new session.
+                startSession(id, bounds, null);
+            }
+        } else {
+            // Update focus on existing session.
+            updateSession(id, bounds, null, gainFocus ? FLAG_FOCUS_GAINED : FLAG_FOCUS_LOST);
+        }
     }
 
     /**
@@ -116,7 +178,11 @@
      * @param view view whose focus changed.
      */
     public void valueChanged(View view) {
-        if (mSession == null) return;
+        ensureServiceClientAddedIfNeeded();
+
+        if (!mEnabled || !mHasSession) {
+            return;
+        }
 
         final AutoFillId id = getAutoFillId(view);
         final AutoFillValue value = view.getAutoFillValue();
@@ -132,7 +198,11 @@
      * @param value new value of the child.
      */
     public void virtualValueChanged(View parent, int childId, AutoFillValue value) {
-        if (mSession == null) return;
+        ensureServiceClientAddedIfNeeded();
+
+        if (!mEnabled || !mHasSession) {
+            return;
+        }
 
         final AutoFillId id = getAutoFillId(parent, childId);
         updateSession(id, null, value, FLAG_VALUE_CHANGED);
@@ -145,30 +215,51 @@
      * call this method after the form is submitted and another page is rendered.
      */
     public void reset() {
-        if (mSession == null) return;
+        ensureServiceClientAddedIfNeeded();
 
-        final IBinder activityToken = mSession.mToken.get();
-        if (activityToken == null) {
-            Log.wtf(TAG, "finishSession(): token already GC'ed");
+        if (!mEnabled && !mHasSession) {
             return;
         }
-        try {
-            mService.finishSession(activityToken);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            mSession = null;
-        }
+
+        finishSession();
     }
 
-    /**
-     * Gets the current session, if any.
-     *
-     * @hide
-     */
-    @Nullable
-    public AutoFillSession getSession() {
-        return mSession;
+    /** @hide */
+    public static void addClient(IBinder token, AutoFillClient client) {
+        sPendingClients.put(token, client);
+    }
+
+    /** @hide */
+    public static boolean isClientActive(IBinder token) {
+        return !sPendingClients.containsKey(token);
+    }
+
+    private void activateClient() {
+        mClient = sPendingClients.remove(mContext.getActivityToken());
+    }
+
+    private AutoFillClient getClient() {
+        if (mClient == null) {
+            return sPendingClients.get(mContext.getActivityToken());
+        }
+        return mClient;
+    }
+
+    /** @hide */
+    public void onAuthenticationResult(Intent data) {
+        if (data == null) {
+            return;
+        }
+        Parcelable result = data.getParcelableExtra(
+                EXTRA_AUTHENTICATION_RESULT);
+        Bundle responseData = new Bundle();
+        responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result);
+        try {
+            mService.setAuthenticationResult(responseData,
+                    mContext.getActivityToken(), mContext.getUserId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error delivering authentication result", e);
+        }
     }
 
     private AutoFillId getAutoFillId(View view) {
@@ -180,34 +271,98 @@
     }
 
     private void startSession(AutoFillId id, Rect bounds, AutoFillValue value) {
-        if (VERBOSE) {
+        if (DEBUG) {
             Log.v(TAG, "startSession(): id=" + id + ", bounds=" + bounds + ", value=" + value);
         }
-
-        final IBinder activityToken = mContext.getActivityToken();
-        mSession = new AutoFillSession(this, activityToken);
-        final IBinder appCallback = mSession.getCallback().asBinder();
         try {
-            mService.startSession(activityToken, appCallback, id, bounds, value);
+            mService.startSession(mContext.getActivityToken(), mServiceClient.asBinder(),
+                    id, bounds, value, mContext.getUserId());
+            mHasSession = true;
+            activateClient();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private void finishSession() {
+        if (DEBUG) {
+            Log.v(TAG, "finishSession()");
+        }
+        mHasSession = false;
+        try {
+            mService.finishSession(mContext.getActivityToken(), mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     private void updateSession(AutoFillId id, Rect bounds, AutoFillValue value, int flags) {
-        if (VERBOSE) {
+        if (DEBUG) {
             Log.v(TAG, "updateSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
                     + ", flags=" + flags);
         }
-
-        final IBinder activityToken = mSession.mToken.get();
-        if (activityToken == null) {
-            return;
-        }
         try {
-            mService.updateSession(activityToken, id, bounds, value, flags);
+            mService.updateSession(mContext.getActivityToken(), id, bounds, value, flags,
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
+
+    private void ensureServiceClientAddedIfNeeded() {
+        if (getClient() == null) {
+            return;
+        }
+        if (mServiceClient == null) {
+            mServiceClient = new AutoFillManagerClient(this);
+            try {
+                mEnabled = mService.addClient(mServiceClient, mContext.getUserId());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    private static final class AutoFillManagerClient extends IAutoFillManagerClient.Stub {
+        private final WeakReference<AutoFillManager> mAutoFillManager;
+
+        AutoFillManagerClient(AutoFillManager autoFillManager) {
+            mAutoFillManager = new WeakReference<>(autoFillManager);
+        }
+
+        @Override
+        public void setState(boolean enabled) {
+            final AutoFillManager autoFillManager = mAutoFillManager.get();
+            if (autoFillManager != null) {
+                autoFillManager.mContext.getMainThreadHandler().post(() ->
+                        autoFillManager.mEnabled = enabled);
+            }
+        }
+
+        @Override
+        public void autoFill(List<AutoFillId> ids, List<AutoFillValue> values) {
+            // TODO(b/33197203): must keep the dataset so subsequent calls pass the same
+            // dataset.extras to service
+            final AutoFillManager autoFillManager = mAutoFillManager.get();
+            if (autoFillManager != null) {
+                autoFillManager.mContext.getMainThreadHandler().post(() -> {
+                    if (autoFillManager.getClient() != null) {
+                        autoFillManager.getClient().autoFill(ids, values);
+                    }
+                });
+            }
+        }
+
+        @Override
+        public void authenticate(IntentSender intent, Intent fillInIntent) {
+            final AutoFillManager autoFillManager = mAutoFillManager.get();
+            if (autoFillManager != null) {
+                autoFillManager.mContext.getMainThreadHandler().post(() -> {
+                    if (autoFillManager.getClient() != null) {
+                        autoFillManager.getClient().authenticate(intent, fillInIntent);
+                    }
+                });
+            }
+        }
+    }
 }
diff --git a/core/java/android/view/autofill/AutoFillSession.java b/core/java/android/view/autofill/AutoFillSession.java
deleted file mode 100644
index 64df62f..0000000
--- a/core/java/android/view/autofill/AutoFillSession.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2017 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.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.os.IBinder;
-import android.service.autofill.IAutoFillAppCallback;
-import android.util.Log;
-import android.view.View;
-
-import java.lang.ref.WeakReference;
-
-/**
- * An auto-fill session associated with an activity.
- *
- * @hide
- */
-public final class AutoFillSession {
-
-    private static final String TAG = "AutoFillSession";
-
-    private final IAutoFillAppCallback mCallback = new IAutoFillAppCallback.Stub() {
-
-        @Override
-        public void enableSession() {
-            if (DEBUG) Log.d(TAG, "enableSession()");
-
-            mEnabled = true;
-        }
-
-        @Override
-        public void autoFill(Dataset dataset) {
-            final Activity activity = mActivity.get();
-            if (activity == null) {
-                if (DEBUG) Log.d(TAG, "autoFill(): activity already GCed");
-                return;
-            }
-            // TODO(b/33197203): must keep the dataset so subsequent calls pass the same
-            // dataset.extras to service
-            activity.runOnUiThread(() -> {
-                final View root = activity.getWindow().getDecorView().getRootView();
-                final int itemCount = dataset.getFieldIds().size();
-                for (int i = 0; i < itemCount; i++) {
-                    final AutoFillId id = dataset.getFieldIds().get(i);
-                    final AutoFillValue value = dataset.getFieldValues().get(i);
-                    final int viewId = id.getViewId();
-                    final View view = root.findViewByAccessibilityIdTraversal(viewId);
-                    if (view == null) {
-                        Log.w(TAG, "autoFill(): no View with id " + viewId);
-                        continue;
-                    }
-
-                    if (id.isVirtual()) {
-                        view.autoFillVirtual(id.getVirtualChildId(), value);
-                    } else {
-                        view.autoFill(value);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void startIntentSender(IntentSender intent, Intent fillInIntent) {
-            final Activity activity = mActivity.get();
-            if (activity != null) {
-                activity.runOnUiThread(() -> {
-                    try {
-                        activity.startIntentSender(intent, fillInIntent, 0, 0, 0);
-                    } catch (IntentSender.SendIntentException e) {
-                        Log.e(TAG, "startIntentSender() failed for intent:" + intent, e);
-                    }
-                });
-            }
-        }
-    };
-
-    private final AutoFillManager mAfm;
-    private WeakReference<Activity> mActivity;
-
-    // Reference to the token, which is used by the server.
-    final WeakReference<IBinder> mToken;
-
-    private boolean mEnabled;
-
-    public AutoFillSession(AutoFillManager afm, IBinder token) {
-        mToken = new WeakReference<>(token);
-        mAfm = afm;
-    }
-
-    /**
-     * Called by the {@link Activity} when it was asked to provider auto-fill data.
-     */
-    public void attachActivity(Activity activity) {
-        if (mActivity != null) {
-            Log.w(TAG, "attachActivity(): already attached");
-            return;
-        }
-        mActivity = new WeakReference<>(activity);
-    }
-
-    /**
-     * Checks whether auto-fill is enabled for this session, as decided by the
-     * {@code AutoFillManagerService}.
-     */
-    public boolean isEnabled() {
-        return mEnabled;
-    }
-
-    /**
-     * Notifies the manager that a session finished.
-     */
-    // TODO(b/33197203): hook it to other lifecycle events like fragments transition
-    public void finishSession() {
-        if (mAfm != null) {
-            try {
-                mAfm.reset();
-            } catch (RuntimeException e) {
-                Log.w(TAG, "Failed to finish session for " + mToken.get() + ": " + e);
-            }
-        }
-    }
-
-    public IAutoFillAppCallback getCallback() {
-        return mCallback;
-    }
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        return "AutoFillSession[activityoken=" + mToken.get() + "]";
-    }
-}
diff --git a/core/java/android/view/autofill/FieldId.aidl b/core/java/android/view/autofill/FieldId.aidl
deleted file mode 100644
index 35af645..0000000
--- a/core/java/android/view/autofill/FieldId.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2016, 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.view.autofill;
-
-parcelable FieldId;
\ No newline at end of file
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
new file mode 100644
index 0000000..0433a8f
--- /dev/null
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.view.autofill;
+
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillValue;
+import android.view.autofill.IAutoFillManagerClient;
+
+/**
+ * Mediator between apps being auto-filled and auto-fill service implementations.
+ *
+ * {@hide}
+ */
+interface IAutoFillManager {
+    boolean addClient(in IAutoFillManagerClient client, int userId);
+    oneway void startSession(in IBinder activityToken, in IBinder appCallback,
+            in AutoFillId autoFillId, in Rect bounds, in AutoFillValue value, int userId);
+    oneway void updateSession(in IBinder activityToken, in AutoFillId id, in Rect bounds,
+            in AutoFillValue value, int flags, int userId);
+    oneway void finishSession(in IBinder activityToken, int userId);
+    oneway void setAuthenticationResult(in Bundle data,
+            in IBinder activityToken, int userId);
+}
diff --git a/core/java/android/service/autofill/IAutoFillAppCallback.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
similarity index 64%
rename from core/java/android/service/autofill/IAutoFillAppCallback.aidl
rename to core/java/android/view/autofill/IAutoFillManagerClient.aidl
index c2e72e8..45f363d 100644
--- a/core/java/android/service/autofill/IAutoFillAppCallback.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -14,34 +14,33 @@
  * limitations under the License.
  */
 
-package android.service.autofill;
+package android.view.autofill;
 
 import java.util.List;
 
 import android.content.Intent;
 import android.content.IntentSender;
-import android.view.autofill.Dataset;
+import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillValue;
 
 /**
  * Object running in the application process and responsible for auto-filling it.
  *
  * @hide
  */
-// TODO(b/33197203): rename IAutoFillAppSession
-oneway interface IAutoFillAppCallback {
+oneway interface IAutoFillManagerClient {
+    /**
+     * Notifies the client when the auto-fill enabled state changed.
+     */
+    void setState(boolean enabled);
+
     /**
       * Auto-fills the activity with the contents of a dataset.
       */
-    void autoFill(in Dataset dataset);
+    void autoFill(in List<AutoFillId> ids, in List<AutoFillValue> values);
 
     /**
-      * Start an intent sender from the context of the filled app
+      * Authenticates a fill response or a data set.
       */
-    void startIntentSender(in IntentSender intent, in Intent fillInIntent);
-
-    /**
-      * Called by system_service to enable auto-fill in a session, after it was asynchronously
-      * started by the manager.
-      */
-    void enableSession();
+    void authenticate(in IntentSender intent, in Intent fillInIntent);
 }
diff --git a/services/autofill/java/com/android/server/autofill/AnchoredWindow.java b/services/autofill/java/com/android/server/autofill/AnchoredWindow.java
index ed0d234..64c6abd 100644
--- a/services/autofill/java/com/android/server/autofill/AnchoredWindow.java
+++ b/services/autofill/java/com/android/server/autofill/AnchoredWindow.java
@@ -126,13 +126,13 @@
             int oldLeft, int oldTop, int oldRight, int oldBottom) {
         if (view == mWindowSizeListenerView) {
             if (DEBUG) Slog.d(TAG, "onLayoutChange() for mWindowSizeListenerView");
-            // mWindowSizeListenerView layout changed, get the size of the display bounds and update
+            // mWindowSizeListenerView layout changed, get the size of the display bounds and updateLocked
             // the window.
             final Rect displayBounds = new Rect();
             view.getBoundsOnScreen(displayBounds);
             updateDisplayBounds(displayBounds);
         } else if (view == mContentView) {
-            // mContentView layout changed, update the window in case its height changed.
+            // mContentView layout changed, updateLocked the window in case its height changed.
             if (DEBUG) Slog.d(TAG, "onLayoutChange() for mContentView");
             updateHeight();
         }
@@ -159,7 +159,7 @@
                 MeasureSpec.makeMeasureSpec(displayBounds.height(), MeasureSpec.AT_MOST));
         int height = mContentView.getMeasuredHeight();
         if (height != mLastHeight) {
-            if (DEBUG) Slog.d(TAG, "update height=" + height);
+            if (DEBUG) Slog.d(TAG, "updateLocked height=" + height);
             mLastHeight = height;
             update(height, mLastBounds, displayBounds);
             return true;
@@ -170,7 +170,7 @@
 
     private void updateBounds(Rect bounds) {
         if (!bounds.equals(mLastBounds)) {
-            if (DEBUG) Slog.d(TAG, "update bounds=" + bounds);
+            if (DEBUG) Slog.d(TAG, "updateLocked bounds=" + bounds);
             mLastBounds = bounds;
 
             update(mLastHeight, bounds, mLastDisplayBounds);
@@ -179,7 +179,7 @@
 
     private void updateDisplayBounds(Rect displayBounds) {
         if (!displayBounds.equals(mLastDisplayBounds)) {
-            if (DEBUG) Slog.d(TAG, "update displayBounds=" + displayBounds);
+            if (DEBUG) Slog.d(TAG, "updateLocked displayBounds=" + displayBounds);
             mLastDisplayBounds = displayBounds;
 
             if (!updateHeight()) {
@@ -195,7 +195,7 @@
             return;
         }
 
-        if (DEBUG) Slog.d(TAG, "update height=" + height + ", bounds=" + bounds
+        if (DEBUG) Slog.d(TAG, "updateLocked height=" + height + ", bounds=" + bounds
                 + ", displayBounds=" + displayBounds);
 
         final LayoutParams params = createWindowLayoutParams(mAppToken,
@@ -220,7 +220,7 @@
      * the bounds is preferred, if it fits. Otherwise, anchor the window on the side with more
      * space.
      *
-     * @param params the params to update
+     * @param params the params to updateLocked
      * @param height the requested height of the window
      * @param minMargin the minimum margin between the window and the display bounds
      * @param bounds the region the window should be anchored to
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index c16a51c..3257812 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -22,14 +22,14 @@
 import static com.android.server.autofill.Helper.VERBOSE;
 
 import android.Manifest;
-import android.annotation.Nullable;
+import android.annotation.NonNull;
 import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
-import android.content.ComponentName;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
 import android.database.ContentObserver;
 import android.graphics.Rect;
 import android.net.Uri;
@@ -37,14 +37,11 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.service.autofill.IAutoFillManagerService;
-import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.Slog;
@@ -52,11 +49,12 @@
 import android.view.autofill.AutoFillId;
 import android.view.autofill.AutoFillValue;
 
+import android.view.autofill.IAutoFillManager;
+import android.view.autofill.IAutoFillManagerClient;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
-import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.os.SomeArgs;
+import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
@@ -68,21 +66,15 @@
 /**
  * Entry point service for auto-fill management.
  *
- * <p>This service provides the {@link IAutoFillManagerService} implementation and keeps a list of
+ * <p>This service provides the {@link IAutoFillManager} implementation and keeps a list of
  * {@link AutoFillManagerServiceImpl} per user; the real work is done by
  * {@link AutoFillManagerServiceImpl} itself.
  */
+// TODO(b/33197203): Handle removing of packages
 public final class AutoFillManagerService extends SystemService {
 
     private static final String TAG = "AutoFillManagerService";
 
-    private static final int MSG_START_SESSION = 1;
-    private static final int MSG_UPDATE_SESSION = 2;
-    private static final int MSG_FINISH_SESSION = 3;
-    private static final int MSG_REQUEST_SAVE_FOR_USER = 4;
-    private static final int MSG_LIST_SESSIONS = 5;
-    private static final int MSG_RESET = 6;
-
     static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
 
     private final Context mContext;
@@ -90,48 +82,6 @@
 
     private final Object mLock = new Object();
 
-    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
-        switch (msg.what) {
-            case MSG_START_SESSION: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final int userId = msg.arg1;
-                final IBinder activityToken = (IBinder) args.arg1;
-                final IBinder appCallback = (IBinder) args.arg2;
-                final AutoFillId autoFillId = (AutoFillId) args.arg3;
-                final Rect bounds = (Rect) args.arg4;
-                final AutoFillValue value = (AutoFillValue) args.arg5;
-                handleStartSession(userId, activityToken, appCallback, autoFillId, bounds, value);
-                return;
-            } case MSG_FINISH_SESSION: {
-                handleFinishSession(msg.arg1, (IBinder) msg.obj);
-                return;
-            } case MSG_REQUEST_SAVE_FOR_USER: {
-                handleSaveForUser(msg.arg1);
-                return;
-            } case MSG_UPDATE_SESSION: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final IBinder activityToken = (IBinder) args.arg1;
-                final AutoFillId autoFillId = (AutoFillId) args.arg2;
-                final Rect bounds = (Rect) args.arg3;
-                final AutoFillValue value = (AutoFillValue) args.arg4;
-                final int userId = args.argi5;
-                final int flags = args.argi6;
-                handleUpdateSession(userId, activityToken, autoFillId, bounds, value, flags);
-                return;
-            } case MSG_LIST_SESSIONS: {
-                handleListForUser(msg.arg1, (IResultReceiver) msg.obj);
-                return;
-            } case MSG_RESET: {
-                handleReset();
-                return;
-            } default: {
-                Slog.w(TAG, "Invalid message: " + msg);
-            }
-        }
-    };
-
-    private HandlerCaller mHandlerCaller;
-
     /**
      * Cache of {@link AutoFillManagerServiceImpl} per user id.
      * <p>
@@ -152,11 +102,26 @@
     // TODO(b/33197203): set a different max (or disable it) on low-memory devices.
     private final LocalLog mRequestsHistory = new LocalLog(100);
 
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
+                final String reason = intent.getStringExtra("reason");
+                if (DEBUG) Slog.d(TAG, "close system dialogs: " + reason);
+                mUi.hideAll();
+            }
+        }
+    };
+
     public AutoFillManagerService(Context context) {
         super(context);
-        mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
         mContext = context;
         mUi = new AutoFillUI(mContext);
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        mContext.registerReceiver(mBroadcastReceiver, filter, null,
+                FgThread.getHandler());
     }
 
     @Override
@@ -171,46 +136,30 @@
         }
     }
 
-    private AutoFillManagerServiceImpl newServiceForUser(int userId) {
-        ComponentName serviceComponent = null;
-        ServiceInfo serviceInfo = null;
-        final String componentName = Settings.Secure.getStringForUser(
-                mContext.getContentResolver(), Settings.Secure.AUTO_FILL_SERVICE, userId);
-        if (!TextUtils.isEmpty(componentName)) {
-            try {
-                serviceComponent = ComponentName.unflattenFromString(componentName);
-                serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0,
-                        userId);
-            } catch (RuntimeException | RemoteException e) {
-                Slog.e(TAG, "Bad auto-fill service name " + componentName, e);
-                return null;
-            }
+    @Override
+    public void onUnlockUser(int userId) {
+        synchronized (mLock) {
+            updateCachedServiceLocked(userId);
         }
+    }
 
-        if (serviceInfo == null) {
-            return null;
+    @Override
+    public void onStopUser(int userId) {
+        synchronized (mLock) {
+            removeCachedServiceLocked(userId);
         }
-
-        try {
-            return new AutoFillManagerServiceImpl(mContext, mLock, mRequestsHistory,
-                    userId, serviceComponent, mUi);
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.w(TAG, "Auto-fill service not found: " + serviceComponent, e);
-        }
-
-        return null;
     }
 
     /**
      * Gets the service instance for an user.
      *
-     * @return service instance or {@code null} if user does not have a service set.
+     * @return service instance.
      */
-    @Nullable
-    AutoFillManagerServiceImpl getServiceForUserLocked(int userId) {
+    @NonNull AutoFillManagerServiceImpl getServiceForUserLocked(int userId) {
         AutoFillManagerServiceImpl service = mServicesCache.get(userId);
         if (service == null) {
-            service = newServiceForUser(userId);
+            service = new AutoFillManagerServiceImpl(mContext, mLock,
+                    mRequestsHistory, userId, mUi);
             mServicesCache.put(userId, service);
         }
         return service;
@@ -220,81 +169,6 @@
     void requestSaveForUser(int userId) {
         Slog.i(TAG, "requestSaveForUser(): " + userId);
         mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageI(
-                MSG_REQUEST_SAVE_FOR_USER, userId));
-    }
-
-    // Called by Shell command.
-    void listSessions(int userId, IResultReceiver receiver) {
-        Slog.i(TAG, "listSessions() for userId " + userId);
-        mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        mHandlerCaller.sendMessage(
-                mHandlerCaller.obtainMessageIO(MSG_LIST_SESSIONS, userId, receiver));
-    }
-
-    // Called by Shell command.
-    void reset() {
-        Slog.i(TAG, "reset()");
-        mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_RESET));
-    }
-
-    /**
-     * Removes a cached service for a given user.
-     */
-    void removeCachedServiceLocked(int userId) {
-        final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
-        if (service != null) {
-            mServicesCache.delete(userId);
-            service.destroyLocked();
-        }
-    }
-
-    private void handleStartSession(int userId, IBinder activityToken, IBinder appCallback,
-            AutoFillId autoFillId, Rect bounds, AutoFillValue value) {
-        synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
-            if (service == null) {
-                return;
-            }
-           service.startSessionLocked(activityToken, appCallback, autoFillId, bounds, value);
-        }
-    }
-
-    private void handleFinishSession(int userId, IBinder activityToken) {
-        synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
-            if (service == null) {
-                return;
-            }
-            service.finishSessionLocked(activityToken);
-        }
-    }
-
-    private void handleUpdateSession(int userId, IBinder activityToken, AutoFillId autoFillId,
-            Rect bounds, AutoFillValue value, int flags) {
-        synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
-            if (service == null) {
-                return;
-            }
-
-            service.updateSessionLocked(activityToken, autoFillId, bounds, value, flags);
-        }
-    }
-
-    private IBinder getTopActivityForUser() {
-        final List<IBinder> topActivities = LocalServices
-                .getService(ActivityManagerInternal.class).getTopVisibleActivities();
-        if (DEBUG) Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
-        if (topActivities.isEmpty()) {
-            Slog.w(TAG, "Could not get top activity");
-            return null;
-        }
-        return topActivities.get(0);
-    }
-
-    private void handleSaveForUser(int userId) {
         final IBinder activityToken = getTopActivityForUser();
         if (activityToken != null) {
             synchronized (mLock) {
@@ -309,7 +183,10 @@
         }
     }
 
-    private void handleListForUser(int userId, IResultReceiver receiver) {
+    // Called by Shell command.
+    void listSessions(int userId, IResultReceiver receiver) {
+        Slog.i(TAG, "listSessions() for userId " + userId);
+        mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
         final Bundle resultData = new Bundle();
         final ArrayList<String> sessions = new ArrayList<>();
 
@@ -332,7 +209,10 @@
         }
     }
 
-    private void handleReset() {
+    // Called by Shell command.
+    void reset() {
+        Slog.i(TAG, "reset()");
+        mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
         synchronized (mLock) {
             final int size = mServicesCache.size();
             for (int i = 0; i < size; i++) {
@@ -342,48 +222,98 @@
         }
     }
 
-    final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub {
+    /**
+     * Removes a cached service for a given user.
+     */
+    private void removeCachedServiceLocked(int userId) {
+        final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+        if (service != null) {
+            mServicesCache.delete(userId);
+            service.destroyLocked();
+        }
+    }
+
+    /**
+     * Updates a cached service for a given user.
+     */
+    private void updateCachedServiceLocked(int userId) {
+        AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+        if (service != null) {
+            service.updateLocked();
+        }
+    }
+
+    private IBinder getTopActivityForUser() {
+        final List<IBinder> topActivities = LocalServices
+                .getService(ActivityManagerInternal.class).getTopVisibleActivities();
+        if (DEBUG) Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
+        if (topActivities.isEmpty()) {
+            Slog.w(TAG, "Could not get top activity");
+            return null;
+        }
+        return topActivities.get(0);
+    }
+
+    final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
+        @Override
+        public boolean addClient(IAutoFillManagerClient client, int userId) {
+            synchronized (mLock) {
+                return getServiceForUserLocked(userId).addClientLocked(client);
+            }
+        }
+
+        @Override
+        public void setAuthenticationResult(Bundle data, IBinder activityToken, int userId) {
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                service.setAuthenticationResultLocked(data, activityToken);
+            }
+        }
 
         @Override
         public void startSession(IBinder activityToken, IBinder appCallback, AutoFillId autoFillId,
-                Rect bounds, AutoFillValue value) throws RemoteException {
+                Rect bounds, AutoFillValue value, int userId) {
             // TODO(b/33197203): make sure it's called by resumed / focused activity
 
-            final int userId = UserHandle.getCallingUserId();
             if (VERBOSE) {
                 Slog.v(TAG, "startSession: autoFillId=" + autoFillId + ", bounds=" + bounds
                         + ", value=" + value);
             }
 
-            final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = activityToken;
-            args.arg2 = appCallback;
-            args.arg3 = autoFillId;
-            args.arg4 = bounds;
-            args.arg5 = value;
-
-            mHandlerCaller.sendMessage(mHandlerCaller.getHandler().obtainMessage(MSG_START_SESSION,
-                    userId, 0, args));
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                service.startSessionLocked(activityToken, appCallback, autoFillId, bounds, value);
+            }
         }
 
         @Override
         public void updateSession(IBinder activityToken, AutoFillId id, Rect bounds,
-                AutoFillValue value, int flags) throws RemoteException {
+                AutoFillValue value, int flags, int userId) {
             if (DEBUG) {
                 Slog.d(TAG, "updateSession: flags=" + flags + ", autoFillId=" + id
                         + ", bounds=" + bounds + ", value=" + value);
             }
 
-            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOOII(MSG_UPDATE_SESSION,
-                    activityToken, id, bounds, value, UserHandle.getCallingUserId(), flags));
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service = mServicesCache.get(
+                        UserHandle.getCallingUserId());
+                if (service != null) {
+                    service.updateSessionLocked(activityToken, id, bounds, value, flags);
+                }
+            }
         }
 
         @Override
-        public void finishSession(IBinder activityToken) throws RemoteException {
+        public void finishSession(IBinder activityToken, int userId) {
             if (VERBOSE) Slog.v(TAG, "finishSession(): " + activityToken);
 
-            mHandlerCaller.sendMessage(mHandlerCaller.getHandler().obtainMessage(MSG_FINISH_SESSION,
-                    UserHandle.getCallingUserId(), 0, activityToken));
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service = mServicesCache.get(
+                        UserHandle.getCallingUserId());
+                if (service != null) {
+                    service.finishSessionLocked(activityToken);
+                }
+            }
         }
 
         @Override
@@ -433,7 +363,7 @@
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
             synchronized (mLock) {
-                removeCachedServiceLocked(userId);
+                updateCachedServiceLocked(userId);
             }
         }
     }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index 2891518..8d43dfb 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -31,43 +31,44 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.IActivityManager;
+import android.app.AppGlobals;
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.app.assist.AssistStructure.WindowNode;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.graphics.Rect;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.ICancellationSignal;
 import android.os.Looper;
+import android.os.Parcelable;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.service.autofill.AutoFillService;
 import android.service.autofill.AutoFillServiceInfo;
-import android.service.autofill.FillCallback;
-import android.service.autofill.IAutoFillAppCallback;
+import android.service.autofill.Dataset;
+import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
-import android.service.autofill.IFillCallback;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillManager;
 import android.view.autofill.AutoFillValue;
-import android.view.autofill.Dataset;
-import android.view.autofill.FillResponse;
 
+import android.view.autofill.IAutoFillManagerClient;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.IResultReceiver;
-import com.android.server.FgThread;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -86,26 +87,14 @@
     private static final int MSG_SERVICE_SAVE = 1;
 
     private final int mUserId;
-    private final ComponentName mComponent;
-    private final String mComponentName;
     private final Context mContext;
-    private final IActivityManager mAm;
     private final Object mLock;
-    private final AutoFillServiceInfo mInfo;
     private final AutoFillUI mUi;
 
-    private final LocalLog mRequestsHistory;
+    private RemoteCallbackList<IAutoFillManagerClient> mClients;
+    private AutoFillServiceInfo mInfo;
 
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
-                final String reason = intent.getStringExtra("reason");
-                if (DEBUG) Slog.d(TAG, "close system dialogs: " + reason);
-                mUi.hideAll();
-            }
-        }
-    };
+    private final LocalLog mRequestsHistory;
 
     private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
         switch (msg.what) {
@@ -119,6 +108,7 @@
 
     private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
             mHandlerCallback, true);
+
     /**
      * Cache of pending {@link Session}s, keyed by {@code activityToken}.
      *
@@ -139,7 +129,6 @@
             if (DEBUG) Slog.d(TAG, "resultCode on mAssistReceiver: " + resultCode);
 
             final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
-
             if (structure == null) {
                 Slog.w(TAG, "no assist structure for id " + resultCode);
                 return;
@@ -183,28 +172,61 @@
     };
 
     AutoFillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
-            int userId, ComponentName component, AutoFillUI ui)
-            throws PackageManager.NameNotFoundException {
+            int userId, AutoFillUI ui) {
         mContext = context;
         mLock = lock;
         mRequestsHistory = requestsHistory;
         mUserId = userId;
-        mComponent = component;
-        mComponentName = mComponent.flattenToShortString();
-        mAm = ActivityManager.getService();
         mUi = ui;
-        mInfo = new AutoFillServiceInfo(context.getPackageManager(), component, mUserId);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        mContext.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
+        updateLocked();
     }
 
+    void updateLocked() {
+        ComponentName serviceComponent = null;
+        ServiceInfo serviceInfo = null;
+        final String componentName = Settings.Secure.getStringForUser(
+                mContext.getContentResolver(), Settings.Secure.AUTO_FILL_SERVICE, mUserId);
+        if (!TextUtils.isEmpty(componentName)) {
+            try {
+                serviceComponent = ComponentName.unflattenFromString(componentName);
+                serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
+                        0, mUserId);
+            } catch (RuntimeException | RemoteException e) {
+                Slog.e(TAG, "Bad auto-fill service name " + componentName, e);
+                return;
+            }
+        }
+        try {
+            final boolean hadService = hasService();
+            if (serviceInfo != null) {
+                mInfo = new AutoFillServiceInfo(mContext.getPackageManager(),
+                        serviceComponent, mUserId);
+            } else {
+                mInfo = null;
+            }
+            if (hadService != hasService()) {
+                if (!hasService()) {
+                    final int sessionCount = mSessions.size();
+                    for (int i = sessionCount - 1; i >= 0; i--) {
+                        Session session = mSessions.valueAt(i);
+                        session.destroyLocked();
+                        mSessions.removeAt(i);
+                    }
+                }
+                sendStateToClients();
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "Bad auto-fill service name " + componentName, e);
+        }
+    }
 
     /**
      * Used by {@link AutoFillManagerServiceShellCommand} to request save for the current top app.
      */
     void requestSaveForUserLocked(IBinder activityToken) {
+        if (!hasService()) {
+            return;
+        }
         final Session session = mSessions.get(activityToken);
         if (session == null) {
             Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
@@ -214,9 +236,32 @@
         session.callSaveLocked();
     }
 
+    boolean addClientLocked(IAutoFillManagerClient client) {
+        if (mClients == null) {
+            mClients = new RemoteCallbackList<>();
+        }
+        mClients.register(client);
+        return hasService();
+    }
+
+    void setAuthenticationResultLocked(Bundle data, IBinder activityToken) {
+        if (!hasService()) {
+            return;
+        }
+        final Session session = mSessions.get(activityToken);
+        if (session != null) {
+            session.setAuthenticationResultLocked(data);
+        }
+    }
+
     void startSessionLocked(IBinder activityToken, IBinder appCallbackToken, AutoFillId autoFillId,
             Rect bounds, AutoFillValue value) {
-        final String historyItem = "s=" + mComponentName + " u=" + mUserId + " a=" + activityToken
+        if (!hasService()) {
+            return;
+        }
+
+        final String historyItem = "s=" + new ComponentName(mInfo.getServiceInfo().packageName,
+                mInfo.getServiceInfo().name) + " u=" + mUserId + " a=" + activityToken
                 + " i=" + autoFillId + " b=" + bounds + " v=" + value;
         mRequestsHistory.log(historyItem);
 
@@ -229,24 +274,23 @@
 
         final Session newSession = createSessionByTokenLocked(activityToken, appCallbackToken);
         newSession.updateLocked(autoFillId, bounds, value, FLAG_START_SESSION);
-        newSession.enableSessionLocked();
     }
 
     void finishSessionLocked(IBinder activityToken) {
-        if (DEBUG) Slog.d(TAG, "finishSessionLocked(): " + activityToken);
-        final Session session = mSessions.get(activityToken);
+        if (!hasService()) {
+            return;
+        }
 
+        final Session session = mSessions.get(activityToken);
         if (session == null) {
             Slog.w(TAG, "finishSessionLocked(): no session for " + activityToken);
             return;
         }
 
-        mUi.hideFillUi();
         session.showSaveLocked();
     }
 
     private Session createSessionByTokenLocked(IBinder activityToken, IBinder appCallbackToken) {
-
         final Session newSession = new Session(mContext, activityToken, appCallbackToken);
         mSessions.put(activityToken, newSession);
 
@@ -261,10 +305,16 @@
             // TODO(b/33197203): add MetricsLogger call
             final Bundle receiverExtras = new Bundle();
             receiverExtras.putBinder(EXTRA_ACTIVITY_TOKEN, activityToken);
-            if (!mAm.requestAutoFillData(mAssistReceiver, receiverExtras, activityToken)) {
-                // TODO(b/33197203): might need a way to warn user (perhaps a new method on
-                // AutoFillService).
-                Slog.w(TAG, "failed to request auto-fill data for " + activityToken);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                if (!ActivityManager.getService().requestAutoFillData(mAssistReceiver,
+                        receiverExtras, activityToken)) {
+                    // TODO(b/33197203): might need a way to warn user (perhaps a new method on
+                    // AutoFillService).
+                    Slog.w(TAG, "failed to request auto-fill data for " + activityToken);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
             }
         } catch (RemoteException e) {
             // Should not happen, it's a local call.
@@ -274,7 +324,6 @@
 
     void updateSessionLocked(IBinder activityToken, AutoFillId autoFillId, Rect bounds,
             AutoFillValue value, int flags) {
-
         // TODO(b/33197203): add MetricsLogger call
         final Session session = mSessions.get(activityToken);
         if (session == null) {
@@ -286,7 +335,6 @@
     }
 
     private void handleSessionSave(IBinder activityToken) {
-
         synchronized (mLock) {
             final Session session = mSessions.get(activityToken);
             if (session == null) {
@@ -301,7 +349,6 @@
     void destroyLocked() {
         if (VERBOSE) Slog.v(TAG, "destroyLocked()");
 
-        mContext.unregisterReceiver(mBroadcastReceiver);
         for (Session session : mSessions.values()) {
             session.destroyLocked();
         }
@@ -311,7 +358,8 @@
     void dumpLocked(String prefix, PrintWriter pw) {
         final String prefix2 = prefix + "  ";
 
-        pw.print(prefix); pw.println("Component:"); pw.println(mComponentName);
+        pw.print(prefix); pw.println("Component:"); pw.println(mInfo != null
+                ? mInfo.getServiceInfo().getComponentName() : null);
 
         if (VERBOSE) {
             // ServiceInfo dump is too noisy and redundant (it can be obtained through other dumps)
@@ -333,14 +381,44 @@
 
     void listSessionsLocked(ArrayList<String> output) {
         for (IBinder activityToken : mSessions.keySet()) {
-            output.add(mComponentName + ":" + activityToken);
+            output.add((mInfo != null ? mInfo.getServiceInfo().getComponentName()
+                    : null) + ":" + activityToken);
         }
     }
 
+    private void sendStateToClients() {
+        final RemoteCallbackList<IAutoFillManagerClient> clients;
+        final int userClientCount;
+        synchronized (mLock) {
+            if (mClients == null) {
+                return;
+            }
+            clients = mClients;
+            userClientCount = clients.beginBroadcast();
+        }
+        try {
+            for (int i = 0; i < userClientCount; i++) {
+                IAutoFillManagerClient client = clients.getBroadcastItem(i);
+                try {
+                    client.setState(hasService());
+                } catch (RemoteException re) {
+                    /* ignore */
+                }
+            }
+        } finally {
+            clients.finishBroadcast();
+        }
+    }
+
+    private boolean hasService() {
+        return mInfo != null;
+    }
+
     @Override
     public String toString() {
         return "AutoFillManagerServiceImpl: [userId=" + mUserId
-                + ", component=" + mComponentName + "]";
+                + ", component=" + (mInfo != null
+                ? mInfo.getServiceInfo().getComponentName() : null) + "]";
     }
 
     /**
@@ -418,7 +496,6 @@
             pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated);
             pw.print(prefix); pw.print("bounds:" ); pw.println(mBounds);
         }
-
     }
 
     /**
@@ -448,7 +525,7 @@
         @Nullable
         private ViewState mCurrentViewState;
 
-        private final IAutoFillAppCallback mAppCallback;
+        private final IAutoFillManagerClient mClient;
 
         @GuardedBy("mLock")
         RemoteFillService mRemoteFillService;
@@ -471,19 +548,20 @@
         @GuardedBy("mLock")
         private AssistStructure mStructure;
 
-        private Session(Context context, IBinder activityToken, IBinder appCallback) {
-            mRemoteFillService = new RemoteFillService(context, mComponent, mUserId, this);
+        private Session(Context context, IBinder activityToken, IBinder client) {
+            mRemoteFillService = new RemoteFillService(context,
+                    mInfo.getServiceInfo().getComponentName(), mUserId, this);
             mActivityToken = activityToken;
 
-            mAppCallback = IAutoFillAppCallback.Stub.asInterface(appCallback);
+            mClient = IAutoFillManagerClient.Stub.asInterface(client);
             try {
-                appCallback.linkToDeath(() -> {
+                client.linkToDeath(() -> {
                     if (DEBUG) Slog.d(TAG, "app binder died");
 
                     removeSelf();
                 }, 0);
             } catch (RemoteException e) {
-                Slog.w(TAG, "linkToDeath() on mAppCallback failed: " + e);
+                Slog.w(TAG, "linkToDeath() on mClient failed: " + e);
             }
         }
 
@@ -528,7 +606,7 @@
         // FillServiceCallbacks
         @Override
         public void authenticate(IntentSender intent, Intent fillInIntent) {
-            startAuthIntent(intent, fillInIntent);
+            startAuthentication(intent, fillInIntent);
         }
 
         // FillServiceCallbacks
@@ -550,6 +628,30 @@
                     .sendToTarget();
         }
 
+        public void setAuthenticationResultLocked(Bundle data) {
+            if (mCurrentResponse == null || data == null) {
+                removeSelf();
+            } else {
+                Parcelable result = data.getParcelable(
+                        AutoFillManager.EXTRA_AUTHENTICATION_RESULT);
+                if (result instanceof FillResponse) {
+                    mCurrentResponse = (FillResponse) result;
+                    processResponseLocked(mCurrentResponse);
+                } else if (result instanceof Dataset) {
+                    Dataset dataset = (Dataset) result;
+                    final int datasetIndex = Helper.indexOfDataset(
+                            dataset.getName(), mCurrentResponse);
+                    if (datasetIndex <= 0) {
+                        Slog.e(TAG, "Response for a dataset auth has"
+                                + " an invalid dataset result: " + dataset.getName());
+                    }
+                    mCurrentResponse.getDatasets().removeAt(datasetIndex);
+                    mCurrentResponse.getDatasets().add(dataset);
+                    autoFill(dataset);
+                }
+            }
+        }
+
         /**
          * Show the save UI, when session can be saved.
          */
@@ -665,7 +767,7 @@
                 mViewStates.put(id, viewState);
             }
 
-            if ((flags & FLAG_START_SESSION) != 0 ) {
+            if ((flags & FLAG_START_SESSION) != 0) {
                 // View is triggering auto-fill.
                 mCurrentViewState = viewState;
                 viewState.update(value, bounds);
@@ -738,7 +840,7 @@
 
         private void processResponseLocked(FillResponse response) {
             if (DEBUG) Slog.d(TAG, "processResponseLocked(authRequired="
-                    + response.getAuthentication() +"):" + response);
+                    + response.getAuthentication() + "):" + response);
 
             // TODO(b/33197203): add MetricsLogger calls
 
@@ -746,30 +848,10 @@
 
             if (mCurrentResponse.getAuthentication() != null) {
                 // Handle authentication.
-                final Intent fillInIntent = createAuthFillInIntent(response.getId(), mStructure,
-                        new Bundle(), new FillCallback(new IFillCallback.Stub() {
-                            @Override
-                            public void onCancellable(ICancellationSignal cancellation) {
-                                // TODO(b/33197203): Handle cancellation
-                            }
-
-                            @Override
-                            public void onSuccess(FillResponse response) {
-                                mCurrentResponse = createAuthenticatedResponse(
-                                        mCurrentResponse, response);
-                                processResponseLocked(mCurrentResponse);
-                            }
-
-                            @Override
-                            public void onFailure(CharSequence message) {
-                                getUiForShowing().showError(message);
-                                removeSelf();
-                            }
-                        }));
-
-                 getUiForShowing().showFillResponseAuthRequest(
-                         mCurrentResponse.getAuthentication(), fillInIntent);
-                 return;
+                final Intent fillInIntent = createAuthFillInIntent(mStructure);
+                getUiForShowing().showFillResponseAuthRequest(
+                        mCurrentResponse.getAuthentication(), fillInIntent);
+                return;
             }
 
             final ArraySet<AutoFillId> savableIds = mCurrentResponse.getSavableIds();
@@ -797,48 +879,20 @@
                 }
 
                 // ...or handle authentication.
-                Intent fillInIntent = createAuthFillInIntent(dataset.getId(), mStructure,
-                        new Bundle(), new FillCallback(new IFillCallback.Stub() {
-                    @Override
-                    public void onCancellable(ICancellationSignal cancellation) {
-                        // TODO(b/33197203): Handle cancellation
-                    }
-
-                    @Override
-                    public void onSuccess(FillResponse response) {
-                        mCurrentResponse = createAuthenticatedResponse(
-                                mCurrentResponse, response);
-                        final Dataset augmentedDataset = Helper.findDatasetById(dataset.getId(),
-                                mCurrentResponse);
-                        if (augmentedDataset != null) {
-                            autoFill(augmentedDataset);
-                        }
-                    }
-
-                    @Override
-                    public void onFailure(CharSequence message) {
-                        getUiForShowing().showError(message);
-                        removeSelf();
-                    }
-                }));
-
-                startAuthIntent(dataset.getAuthentication(), fillInIntent);
+                Intent fillInIntent = createAuthFillInIntent(mStructure);
+                startAuthentication(dataset.getAuthentication(), fillInIntent);
             }
         }
 
-        private Intent createAuthFillInIntent(String itemId, AssistStructure structure,
-                Bundle extras, FillCallback fillCallback) {
+        private Intent createAuthFillInIntent(AssistStructure structure) {
             Intent fillInIntent = new Intent();
-            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_ITEM_ID, itemId);
-            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_ASSIST_STRUCTURE, structure);
-            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_EXTRAS, extras);
-            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_CALLBACK, fillCallback);
+            fillInIntent.putExtra(AutoFillManager.EXTRA_ASSIST_STRUCTURE, structure);
             return fillInIntent;
         }
 
-        private void startAuthIntent(IntentSender intent, Intent fillInIntent) {
+        private void startAuthentication(IntentSender intent, Intent fillInIntent) {
             try {
-                mAppCallback.startIntentSender(intent, fillInIntent);
+                mClient.authenticate(intent, fillInIntent);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error launching auth intent", e);
             }
@@ -874,7 +928,7 @@
                 try {
                     if (DEBUG) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
 
-                    mAppCallback.autoFill(dataset);
+                    mClient.autoFill(dataset.getFieldIds(), dataset.getFieldValues());
                     mAutoFilledDataset = dataset;
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Error auto-filling activity: " + e);
@@ -882,16 +936,6 @@
             }
         }
 
-        void enableSessionLocked() {
-            if (DEBUG) Slog.d(TAG, "enableSessionLocked()");
-
-            try {
-                mAppCallback.enableSession();
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Error enabling session: " + e);
-            }
-        }
-
         private AutoFillUI getUiForShowing() {
             synchronized (mLock) {
                 mUi.setCallbackLocked(this, mActivityToken);
@@ -946,81 +990,5 @@
                 mSessions.remove(mActivityToken);
             }
         }
-
-        /**
-         * Creates a response from the {@code original} and an {@code update} by
-         * replacing all items that needed authentication (response or datasets)
-         * with their updated version if the latter does not need authentication.
-         * New datasets that don't require auth are appended.
-         *
-         * @param original The original response requiring auth at some level.
-         * @param update An updated response with auth not needed anymore at some level.
-         * @return A new response with updated items where auth is not needed anymore.
-         */
-        // TODO(b/33197203) Unit test
-        FillResponse createAuthenticatedResponse(FillResponse original, FillResponse update) {
-            // Can update only if ids match
-            if (!original.getId().equals(update.getId())) {
-                return original;
-            }
-
-            // If the original required auth and the update doesn't, the update wins
-            // but only if none of the update's datasets requires authentication.
-            if (original.getAuthentication() != null && update.getAuthentication() == null) {
-                ArraySet<Dataset> updateDatasets = update.getDatasets();
-                final int udpateDatasetCount = updateDatasets.size();
-                for (int i = 0; i < udpateDatasetCount; i++) {
-                    Dataset updateDataset = updateDatasets.valueAt(i);
-                    if (updateDataset.getAuthentication() != null) {
-                        return original;
-                    }
-                }
-                return update;
-            }
-
-            // If no auth on response level we create a response that has all
-            // datasets from the original with the ones that required auth but
-            // not anymore updated and new ones not requiring auth appended.
-
-            // The update shouldn't require auth
-            if (update.getAuthentication() != null) {
-                return original;
-            }
-
-            final FillResponse.Builder builder = new FillResponse.Builder(original.getId());
-
-            // Update existing datasets
-            final ArraySet<Dataset> origDatasets = original.getDatasets();
-            final int origDatasetCount = origDatasets.size();
-            for (int i = 0; i < origDatasetCount; i++) {
-                Dataset origDataset = origDatasets.valueAt(i);
-                ArraySet<Dataset> updateDatasets = update.getDatasets();
-                final int updateDatasetCount = updateDatasets.size();
-                for (int j = 0; j < updateDatasetCount; j++) {
-                    Dataset updateDataset = updateDatasets.valueAt(j);
-                    if (origDataset.getId().equals(updateDataset.getId())) {
-                        // The update shouldn't require auth
-                        if (updateDataset.getAuthentication() == null) {
-                            origDataset = updateDataset;
-                            updateDatasets.removeAt(j);
-                        }
-                        break;
-                    }
-                }
-                builder.addDataset(origDataset);
-            }
-
-            // Add new datasets
-            final ArraySet<Dataset> updateDatasets = update.getDatasets();
-            final int updateDatasetCount = updateDatasets.size();
-            for (int i = 0; i < updateDatasetCount; i++) {
-                final Dataset updateDataset = updateDatasets.valueAt(i);
-                builder.addDataset(updateDataset);
-            }
-
-            // For now no extras and savable id updates.
-
-            return builder.build();
-        }
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
index 0763c74..9770040 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
@@ -30,15 +30,13 @@
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
+import android.service.autofill.Dataset;
 import android.util.ArraySet;
 import android.os.Looper;
 import android.text.format.DateUtils;
 import android.util.Slog;
-import android.view.autofill.Dataset;
-import android.view.autofill.FillResponse;
 import android.view.Gravity;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 import android.widget.Toast;
@@ -200,7 +198,8 @@
     }
 
     /**
-     * Shows an UI affordance indicating that user action is required before a {@link FillResponse}
+     * Shows an UI affordance indicating that user action is required before a {@link
+     * android.service.autofill.FillResponse}
      * can be used.
      *
      * <p>It typically replaces the auto-fill bar with a message saying "Press fingerprint or tap to
diff --git a/services/autofill/java/com/android/server/autofill/DatasetPicker.java b/services/autofill/java/com/android/server/autofill/DatasetPicker.java
index 9bee61a..a54cab9 100644
--- a/services/autofill/java/com/android/server/autofill/DatasetPicker.java
+++ b/services/autofill/java/com/android/server/autofill/DatasetPicker.java
@@ -17,9 +17,9 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.service.autofill.Dataset;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.view.autofill.Dataset;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 0f2bb60..48ae635 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -18,11 +18,11 @@
 
 import android.annotation.Nullable;
 import android.os.Bundle;
+import android.service.autofill.Dataset;
+import android.service.autofill.FillResponse;
 import android.util.ArraySet;
 import android.view.autofill.AutoFillId;
 import android.view.autofill.AutoFillValue;
-import android.view.autofill.Dataset;
-import android.view.autofill.FillResponse;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -78,25 +78,25 @@
     }
 
     /**
-     * Finds a data set by id in a response.
+     * Finds the index of a data set given its name.
      *
-     * @param id The dataset id.
+     * @param name The dataset name.
      * @param response The response to search.
-     * @return The dataset if found or null.
+     * @return The index of dataset if found or -1.
      */
-    static Dataset findDatasetById(String id, FillResponse response) {
+    static int indexOfDataset(CharSequence name, FillResponse response) {
         ArraySet<Dataset> datasets = response.getDatasets();
         if (datasets == null || datasets.isEmpty()) {
-            return null;
+            return -1;
         }
         final int datasetCount = datasets.size();
         for (int i = 0; i < datasetCount; i++) {
             Dataset dataset = datasets.valueAt(i);
-            if (dataset.getId().equals(id)) {
-                return dataset;
+            if (dataset.getName().toString().equals(name.toString())) {
+                return i;
             }
         }
-        return null;
+        return -1;
     }
 
     private Helper() {
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index c070f77..767fb46 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -31,12 +31,12 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.autofill.AutoFillService;
+import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
 import android.service.autofill.IFillCallback;
 import android.service.autofill.ISaveCallback;
 import android.text.format.DateUtils;
 import android.util.Slog;
-import android.view.autofill.FillResponse;
 import com.android.internal.os.HandlerCaller;
 import com.android.server.FgThread;