Merge "Changes on the ContentCaptureContext APIs."
diff --git a/api/current.txt b/api/current.txt
index d8c7342..833b87b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10284,6 +10284,7 @@
     field public static final String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT";
     field public static final String ACTION_USER_UNLOCKED = "android.intent.action.USER_UNLOCKED";
     field public static final String ACTION_VIEW = "android.intent.action.VIEW";
+    field public static final String ACTION_VIEW_LOCUS = "android.intent.action.VIEW_LOCUS";
     field public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
     field @Deprecated public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
     field public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
@@ -10368,6 +10369,7 @@
     field public static final String EXTRA_INTENT = "android.intent.extra.INTENT";
     field public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
     field public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
+    field public static final String EXTRA_LOCUS_ID = "android.intent.extra.LOCUS_ID";
     field public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
     field public static final String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
     field public static final String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
@@ -10620,6 +10622,14 @@
     method @Deprecated public void onLoadComplete(android.content.Loader<D>, D);
   }
 
+  public final class LocusId implements android.os.Parcelable {
+    ctor public LocusId(@NonNull android.net.Uri);
+    method public int describeContents();
+    method @NonNull public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.content.LocusId> CREATOR;
+  }
+
   public class MutableContextWrapper extends android.content.ContextWrapper {
     ctor public MutableContextWrapper(android.content.Context);
     method public void setBaseContext(android.content.Context);
@@ -53471,16 +53481,17 @@
 
   public final class ContentCaptureContext implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.contentcapture.ContentCaptureContext forLocusId(@NonNull android.net.Uri);
+    method @Nullable public android.os.Bundle getExtras();
+    method @NonNull public android.content.LocusId getLocusId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureContext> CREATOR;
   }
 
   public static final class ContentCaptureContext.Builder {
-    ctor public ContentCaptureContext.Builder();
+    ctor public ContentCaptureContext.Builder(@NonNull android.content.LocusId);
     method public android.view.contentcapture.ContentCaptureContext build();
-    method @NonNull public android.view.contentcapture.ContentCaptureContext.Builder setAction(@NonNull String);
     method @NonNull public android.view.contentcapture.ContentCaptureContext.Builder setExtras(@NonNull android.os.Bundle);
-    method @NonNull public android.view.contentcapture.ContentCaptureContext.Builder setUri(@NonNull android.net.Uri);
   }
 
   public final class ContentCaptureManager {
@@ -53513,8 +53524,8 @@
 
   public final class UserDataRemovalRequest implements android.os.Parcelable {
     method public int describeContents();
+    method @NonNull public java.util.List<android.view.contentcapture.UserDataRemovalRequest.LocusIdRequest> getLocusIdRequests();
     method @NonNull public String getPackageName();
-    method @NonNull public java.util.List<android.view.contentcapture.UserDataRemovalRequest.UriRequest> getUriRequests();
     method public boolean isForEverything();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.contentcapture.UserDataRemovalRequest> CREATOR;
@@ -53522,13 +53533,13 @@
 
   public static final class UserDataRemovalRequest.Builder {
     ctor public UserDataRemovalRequest.Builder();
-    method public android.view.contentcapture.UserDataRemovalRequest.Builder addUri(@NonNull android.net.Uri, boolean);
+    method public android.view.contentcapture.UserDataRemovalRequest.Builder addLocusId(@NonNull android.content.LocusId, boolean);
     method @NonNull public android.view.contentcapture.UserDataRemovalRequest build();
     method @NonNull public android.view.contentcapture.UserDataRemovalRequest.Builder forEverything();
   }
 
-  public final class UserDataRemovalRequest.UriRequest {
-    method @NonNull public android.net.Uri getUri();
+  public final class UserDataRemovalRequest.LocusIdRequest {
+    method @NonNull public android.content.LocusId getLocusId();
     method @NonNull public boolean isRecursive();
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index 0239660..5c89b05 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9379,14 +9379,11 @@
 package android.view.contentcapture {
 
   public final class ContentCaptureContext implements android.os.Parcelable {
-    method @Nullable public String getAction();
     method @Nullable public android.content.ComponentName getActivityComponent();
     method public int getDisplayId();
-    method @Nullable public android.os.Bundle getExtras();
     method public int getFlags();
     method @Nullable public android.view.contentcapture.ContentCaptureSessionId getParentSessionId();
     method public int getTaskId();
-    method @Nullable public android.net.Uri getUri();
     field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
     field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 1ed8562..963584c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2728,14 +2728,11 @@
 package android.view.contentcapture {
 
   public final class ContentCaptureContext implements android.os.Parcelable {
-    method @Nullable public String getAction();
     method @Nullable public android.content.ComponentName getActivityComponent();
     method public int getDisplayId();
-    method @Nullable public android.os.Bundle getExtras();
     method public int getFlags();
     method @Nullable public android.view.contentcapture.ContentCaptureSessionId getParentSessionId();
     method public int getTaskId();
-    method @Nullable public android.net.Uri getUri();
     field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
     field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
   }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 17dc480..b67349f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4344,6 +4344,18 @@
             "android.intent.action.DEVICE_CUSTOMIZATION_READY";
 
 
+    /**
+     * Activity Action: Display an activity state associated with an unique {@link LocusId}.
+     *
+     * <p>For example, a chat app could use the context to resume a conversation between 2 users.
+     *
+     * <p>Input: {@link #EXTRA_LOCUS_ID} specifies the unique identifier of the locus in the
+     * app domain. Should be stable across reboots and backup / restore.
+     * <p>Output: nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_VIEW_LOCUS = "android.intent.action.VIEW_LOCUS";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent categories (see addCategory()).
@@ -5542,6 +5554,15 @@
      */
     public static final int EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC = 1;
 
+    /**
+     * Intent extra: ID of the context used on {@link #ACTION_VIEW_LOCUS}.
+     *
+     * <p>
+     * Type: {@link LocusId}
+     * </p>
+     */
+    public static final String EXTRA_LOCUS_ID = "android.intent.extra.LOCUS_ID";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
diff --git a/core/java/android/content/LocusId.java b/core/java/android/content/LocusId.java
new file mode 100644
index 0000000..9548f9c
--- /dev/null
+++ b/core/java/android/content/LocusId.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 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.content;
+
+import android.annotation.NonNull;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+
+/**
+ * Identifier for an unique state in the application.
+ *
+ * <p>Should be stable across reboots and backup / restore.
+ *
+ * <p>For example, a chat app could use the context to resume a conversation between 2 users.
+ */
+// TODO(b/123577059): make sure this is well documented and understandable
+public final class LocusId implements Parcelable {
+
+    private final Uri mUri;
+
+    /**
+     * Default constructor.
+     */
+    public LocusId(@NonNull Uri uri) {
+        mUri = Preconditions.checkNotNull(uri);
+    }
+
+    /**
+     * Gets the {@code uri} associated with the locus.
+     */
+    @NonNull
+    public Uri getUri() {
+        return mUri;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mUri == null) ? 0 : mUri.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        final LocusId other = (LocusId) obj;
+        if (mUri == null) {
+            if (other.mUri != null) return false;
+        } else {
+            if (!mUri.equals(other.mUri)) return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "LocusId[uri=" + getSanitizedUri() + "]";
+    }
+
+    /** @hide */
+    public void dump(@NonNull PrintWriter pw) {
+        pw.print("uri:"); pw.println(getSanitizedUri());
+    }
+
+    private String getSanitizedUri() {
+        final int size = mUri.toString().length();
+        return size + "_chars";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mUri, flags);
+    }
+
+    public static final Parcelable.Creator<LocusId> CREATOR =
+            new Parcelable.Creator<LocusId>() {
+
+        @Override
+        public LocusId createFromParcel(Parcel source) {
+            final Uri uri = source.readParcelable(null);
+            return new LocusId(uri);
+        }
+
+        @Override
+        public LocusId[] newArray(int size) {
+            return new LocusId[size];
+        }
+    };
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2b440dc..a78f2b0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9463,17 +9463,24 @@
      * the Content Capture events associated with this view or its view hierarchy (if it's a
      * {@link ViewGroup}).
      *
+     * <p>For example, if your activity is associated with a web domain, first you would need to
+     * set the context for the main DOM:
+     *
+     * <pre>
+     *   ContentCaptureSession mainSession = rootView.getContentCaptureSession();
+     *   mainSession.setContentCaptureContext(ContentCaptureContext.forLocusId(Uri.parse(myUrl));
+     * <pre>
+     *
+     * <p>Then if the page had an {@code IFRAME}, you would create a new session for it:
+     *
      * <p>For example, if your activity is associated with a web domain, you could create a session
      * {@code onCreate()} and associate it with the root view of the activity:
      *
      * <pre>
-     *   ContentCaptureSession oldSession = rootView.getContentCaptureSession();
-     *   if (oldSession != null) {
-     *     ContentCaptureSession newSession = oldSession.createContentCaptureSession(new
-     *        ContentCaptureContext.Builder().setUri(myUrl).build());
-     *     rootView.setContentCaptureSession(newSession);
-     *  }
-     * </pre>
+     *   ContentCaptureSession iframeSession = mainSession.createContentCaptureSession(
+     *       ContentCaptureContext.forLocusId(Uri.parse(iframeUrl)));
+     *   iframeView.setContentCaptureSession(iframeSession);
+     * <pre>
      *
      * @param contentCaptureSession a session created by
      * {@link ContentCaptureSession#createContentCaptureSession(
diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java
index 6a9759d..8bb4d21 100644
--- a/core/java/android/view/contentcapture/ContentCaptureContext.java
+++ b/core/java/android/view/contentcapture/ContentCaptureContext.java
@@ -23,7 +23,7 @@
 import android.app.TaskInfo;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
+import android.content.LocusId;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -88,8 +88,7 @@
 
     // Fields below are set by app on Builder
     private final @Nullable Bundle mExtras;
-    private final @Nullable Uri mUri;
-    private final @Nullable String mAction;
+    private final @Nullable LocusId mId;
 
     // Fields below are set by server when the session starts
     private final @Nullable ComponentName mComponentName;
@@ -106,13 +105,11 @@
         if (clientContext != null) {
             mHasClientContext = true;
             mExtras = clientContext.mExtras;
-            mUri = clientContext.mUri;
-            mAction = clientContext.mAction;
+            mId = clientContext.mId;
         } else {
             mHasClientContext = false;
             mExtras = null;
-            mUri = null;
-            mAction = null;
+            mId = null;
         }
         mComponentName = Preconditions.checkNotNull(componentName);
         mTaskId = taskId;
@@ -123,8 +120,7 @@
     private ContentCaptureContext(@NonNull Builder builder) {
         mHasClientContext = true;
         mExtras = builder.mExtras;
-        mUri = builder.mUri;
-        mAction = builder.mAction;
+        mId = builder.mId;
 
         mComponentName  = null;
         mTaskId = mFlags = 0;
@@ -135,38 +131,18 @@
      * Gets the (optional) extras set by the app (through {@link Builder#setExtras(Bundle)}).
      *
      * <p>It can be used to provide vendor-specific data that can be modified and examined.
-     *
-     * @hide
      */
-    @SystemApi
-    @TestApi
     @Nullable
     public Bundle getExtras() {
         return mExtras;
     }
 
     /**
-     * Gets the (optional) URI set by the app (through {@link Builder#setUri(Uri)}).
-     *
-     * @hide
+     * Gets the context id.
      */
-    @SystemApi
-    @TestApi
-    @Nullable
-    public Uri getUri() {
-        return mUri;
-    }
-
-    /**
-     * Gets the (optional) action set by the app (through {@link Builder#setAction(String)}).
-     *
-     * @hide
-     */
-    @SystemApi
-    @TestApi
-    @Nullable
-    public String getAction() {
-        return mAction;
+    @NonNull
+    public LocusId getLocusId() {
+        return mId;
     }
 
     /**
@@ -236,13 +212,38 @@
     }
 
     /**
+     * Helper that creates a {@link ContentCaptureContext} associated with the given {@code uri}.
+     */
+    public static ContentCaptureContext forLocusId(@NonNull Uri uri) {
+        return new Builder(new LocusId(uri)).build();
+    }
+
+    /**
      * Builder for {@link ContentCaptureContext} objects.
      */
     public static final class Builder {
         private Bundle mExtras;
-        private Uri mUri;
+        private final LocusId mId;
         private boolean mDestroyed;
-        private String mAction;
+
+        /**
+         * Creates a new builder.
+         *
+         * <p>The context must have an id, which is usually one of the following:
+         *
+         * <ul>
+         *   <li>A URL representing a web page (or {@code IFRAME}) that's being rendered by the
+         *   activity (See {@link View#setContentCaptureSession(ContentCaptureSession)} for an
+         *   example).
+         *   <li>A unique identifier of the application state (for example, a conversation between
+         *   2 users in a chat app).
+         *
+         * @param id id associated with this context.
+         */
+        // TODO(b/123577059): make sure this is well documented and understandable
+        public Builder(@NonNull LocusId id) {
+            mId = Preconditions.checkNotNull(id);
+        }
 
         /**
          * Sets extra options associated with this context.
@@ -262,50 +263,14 @@
         }
 
         /**
-         * Sets the {@link Uri} associated with this context.
-         *
-         * <p>See {@link View#setContentCaptureSession(ContentCaptureSession)} for an example.
-         *
-         * @param uri URI associated with this context.
-         * @return this builder.
-         *
-         * @throws IllegalStateException if {@link #build()} was already called.
-         */
-        @NonNull
-        public Builder setUri(@NonNull Uri uri) {
-            mUri = Preconditions.checkNotNull(uri);
-            throwIfDestroyed();
-            return this;
-        }
-
-        /**
-         * Sets an {@link Intent#getAction() intent action} associated with this context.
-         *
-         * @param action intent action
-         *
-         * @return this builder
-         *
-         * @throws IllegalStateException if {@link #build()} was already called.
-         */
-        @NonNull
-        public Builder setAction(@NonNull String action) {
-            mAction = Preconditions.checkNotNull(action);
-            throwIfDestroyed();
-            return this;
-        }
-
-        /**
          * Builds the {@link ContentCaptureContext}.
          *
-         * @throws IllegalStateException if {@link #build()} was already called or no call to either
-         * {@link #setExtras(Bundle)}, {@link #setAction(String)}, or {@link #setUri(Uri)} was made.
+         * @throws IllegalStateException if {@link #build()} was already called.
          *
          * @return the built {@code ContentCaptureContext}
          */
         public ContentCaptureContext build() {
             throwIfDestroyed();
-            Preconditions.checkState(mExtras != null || mUri != null || mAction != null,
-                    "Must call setUri() or setExtras() or setUri() before calling build()");
             mDestroyed = true;
             return new ContentCaptureContext(this);
         }
@@ -320,7 +285,12 @@
      */
     // TODO(b/111276913): dump to proto as well
     public void dump(PrintWriter pw) {
-        pw.print("comp="); pw.print(ComponentName.flattenToShortString(mComponentName));
+        if (mComponentName != null) {
+            pw.print("activity="); pw.print(mComponentName.flattenToShortString());
+        }
+        if (mId != null) {
+            pw.print(", id="); mId.dump(pw);
+        }
         pw.print(", taskId="); pw.print(mTaskId);
         pw.print(", displayId="); pw.print(mDisplayId);
         if (mParentSessionId != null) {
@@ -333,38 +303,31 @@
             // NOTE: cannot dump because it could contain PII
             pw.print(", hasExtras");
         }
-        if (mUri != null) {
-            // NOTE: cannot dump because it could contain PII
-            pw.print(", hasUri");
-        }
-        if (mAction != null) {
-            // NOTE: cannot dump because it could contain PII
-            pw.print(", hasAction");
-        }
+    }
+
+    private boolean fromServer() {
+        return mComponentName != null;
     }
 
     @Override
     public String toString() {
-        final StringBuilder builder = new StringBuilder("Context[act=")
-                .append(ComponentName.flattenToShortString(mComponentName))
+        final StringBuilder builder = new StringBuilder("Context[");
+
+        if (fromServer()) {
+            builder.append("act=").append(ComponentName.flattenToShortString(mComponentName))
                 .append(", taskId=").append(mTaskId)
                 .append(", displayId=").append(mDisplayId)
                 .append(", flags=").append(mFlags);
+        } else {
+            builder.append("id=").append(mId);
+            if (mExtras != null) {
+                // NOTE: cannot print because it could contain PII
+                builder.append(", hasExtras");
+            }
+        }
         if (mParentSessionId != null) {
             builder.append(", parentId=").append(mParentSessionId);
         }
-        if (mExtras != null) {
-            // NOTE: cannot print because it could contain PII
-            builder.append(", hasExtras");
-        }
-        if (mUri != null) {
-            // NOTE: cannot print because it could contain PII
-            builder.append(", hasUri");
-        }
-        if (mAction != null) {
-            // NOTE: cannot print because it could contain PII
-            builder.append(", hasAction");
-        }
         return builder.append(']').toString();
     }
 
@@ -377,12 +340,11 @@
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mHasClientContext ? 1 : 0);
         if (mHasClientContext) {
-            parcel.writeParcelable(mUri, flags);
-            parcel.writeString(mAction);
+            parcel.writeParcelable(mId, flags);
             parcel.writeBundle(mExtras);
         }
         parcel.writeParcelable(mComponentName, flags);
-        if (mComponentName != null) {
+        if (fromServer()) {
             parcel.writeInt(mTaskId);
             parcel.writeInt(mDisplayId);
             parcel.writeInt(mFlags);
@@ -399,12 +361,9 @@
             final ContentCaptureContext clientContext;
             if (hasClientContext) {
                 // Must reconstruct the client context using the Builder API
-                final Builder builder = new Builder();
-                final Uri uri = parcel.readParcelable(null);
-                final String action = parcel.readString();
+                final LocusId id = parcel.readParcelable(null);
                 final Bundle extras = parcel.readBundle();
-                if (uri != null) builder.setUri(uri);
-                if (action != null) builder.setAction(action);
+                final Builder builder = new Builder(id);
                 if (extras != null) builder.setExtras(extras);
                 clientContext = new ContentCaptureContext(builder);
             } else {
diff --git a/core/java/android/view/contentcapture/UserDataRemovalRequest.java b/core/java/android/view/contentcapture/UserDataRemovalRequest.java
index 8fedcd5..7d66af9 100644
--- a/core/java/android/view/contentcapture/UserDataRemovalRequest.java
+++ b/core/java/android/view/contentcapture/UserDataRemovalRequest.java
@@ -17,7 +17,7 @@
 
 import android.annotation.NonNull;
 import android.app.ActivityThread;
-import android.net.Uri;
+import android.content.LocusId;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.IntArray;
@@ -36,16 +36,16 @@
     private final String mPackageName;
 
     private final boolean mForEverything;
-    private ArrayList<UriRequest> mUriRequests;
+    private ArrayList<LocusIdRequest> mLocusIdRequests;
 
     private UserDataRemovalRequest(@NonNull Builder builder) {
         mPackageName = ActivityThread.currentActivityThread().getApplication().getPackageName();
         mForEverything = builder.mForEverything;
-        if (builder.mUris != null) {
-            final int size = builder.mUris.size();
-            mUriRequests = new ArrayList<>(size);
+        if (builder.mLocusIds != null) {
+            final int size = builder.mLocusIds.size();
+            mLocusIdRequests = new ArrayList<>(size);
             for (int i = 0; i < size; i++) {
-                mUriRequests.add(new UriRequest(builder.mUris.get(i),
+                mLocusIdRequests.add(new LocusIdRequest(builder.mLocusIds.get(i),
                         builder.mRecursive.get(i) == 1));
             }
         }
@@ -56,9 +56,9 @@
         mForEverything = parcel.readBoolean();
         if (!mForEverything) {
             final int size = parcel.readInt();
-            mUriRequests = new ArrayList<>(size);
+            mLocusIdRequests = new ArrayList<>(size);
             for (int i = 0; i < size; i++) {
-                mUriRequests.add(new UriRequest((Uri) parcel.readValue(null),
+                mLocusIdRequests.add(new LocusIdRequest((LocusId) parcel.readValue(null),
                         parcel.readBoolean()));
             }
         }
@@ -80,11 +80,11 @@
     }
 
     /**
-     * Gets the list of {@code Uri}s the apps is requesting to remove.
+     * Gets the list of {@code LousId}s the apps is requesting to remove.
      */
     @NonNull
-    public List<UriRequest> getUriRequests() {
-        return mUriRequests;
+    public List<LocusIdRequest> getLocusIdRequests() {
+        return mLocusIdRequests;
     }
 
     /**
@@ -93,7 +93,7 @@
     public static final class Builder {
 
         private boolean mForEverything;
-        private ArrayList<Uri> mUris;
+        private ArrayList<LocusId> mLocusIds;
         private IntArray mRecursive;
 
         private boolean mDestroyed;
@@ -106,36 +106,32 @@
         @NonNull
         public Builder forEverything() {
             throwIfDestroyed();
-            if (mUris != null) {
-                throw new IllegalStateException("Already added Uris");
-            }
+            Preconditions.checkState(mLocusIds == null, "Already added LocusIds");
 
             mForEverything = true;
             return this;
         }
 
         /**
-         * Request service to remove data associated with a given {@link Uri}.
+         * Request service to remove data associated with a given {@link LocusId}.
          *
-         * @param uri URI being requested to be removed.
-         * @param recursive whether it should remove the data associated with just the URI or its
-         * tree of descendants.
+         * @param locusId the {@link LocusId} being requested to be removed.
+         * @param recursive whether it should remove the data associated with just the
+         * {@code LocusId} or its tree of descendants.
          *
          * @return this builder
          */
-        public Builder addUri(@NonNull Uri uri, boolean recursive) {
+        public Builder addLocusId(@NonNull LocusId locusId, boolean recursive) {
             throwIfDestroyed();
-            if (mForEverything) {
-                throw new IllegalStateException("Already is for everything");
-            }
-            Preconditions.checkNotNull(uri);
+            Preconditions.checkState(!mForEverything, "Already is for everything");
+            Preconditions.checkNotNull(locusId);
 
-            if (mUris == null) {
-                mUris = new ArrayList<>();
+            if (mLocusIds == null) {
+                mLocusIds = new ArrayList<>();
                 mRecursive = new IntArray();
             }
 
-            mUris.add(uri);
+            mLocusIds.add(locusId);
             mRecursive.add(recursive ? 1 : 0);
             return this;
         }
@@ -147,7 +143,7 @@
         public UserDataRemovalRequest build() {
             throwIfDestroyed();
 
-            Preconditions.checkState(mForEverything || mUris != null);
+            Preconditions.checkState(mForEverything || mLocusIds != null);
 
             mDestroyed = true;
             return new UserDataRemovalRequest(this);
@@ -168,11 +164,11 @@
         parcel.writeString(mPackageName);
         parcel.writeBoolean(mForEverything);
         if (!mForEverything) {
-            final int size = mUriRequests.size();
+            final int size = mLocusIdRequests.size();
             parcel.writeInt(size);
             for (int i = 0; i < size; i++) {
-                final UriRequest request = mUriRequests.get(i);
-                parcel.writeValue(request.getUri());
+                final LocusIdRequest request = mLocusIdRequests.get(i);
+                parcel.writeValue(request.getLocusId());
                 parcel.writeBoolean(request.isRecursive());
             }
         }
@@ -193,28 +189,28 @@
     };
 
     /**
-     * Representation of a request to remove data associated with an {@link Uri}.
+     * Representation of a request to remove data associated with a {@link LocusId}.
      */
-    public final class UriRequest {
-        private final @NonNull Uri mUri;
+    public final class LocusIdRequest {
+        private final @NonNull LocusId mLocusId;
         private final boolean mRecursive;
 
-        private UriRequest(@NonNull Uri uri, boolean recursive) {
-            this.mUri = uri;
+        private LocusIdRequest(@NonNull LocusId locusId, boolean recursive) {
+            this.mLocusId = locusId;
             this.mRecursive = recursive;
         }
 
         /**
-         * Gets the URI per se.
+         * Gets the {@code LocusId} per se.
          */
         @NonNull
-        public Uri getUri() {
-            return mUri;
+        public LocusId getLocusId() {
+            return mLocusId;
         }
 
         /**
-         * Checks whether the request is to remove just the data associated with the URI per se, or
-         * also its descendants.
+         * Checks whether the request is to remove just the data associated with the {@link LocusId}
+         *  per se, or also its descendants.
          */
         @NonNull
         public boolean isRecursive() {
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
index a97c3fa..a5ac270 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -24,6 +24,8 @@
 
 import static org.testng.Assert.assertThrows;
 
+import android.content.LocusId;
+import android.net.Uri;
 import android.os.Parcel;
 import android.os.SystemClock;
 import android.view.autofill.AutofillId;
@@ -45,9 +47,11 @@
 
     private static final long MY_EPOCH = SystemClock.uptimeMillis();
 
+    private static final LocusId ID = new LocusId(Uri.parse("WHATEVER"));
+
     // Not using @Mock because it's final - no need to be fancy here....
-    private final ContentCaptureContext mClientContext = new ContentCaptureContext.Builder()
-            .setAction("WHATEVER").build();
+    private final ContentCaptureContext mClientContext =
+            new ContentCaptureContext.Builder(ID).build();
 
     @Test
     public void testSetAutofillId_null() {
@@ -177,7 +181,7 @@
         assertThat(event.getViewNode()).isNull();
         final ContentCaptureContext clientContext = event.getContentCaptureContext();
         assertThat(clientContext).isNotNull();
-        assertThat(clientContext.getAction()).isEqualTo("WHATEVER");
+        assertThat(clientContext.getLocusId()).isEqualTo(ID);
     }
 
     @Test
@@ -210,7 +214,6 @@
         assertThat(event.getContentCaptureContext()).isNull();
     }
 
-
     @Test
     public void testContextUpdated_directly() {
         final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_CONTEXT_UPDATED)
@@ -239,7 +242,7 @@
         assertThat(event.getViewNode()).isNull();
         final ContentCaptureContext clientContext = event.getContentCaptureContext();
         assertThat(clientContext).isNotNull();
-        assertThat(clientContext.getAction()).isEqualTo("WHATEVER");
+        assertThat(clientContext.getLocusId()).isEqualTo(ID);
     }
 
     // TODO(b/123036895): add test for all events type (right now we're just testing the 3 types