Merge "Require an app activity for launching UIs."
diff --git a/cmds/idmap2/self_targeting/SelfTargeting.cpp b/cmds/idmap2/self_targeting/SelfTargeting.cpp
index 20aa7d3..a8aa033 100644
--- a/cmds/idmap2/self_targeting/SelfTargeting.cpp
+++ b/cmds/idmap2/self_targeting/SelfTargeting.cpp
@@ -38,9 +38,10 @@
 constexpr const mode_t kIdmapFilePermission = S_IRUSR | S_IWUSR;  // u=rw-, g=---, o=---
 
 extern "C" bool
-CreateFrroFile(std::string& out_err_result, std::string& packageName, std::string& overlayName,
-               std::string& targetPackageName, std::optional<std::string>& targetOverlayable,
-               std::vector<FabricatedOverlayEntryParameters>& entries_params,
+CreateFrroFile(std::string& out_err_result, const std::string& packageName,
+               const std::string& overlayName, const std::string& targetPackageName,
+               const std::optional<std::string>& targetOverlayable,
+               const std::vector<FabricatedOverlayEntryParameters>& entries_params,
                const std::string& frro_file_path) {
     android::idmap2::FabricatedOverlay::Builder builder(packageName, overlayName,
                                                         targetPackageName);
@@ -90,9 +91,46 @@
     return true;
 }
 
+static PolicyBitmask GetFulfilledPolicy(const bool isSystem, const bool isVendor,
+                                        const bool isProduct, const bool isTargetSignature,
+                                        const bool isOdm, const bool isOem) {
+    auto fulfilled_policy = static_cast<PolicyBitmask>(PolicyFlags::PUBLIC);
+
+    if (isSystem) {
+        fulfilled_policy |= PolicyFlags::SYSTEM_PARTITION;
+    }
+    if (isVendor) {
+        fulfilled_policy |= PolicyFlags::VENDOR_PARTITION;
+    }
+    if (isProduct) {
+        fulfilled_policy |= PolicyFlags::PRODUCT_PARTITION;
+    }
+    if (isOdm) {
+        fulfilled_policy |= PolicyFlags::ODM_PARTITION;
+    }
+    if (isOem) {
+        fulfilled_policy |= PolicyFlags::OEM_PARTITION;
+    }
+    if (isTargetSignature) {
+        fulfilled_policy |= PolicyFlags::SIGNATURE;
+    }
+
+    // Not support actor_signature and config_overlay_signature
+    fulfilled_policy &=
+            ~(PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::CONFIG_SIGNATURE);
+
+    ALOGV(
+            "fulfilled_policy = 0x%08x, isSystem = %d, isVendor = %d, isProduct = %d,"
+            " isTargetSignature = %d, isOdm = %d, isOem = %d,",
+            fulfilled_policy, isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem);
+    return fulfilled_policy;
+}
+
 extern "C" bool
 CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std::string& overlayPath,
-                const std::string& idmapPath, const std::string& overlayName) {
+                const std::string& idmapPath, const std::string& overlayName,
+                const bool isSystem, const bool isVendor, const bool isProduct,
+                const bool isTargetSignature, const bool isOdm, const bool isOem) {
     // idmap files are mapped with mmap in libandroidfw. Deleting and recreating the idmap
     // guarantees that existing memory maps will continue to be valid and unaffected. The file must
     // be deleted before attempting to create the idmap, so that if idmap  creation fails, the
@@ -114,14 +152,11 @@
     }
 
     // Overlay self target process. Only allow self-targeting types.
-    const auto fulfilled_policies = static_cast<PolicyBitmask>(
-            PolicyFlags::PUBLIC | PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION |
-            PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE | PolicyFlags::ODM_PARTITION |
-            PolicyFlags::OEM_PARTITION | PolicyFlags::ACTOR_SIGNATURE |
-            PolicyFlags::CONFIG_SIGNATURE);
+    const auto fulfilled_policies = GetFulfilledPolicy(isSystem, isVendor, isProduct,
+                                                       isTargetSignature, isOdm, isOem);
 
     const auto idmap = Idmap::FromContainers(**target, **overlay, overlayName,
-                                             fulfilled_policies, false /* enforce_overlayable */);
+                                             fulfilled_policies, true /* enforce_overlayable */);
     if (!idmap) {
         out_err = base::StringPrintf("Failed to create idmap because of %s",
                                      idmap.GetErrorMessage().c_str());
diff --git a/core/api/current.txt b/core/api/current.txt
index e83214c..dab32d2 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -39328,6 +39328,149 @@
 
 }
 
+package android.service.credentials {
+
+  public final class Action implements android.os.Parcelable {
+    ctor public Action(@NonNull android.app.slice.Slice, @NonNull android.app.PendingIntent);
+    method public int describeContents();
+    method @NonNull public android.app.PendingIntent getPendingIntent();
+    method @NonNull public android.app.slice.Slice getSlice();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.Action> CREATOR;
+  }
+
+  public final class BeginCreateCredentialRequest implements android.os.Parcelable {
+    ctor public BeginCreateCredentialRequest(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
+    method public int describeContents();
+    method @NonNull public String getCallingPackage();
+    method @NonNull public android.os.Bundle getData();
+    method @NonNull public String getType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginCreateCredentialRequest> CREATOR;
+  }
+
+  public final class BeginCreateCredentialResponse implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.service.credentials.CreateEntry> getCreateEntries();
+    method @Nullable public android.service.credentials.CreateEntry getRemoteCreateEntry();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginCreateCredentialResponse> CREATOR;
+  }
+
+  public static final class BeginCreateCredentialResponse.Builder {
+    ctor public BeginCreateCredentialResponse.Builder();
+    method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder addCreateEntry(@NonNull android.service.credentials.CreateEntry);
+    method @NonNull public android.service.credentials.BeginCreateCredentialResponse build();
+    method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder setCreateEntries(@NonNull java.util.List<android.service.credentials.CreateEntry>);
+    method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder setRemoteCreateEntry(@Nullable android.service.credentials.CreateEntry);
+  }
+
+  public final class CreateCredentialRequest implements android.os.Parcelable {
+    ctor public CreateCredentialRequest(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
+    method public int describeContents();
+    method @NonNull public String getCallingPackage();
+    method @NonNull public android.os.Bundle getData();
+    method @NonNull public String getType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CreateCredentialRequest> CREATOR;
+  }
+
+  public final class CreateEntry implements android.os.Parcelable {
+    ctor public CreateEntry(@NonNull android.app.slice.Slice, @NonNull android.app.PendingIntent);
+    method public int describeContents();
+    method @NonNull public android.app.PendingIntent getPendingIntent();
+    method @NonNull public android.app.slice.Slice getSlice();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CreateEntry> CREATOR;
+  }
+
+  public final class CredentialEntry implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.credentials.Credential getCredential();
+    method @Nullable public android.app.PendingIntent getPendingIntent();
+    method @NonNull public android.app.slice.Slice getSlice();
+    method @NonNull public String getType();
+    method public boolean isAutoSelectAllowed();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CredentialEntry> CREATOR;
+  }
+
+  public static final class CredentialEntry.Builder {
+    ctor public CredentialEntry.Builder(@NonNull String, @NonNull android.app.slice.Slice, @NonNull android.app.PendingIntent);
+    ctor public CredentialEntry.Builder(@NonNull String, @NonNull android.app.slice.Slice, @NonNull android.credentials.Credential);
+    method @NonNull public android.service.credentials.CredentialEntry build();
+    method @NonNull public android.service.credentials.CredentialEntry.Builder setAutoSelectAllowed(@NonNull boolean);
+  }
+
+  public class CredentialProviderException extends java.lang.Exception {
+    ctor public CredentialProviderException(int, @NonNull String, @NonNull Throwable);
+    ctor public CredentialProviderException(int, @NonNull String);
+    ctor public CredentialProviderException(int, @NonNull Throwable);
+    ctor public CredentialProviderException(int);
+    method public int getErrorCode();
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+  }
+
+  public abstract class CredentialProviderService extends android.app.Service {
+    ctor public CredentialProviderService();
+    method public abstract void onBeginCreateCredential(@NonNull android.service.credentials.BeginCreateCredentialRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.credentials.BeginCreateCredentialResponse,android.service.credentials.CredentialProviderException>);
+    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onGetCredentials(@NonNull android.service.credentials.GetCredentialsRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.credentials.GetCredentialsResponse,android.service.credentials.CredentialProviderException>);
+    field public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
+    field public static final String EXTRA_CREATE_CREDENTIAL_REQUEST = "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
+    field public static final String EXTRA_CREATE_CREDENTIAL_RESULT = "android.service.credentials.extra.CREATE_CREDENTIAL_RESULT";
+    field public static final String EXTRA_CREDENTIAL_RESULT = "android.service.credentials.extra.CREDENTIAL_RESULT";
+    field public static final String EXTRA_ERROR = "android.service.credentials.extra.ERROR";
+    field public static final String EXTRA_GET_CREDENTIALS_CONTENT_RESULT = "android.service.credentials.extra.GET_CREDENTIALS_CONTENT_RESULT";
+    field public static final String SERVICE_INTERFACE = "android.service.credentials.CredentialProviderService";
+  }
+
+  public final class CredentialsResponseContent implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.service.credentials.Action> getActions();
+    method @NonNull public java.util.List<android.service.credentials.CredentialEntry> getCredentialEntries();
+    method @Nullable public android.service.credentials.CredentialEntry getRemoteCredentialEntry();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CredentialsResponseContent> CREATOR;
+  }
+
+  public static final class CredentialsResponseContent.Builder {
+    ctor public CredentialsResponseContent.Builder();
+    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder addAction(@NonNull android.service.credentials.Action);
+    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder addCredentialEntry(@NonNull android.service.credentials.CredentialEntry);
+    method @NonNull public android.service.credentials.CredentialsResponseContent build();
+    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setActions(@NonNull java.util.List<android.service.credentials.Action>);
+    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setCredentialEntries(@NonNull java.util.List<android.service.credentials.CredentialEntry>);
+    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setRemoteCredentialEntry(@Nullable android.service.credentials.CredentialEntry);
+  }
+
+  public final class GetCredentialsRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getCallingPackage();
+    method @NonNull public java.util.List<android.credentials.GetCredentialOption> getGetCredentialOptions();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialsRequest> CREATOR;
+  }
+
+  public static final class GetCredentialsRequest.Builder {
+    ctor public GetCredentialsRequest.Builder(@NonNull String);
+    method @NonNull public android.service.credentials.GetCredentialsRequest.Builder addGetCredentialOption(@NonNull android.credentials.GetCredentialOption);
+    method @NonNull public android.service.credentials.GetCredentialsRequest build();
+    method @NonNull public android.service.credentials.GetCredentialsRequest.Builder setGetCredentialOptions(@NonNull java.util.List<android.credentials.GetCredentialOption>);
+  }
+
+  public final class GetCredentialsResponse implements android.os.Parcelable {
+    method @NonNull public static android.service.credentials.GetCredentialsResponse createWithAuthentication(@NonNull android.service.credentials.Action);
+    method @NonNull public static android.service.credentials.GetCredentialsResponse createWithResponseContent(@NonNull android.service.credentials.CredentialsResponseContent);
+    method public int describeContents();
+    method @Nullable public android.service.credentials.Action getAuthenticationAction();
+    method @Nullable public android.service.credentials.CredentialsResponseContent getCredentialsResponseContent();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialsResponse> CREATOR;
+  }
+
+}
+
 package android.service.dreams {
 
   public class DreamService extends android.app.Service implements android.view.Window.Callback {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index eac990d..802e614 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -12818,14 +12818,14 @@
     method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
   }
 
-  @Deprecated public final class CallAttributes implements android.os.Parcelable {
-    ctor @Deprecated public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
-    method @Deprecated public int describeContents();
-    method @Deprecated @NonNull public android.telephony.CallQuality getCallQuality();
-    method @Deprecated public int getNetworkType();
-    method @Deprecated @NonNull public android.telephony.PreciseCallState getPreciseCallState();
-    method @Deprecated public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
+  public final class CallAttributes implements android.os.Parcelable {
+    ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
+    method public int describeContents();
+    method @NonNull public android.telephony.CallQuality getCallQuality();
+    method public int getNetworkType();
+    method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
   }
 
   public final class CallForwardingInfo implements android.os.Parcelable {
@@ -12905,28 +12905,6 @@
     method @NonNull public android.telephony.CallQuality.Builder setUplinkCallQualityLevel(int);
   }
 
-  public final class CallState implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public android.telephony.CallQuality getCallQuality();
-    method public int getCallState();
-    method public int getImsCallServiceType();
-    method @Nullable public String getImsCallSessionId();
-    method public int getImsCallType();
-    method public int getNetworkType();
-    method public void writeToParcel(@Nullable android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallState> CREATOR;
-  }
-
-  public static final class CallState.Builder {
-    ctor public CallState.Builder(int);
-    method @NonNull public android.telephony.CallState build();
-    method @NonNull public android.telephony.CallState.Builder setCallQuality(@Nullable android.telephony.CallQuality);
-    method @NonNull public android.telephony.CallState.Builder setImsCallServiceType(int);
-    method @NonNull public android.telephony.CallState.Builder setImsCallSessionId(@Nullable String);
-    method @NonNull public android.telephony.CallState.Builder setImsCallType(int);
-    method @NonNull public android.telephony.CallState.Builder setNetworkType(int);
-  }
-
   public class CarrierConfigManager {
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
     method @NonNull public static android.os.PersistableBundle getDefaultConfig();
@@ -13677,8 +13655,7 @@
   }
 
   public static interface TelephonyCallback.CallAttributesListener {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public default void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public default void onCallStatesChanged(@NonNull java.util.List<android.telephony.CallState>);
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
   }
 
   public static interface TelephonyCallback.DataEnabledListener {
@@ -14779,7 +14756,6 @@
     field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
     field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
     field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
-    field public static final int CALL_TYPE_NONE = 0; // 0x0
     field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
     field public static final int CALL_TYPE_VOICE = 2; // 0x2
     field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5aa8f1f..884870b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6426,23 +6426,28 @@
     }
 
     private void handleTrimMemory(int level) {
-        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory: " + level);
+        }
         if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
 
-        if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
-            PropertyInvalidatedCache.onTrimMemory();
-        }
+        try {
+            if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+                PropertyInvalidatedCache.onTrimMemory();
+            }
 
-        final ArrayList<ComponentCallbacks2> callbacks =
-                collectComponentCallbacks(true /* includeUiContexts */);
+            final ArrayList<ComponentCallbacks2> callbacks =
+                    collectComponentCallbacks(true /* includeUiContexts */);
 
-        final int N = callbacks.size();
-        for (int i = 0; i < N; i++) {
-            callbacks.get(i).onTrimMemory(level);
+            final int N = callbacks.size();
+            for (int i = 0; i < N; i++) {
+                callbacks.get(i).onTrimMemory(level);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
 
         WindowManagerGlobal.getInstance().trimMemory(level);
-        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
         if (SystemProperties.getInt("debug.am.run_gc_trim_level", Integer.MAX_VALUE) <= level) {
             unscheduleGcIdler();
diff --git a/core/java/android/service/credentials/Action.java b/core/java/android/service/credentials/Action.java
index 553a324..7757081 100644
--- a/core/java/android/service/credentials/Action.java
+++ b/core/java/android/service/credentials/Action.java
@@ -27,8 +27,6 @@
 /**
  * An action defined by the provider that intents into the provider's app for specific
  * user actions.
- *
- * @hide
  */
 public final class Action implements Parcelable {
     /** Slice object containing display content to be displayed with this action on the UI. */
@@ -39,6 +37,13 @@
     /**
      * Constructs an action to be displayed on the UI.
      *
+     * <p> Actions must be used for any provider related operations, such as opening the provider
+     * app, intenting straight into certain app activities like 'manage credentials', top
+     * level authentication before displaying any content etc.
+     *
+     * <p> See details on usage of {@code Action} for various actionable entries in
+     * {@link BeginCreateCredentialResponse} and {@link GetCredentialsResponse}.
+     *
      * @param slice the display content to be displayed on the UI, along with this action
      * @param pendingIntent the intent to be invoked when the user selects this action
      */
diff --git a/core/java/android/service/credentials/BeginCreateCredentialRequest.aidl b/core/java/android/service/credentials/BeginCreateCredentialRequest.aidl
new file mode 100644
index 0000000..30cab8d
--- /dev/null
+++ b/core/java/android/service/credentials/BeginCreateCredentialRequest.aidl
@@ -0,0 +1,3 @@
+package android.service.credentials;
+
+parcelable BeginCreateCredentialRequest;
\ No newline at end of file
diff --git a/core/java/android/service/credentials/BeginCreateCredentialRequest.java b/core/java/android/service/credentials/BeginCreateCredentialRequest.java
new file mode 100644
index 0000000..1918d8c
--- /dev/null
+++ b/core/java/android/service/credentials/BeginCreateCredentialRequest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 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.credentials;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Request for beginning a create credential request.
+ *
+ * See {@link BeginCreateCredentialResponse} for the counterpart response
+ */
+public final class BeginCreateCredentialRequest implements Parcelable {
+    private final @NonNull String mCallingPackage;
+    private final @NonNull String mType;
+    private final @NonNull Bundle mData;
+
+    /**
+     * Constructs a new instance.
+     *
+     * @throws IllegalArgumentException If {@code callingPackage}, or {@code type} string is
+     * null or empty.
+     * @throws NullPointerException If {@code data} is null.
+     */
+    public BeginCreateCredentialRequest(@NonNull String callingPackage,
+            @NonNull String type, @NonNull Bundle data) {
+        mCallingPackage = Preconditions.checkStringNotEmpty(callingPackage,
+                "callingPackage must not be null or empty");
+        mType = Preconditions.checkStringNotEmpty(type,
+                "type must not be null or empty");
+        mData = Objects.requireNonNull(data, "data must not be null");
+    }
+
+    private BeginCreateCredentialRequest(@NonNull Parcel in) {
+        mCallingPackage = in.readString8();
+        mType = in.readString8();
+        mData = in.readBundle(Bundle.class.getClassLoader());
+    }
+
+    public static final @NonNull Creator<BeginCreateCredentialRequest> CREATOR =
+            new Creator<BeginCreateCredentialRequest>() {
+                @Override
+                public BeginCreateCredentialRequest createFromParcel(@NonNull Parcel in) {
+                    return new BeginCreateCredentialRequest(in);
+                }
+
+                @Override
+                public BeginCreateCredentialRequest[] newArray(int size) {
+                    return new BeginCreateCredentialRequest[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(mCallingPackage);
+        dest.writeString8(mType);
+        dest.writeBundle(mData);
+    }
+
+    /** Returns the calling package of the calling app. */
+    @NonNull
+    public String getCallingPackage() {
+        return mCallingPackage;
+    }
+
+    /** Returns the type of the credential to be created. */
+    @NonNull
+    public String getType() {
+        return mType;
+    }
+
+    /** Returns the data to be used while resolving the credential to create. */
+    @NonNull
+    public Bundle getData() {
+        return mData;
+    }
+}
diff --git a/core/java/android/service/credentials/CreateCredentialResponse.aidl b/core/java/android/service/credentials/BeginCreateCredentialResponse.aidl
similarity index 93%
rename from core/java/android/service/credentials/CreateCredentialResponse.aidl
rename to core/java/android/service/credentials/BeginCreateCredentialResponse.aidl
index 73c9147..d2a1408 100644
--- a/core/java/android/service/credentials/CreateCredentialResponse.aidl
+++ b/core/java/android/service/credentials/BeginCreateCredentialResponse.aidl
@@ -16,4 +16,4 @@
 
 package android.service.credentials;
 
-parcelable CreateCredentialResponse;
+parcelable BeginCreateCredentialResponse;
diff --git a/core/java/android/service/credentials/BeginCreateCredentialResponse.java b/core/java/android/service/credentials/BeginCreateCredentialResponse.java
new file mode 100644
index 0000000..022678e
--- /dev/null
+++ b/core/java/android/service/credentials/BeginCreateCredentialResponse.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 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.credentials;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Response to a {@link BeginCreateCredentialRequest}.
+ */
+public final class BeginCreateCredentialResponse implements Parcelable {
+    private final @NonNull List<CreateEntry> mCreateEntries;
+    private final @Nullable CreateEntry mRemoteCreateEntry;
+
+    private BeginCreateCredentialResponse(@NonNull Parcel in) {
+        List<CreateEntry> createEntries = new ArrayList<>();
+        in.readTypedList(createEntries, CreateEntry.CREATOR);
+        mCreateEntries = createEntries;
+        mRemoteCreateEntry = in.readTypedObject(CreateEntry.CREATOR);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedList(mCreateEntries);
+        dest.writeTypedObject(mRemoteCreateEntry, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<BeginCreateCredentialResponse> CREATOR =
+            new Creator<BeginCreateCredentialResponse>() {
+                @Override
+                public BeginCreateCredentialResponse createFromParcel(@NonNull Parcel in) {
+                    return new BeginCreateCredentialResponse(in);
+                }
+
+                @Override
+                public BeginCreateCredentialResponse[] newArray(int size) {
+                    return new BeginCreateCredentialResponse[size];
+                }
+            };
+
+    /* package-private */ BeginCreateCredentialResponse(
+            @NonNull List<CreateEntry> createEntries,
+            @Nullable CreateEntry remoteCreateEntry) {
+        this.mCreateEntries = createEntries;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mCreateEntries);
+        this.mRemoteCreateEntry = remoteCreateEntry;
+    }
+
+    /** Returns the list of create entries to be displayed on the UI. */
+    public @NonNull List<CreateEntry> getCreateEntries() {
+        return mCreateEntries;
+    }
+
+    /** Returns the remote create entry to be displayed on the UI. */
+    public @Nullable CreateEntry getRemoteCreateEntry() {
+        return mRemoteCreateEntry;
+    }
+
+    /**
+     * A builder for {@link BeginCreateCredentialResponse}
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    public static final class Builder {
+        private @NonNull List<CreateEntry> mCreateEntries = new ArrayList<>();
+        private @Nullable CreateEntry mRemoteCreateEntry;
+
+        /**
+         * Sets the list of create entries to be shown on the UI.
+         *
+         * @throws IllegalArgumentException If {@code createEntries} is empty.
+         * @throws NullPointerException If {@code createEntries} is null, or any of its elements
+         * are null.
+         */
+        public @NonNull Builder setCreateEntries(@NonNull List<CreateEntry> createEntries) {
+            Preconditions.checkCollectionNotEmpty(createEntries, "createEntries");
+            mCreateEntries = Preconditions.checkCollectionElementsNotNull(
+                    createEntries, "createEntries");
+            return this;
+        }
+
+        /**
+         * Adds an entry to the list of create entries to be shown on the UI.
+         *
+         * @throws NullPointerException If {@code createEntry} is null.
+         */
+        public @NonNull Builder addCreateEntry(@NonNull CreateEntry createEntry) {
+            mCreateEntries.add(Objects.requireNonNull(createEntry));
+            return this;
+        }
+
+        /**
+         * Sets a remote create entry to be shown on the UI. Provider must set this entry if they
+         * wish to create the credential on a different device.
+         *
+         * <p> When constructing the {@link CreateEntry} object, the {@code pendingIntent} must be
+         * set such that it leads to an activity that can provide UI to fulfill the request on
+         * a remote device. When user selects this {@code remoteCreateEntry}, the system will
+         * invoke the {@code pendingIntent} set on the {@link CreateEntry}.
+         *
+         * <p> Once the remote credential flow is complete, the {@link android.app.Activity}
+         * result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
+         * {@link CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESULT} key should be populated
+         * with a {@link android.credentials.CreateCredentialResponse} object.
+         */
+        public @NonNull Builder setRemoteCreateEntry(@Nullable CreateEntry remoteCreateEntry) {
+            mRemoteCreateEntry = remoteCreateEntry;
+            return this;
+        }
+
+        /**
+         * Builds a new instance of {@link BeginCreateCredentialResponse}.
+         *
+         * @throws NullPointerException If {@code createEntries} is null.
+         * @throws IllegalArgumentException If {@code createEntries} is empty.
+         */
+        public @NonNull BeginCreateCredentialResponse build() {
+            Preconditions.checkCollectionNotEmpty(mCreateEntries, "createEntries must "
+                    + "not be null, or empty");
+            return new BeginCreateCredentialResponse(mCreateEntries, mRemoteCreateEntry);
+        }
+    }
+}
diff --git a/core/java/android/service/credentials/CreateCredentialRequest.aidl b/core/java/android/service/credentials/CreateCredentialRequest.aidl
deleted file mode 100644
index eb7fba9..0000000
--- a/core/java/android/service/credentials/CreateCredentialRequest.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.service.credentials;
-
-parcelable CreateCredentialRequest;
\ No newline at end of file
diff --git a/core/java/android/service/credentials/CreateCredentialRequest.java b/core/java/android/service/credentials/CreateCredentialRequest.java
index e6da349..aee85ab 100644
--- a/core/java/android/service/credentials/CreateCredentialRequest.java
+++ b/core/java/android/service/credentials/CreateCredentialRequest.java
@@ -27,8 +27,6 @@
 
 /**
  * Request for creating a credential.
- *
- * @hide
  */
 public final class CreateCredentialRequest implements Parcelable {
     private final @NonNull String mCallingPackage;
diff --git a/core/java/android/service/credentials/CreateCredentialResponse.java b/core/java/android/service/credentials/CreateCredentialResponse.java
deleted file mode 100644
index f69dca8..0000000
--- a/core/java/android/service/credentials/CreateCredentialResponse.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2022 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.credentials;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Response to a {@link CreateCredentialRequest}.
- *
- * @hide
- */
-public final class CreateCredentialResponse implements Parcelable {
-    private final @NonNull List<SaveEntry> mSaveEntries;
-    private final @Nullable Action mRemoteSaveEntry;
-    //TODO : Add actions if needed
-
-    private CreateCredentialResponse(@NonNull Parcel in) {
-        List<SaveEntry> saveEntries = new ArrayList<>();
-        in.readTypedList(saveEntries, SaveEntry.CREATOR);
-        mSaveEntries = saveEntries;
-        mRemoteSaveEntry = in.readTypedObject(Action.CREATOR);
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeTypedList(mSaveEntries);
-        dest.writeTypedObject(mRemoteSaveEntry, flags);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @NonNull Creator<CreateCredentialResponse> CREATOR =
-            new Creator<CreateCredentialResponse>() {
-                @Override
-                public CreateCredentialResponse createFromParcel(@NonNull Parcel in) {
-                    return new CreateCredentialResponse(in);
-                }
-
-                @Override
-                public CreateCredentialResponse[] newArray(int size) {
-                    return new CreateCredentialResponse[size];
-                }
-            };
-
-    /* package-private */ CreateCredentialResponse(
-            @NonNull List<SaveEntry> saveEntries,
-            @Nullable Action remoteSaveEntry) {
-        this.mSaveEntries = saveEntries;
-        com.android.internal.util.AnnotationValidations.validate(
-                NonNull.class, null, mSaveEntries);
-        this.mRemoteSaveEntry = remoteSaveEntry;
-    }
-
-    /** Returns the list of save entries to be displayed on the UI. */
-    public @NonNull List<SaveEntry> getSaveEntries() {
-        return mSaveEntries;
-    }
-
-    /** Returns the remote save entry to be displayed on the UI. */
-    public @NonNull Action getRemoteSaveEntry() {
-        return mRemoteSaveEntry;
-    }
-
-    /**
-     * A builder for {@link CreateCredentialResponse}
-     */
-    @SuppressWarnings("WeakerAccess")
-    public static final class Builder {
-        private @NonNull List<SaveEntry> mSaveEntries = new ArrayList<>();
-        private @Nullable Action mRemoteSaveEntry;
-
-        /**
-         * Sets the list of save entries to be shown on the UI.
-         *
-         * @throws IllegalArgumentException If {@code saveEntries} is empty.
-         * @throws NullPointerException If {@code saveEntries} is null, or any of its elements
-         * are null.
-         */
-        public @NonNull Builder setSaveEntries(@NonNull List<SaveEntry> saveEntries) {
-            Preconditions.checkCollectionNotEmpty(saveEntries, "saveEntries");
-            mSaveEntries = Preconditions.checkCollectionElementsNotNull(
-                    saveEntries, "saveEntries");
-            return this;
-        }
-
-        /**
-         * Adds an entry to the list of save entries to be shown on the UI.
-         *
-         * @throws NullPointerException If {@code saveEntry} is null.
-         */
-        public @NonNull Builder addSaveEntry(@NonNull SaveEntry saveEntry) {
-            mSaveEntries.add(Objects.requireNonNull(saveEntry));
-            return this;
-        }
-
-        /**
-         * Sets a remote save entry to be shown on the UI.
-         */
-        public @NonNull Builder setRemoteSaveEntry(@Nullable Action remoteSaveEntry) {
-            mRemoteSaveEntry = remoteSaveEntry;
-            return this;
-        }
-
-        /**
-         * Builds the instance.
-         *
-         * @throws IllegalArgumentException If {@code saveEntries} is empty.
-         */
-        public @NonNull CreateCredentialResponse build() {
-            Preconditions.checkCollectionNotEmpty(mSaveEntries, "saveEntries must "
-                    + "not be empty");
-            return new CreateCredentialResponse(
-                    mSaveEntries,
-                    mRemoteSaveEntry);
-        }
-    }
-}
diff --git a/core/java/android/service/credentials/SaveEntry.java b/core/java/android/service/credentials/CreateEntry.java
similarity index 77%
rename from core/java/android/service/credentials/SaveEntry.java
rename to core/java/android/service/credentials/CreateEntry.java
index 55ff6ff..eb25e25 100644
--- a/core/java/android/service/credentials/SaveEntry.java
+++ b/core/java/android/service/credentials/CreateEntry.java
@@ -25,27 +25,25 @@
 /**
  * An entry to be shown on the UI. This entry represents where the credential to be created will
  * be stored. Examples include user's account, family group etc.
- *
- * @hide
  */
-public final class SaveEntry implements Parcelable {
+public final class CreateEntry implements Parcelable {
     private final @NonNull Slice mSlice;
     private final @NonNull PendingIntent mPendingIntent;
 
-    private SaveEntry(@NonNull Parcel in) {
+    private CreateEntry(@NonNull Parcel in) {
         mSlice = in.readTypedObject(Slice.CREATOR);
         mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
     }
 
-    public static final @NonNull Creator<SaveEntry> CREATOR = new Creator<SaveEntry>() {
+    public static final @NonNull Creator<CreateEntry> CREATOR = new Creator<CreateEntry>() {
         @Override
-        public SaveEntry createFromParcel(@NonNull Parcel in) {
-            return new SaveEntry(in);
+        public CreateEntry createFromParcel(@NonNull Parcel in) {
+            return new CreateEntry(in);
         }
 
         @Override
-        public SaveEntry[] newArray(int size) {
-            return new SaveEntry[size];
+        public CreateEntry[] newArray(int size) {
+            return new CreateEntry[size];
         }
     };
 
@@ -61,12 +59,12 @@
     }
 
     /**
-     * Constructs a save entry to be displayed on the UI.
+     * Constructs a CreateEntry to be displayed on the UI.
      *
      * @param slice the display content to be displayed on the UI, along with this entry
      * @param pendingIntent the intent to be invoked when the user selects this entry
      */
-    public SaveEntry(
+    public CreateEntry(
             @NonNull Slice slice,
             @NonNull PendingIntent pendingIntent) {
         this.mSlice = slice;
@@ -77,12 +75,12 @@
                 NonNull.class, null, mPendingIntent);
     }
 
-    /** Returns the content to be displayed with this save entry on the UI. */
+    /** Returns the content to be displayed with this create entry on the UI. */
     public @NonNull Slice getSlice() {
         return mSlice;
     }
 
-    /** Returns the pendingIntent to be invoked when this save entry on the UI is selectcd. */
+    /** Returns the pendingIntent to be invoked when this create entry on the UI is selectcd. */
     public @NonNull PendingIntent getPendingIntent() {
         return mPendingIntent;
     }
diff --git a/core/java/android/service/credentials/CredentialEntry.java b/core/java/android/service/credentials/CredentialEntry.java
index 98c537a..941db02b 100644
--- a/core/java/android/service/credentials/CredentialEntry.java
+++ b/core/java/android/service/credentials/CredentialEntry.java
@@ -31,8 +31,6 @@
 /**
  * A credential entry that is displayed on the account selector UI. Each entry corresponds to
  * something that the user can select.
- *
- * @hide
  */
 public final class CredentialEntry implements Parcelable {
     /** The type of the credential entry to be shown on the UI. */
@@ -145,61 +143,67 @@
         private boolean mAutoSelectAllowed = false;
 
         /**
-         * Builds the instance.
+         * Creates a builder for a {@link CredentialEntry} that should invoke a
+         * {@link PendingIntent} when selected by the user.
+         *
+         * <p>The {@code pendingIntent} can be used to launch activities that require some user
+         * engagement before getting the credential corresponding to this entry,
+         * e.g. authentication, confirmation etc.
+         * Once the activity fulfills the required user engagement, the
+         * {@link android.app.Activity} result should be set to
+         * {@link android.app.Activity#RESULT_OK}, and the
+         * {@link CredentialProviderService#EXTRA_CREDENTIAL_RESULT} must be set with a
+         * {@link Credential} object.
+         *
          * @param type the type of credential underlying this credential entry
          * @param slice the content to be displayed with this entry on the UI
+         * @param pendingIntent the pendingIntent to be invoked when this entry is selected by the
+         *                      user
          *
-         * @throws IllegalArgumentException If {@code type} is null or empty.
-         * @throws NullPointerException If {@code slice} is null.
+         * @throws NullPointerException If {@code slice}, or {@code pendingIntent} is null.
+         * @throws IllegalArgumentException If {@code type} is null or empty, or if
+         * {@code pendingIntent} was not created with {@link PendingIntent#getActivity}
+         * or {@link PendingIntent#getActivities}.
          */
-        public Builder(@NonNull String type, @NonNull Slice slice) {
+        public Builder(@NonNull String type, @NonNull Slice slice,
+                @NonNull PendingIntent pendingIntent) {
             mType = Preconditions.checkStringNotEmpty(type, "type must not be "
                     + "null, or empty");
             mSlice = Objects.requireNonNull(slice,
                     "slice must not be null");
+            mPendingIntent = Objects.requireNonNull(pendingIntent,
+                    "pendingIntent must not be null");
+            if (!mPendingIntent.isActivity()) {
+                throw new IllegalStateException("Pending intent must start an activity");
+            }
         }
 
         /**
-         * Sets the pendingIntent to be invoked if the user selects this entry.
+         * Creates a builder for a {@link CredentialEntry} that contains a {@link Credential},
+         * and does not require further action.
+         * @param type the type of credential underlying this credential entry
+         * @param slice the content to be displayed with this entry on the UI
+         * @param credential the credential to be returned to the client app, when this entry is
+         *                   selected by the user
          *
-         * The pending intent can be used to launch activities that require some user engagement
-         * before getting the credential corresponding to this entry, e.g. authentication,
-         * confirmation etc.
-         * Once the activity fulfills the required user engagement, a {@link Credential} object
-         * must be returned as an extra on activity finish.
-         *
-         * @throws IllegalStateException If {@code credential} is already set. Must either set the
-         * {@code credential}, or the {@code pendingIntent}.
+         * @throws IllegalArgumentException If {@code type} is null or empty.
+         * @throws NullPointerException If {@code slice}, or {@code credential} is null.
          */
-        public @NonNull Builder setPendingIntent(@Nullable PendingIntent pendingIntent) {
-            if (pendingIntent != null) {
-                Preconditions.checkState(mCredential == null,
-                        "credential is already set. Cannot set both the pendingIntent "
-                                + "and the credential");
-            }
-            mPendingIntent = pendingIntent;
-            return this;
-        }
-
-        /**
-         * Sets the credential to be used, if the user selects this entry.
-         *
-         * @throws IllegalStateException If {@code pendingIntent} is already set. Must either set
-         * the {@code pendingIntent}, or the {@code credential}.
-         */
-        public @NonNull Builder setCredential(@Nullable Credential credential) {
-            if (credential != null) {
-                Preconditions.checkState(mPendingIntent == null,
-                        "pendingIntent is already set. Cannot set both the "
-                                + "pendingIntent and the credential");
-            }
-            mCredential = credential;
-            return this;
+        public Builder(@NonNull String type, @NonNull Slice slice, @NonNull Credential credential) {
+            mType = Preconditions.checkStringNotEmpty(type, "type must not be "
+                    + "null, or empty");
+            mSlice = Objects.requireNonNull(slice,
+                    "slice must not be null");
+            mCredential = Objects.requireNonNull(credential,
+                    "credential must not be null");
         }
 
         /**
          * Sets whether the entry is allowed to be auto selected by the framework.
          * The default value is set to false.
+         *
+         * <p> The entry is only auto selected if it is the only entry on the user selector,
+         * AND the developer has also enabled auto select, while building the request.
          */
         public @NonNull Builder setAutoSelectAllowed(@NonNull boolean autoSelectAllowed) {
             mAutoSelectAllowed = autoSelectAllowed;
diff --git a/core/java/android/service/credentials/CredentialProviderException.java b/core/java/android/service/credentials/CredentialProviderException.java
index 06f0052..02b7443 100644
--- a/core/java/android/service/credentials/CredentialProviderException.java
+++ b/core/java/android/service/credentials/CredentialProviderException.java
@@ -24,8 +24,6 @@
 
 /**
  * Contains custom exceptions to be used by credential providers on failure.
- *
- * @hide
  */
 public class CredentialProviderException extends Exception {
     public static final int ERROR_UNKNOWN = 0;
@@ -59,6 +57,11 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface CredentialProviderError { }
 
+    public CredentialProviderException(@CredentialProviderError int errorCode,
+            @NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+        mErrorCode = errorCode;
+    }
 
     public CredentialProviderException(@CredentialProviderError int errorCode,
             @NonNull String message) {
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index 24b7c3c..32646e6 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -37,30 +37,63 @@
 /**
  * Service to be extended by credential providers, in order to return user credentials
  * to the framework.
- *
- * @hide
  */
 public abstract class CredentialProviderService extends Service {
-    /** Extra to be used by provider to populate the credential when ending the activity started
-     * through the {@code pendingIntent} on the selected {@link SaveEntry}. **/
-    public static final String EXTRA_CREATE_CREDENTIAL_RESPONSE =
-            "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE";
-
-    /** Extra to be used by provider to populate the {@link CredentialsDisplayContent} when
-     * an authentication action entry is selected. **/
-    public static final String EXTRA_GET_CREDENTIALS_DISPLAY_CONTENT =
-            "android.service.credentials.extra.GET_CREDENTIALS_DISPLAY_CONTENT";
+    /**
+     * Intent extra: The {@link android.credentials.CreateCredentialRequest} attached with
+     * the {@code pendingIntent} that is invoked when the user selects a {@link CreateEntry}
+     * returned as part of the {@link BeginCreateCredentialResponse}
+     *
+     * <p>
+     * Type: {@link android.credentials.CreateCredentialRequest}
+     */
+    public static final String EXTRA_CREATE_CREDENTIAL_REQUEST =
+            "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
 
     /**
-     * Provider must read the value against this extra to receive the complete create credential
-     * request parameters, when a pending intent is launched.
+     * Intent extra: The result of a create flow operation, to be set on finish of the
+     * {@link android.app.Activity} invoked through the {@code pendingIntent} set on
+     * a {@link CreateEntry}.
+     *
+     * <p>
+     * Type: {@link android.credentials.CreateCredentialResponse}
      */
-    public static final String EXTRA_CREATE_CREDENTIAL_REQUEST_PARAMS =
-            "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST_PARAMS";
+    public static final String EXTRA_CREATE_CREDENTIAL_RESULT =
+            "android.service.credentials.extra.CREATE_CREDENTIAL_RESULT";
 
-    /** Extra to be used by the provider when setting the credential result. */
-    public static final String EXTRA_GET_CREDENTIAL =
-            "android.service.credentials.extra.GET_CREDENTIAL";
+    /**
+     * Intent extra: The result of a get credential flow operation, to be set on finish of the
+     * {@link android.app.Activity} invoked through the {@code pendingIntent} set on
+     * a {@link CredentialEntry}.
+     *
+     * <p>
+     * Type: {@link android.credentials.Credential}
+     */
+    public static final String EXTRA_CREDENTIAL_RESULT =
+            "android.service.credentials.extra.CREDENTIAL_RESULT";
+
+    /**
+     * Intent extra: The result of an authentication flow, to be set on finish of the
+     * {@link android.app.Activity} invoked through the {@link android.app.PendingIntent} set on
+     * a {@link GetCredentialsResponse}. This result should contain the actual content, including
+     * credential entries and action entries, to be shown on the selector.
+     *
+     * <p>
+     * Type: {@link CredentialsResponseContent}
+     */
+    public static final String EXTRA_GET_CREDENTIALS_CONTENT_RESULT =
+            "android.service.credentials.extra.GET_CREDENTIALS_CONTENT_RESULT";
+
+    /**
+     * Intent extra: The error result of any {@link android.app.PendingIntent} flow, to be set
+     * on finish of the corresponding {@link android.app.Activity}. This result should contain an
+     * error code, representing the error encountered by the provider.
+     *
+     * <p>
+     * Type: {@link String}
+     */
+    public static final String EXTRA_ERROR =
+            "android.service.credentials.extra.ERROR";
 
     private static final String TAG = "CredProviderService";
 
@@ -129,20 +162,21 @@
         }
 
         @Override
-        public ICancellationSignal onCreateCredential(CreateCredentialRequest request,
-                ICreateCredentialCallback callback) {
+        public ICancellationSignal onBeginCreateCredential(BeginCreateCredentialRequest request,
+                IBeginCreateCredentialCallback callback) {
             Objects.requireNonNull(request);
             Objects.requireNonNull(callback);
 
             ICancellationSignal transport = CancellationSignal.createTransport();
 
             mHandler.sendMessage(obtainMessage(
-                    CredentialProviderService::onCreateCredential,
+                    CredentialProviderService::onBeginCreateCredential,
                     CredentialProviderService.this, request,
                     CancellationSignal.fromTransport(transport),
-                    new OutcomeReceiver<CreateCredentialResponse, CredentialProviderException>() {
+                    new OutcomeReceiver<
+                            BeginCreateCredentialResponse, CredentialProviderException>() {
                         @Override
-                        public void onResult(CreateCredentialResponse result) {
+                        public void onResult(BeginCreateCredentialResponse result) {
                             try {
                                 callback.onSuccess(result);
                             } catch (RemoteException e) {
@@ -182,8 +216,8 @@
      *                           the android system.
      * @param callback Object used to relay the response of the credential creation request.
      */
-    public abstract void onCreateCredential(@NonNull CreateCredentialRequest request,
+    public abstract void onBeginCreateCredential(@NonNull BeginCreateCredentialRequest request,
             @NonNull CancellationSignal cancellationSignal,
-            @NonNull OutcomeReceiver<CreateCredentialResponse,
+            @NonNull OutcomeReceiver<BeginCreateCredentialResponse,
                     CredentialProviderException> callback);
 }
diff --git a/core/java/android/service/credentials/CredentialsDisplayContent.java b/core/java/android/service/credentials/CredentialsResponseContent.java
similarity index 64%
rename from core/java/android/service/credentials/CredentialsDisplayContent.java
rename to core/java/android/service/credentials/CredentialsResponseContent.java
index 4b23800..32cab50 100644
--- a/core/java/android/service/credentials/CredentialsDisplayContent.java
+++ b/core/java/android/service/credentials/CredentialsResponseContent.java
@@ -28,12 +28,10 @@
 import java.util.Objects;
 
 /**
- * Content to be displayed on the account selector UI, including credential entries,
- * actions etc.
- *
- * @hide
+ * The content to be displayed on the account selector UI, including credential entries,
+ * actions etc. Returned as part of {@link GetCredentialsResponse}
  */
-public final class CredentialsDisplayContent implements Parcelable {
+public final class CredentialsResponseContent implements Parcelable {
     /** List of credential entries to be displayed on the UI. */
     private final @NonNull List<CredentialEntry> mCredentialEntries;
 
@@ -41,36 +39,36 @@
     private final @NonNull List<Action> mActions;
 
     /** Remote credential entry to get the response from a different device. */
-    private final @Nullable Action mRemoteCredentialEntry;
+    private final @Nullable CredentialEntry mRemoteCredentialEntry;
 
-    private CredentialsDisplayContent(@NonNull List<CredentialEntry> credentialEntries,
+    private CredentialsResponseContent(@NonNull List<CredentialEntry> credentialEntries,
             @NonNull List<Action> actions,
-            @Nullable Action remoteCredentialEntry) {
+            @Nullable CredentialEntry remoteCredentialEntry) {
         mCredentialEntries = credentialEntries;
         mActions = actions;
         mRemoteCredentialEntry = remoteCredentialEntry;
     }
 
-    private CredentialsDisplayContent(@NonNull Parcel in) {
+    private CredentialsResponseContent(@NonNull Parcel in) {
         List<CredentialEntry> credentialEntries = new ArrayList<>();
         in.readTypedList(credentialEntries, CredentialEntry.CREATOR);
         mCredentialEntries = credentialEntries;
         List<Action> actions = new ArrayList<>();
         in.readTypedList(actions, Action.CREATOR);
         mActions = actions;
-        mRemoteCredentialEntry = in.readTypedObject(Action.CREATOR);
+        mRemoteCredentialEntry = in.readTypedObject(CredentialEntry.CREATOR);
     }
 
-    public static final @NonNull Creator<CredentialsDisplayContent> CREATOR =
-            new Creator<CredentialsDisplayContent>() {
+    public static final @NonNull Creator<CredentialsResponseContent> CREATOR =
+            new Creator<CredentialsResponseContent>() {
                 @Override
-                public CredentialsDisplayContent createFromParcel(@NonNull Parcel in) {
-                    return new CredentialsDisplayContent(in);
+                public CredentialsResponseContent createFromParcel(@NonNull Parcel in) {
+                    return new CredentialsResponseContent(in);
                 }
 
                 @Override
-                public CredentialsDisplayContent[] newArray(int size) {
-                    return new CredentialsDisplayContent[size];
+                public CredentialsResponseContent[] newArray(int size) {
+                    return new CredentialsResponseContent[size];
                 }
             };
 
@@ -103,22 +101,34 @@
     /**
      * Returns the remote credential entry to be displayed on the UI.
      */
-    public @Nullable Action getRemoteCredentialEntry() {
+    public @Nullable CredentialEntry getRemoteCredentialEntry() {
         return mRemoteCredentialEntry;
     }
 
     /**
-     * Builds an instance of {@link CredentialsDisplayContent}.
+     * Builds an instance of {@link CredentialsResponseContent}.
      */
     public static final class Builder {
         private List<CredentialEntry> mCredentialEntries = new ArrayList<>();
         private List<Action> mActions = new ArrayList<>();
-        private Action mRemoteCredentialEntry;
+        private CredentialEntry mRemoteCredentialEntry;
 
         /**
-         * Sets the remote credential entry to be displayed on the UI.
+         * Sets a remote credential entry to be shown on the UI. Provider must set this if they
+         * wish to get the credential from a different device.
+         *
+         * <p> When constructing the {@link CredentialEntry} object, the {@code pendingIntent}
+         * must be set such that it leads to an activity that can provide UI to fulfill the request
+         * on a remote device. When user selects this {@code remoteCredentialEntry}, the system will
+         * invoke the {@code pendingIntent} set on the {@link CredentialEntry}.
+         *
+         * <p> Once the remote credential flow is complete, the {@link android.app.Activity}
+         * result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
+         * {@link CredentialProviderService#EXTRA_CREDENTIAL_RESULT} key should be populated
+         * with a {@link android.credentials.Credential} object.
          */
-        public @NonNull Builder setRemoteCredentialEntry(@Nullable Action remoteCredentialEntry) {
+        public @NonNull Builder setRemoteCredentialEntry(@Nullable CredentialEntry
+                remoteCredentialEntry) {
             mRemoteCredentialEntry = remoteCredentialEntry;
             return this;
         }
@@ -138,6 +148,11 @@
          * Adds an {@link Action} to the list of actions to be displayed on
          * the UI.
          *
+         * <p> An {@code action} must be used for independent user actions,
+         * such as opening the app, intenting directly into a certain app activity etc. The
+         * {@code pendingIntent} set with the {@code action} must invoke the corresponding
+         * activity.
+         *
          * @throws NullPointerException If {@code action} is null.
          */
         public @NonNull Builder addAction(@NonNull Action action) {
@@ -175,17 +190,16 @@
         /**
          * Builds a {@link GetCredentialsResponse} instance.
          *
-         * @throws NullPointerException If {@code credentialEntries} is null.
-         * @throws IllegalStateException if both {@code credentialEntries} and
-         * {@code actions} are empty.
+         * @throws IllegalStateException if {@code credentialEntries}, {@code actions}
+         * and {@code remoteCredentialEntry} are all null or empty.
          */
-        public @NonNull CredentialsDisplayContent build() {
+        public @NonNull CredentialsResponseContent build() {
             if (mCredentialEntries != null && mCredentialEntries.isEmpty()
-                    && mActions != null && mActions.isEmpty()) {
+                    && mActions != null && mActions.isEmpty() && mRemoteCredentialEntry == null) {
                 throw new IllegalStateException("credentialEntries and actions must not both "
                         + "be empty");
             }
-            return new CredentialsDisplayContent(mCredentialEntries, mActions,
+            return new CredentialsResponseContent(mCredentialEntries, mActions,
                     mRemoteCredentialEntry);
         }
     }
diff --git a/core/java/android/service/credentials/GetCredentialsRequest.java b/core/java/android/service/credentials/GetCredentialsRequest.java
index 03ba20e..9052b54 100644
--- a/core/java/android/service/credentials/GetCredentialsRequest.java
+++ b/core/java/android/service/credentials/GetCredentialsRequest.java
@@ -29,8 +29,6 @@
 
 /**
  * Request for getting user's credentials from a given credential provider.
- *
- * @hide
  */
 public final class GetCredentialsRequest implements Parcelable {
     /** Calling package of the app requesting for credentials. */
diff --git a/core/java/android/service/credentials/GetCredentialsResponse.java b/core/java/android/service/credentials/GetCredentialsResponse.java
index 979a699..5263141 100644
--- a/core/java/android/service/credentials/GetCredentialsResponse.java
+++ b/core/java/android/service/credentials/GetCredentialsResponse.java
@@ -26,12 +26,10 @@
 /**
  * Response from a credential provider, containing credential entries and other associated
  * data to be shown on the account selector UI.
- *
- * @hide
  */
 public final class GetCredentialsResponse implements Parcelable {
     /** Content to be used for the UI. */
-    private final @Nullable CredentialsDisplayContent mCredentialsDisplayContent;
+    private final @Nullable CredentialsResponseContent mCredentialsResponseContent;
 
     /**
      * Authentication action that must be launched and completed before showing any content
@@ -40,11 +38,17 @@
     private final @Nullable Action mAuthenticationAction;
 
     /**
-     * Creates a {@link GetCredentialsRequest} instance with an authentication action set.
+     * Creates a {@link GetCredentialsResponse} instance with an authentication {@link Action} set.
      * Providers must use this method when no content can be shown before authentication.
      *
-     * Once the authentication action activity is launched, and the user is authenticated, providers
-     * should create another response with {@link CredentialsDisplayContent} using
+     * <p> When the user selects this {@code authenticationAction}, the system invokes the
+     * corresponding {@code pendingIntent}. Once the authentication flow is complete,
+     * the {@link android.app.Activity} result should be set
+     * to {@link android.app.Activity#RESULT_OK} and the
+     * {@link CredentialProviderService#EXTRA_GET_CREDENTIALS_CONTENT_RESULT} extra should be set
+     * with a fully populated {@link CredentialsResponseContent} object.
+     * the authentication action activity is launched, and the user is authenticated, providers
+     * should create another response with {@link CredentialsResponseContent} using
      * {@code createWithDisplayContent}, and add that response to the result of the authentication
      * activity.
      *
@@ -58,27 +62,27 @@
     }
 
     /**
-     * Creates a {@link GetCredentialsRequest} instance with display content to be shown on the UI.
+     * Creates a {@link GetCredentialsRequest} instance with content to be shown on the UI.
      * Providers must use this method when there is content to be shown without top level
-     * authentication required.
+     * authentication required, including credential entries, action entries or a remote entry,
      *
-     * @throws NullPointerException If {@code credentialsDisplayContent} is null.
+     * @throws NullPointerException If {@code credentialsResponseContent} is null.
      */
-    public static @NonNull GetCredentialsResponse createWithDisplayContent(
-            @NonNull CredentialsDisplayContent credentialsDisplayContent) {
-        Objects.requireNonNull(credentialsDisplayContent,
-                "credentialsDisplayContent must not be null");
-        return new GetCredentialsResponse(credentialsDisplayContent, null);
+    public static @NonNull GetCredentialsResponse createWithResponseContent(
+            @NonNull CredentialsResponseContent credentialsResponseContent) {
+        Objects.requireNonNull(credentialsResponseContent,
+                "credentialsResponseContent must not be null");
+        return new GetCredentialsResponse(credentialsResponseContent, null);
     }
 
-    private GetCredentialsResponse(@Nullable CredentialsDisplayContent credentialsDisplayContent,
+    private GetCredentialsResponse(@Nullable CredentialsResponseContent credentialsResponseContent,
             @Nullable Action authenticationAction) {
-        mCredentialsDisplayContent = credentialsDisplayContent;
+        mCredentialsResponseContent = credentialsResponseContent;
         mAuthenticationAction = authenticationAction;
     }
 
     private GetCredentialsResponse(@NonNull Parcel in) {
-        mCredentialsDisplayContent = in.readTypedObject(CredentialsDisplayContent.CREATOR);
+        mCredentialsResponseContent = in.readTypedObject(CredentialsResponseContent.CREATOR);
         mAuthenticationAction = in.readTypedObject(Action.CREATOR);
     }
 
@@ -102,23 +106,23 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeTypedObject(mCredentialsDisplayContent, flags);
+        dest.writeTypedObject(mCredentialsResponseContent, flags);
         dest.writeTypedObject(mAuthenticationAction, flags);
     }
 
     /**
-     * Returns the authentication action to be invoked before any other content
-     * can be shown to the user.
+     * If this response represents a top level authentication action, returns the authentication
+     * action to be invoked before any other content can be shown to the user.
      */
     public @Nullable Action getAuthenticationAction() {
         return mAuthenticationAction;
     }
 
     /**
-     * Returns the credentialDisplayContent that does not require authentication, and
-     * can be shown to the user on the account selector UI.
+     * Returns the actual content to be displayed on the selector, if this response does not
+     * require any top level authentication.
      */
-    public @Nullable CredentialsDisplayContent getCredentialsDisplayContent() {
-        return mCredentialsDisplayContent;
+    public @Nullable CredentialsResponseContent getCredentialsResponseContent() {
+        return mCredentialsResponseContent;
     }
 }
diff --git a/core/java/android/service/credentials/IBeginCreateCredentialCallback.aidl b/core/java/android/service/credentials/IBeginCreateCredentialCallback.aidl
new file mode 100644
index 0000000..ec0bc36
--- /dev/null
+++ b/core/java/android/service/credentials/IBeginCreateCredentialCallback.aidl
@@ -0,0 +1,13 @@
+package android.service.credentials;
+
+import android.service.credentials.BeginCreateCredentialResponse;
+
+/**
+ * Interface from the system to a credential provider service.
+ *
+ * @hide
+ */
+oneway interface IBeginCreateCredentialCallback {
+    void onSuccess(in BeginCreateCredentialResponse request);
+    void onFailure(int errorCode, in CharSequence message);
+}
\ No newline at end of file
diff --git a/core/java/android/service/credentials/ICreateCredentialCallback.aidl b/core/java/android/service/credentials/ICreateCredentialCallback.aidl
deleted file mode 100644
index 4cc76a4..0000000
--- a/core/java/android/service/credentials/ICreateCredentialCallback.aidl
+++ /dev/null
@@ -1,13 +0,0 @@
-package android.service.credentials;
-
-import android.service.credentials.CreateCredentialResponse;
-
-/**
- * Interface from the system to a credential provider service.
- *
- * @hide
- */
-oneway interface ICreateCredentialCallback {
-    void onSuccess(in CreateCredentialResponse request);
-    void onFailure(int errorCode, in CharSequence message);
-}
\ No newline at end of file
diff --git a/core/java/android/service/credentials/ICredentialProviderService.aidl b/core/java/android/service/credentials/ICredentialProviderService.aidl
index c21cefa..b9eb3ed 100644
--- a/core/java/android/service/credentials/ICredentialProviderService.aidl
+++ b/core/java/android/service/credentials/ICredentialProviderService.aidl
@@ -18,9 +18,9 @@
 
 import android.os.ICancellationSignal;
 import android.service.credentials.GetCredentialsRequest;
-import android.service.credentials.CreateCredentialRequest;
+import android.service.credentials.BeginCreateCredentialRequest;
 import android.service.credentials.IGetCredentialsCallback;
-import android.service.credentials.ICreateCredentialCallback;
+import android.service.credentials.IBeginCreateCredentialCallback;
 import android.os.ICancellationSignal;
 
 /**
@@ -30,5 +30,5 @@
  */
 interface ICredentialProviderService {
     ICancellationSignal onGetCredentials(in GetCredentialsRequest request, in IGetCredentialsCallback callback);
-    ICancellationSignal onCreateCredential(in CreateCredentialRequest request, in ICreateCredentialCallback callback);
+    ICancellationSignal onBeginCreateCredential(in BeginCreateCredentialRequest request, in IBeginCreateCredentialCallback callback);
 }
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 09d0fc5..e5c9adb 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -26,6 +26,7 @@
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.Looper;
+import android.telephony.Annotation.CallState;
 import android.telephony.Annotation.DisconnectCauses;
 import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.Annotation.RadioPowerState;
@@ -725,7 +726,7 @@
      */
     @Deprecated
     @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true)
-    public void onCallStateChanged(@Annotation.CallState int state, String phoneNumber) {
+    public void onCallStateChanged(@CallState int state, String phoneNumber) {
         // default implementation empty
     }
 
@@ -1568,48 +1569,12 @@
                     () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state)));
         }
 
-        public void onCallStatesChanged(List<CallState> callStateList) {
+        public void onCallAttributesChanged(CallAttributes callAttributes) {
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
             if (psl == null) return;
 
-            if (callStateList == null) return;
-            CallAttributes ca;
-            if (callStateList.isEmpty()) {
-                ca = new CallAttributes(
-                        new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
-                        TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality());
-            } else {
-                int foregroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-                int backgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-                int ringingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-                for (CallState cs : callStateList) {
-                    switch (cs.getCallClassification()) {
-                        case CallState.CALL_CLASSIFICATION_FOREGROUND:
-                            foregroundCallState = cs.getCallState();
-                            break;
-                        case CallState.CALL_CLASSIFICATION_BACKGROUND:
-                            backgroundCallState = cs.getCallState();
-                            break;
-                        case CallState.CALL_CLASSIFICATION_RINGING:
-                            ringingCallState = cs.getCallState();
-                            break;
-                        default:
-                            break;
-                    }
-                }
-                ca = new CallAttributes(
-                        new PreciseCallState(
-                                foregroundCallState, backgroundCallState, ringingCallState,
-                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
-                        callStateList.get(0).getNetworkType(),
-                        callStateList.get(0).getCallQuality());
-            }
             Binder.withCleanCallingIdentity(
-                    () -> mExecutor.execute(
-                            () -> psl.onCallAttributesChanged(ca)));
+                    () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes)));
         }
 
         public void onActiveDataSubIdChanged(int subId) {
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index 54c4b668..e8960b8 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -27,7 +27,6 @@
 import android.os.Build;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
-import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IPhoneStateListener;
@@ -63,7 +62,7 @@
  * appropriate sub-interfaces.
  */
 public class TelephonyCallback {
-    private static final String LOG_TAG = "TelephonyCallback";
+
     /**
      * Experiment flag to set the per-pid registration limit for TelephonyCallback
      *
@@ -1333,9 +1332,7 @@
     @SystemApi
     public interface CallAttributesListener {
         /**
-         * Callback invoked when the call attributes changes on the active call on the registered
-         * subscription. If the user swaps between a foreground and background call the call
-         * attributes will be reported for the active call only.
+         * Callback invoked when the call attributes changes on the registered subscription.
          * Note, the registration subscription ID comes from {@link TelephonyManager} object
          * which registers TelephonyCallback by
          * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
@@ -1349,77 +1346,9 @@
          * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}.
          *
          * @param callAttributes the call attributes
-         * @deprecated Use onCallStatesChanged({@link List<CallState>}) to get each of call
-         *          state for all ongoing calls on the subscription.
          */
         @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-        @Deprecated
-        default void onCallAttributesChanged(@NonNull CallAttributes callAttributes) {
-            Log.w(LOG_TAG, "onCallAttributesChanged(List<CallAttributes>) should be "
-                    + "overridden.");
-        }
-
-        /**
-         * Callback invoked when the call attributes changes on the ongoing calls on the registered
-         * subscription. If there are 1 foreground and 1 background call, Two {@link CallState}
-         * will be passed.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers TelephonyCallback by
-         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         * In the event that there are no active(state is not
-         * {@link PreciseCallState#PRECISE_CALL_STATE_IDLE}) calls, this API will report empty list.
-         *
-         * The calling app should have carrier privileges
-         * (see {@link TelephonyManager#hasCarrierPrivileges}) if it does not have the
-         * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}.
-         *
-         * @param callStateList the list of call states for each ongoing call. If there are
-         *                           a active call and a holding call, 1 call attributes for
-         *                           {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE}  and another
-         *                           for {@link PreciseCallState#PRECISE_CALL_STATE_HOLDING}
-         *                           will be in this list.
-         */
-        // Added as default for backward compatibility
-        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-        default void onCallStatesChanged(@NonNull List<CallState> callStateList) {
-            if (callStateList.size() > 0) {
-                int foregroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-                int backgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-                int ringingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-                for (CallState cs : callStateList) {
-                    switch (cs.getCallClassification()) {
-                        case CallState.CALL_CLASSIFICATION_FOREGROUND:
-                            foregroundCallState = cs.getCallState();
-                            break;
-                        case CallState.CALL_CLASSIFICATION_BACKGROUND:
-                            backgroundCallState = cs.getCallState();
-                            break;
-                        case CallState.CALL_CLASSIFICATION_RINGING:
-                            ringingCallState = cs.getCallState();
-                            break;
-                        default:
-                            break;
-                    }
-                }
-                onCallAttributesChanged(new CallAttributes(
-                        new PreciseCallState(
-                                ringingCallState, foregroundCallState, backgroundCallState,
-                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
-                        callStateList.get(0).getNetworkType(),
-                        callStateList.get(0).getCallQuality()));
-            } else {
-                onCallAttributesChanged(new CallAttributes(
-                        new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
-                        TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality()));
-            }
-        }
+        void onCallAttributesChanged(@NonNull CallAttributes callAttributes);
     }
 
     /**
@@ -1773,13 +1702,14 @@
                     () -> mExecutor.execute(() -> listener.onRadioPowerStateChanged(state)));
         }
 
-        public void onCallStatesChanged(List<CallState> callStateList) {
+        public void onCallAttributesChanged(CallAttributes callAttributes) {
             CallAttributesListener listener =
                     (CallAttributesListener) mTelephonyCallbackWeakRef.get();
             if (listener == null) return;
 
             Binder.withCleanCallingIdentity(
-                    () -> mExecutor.execute(() -> listener.onCallStatesChanged(callStateList)));
+                    () -> mExecutor.execute(() -> listener.onCallAttributesChanged(
+                            callAttributes)));
         }
 
         public void onActiveDataSubIdChanged(int subId) {
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 0a1538de..a3696e3 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -32,13 +32,13 @@
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.DisconnectCauses;
 import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.PreciseCallStates;
 import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
 import android.telephony.emergency.EmergencyNumber;
-import android.telephony.ims.ImsCallSession;
 import android.telephony.ims.ImsReasonInfo;
 import android.util.ArraySet;
 import android.util.Log;
@@ -741,20 +741,17 @@
      * @param slotIndex for which precise call state changed. Can be derived from subId except when
      * subId is invalid.
      * @param subId for which precise call state changed.
-     * @param callStates Array of PreciseCallState of foreground, background & ringing calls.
-     * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId} for
-     *                   ringing, foreground & background calls.
-     * @param imsServiceTypes Array of IMS call service type for ringing, foreground &
-     *                        background calls.
-     * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls.
+     * @param ringCallPreciseState ringCall state.
+     * @param foregroundCallPreciseState foreground call state.
+     * @param backgroundCallPreciseState background call state.
      */
     public void notifyPreciseCallState(int slotIndex, int subId,
-            @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds,
-            @Annotation.ImsCallServiceType int[] imsServiceTypes,
-            @Annotation.ImsCallType int[] imsCallTypes) {
+            @PreciseCallStates int ringCallPreciseState,
+            @PreciseCallStates int foregroundCallPreciseState,
+            @PreciseCallStates int backgroundCallPreciseState) {
         try {
-            sRegistry.notifyPreciseCallState(slotIndex, subId, callStates,
-                    imsCallIds, imsServiceTypes, imsCallTypes);
+            sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
+                foregroundCallPreciseState, backgroundCallPreciseState);
         } catch (RemoteException ex) {
             // system process is dead
             throw ex.rethrowFromSystemServer();
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index d77e499..03b25c2 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -29,6 +29,7 @@
 import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
 import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT;
 import static android.view.WindowInsets.Type.all;
+import static android.view.WindowInsets.Type.displayCutout;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.indexOf;
 import static android.view.WindowInsets.Type.systemBars;
@@ -597,7 +598,10 @@
         return new WindowInsets(null, null,
                 mTypeVisibilityMap,
                 mIsRound, mAlwaysConsumeSystemBars,
-                displayCutoutCopyConstructorArgument(this),
+                // If the system window insets types contain displayCutout, we should also consume
+                // it.
+                (mCompatInsetsTypes & displayCutout()) != 0
+                        ? null : displayCutoutCopyConstructorArgument(this),
                 mRoundedCorners, mPrivacyIndicatorBounds, mCompatInsetsTypes,
                 mCompatIgnoreVisibility);
     }
diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
index 76e068d..6ceccd1 100644
--- a/core/java/com/android/internal/content/om/OverlayManagerImpl.java
+++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
@@ -17,14 +17,20 @@
 package com.android.internal.content.om;
 
 import static android.content.Context.MODE_PRIVATE;
+import static android.content.om.OverlayManagerTransaction.Request.BUNDLE_FABRICATED_OVERLAY;
+import static android.content.om.OverlayManagerTransaction.Request.TYPE_REGISTER_FABRICATED;
+import static android.content.om.OverlayManagerTransaction.Request.TYPE_UNREGISTER_FABRICATED;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
 import static com.android.internal.content.om.OverlayConfig.DEFAULT_PRIORITY;
 
 import android.annotation.NonNull;
+import android.annotation.NonUiContext;
 import android.content.Context;
+import android.content.om.OverlayIdentifier;
 import android.content.om.OverlayInfo;
+import android.content.om.OverlayManagerTransaction;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.parsing.FrameworkParsingPackageUtils;
@@ -48,6 +54,7 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 
@@ -129,10 +136,9 @@
         }
     }
 
-    /**
-     * Ensure the base dir for self-targeting is valid.
-     */
+    /** Ensure the base dir for self-targeting is valid. */
     @VisibleForTesting
+    @NonUiContext
     public void ensureBaseDir() {
         final String baseApkPath = mContext.getApplicationInfo().getBaseCodePath();
         final Path baseApkFolderName = Path.of(baseApkPath).getParent().getFileName();
@@ -170,6 +176,16 @@
         mBasePath = baseFile.toPath();
     }
 
+    private boolean isSameWithTargetSignature(final String targetPackage) {
+        final PackageManager packageManager = mContext.getPackageManager();
+        final String packageName = mContext.getPackageName();
+        if (TextUtils.equals(packageName, targetPackage)) {
+            return true;
+        }
+        return packageManager.checkSignatures(packageName, targetPackage)
+                == PackageManager.SIGNATURE_MATCH;
+    }
+
     /**
      * Check if the overlay name is valid or not.
      *
@@ -202,8 +218,12 @@
     /**
      * Save FabricatedOverlay instance as frro and idmap files.
      *
+     * <p>In order to fill the overlayable policy, it's necessary to collect the information from
+     * app. And then, the information is passed to native layer to fill the overlayable policy
+     *
      * @param overlayInternal the FabricatedOverlayInternal to be saved.
      */
+    @NonUiContext
     public void registerFabricatedOverlay(@NonNull FabricatedOverlayInternal overlayInternal)
             throws IOException, PackageManager.NameNotFoundException {
         ensureBaseDir();
@@ -214,6 +234,9 @@
         final String overlayName = checkOverlayNameValid(overlayInternal.overlayName);
         checkPackageName(overlayInternal.packageName);
         checkPackageName(overlayInternal.targetPackageName);
+        Preconditions.checkStringNotEmpty(
+                overlayInternal.targetOverlayable,
+                "Target overlayable should be neither null nor empty string.");
 
         final ApplicationInfo applicationInfo = mContext.getApplicationInfo();
         final String targetPackage = Preconditions.checkStringNotEmpty(
@@ -223,7 +246,17 @@
 
         createFrroFile(frroPath.toString(), overlayInternal);
         try {
-            createIdmapFile(targetPackage, frroPath.toString(), idmapPath.toString(), overlayName);
+            createIdmapFile(
+                    targetPackage,
+                    frroPath.toString(),
+                    idmapPath.toString(),
+                    overlayName,
+                    applicationInfo.isSystemApp() || applicationInfo.isSystemExt() /* isSystem */,
+                    applicationInfo.isVendor(),
+                    applicationInfo.isProduct(),
+                    isSameWithTargetSignature(overlayInternal.targetPackageName),
+                    applicationInfo.isOdm(),
+                    applicationInfo.isOem());
         } catch (IOException e) {
             if (!frroPath.toFile().delete()) {
                 Log.w(TAG, "Failed to delete file " + frroPath);
@@ -237,6 +270,7 @@
      *
      * @param overlayName the specific name
      */
+    @NonUiContext
     public void unregisterFabricatedOverlay(@NonNull String overlayName) {
         ensureBaseDir();
         checkOverlayNameValid(overlayName);
@@ -252,6 +286,46 @@
     }
 
     /**
+     * Commit the overlay manager transaction
+     *
+     * @param transaction the overlay manager transaction
+     */
+    @NonUiContext
+    public void commit(@NonNull OverlayManagerTransaction transaction)
+            throws PackageManager.NameNotFoundException, IOException {
+        Objects.requireNonNull(transaction);
+
+        for (Iterator<OverlayManagerTransaction.Request> it = transaction.iterator();
+                it.hasNext(); ) {
+            final OverlayManagerTransaction.Request request = it.next();
+            if (request.type == TYPE_REGISTER_FABRICATED) {
+                final FabricatedOverlayInternal fabricatedOverlayInternal =
+                        Objects.requireNonNull(
+                                request.extras.getParcelable(
+                                        BUNDLE_FABRICATED_OVERLAY,
+                                        FabricatedOverlayInternal.class));
+
+                // populate the mandatory data
+                if (TextUtils.isEmpty(fabricatedOverlayInternal.packageName)) {
+                    fabricatedOverlayInternal.packageName = mContext.getPackageName();
+                } else {
+                    if (!TextUtils.equals(
+                            fabricatedOverlayInternal.packageName, mContext.getPackageName())) {
+                        throw new IllegalArgumentException("Unknown package name in transaction");
+                    }
+                }
+
+                registerFabricatedOverlay(fabricatedOverlayInternal);
+            } else if (request.type == TYPE_UNREGISTER_FABRICATED) {
+                final OverlayIdentifier overlayIdentifier = Objects.requireNonNull(request.overlay);
+                unregisterFabricatedOverlay(overlayIdentifier.getOverlayName());
+            } else {
+                throw new IllegalArgumentException("Unknown request in transaction " + request);
+            }
+        }
+    }
+
+    /**
      * Get the list of overlays information for the target package name.
      *
      * @param targetPackage the target package name
@@ -315,7 +389,13 @@
             @NonNull String targetPath,
             @NonNull String overlayPath,
             @NonNull String idmapPath,
-            @NonNull String overlayName)
+            @NonNull String overlayName,
+            boolean isSystem,
+            boolean isVendor,
+            boolean isProduct,
+            boolean isSameWithTargetSignature,
+            boolean isOdm,
+            boolean isOem)
             throws IOException;
 
     private static native FabricatedOverlayInfo getFabricatedOverlayInfo(
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 9cb2e68..4b1753a 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -17,7 +17,7 @@
 package com.android.internal.telephony;
 
 import android.telephony.BarringInfo;
-import android.telephony.CallState;
+import android.telephony.CallAttributes;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.DataConnectionRealTimeInfo;
@@ -62,7 +62,7 @@
     void onPhoneCapabilityChanged(in PhoneCapability capability);
     void onActiveDataSubIdChanged(in int subId);
     void onRadioPowerStateChanged(in int state);
-    void onCallStatesChanged(in List<CallState> callStateList);
+    void onCallAttributesChanged(in CallAttributes callAttributes);
     @SuppressWarnings(value={"untyped-collection"})
     void onEmergencyNumberListChanged(in Map emergencyNumberList);
     void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber, int subscriptionId);
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 7ba2686..c7fa757 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -66,8 +66,8 @@
     void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation);
     @UnsupportedAppUsage
     void notifyCellInfo(in List<CellInfo> cellInfo);
-    void notifyPreciseCallState(int phoneId, int subId, in int[] callStates, in String[] imsCallIds,
-            in int[] imsCallServiceTypes, in int[] imsCallTypes);
+    void notifyPreciseCallState(int phoneId, int subId, int ringingCallState,
+            int foregroundCallState, int backgroundCallState);
     void notifyDisconnectCause(int phoneId, int subId, int disconnectCause,
             int preciseDisconnectCause);
     void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo);
diff --git a/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp b/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp
index df55e42..bba1760 100644
--- a/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp
+++ b/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp
@@ -123,8 +123,12 @@
 
     bool callCreateIdmapFile(std::string& out_error, const std::string& targetPath,
                              const std::string& overlayPath, const std::string& idmapPath,
-                             const std::string& overlayName) {
-        return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName);
+                             const std::string& overlayName, const bool isSystem,
+                             const bool isVendor, const bool isProduct,
+                             const bool isTargetSignature, const bool isOdm, const bool isOem) {
+        return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName,
+                                       isSystem, isVendor, isProduct, isTargetSignature, isOdm,
+                                       isOem);
     }
 
     bool callGetFabricatedOverlayInfo(std::string& out_error, const std::string& overlay_path,
@@ -158,7 +162,10 @@
     typedef bool (*CreateIdmapFileFunc)(std::string& out_error, const std::string& targetPath,
                                         const std::string& overlayPath,
                                         const std::string& idmapPath,
-                                        const std::string& overlayName);
+                                        const std::string& overlayName, const jboolean isSystem,
+                                        const jboolean isVendor, const jboolean isProduct,
+                                        const jboolean isSameWithTargetSignature,
+                                        const jboolean isOdm, const jboolean isOem);
 
     typedef bool (*GetFabricatedOverlayInfoFunc)(std::string& out_error,
                                                  const std::string& overlay_path,
@@ -295,7 +302,9 @@
 }
 
 static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPath,
-                            jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName) {
+                            jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName,
+                            jboolean isSystem, jboolean isVendor, jboolean isProduct,
+                            jboolean isTargetSignature, jboolean isOdm, jboolean isOem) {
     DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env);
     if (!dlLoader) {
         jniThrowNullPointerException(env, "libidmap2 is not loaded");
@@ -327,7 +336,10 @@
 
     std::string err_result;
     if (!dlLoader.callCreateIdmapFile(err_result, targetPath.c_str(), overlayPath.c_str(),
-                                      idmapPath.c_str(), overlayName.c_str())) {
+                                      idmapPath.c_str(), overlayName.c_str(),
+                                      (isSystem == JNI_TRUE), (isVendor == JNI_TRUE),
+                                      (isProduct == JNI_TRUE), (isTargetSignature == JNI_TRUE),
+                                      (isOdm == JNI_TRUE), (isOem == JNI_TRUE))) {
         jniThrowException(env, kIOException, err_result.c_str());
         return;
     }
@@ -374,7 +386,7 @@
         {"createFrroFile", "(Ljava/lang/String;Landroid/os/FabricatedOverlayInternal;)V",
          reinterpret_cast<void*>(self_targeting::CreateFrroFile)},
         {"createIdmapFile",
-         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
+         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZ)V",
          reinterpret_cast<void*>(self_targeting::CreateIdmapFile)},
         {"getFabricatedOverlayInfo", "(Ljava/lang/String;)Landroid/os/FabricatedOverlayInfo;",
          reinterpret_cast<void*>(self_targeting::GetFabricatedOverlayInfo)},
diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp
index 82998db..063c569 100644
--- a/core/tests/overlaytests/device_self_targeting/Android.bp
+++ b/core/tests/overlaytests/device_self_targeting/Android.bp
@@ -29,6 +29,7 @@
         "androidx.test.rules",
         "androidx.test.runner",
         "androidx.test.ext.junit",
+        "mockito-target-minus-junit4",
         "truth-prebuilt",
     ],
 
diff --git a/core/tests/overlaytests/device_self_targeting/res/values/overlayable.xml b/core/tests/overlaytests/device_self_targeting/res/values/overlayable.xml
new file mode 100644
index 0000000..5cc214d
--- /dev/null
+++ b/core/tests/overlaytests/device_self_targeting/res/values/overlayable.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+
+<resources>
+    <overlayable name="PublicOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="public">
+            <item type="color" name="public_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="SignatureOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="signature">
+            <item type="color" name="mycolor" />
+            <item type="color" name="signature_overlayable_color" />
+            <item type="string" name="mystring" />
+            <item type="drawable" name="mydrawable" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="SystemAppOverlayable" actor="overlay://theme">
+        <!-- The app in system partition can overlay the below resources -->
+        <policy type="system">
+            <item type="color" name="system_app_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="OdmOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="odm">
+            <item type="color" name="odm_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="OemOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="oem">
+            <item type="color" name="oem_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="VendorOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="vendor">
+            <item type="color" name="vendor_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="ProductOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="product">
+            <item type="color" name="product_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="ActorOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="actor">
+            <item type="color" name="actor_overlayable_color" />
+        </policy>
+    </overlayable>
+
+    <overlayable name="ConfigOverlayable" actor="overlay://theme">
+        <!-- The app with the same signature can overlay the below resources -->
+        <policy type="config_signature">
+            <item type="color" name="config_overlayable_color" />
+        </policy>
+    </overlayable>
+
+</resources>
diff --git a/core/tests/overlaytests/device_self_targeting/res/values/values.xml b/core/tests/overlaytests/device_self_targeting/res/values/values.xml
index f0b4a6f..d82de97 100644
--- a/core/tests/overlaytests/device_self_targeting/res/values/values.xml
+++ b/core/tests/overlaytests/device_self_targeting/res/values/values.xml
@@ -17,4 +17,14 @@
 <resources>
     <color name="mycolor">#ff112233</color>
     <string name="mystring">hello</string>
+
+    <color name="public_overlayable_color">#000</color>
+    <color name="signature_overlayable_color">#000</color>
+    <color name="system_app_overlayable_color">#000</color>
+    <color name="odm_overlayable_color">#000</color>
+    <color name="oem_overlayable_color">#000</color>
+    <color name="vendor_overlayable_color">#000</color>
+    <color name="product_overlayable_color">#000</color>
+    <color name="actor_overlayable_color">#000</color>
+    <color name="config_overlayable_color">#000</color>
 </resources>
diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
index ca58410..40d0bef 100644
--- a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
+++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
@@ -17,15 +17,24 @@
 package com.android.overlaytest;
 
 import static android.content.Context.MODE_PRIVATE;
+import static android.content.pm.PackageManager.SIGNATURE_NO_MATCH;
 
 import static com.android.internal.content.om.OverlayManagerImpl.SELF_TARGET;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.om.FabricatedOverlay;
 import android.content.om.OverlayInfo;
+import android.content.om.OverlayManagerTransaction;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.os.FabricatedOverlayInternal;
@@ -72,11 +81,23 @@
     private static final String TARGET_COLOR_RES = "color/mycolor";
     private static final String TARGET_STRING_RES = "string/mystring";
     private static final String TARGET_DRAWABLE_RES = "drawable/mydrawable";
+    private static final String PUBLIC_OVERLAYABLE = "PublicOverlayable";
+    private static final String SIGNATURE_OVERLAYABLE = "SignatureOverlayable";
+    private static final String SYSTEM_APP_OVERLAYABLE = "SystemAppOverlayable";
+    private static final String ODM_OVERLAYABLE = "OdmOverlayable";
+    private static final String OEM_OVERLAYABLE = "OemOverlayable";
+    private static final String VENDOR_OVERLAYABLE = "VendorOverlayable";
+    private static final String PRODUCT_OVERLAYABLE = "ProductOverlayable";
+    private static final String ACTOR_OVERLAYABLE = "ActorOverlayable";
+    private static final String CONFIG_OVERLAYABLE = "ConfigOverlayable";
 
     private Context mContext;
     private OverlayManagerImpl mOverlayManagerImpl;
     private String mOverlayName;
 
+    private PackageManager mMockPackageManager;
+    private ApplicationInfo mMockApplicationInfo;
+
     @Rule public TestName mTestName = new TestName();
 
     @Rule public Expect expect = Expect.create();
@@ -111,7 +132,36 @@
     public void setUp() throws IOException {
         clearDir();
         mOverlayName = mTestName.getMethodName();
-        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+        mMockApplicationInfo = mock(ApplicationInfo.class);
+        when(mMockApplicationInfo.isSystemApp()).thenReturn(false);
+        when(mMockApplicationInfo.isSystemExt()).thenReturn(false);
+        when(mMockApplicationInfo.isOdm()).thenReturn(false);
+        when(mMockApplicationInfo.isOem()).thenReturn(false);
+        when(mMockApplicationInfo.isVendor()).thenReturn(false);
+        when(mMockApplicationInfo.isProduct()).thenReturn(false);
+        when(mMockApplicationInfo.getBaseCodePath()).thenReturn(
+                context.getApplicationInfo().getBaseCodePath());
+        mMockApplicationInfo.sourceDir = context.getApplicationInfo().sourceDir;
+
+        mMockPackageManager = mock(PackageManager.class);
+        when(mMockPackageManager.checkSignatures(anyString(), anyString()))
+                .thenReturn(SIGNATURE_NO_MATCH);
+
+        mContext =
+                new ContextWrapper(context) {
+                    @Override
+                    public ApplicationInfo getApplicationInfo() {
+                        return mMockApplicationInfo;
+                    }
+
+                    @Override
+                    public PackageManager getPackageManager() {
+                        return mMockPackageManager;
+                    }
+                };
+
         mOverlayManagerImpl = new OverlayManagerImpl(mContext);
     }
 
@@ -144,12 +194,14 @@
 
     private <T> FabricatedOverlayInternal createOverlayWithName(
             @NonNull String overlayName,
+            @NonNull String targetOverlayable,
             @NonNull String targetPackageName,
             @NonNull List<Pair<String, Pair<String, T>>> entryDefinitions) {
         final String packageName = mContext.getPackageName();
         FabricatedOverlayInternal overlayInternal = new FabricatedOverlayInternal();
         overlayInternal.overlayName = overlayName;
         overlayInternal.targetPackageName = targetPackageName;
+        overlayInternal.targetOverlayable = targetOverlayable;
         overlayInternal.packageName = packageName;
 
         addOverlayEntry(overlayInternal, entryDefinitions);
@@ -162,6 +214,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SYSTEM_APP_OVERLAYABLE,
                         "android",
                         List.of(Pair.create("color/white", Pair.create(null, Color.BLACK))));
 
@@ -190,6 +243,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
 
@@ -215,6 +269,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_STRING_RES, Pair.create(null, "HELLO"))));
 
@@ -242,6 +297,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_DRAWABLE_RES,
                                             Pair.create(null, parcelFileDescriptor))));
@@ -268,6 +324,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create("color/not_existed", Pair.create(null, "HELLO"))));
 
@@ -301,6 +358,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
         mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -309,6 +367,7 @@
         overlayInternal =
                 createOverlayWithName(
                         secondOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
         mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -341,6 +400,7 @@
         FabricatedOverlayInternal overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
         mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -349,6 +409,7 @@
         overlayInternal =
                 createOverlayWithName(
                         mOverlayName,
+                        SIGNATURE_OVERLAYABLE,
                         mContext.getPackageName(),
                         List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
         mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -392,6 +453,40 @@
     }
 
     @Test
+    public void commit_withNullTransaction_shouldFail() {
+        assertThrows(NullPointerException.class, () -> mOverlayManagerImpl.commit(null));
+    }
+
+    @Test
+    public void commitRegisterOverlay_fromOtherBuilder_shouldWork()
+            throws PackageManager.NameNotFoundException, IOException {
+        FabricatedOverlay overlay =
+                new FabricatedOverlay.Builder(
+                                mContext.getPackageName(), mOverlayName, mContext.getPackageName())
+                        .setTargetOverlayable(SIGNATURE_OVERLAYABLE)
+                        .setResourceValue(
+                                TARGET_COLOR_RES, TypedValue.TYPE_INT_COLOR_ARGB8, Color.WHITE)
+                        .build();
+        OverlayManagerTransaction transaction =
+                new OverlayManagerTransaction.Builder().registerFabricatedOverlay(overlay).build();
+
+        mOverlayManagerImpl.commit(transaction);
+
+        final List<OverlayInfo> overlayInfos =
+                mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName());
+        final int firstNumberOfOverlays = overlayInfos.size();
+        expect.that(firstNumberOfOverlays).isEqualTo(1);
+        final OverlayInfo overlayInfo = overlayInfos.get(0);
+        expect.that(overlayInfo).isNotNull();
+        Truth.assertThat(expect.hasFailures()).isFalse();
+        expect.that(overlayInfo.isFabricated()).isTrue();
+        expect.that(overlayInfo.getOverlayName()).isEqualTo(mOverlayName);
+        expect.that(overlayInfo.getPackageName()).isEqualTo(mContext.getPackageName());
+        expect.that(overlayInfo.getTargetPackageName()).isEqualTo(mContext.getPackageName());
+        expect.that(overlayInfo.getUserId()).isEqualTo(mContext.getUserId());
+    }
+
+    @Test
     public void newOverlayManagerImpl_forOtherUser_shouldFail() {
         Context fakeContext =
                 new ContextWrapper(mContext) {
@@ -408,4 +503,177 @@
 
         assertThrows(SecurityException.class, () -> new OverlayManagerImpl(fakeContext));
     }
+
+    FabricatedOverlayInternal prepareFabricatedOverlayInternal(
+            String targetOverlayableName, String targetEntryName) {
+        return createOverlayWithName(
+                mOverlayName,
+                targetOverlayableName,
+                mContext.getPackageName(),
+                List.of(
+                        Pair.create(
+                                targetEntryName,
+                                Pair.create(null, Color.WHITE))));
+    }
+
+    @Test
+    public void registerOverlayOnSystemOverlayable_selfIsNotSystemApp_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                SYSTEM_APP_OVERLAYABLE,
+                "color/system_app_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnOdmOverlayable_selfIsNotOdm_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                ODM_OVERLAYABLE,
+                "color/odm_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnOemOverlayable_selfIsNotOem_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                OEM_OVERLAYABLE,
+                "color/oem_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnVendorOverlayable_selfIsNotVendor_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                VENDOR_OVERLAYABLE,
+                "color/vendor_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnProductOverlayable_selfIsNotProduct_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                PRODUCT_OVERLAYABLE,
+                "color/product_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnActorOverlayable_notSupport_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                ACTOR_OVERLAYABLE,
+                "color/actor_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnConfigOverlayable_notSupport_shouldFail() {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                CONFIG_OVERLAYABLE,
+                "color/config_overlayable_color");
+
+        assertThrows(
+                IOException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
+    public void registerOverlayOnPublicOverlayable_shouldAlwaysSucceed()
+            throws PackageManager.NameNotFoundException, IOException {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                PUBLIC_OVERLAYABLE,
+                "color/public_overlayable_color");
+
+        mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
+
+        assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void registerOverlayOnSystemOverlayable_selfIsSystemApp_shouldSucceed()
+            throws PackageManager.NameNotFoundException, IOException {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                SYSTEM_APP_OVERLAYABLE,
+                "color/system_app_overlayable_color");
+        when(mMockApplicationInfo.isSystemApp()).thenReturn(true);
+        when(mMockApplicationInfo.isSystemExt()).thenReturn(true);
+
+        mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
+
+        assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void registerOverlayOnOdmOverlayable_selfIsOdm_shouldSucceed()
+            throws PackageManager.NameNotFoundException, IOException {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                ODM_OVERLAYABLE,
+                "color/odm_overlayable_color");
+        when(mMockApplicationInfo.isOdm()).thenReturn(true);
+
+        mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
+
+        assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void registerOverlayOnOemOverlayable_selfIsOem_shouldSucceed()
+            throws PackageManager.NameNotFoundException, IOException {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                OEM_OVERLAYABLE,
+                "color/oem_overlayable_color");
+        when(mMockApplicationInfo.isOem()).thenReturn(true);
+
+        mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
+
+        assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void registerOverlayOnVendorOverlayable_selfIsVendor_shouldSucceed()
+            throws PackageManager.NameNotFoundException, IOException {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                VENDOR_OVERLAYABLE,
+                "color/vendor_overlayable_color");
+        when(mMockApplicationInfo.isVendor()).thenReturn(true);
+
+        mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
+
+        assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void registerOverlayOnProductOverlayable_selfIsProduct_shouldSucceed()
+            throws PackageManager.NameNotFoundException, IOException {
+        final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
+                PRODUCT_OVERLAYABLE,
+                "color/product_overlayable_color");
+        when(mMockApplicationInfo.isProduct()).thenReturn(true);
+
+        mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
+
+        assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
+                .isEqualTo(1);
+    }
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 2bede9a..94bd057 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -39,6 +39,7 @@
 import android.os.Binder
 import android.os.Bundle
 import android.os.ResultReceiver
+import android.service.credentials.CredentialProviderService
 import com.android.credentialmanager.createflow.ActiveEntry
 import com.android.credentialmanager.createflow.CreateCredentialUiState
 import com.android.credentialmanager.createflow.CreateScreenState
@@ -390,11 +391,12 @@
       intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
               or PendingIntent.FLAG_ONE_SHOT))
     val createPasswordRequest = android.service.credentials.CreateCredentialRequest(
-      context.applicationInfo.packageName,
-      "PASSWORD",
-      toBundle("beckett-bakert@gmail.com", "password123")
+            context.applicationInfo.packageName,
+            TYPE_PASSWORD_CREDENTIAL,
+            toBundle("beckett-bakert@gmail.com", "password123")
     )
-    val fillInIntent = Intent().putExtra("create_request_params", createPasswordRequest)
+    val fillInIntent = Intent().putExtra(CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST,
+            createPasswordRequest)
 
     val slice = Slice.Builder(
       Entry.CREDENTIAL_MANAGER_ENTRY_URI, SliceSpec(Entry.VERSION, 1)
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
index 96e2498..decc292 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
@@ -46,7 +46,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt
index a57df0f..063b61c 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt
@@ -50,7 +50,6 @@
     )
 
     fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner)
-        .setIsAllowSearch(true)
         .setUiLayoutFn {
             Preference(object : PreferenceModel {
                 override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
index 7958d11..42ac1ac 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
@@ -55,7 +55,6 @@
         entryList.add(
             createEntry(owner, EntryEnum.STRING_PARAM)
                 // Set attributes
-                .setIsAllowSearch(true)
                 .setIsSearchDataDynamic(true)
                 .setSearchDataFn { ArgumentPageModel.genStringParamSearchData() }
                 .setUiLayoutFn {
@@ -67,7 +66,6 @@
         entryList.add(
             createEntry(owner, EntryEnum.INT_PARAM)
                 // Set attributes
-                .setIsAllowSearch(true)
                 .setIsSearchDataDynamic(true)
                 .setSearchDataFn { ArgumentPageModel.genIntParamSearchData() }
                 .setUiLayoutFn {
@@ -90,8 +88,6 @@
             owner = createSettingsPage(arguments),
             displayName = "${name}_$stringParam",
         )
-            // Set attributes
-            .setIsAllowSearch(false)
             .setSearchDataFn { ArgumentPageModel.genInjectSearchData() }
             .setUiLayoutFn {
                 // Set ui rendering
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt
index 160e77b..7f21a4d 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt
@@ -134,7 +134,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt
index c903cfd..9f24ea9 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt
@@ -20,6 +20,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.common.EntrySearchData
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPage
@@ -42,7 +43,7 @@
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "Some Preference", owner)
-                .setIsAllowSearch(true)
+                .setSearchDataFn { EntrySearchData(title = "Some Preference") }
                 .setUiLayoutFn {
                     Preference(remember {
                         object : PreferenceModel {
@@ -58,7 +59,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt
index e10cf3a..ddf66aa 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt
@@ -72,7 +72,6 @@
 
      fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt
index c354930..4332a81 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt
@@ -46,7 +46,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt
index 1f76557..20d90dd 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt
@@ -48,7 +48,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt
index cb58a95..c0d0abc 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt
@@ -40,7 +40,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
index 73b34a5..a62ec7b 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
@@ -48,7 +48,6 @@
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create("Simple Slider", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SliderPreference(object : SliderPreferenceModel {
                         override val title = "Simple Slider"
@@ -58,7 +57,6 @@
         )
         entryList.add(
             SettingsEntryBuilder.create("Slider with icon", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SliderPreference(object : SliderPreferenceModel {
                         override val title = "Slider with icon"
@@ -72,7 +70,6 @@
         )
         entryList.add(
             SettingsEntryBuilder.create("Slider with changeable icon", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     val initValue = 0
                     var icon by remember { mutableStateOf(Icons.Outlined.MusicOff) }
@@ -93,7 +90,6 @@
         )
         entryList.add(
             SettingsEntryBuilder.create("Slider with steps", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SliderPreference(object : SliderPreferenceModel {
                         override val title = "Slider with steps"
@@ -109,7 +105,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt
index f38a8d4..67e35dc 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt
@@ -44,14 +44,12 @@
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "MainSwitchPreference", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleMainSwitchPreference()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "MainSwitchPreference not changeable", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleNotChangeableMainSwitchPreference()
                 }.build()
@@ -62,7 +60,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt
index 61925a7..eddede7 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt
@@ -43,7 +43,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = owner)
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
index ff89f2b..0c9a043 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
@@ -87,7 +87,6 @@
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             createEntry(EntryEnum.SIMPLE_PREFERENCE)
-                .setIsAllowSearch(true)
                 .setMacro {
                     spaLogger.message(TAG, "create macro for ${EntryEnum.SIMPLE_PREFERENCE}")
                     SimplePreferenceMacro(title = SIMPLE_PREFERENCE_TITLE)
@@ -96,7 +95,6 @@
         )
         entryList.add(
             createEntry(EntryEnum.SUMMARY_PREFERENCE)
-                .setIsAllowSearch(true)
                 .setMacro {
                     spaLogger.message(TAG, "create macro for ${EntryEnum.SUMMARY_PREFERENCE}")
                     SimplePreferenceMacro(
@@ -110,7 +108,6 @@
         entryList.add(singleLineSummaryEntry())
         entryList.add(
             createEntry(EntryEnum.DISABLED_PREFERENCE)
-                .setIsAllowSearch(true)
                 .setHasMutableStatus(true)
                 .setMacro {
                     spaLogger.message(TAG, "create macro for ${EntryEnum.DISABLED_PREFERENCE}")
@@ -126,7 +123,6 @@
         )
         entryList.add(
             createEntry(EntryEnum.ASYNC_SUMMARY_PREFERENCE)
-                .setIsAllowSearch(true)
                 .setHasMutableStatus(true)
                 .setSearchDataFn {
                     EntrySearchData(title = ASYNC_PREFERENCE_TITLE)
@@ -165,7 +161,6 @@
         )
         entryList.add(
             createEntry(EntryEnum.MANUAL_UPDATE_PREFERENCE)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     val model = PreferencePageModel.create()
                     val manualUpdaterSummary = remember { model.getManualUpdaterSummary() }
@@ -179,7 +174,8 @@
                             }
                         }
                     )
-                }.setSliceDataFn { sliceUri, args ->
+                }
+                .setSliceDataFn { sliceUri, args ->
                     val createSliceImpl = { v: Int ->
                         createDemoActionSlice(
                             sliceUri = sliceUri,
@@ -204,7 +200,6 @@
         )
         entryList.add(
             createEntry(EntryEnum.AUTO_UPDATE_PREFERENCE)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     val model = PreferencePageModel.create()
                     val autoUpdaterSummary = remember { model.getAutoUpdaterSummary() }
@@ -251,7 +246,6 @@
     }
 
     private fun singleLineSummaryEntry() = createEntry(EntryEnum.SINGLE_LINE_SUMMARY_PREFERENCE)
-        .setIsAllowSearch(true)
         .setUiLayoutFn {
             Preference(
                 model = object : PreferenceModel {
@@ -267,7 +261,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = owner)
-            .setIsAllowSearch(true)
             .setMacro {
                 spaLogger.message(TAG, "create macro for INJECT entry")
                 SimplePreferenceMacro(
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt
index dab04fd..067911c 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt
@@ -49,35 +49,30 @@
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "SwitchPreference", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleSwitchPreference()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "SwitchPreference with summary", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleSwitchPreferenceWithSummary()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "SwitchPreference with async summary", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleSwitchPreferenceWithAsyncSummary()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "SwitchPreference not changeable", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleNotChangeableSwitchPreference()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "SwitchPreference with icon", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleSwitchPreferenceWithIcon()
                 }.build()
@@ -88,7 +83,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt
index 22da99c..33e5e8d 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt
@@ -46,28 +46,24 @@
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "TwoTargetSwitchPreference", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleTwoTargetSwitchPreference()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "TwoTargetSwitchPreference with summary", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleTwoTargetSwitchPreferenceWithSummary()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "TwoTargetSwitchPreference with async summary", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleTwoTargetSwitchPreferenceWithAsyncSummary()
                 }.build()
         )
         entryList.add(
             SettingsEntryBuilder.create( "TwoTargetSwitchPreference not changeable", owner)
-                .setIsAllowSearch(true)
                 .setUiLayoutFn {
                     SampleNotChangeableTwoTargetSwitchPreference()
                 }.build()
@@ -78,7 +74,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt
index d87cbe8..cb58abf6 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt
@@ -39,7 +39,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
index ec2f436..ba769d2 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
@@ -40,7 +40,6 @@
 
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
-            .setIsAllowSearch(true)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt
index bb1cd6e..76f6611 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.spaprivileged.framework.common
 
+import android.app.ActivityManager
 import android.app.AlarmManager
 import android.app.AppOpsManager
 import android.app.admin.DevicePolicyManager
@@ -28,6 +29,9 @@
 import android.os.UserManager
 import android.permission.PermissionControllerManager
 
+/** The [ActivityManager] instance. */
+val Context.activityManager get() = getSystemService(ActivityManager::class.java)!!
+
 /** The [AlarmManager] instance. */
 val Context.alarmManager get() = getSystemService(AlarmManager::class.java)!!
 
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 2e0155b..caaa88d 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1105,6 +1105,8 @@
     <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> left until full</string>
     <!-- [CHAR_LIMIT=80] Label for battery level chart when charge been limited -->
     <string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Charging is paused</string>
+    <!-- [CHAR_LIMIT=80] Label for battery charging future pause -->
+    <string name="power_charging_future_paused"><xliff:g id="level">%1$s</xliff:g> - Charging to <xliff:g id="dock_defender_threshold">%2$s</xliff:g></string>
 
     <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="battery_info_status_unknown">Unknown</string>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 8609e4a..10d31ea 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -972,13 +972,8 @@
 
         if (imageData.uri != null) {
             if (!imageData.owner.equals(Process.myUserHandle())) {
-                // TODO: Handle non-primary user ownership (e.g. Work Profile)
-                // This image is owned by another user. Special treatment will be
-                // required in the UI (badging) as well as sending intents which can
-                // correctly forward those URIs on to be read (actions).
-
-                Log.d(TAG, "*** Screenshot saved to a non-primary user ("
-                        + imageData.owner + ") as " + imageData.uri);
+                Log.d(TAG, "Screenshot saved to user " + imageData.owner + " as "
+                        + imageData.uri);
             }
             mScreenshotHandler.post(() -> {
                 if (mScreenshotAnimation != null && mScreenshotAnimation.isRunning()) {
@@ -1059,6 +1054,11 @@
                     R.string.screenshot_failed_to_save_text);
         } else {
             mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED, 0, mPackageName);
+            if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)
+                    && mUserManager.isManagedProfile(imageData.owner.getIdentifier())) {
+                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED_TO_WORK_PROFILE, 0,
+                        mPackageName);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index a3d9965..7fbdeca 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -2072,13 +2072,6 @@
                 mInitialTouchX = x;
                 initVelocityTracker();
                 trackMovement(event);
-                float qsExpansionFraction = computeQsExpansionFraction();
-                // Intercept the touch if QS is between fully collapsed and fully expanded state
-                if (qsExpansionFraction > 0.0 && qsExpansionFraction < 1.0) {
-                    mShadeLog.logMotionEvent(event,
-                            "onQsIntercept: down action, QS partially expanded/collapsed");
-                    return true;
-                }
                 if (mKeyguardShowing
                         && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) {
                     // Dragging down on the lockscreen statusbar should prohibit other interactions
@@ -2331,13 +2324,6 @@
         if (!isFullyCollapsed()) {
             handleQsDown(event);
         }
-        // defer touches on QQS to shade while shade is collapsing. Added margin for error
-        // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS.
-        if (computeQsExpansionFraction() <= 0.01 && getExpandedFraction() < 1.0) {
-            mShadeLog.logMotionEvent(event,
-                    "handleQsTouch: QQS touched while shade collapsing");
-            mQsTracking = false;
-        }
         if (!mQsExpandImmediate && mQsTracking) {
             onQsTouch(event);
             if (!mConflictingQsExpansionGesture && !mSplitShadeEnabled) {
@@ -2578,6 +2564,7 @@
         // Reset scroll position and apply that position to the expanded height.
         float height = mQsExpansionHeight;
         setQsExpansionHeight(height);
+        updateExpandedHeightToMaxHeight();
         mNotificationStackScrollLayoutController.checkSnoozeLeavebehind();
 
         // When expanding QS, let's authenticate the user if possible,
diff --git a/services/OWNERS b/services/OWNERS
index 495c0737..eace906 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -3,7 +3,7 @@
 # art-team@ manages the system server profile
 per-file art-profile* = calin@google.com, ngeoffray@google.com, vmarko@google.com
 
-per-file java/com/android/server/* = toddke@google.com,patb@google.com
+per-file java/com/android/server/* = patb@google.com #{LAST_RESORT_SUGGESTION}
 per-file tests/servicestests/src/com/android/server/systemconfig/* = patb@google.com
 
 per-file proguard.flags = jdduke@google.com
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 30d4b8b..ca86021c 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -52,8 +52,8 @@
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.BarringInfo;
+import android.telephony.CallAttributes;
 import android.telephony.CallQuality;
-import android.telephony.CallState;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.CellSignalStrength;
@@ -82,7 +82,6 @@
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.telephony.emergency.EmergencyNumber;
-import android.telephony.ims.ImsCallSession;
 import android.telephony.ims.ImsReasonInfo;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -350,9 +349,9 @@
 
     private CallQuality[] mCallQuality;
 
-    private ArrayList<List<CallState>> mCallStateLists;
+    private CallAttributes[] mCallAttributes;
 
-    // network type of the call associated with the mCallStateLists and mCallQuality
+    // network type of the call associated with the mCallAttributes and mCallQuality
     private int[] mCallNetworkType;
 
     private int[] mSrvccState;
@@ -688,6 +687,7 @@
             mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
             mCallQuality = copyOf(mCallQuality, mNumPhones);
             mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
+            mCallAttributes = copyOf(mCallAttributes, mNumPhones);
             mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
             mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
             mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
@@ -707,7 +707,6 @@
                 cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
                 cutListToSize(mCarrierPrivilegeStates, mNumPhones);
                 cutListToSize(mCarrierServiceStates, mNumPhones);
-                cutListToSize(mCallStateLists, mNumPhones);
                 return;
             }
 
@@ -731,7 +730,8 @@
                 mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
                 mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
                 mCallQuality[i] = createCallQuality();
-                mCallStateLists.add(i, new ArrayList<>());
+                mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
+                        TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
                 mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
                 mPreciseCallState[i] = createPreciseCallState();
                 mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
@@ -799,7 +799,7 @@
         mCallPreciseDisconnectCause = new int[numPhones];
         mCallQuality = new CallQuality[numPhones];
         mCallNetworkType = new int[numPhones];
-        mCallStateLists = new ArrayList<>();
+        mCallAttributes = new CallAttributes[numPhones];
         mPreciseDataConnectionStates = new ArrayList<>();
         mCellInfo = new ArrayList<>(numPhones);
         mImsReasonInfo = new ArrayList<>();
@@ -837,7 +837,8 @@
             mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
             mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
             mCallQuality[i] = createCallQuality();
-            mCallStateLists.add(i, new ArrayList<>());
+            mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
+                    TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
             mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
             mPreciseCallState[i] = createPreciseCallState();
             mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
@@ -1335,7 +1336,7 @@
                 }
                 if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) {
                     try {
-                        r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId));
+                        r.callback.onCallAttributesChanged(mCallAttributes[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -2170,30 +2171,11 @@
         }
     }
 
-    /**
-     * Send a notification to registrants that the precise call state has changed.
-     *
-     * @param phoneId the phoneId carrying the data connection
-     * @param subId the subscriptionId for the data connection
-     * @param callStates Array of PreciseCallState of foreground, background & ringing calls.
-     * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId()} for
-     *                   ringing, foreground & background calls.
-     * @param imsServiceTypes Array of IMS call service type for ringing, foreground &
-     *                        background calls.
-     * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls.
-     */
-    public void notifyPreciseCallState(int phoneId, int subId,
-            @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds,
-            @Annotation.ImsCallServiceType int[] imsServiceTypes,
-            @Annotation.ImsCallType int[] imsCallTypes) {
+    public void notifyPreciseCallState(int phoneId, int subId, int ringingCallState,
+                                       int foregroundCallState, int backgroundCallState) {
         if (!checkNotifyPermission("notifyPreciseCallState()")) {
             return;
         }
-
-        int ringingCallState = callStates[CallState.CALL_CLASSIFICATION_RINGING];
-        int foregroundCallState = callStates[CallState.CALL_CLASSIFICATION_FOREGROUND];
-        int backgroundCallState = callStates[CallState.CALL_CLASSIFICATION_BACKGROUND];
-
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
                 mRingingCallState[phoneId] = ringingCallState;
@@ -2204,11 +2186,11 @@
                         backgroundCallState,
                         DisconnectCause.NOT_VALID,
                         PreciseDisconnectCause.NOT_VALID);
-                boolean notifyCallState = true;
+                boolean notifyCallAttributes = true;
                 if (mCallQuality == null) {
                     log("notifyPreciseCallState: mCallQuality is null, "
                             + "skipping call attributes");
-                    notifyCallState = false;
+                    notifyCallAttributes = false;
                 } else {
                     // If the precise call state is no longer active, reset the call network type
                     // and call quality.
@@ -2217,54 +2199,8 @@
                         mCallNetworkType[phoneId] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
                         mCallQuality[phoneId] = createCallQuality();
                     }
-                    mCallStateLists.get(phoneId).clear();
-                    if (foregroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) {
-                        CallQuality callQuality = mCallQuality[phoneId];
-                        mCallStateLists.get(phoneId).add(
-                                new CallState.Builder(
-                                        callStates[CallState.CALL_CLASSIFICATION_FOREGROUND])
-                                        .setNetworkType(mCallNetworkType[phoneId])
-                                        .setCallQuality(callQuality)
-                                        .setCallClassification(
-                                                CallState.CALL_CLASSIFICATION_FOREGROUND)
-                                        .setImsCallSessionId(imsCallIds[
-                                                        CallState.CALL_CLASSIFICATION_FOREGROUND])
-                                        .setImsCallServiceType(imsServiceTypes[
-                                                CallState.CALL_CLASSIFICATION_FOREGROUND])
-                                        .setImsCallType(imsCallTypes[
-                                                CallState.CALL_CLASSIFICATION_FOREGROUND]).build());
-
-                    }
-                    if (backgroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) {
-                        mCallStateLists.get(phoneId).add(
-                                new CallState.Builder(
-                                        callStates[CallState.CALL_CLASSIFICATION_BACKGROUND])
-                                        .setNetworkType(mCallNetworkType[phoneId])
-                                        .setCallQuality(createCallQuality())
-                                        .setCallClassification(
-                                                CallState.CALL_CLASSIFICATION_BACKGROUND)
-                                        .setImsCallSessionId(imsCallIds[
-                                                CallState.CALL_CLASSIFICATION_BACKGROUND])
-                                        .setImsCallServiceType(imsServiceTypes[
-                                                CallState.CALL_CLASSIFICATION_BACKGROUND])
-                                        .setImsCallType(imsCallTypes[
-                                                CallState.CALL_CLASSIFICATION_BACKGROUND]).build());
-                    }
-                    if (ringingCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) {
-                        mCallStateLists.get(phoneId).add(
-                                new CallState.Builder(
-                                        callStates[CallState.CALL_CLASSIFICATION_RINGING])
-                                        .setNetworkType(mCallNetworkType[phoneId])
-                                        .setCallQuality(createCallQuality())
-                                        .setCallClassification(
-                                                CallState.CALL_CLASSIFICATION_RINGING)
-                                        .setImsCallSessionId(imsCallIds[
-                                                CallState.CALL_CLASSIFICATION_RINGING])
-                                        .setImsCallServiceType(imsServiceTypes[
-                                                CallState.CALL_CLASSIFICATION_RINGING])
-                                        .setImsCallType(imsCallTypes[
-                                                CallState.CALL_CLASSIFICATION_RINGING]).build());
-                    }
+                    mCallAttributes[phoneId] = new CallAttributes(mPreciseCallState[phoneId],
+                            mCallNetworkType[phoneId], mCallQuality[phoneId]);
                 }
 
                 for (Record r : mRecords) {
@@ -2277,11 +2213,11 @@
                             mRemoveList.add(r.binder);
                         }
                     }
-                    if (notifyCallState && r.matchTelephonyCallbackEvent(
+                    if (notifyCallAttributes && r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r, subId, phoneId)) {
                         try {
-                            r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+                            r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -2579,29 +2515,15 @@
                 // merge CallQuality with PreciseCallState and network type
                 mCallQuality[phoneId] = callQuality;
                 mCallNetworkType[phoneId] = callNetworkType;
-                if (mCallStateLists.get(phoneId).size() > 0
-                        && mCallStateLists.get(phoneId).get(0).getCallState()
-                        == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
-                    CallState prev = mCallStateLists.get(phoneId).remove(0);
-                    mCallStateLists.get(phoneId).add(
-                            0, new CallState.Builder(prev.getCallState())
-                                    .setNetworkType(callNetworkType)
-                                    .setCallQuality(callQuality)
-                                    .setCallClassification(prev.getCallClassification())
-                                    .setImsCallSessionId(prev.getImsCallSessionId())
-                                    .setImsCallServiceType(prev.getImsCallServiceType())
-                                    .setImsCallType(prev.getImsCallType()).build());
-                } else {
-                    log("There is no active call to report CallQaulity");
-                    return;
-                }
+                mCallAttributes[phoneId] = new CallAttributes(mPreciseCallState[phoneId],
+                        callNetworkType, callQuality);
 
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r, subId, phoneId)) {
                         try {
-                            r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+                            r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -3069,6 +2991,7 @@
                 pw.println("mSrvccState=" + mSrvccState[i]);
                 pw.println("mCallPreciseDisconnectCause=" + mCallPreciseDisconnectCause[i]);
                 pw.println("mCallQuality=" + mCallQuality[i]);
+                pw.println("mCallAttributes=" + mCallAttributes[i]);
                 pw.println("mCallNetworkType=" + mCallNetworkType[i]);
                 pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i));
                 pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 2669d21..8d247f6 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -140,9 +140,7 @@
 import com.android.server.location.provider.proxy.ProxyLocationProvider;
 import com.android.server.location.settings.LocationSettings;
 import com.android.server.location.settings.LocationUserSettings;
-import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.permission.LegacyPermissionManagerInternal;
-import com.android.server.utils.Slogf;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -310,10 +308,6 @@
         permissionManagerInternal.setLocationExtraPackagesProvider(
                 userId -> mContext.getResources().getStringArray(
                         com.android.internal.R.array.config_locationExtraPackageNames));
-
-        // TODO(b/241604546): properly handle this callback
-        LocalServices.getService(UserManagerInternal.class).addUserVisibilityListener(
-                (u, v) -> Slogf.i(TAG, "onUserVisibilityChanged(): %d -> %b", u, v));
     }
 
     @Nullable
@@ -1702,7 +1696,7 @@
 
         private final Context mContext;
 
-        private final UserInfoHelper mUserInfoHelper;
+        private final SystemUserInfoHelper mUserInfoHelper;
         private final LocationSettings mLocationSettings;
         private final AlarmHelper mAlarmHelper;
         private final SystemAppOpsHelper mAppOpsHelper;
@@ -1725,7 +1719,7 @@
         @GuardedBy("this")
         private boolean mSystemReady;
 
-        SystemInjector(Context context, UserInfoHelper userInfoHelper) {
+        SystemInjector(Context context, SystemUserInfoHelper userInfoHelper) {
             mContext = context;
 
             mUserInfoHelper = userInfoHelper;
@@ -1745,6 +1739,7 @@
         }
 
         synchronized void onSystemReady() {
+            mUserInfoHelper.onSystemReady();
             mAppOpsHelper.onSystemReady();
             mLocationPermissionsHelper.onSystemReady();
             mSettingsHelper.onSystemReady();
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index 45436e7..cb952ed 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -110,6 +110,11 @@
         addLog(new UserSwitchedEvent(userIdFrom, userIdTo));
     }
 
+    /** Logs a user visibility changed event. */
+    public void logUserVisibilityChanged(int userId, boolean visible) {
+        addLog(new UserVisibilityChangedEvent(userId, visible));
+    }
+
     /** Logs a location enabled/disabled event. */
     public void logLocationEnabled(int userId, boolean enabled) {
         addLog(new LocationEnabledEvent(userId, enabled));
@@ -475,6 +480,22 @@
         }
     }
 
+    private static final class UserVisibilityChangedEvent {
+
+        private final int mUserId;
+        private final boolean mVisible;
+
+        UserVisibilityChangedEvent(int userId, boolean visible) {
+            mUserId = userId;
+            mVisible = visible;
+        }
+
+        @Override
+        public String toString() {
+            return "[u" + mUserId + "] " + (mVisible ? "visible" : "invisible");
+        }
+    }
+
     private static final class LocationEnabledEvent {
 
         private final int mUserId;
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
index 0f5e3d4..d3ceddd 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
@@ -387,7 +387,7 @@
             if (!mSettingsHelper.isLocationEnabled(identity.getUserId())) {
                 return false;
             }
-            if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) {
+            if (!mUserInfoHelper.isVisibleUserId(identity.getUserId())) {
                 return false;
             }
             if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(),
@@ -534,7 +534,10 @@
     }
 
     void onUserChanged(int userId, int change) {
-        if (change == UserListener.CURRENT_USER_CHANGED) {
+        // current user changes affect whether system server location requests are allowed to access
+        // location, and visibility changes affect whether any given user may access location.
+        if (change == UserListener.CURRENT_USER_CHANGED
+                || change == UserListener.USER_VISIBILITY_CHANGED) {
             updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
         }
     }
diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
index 349b94b..567d8ac 100644
--- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
+++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
@@ -317,7 +317,7 @@
                     identity.getUserId())) {
                 return false;
             }
-            if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) {
+            if (!mUserInfoHelper.isVisibleUserId(identity.getUserId())) {
                 return false;
             }
             if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(),
@@ -394,7 +394,10 @@
     }
 
     private void onUserChanged(int userId, int change) {
-        if (change == UserListener.CURRENT_USER_CHANGED) {
+        // current user changes affect whether system server location requests are allowed to access
+        // location, and visibility changes affect whether any given user may access location.
+        if (change == UserListener.CURRENT_USER_CHANGED
+                || change == UserListener.USER_VISIBILITY_CHANGED) {
             updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
         }
     }
diff --git a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
index ed1e654..40dd979 100644
--- a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
@@ -33,9 +33,11 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
+import com.android.server.pm.UserManagerInternal;
 
 import java.io.FileDescriptor;
 import java.util.Arrays;
+import java.util.Objects;
 
 /**
  * Provides accessors and listeners for all user info.
@@ -50,11 +52,21 @@
     @Nullable private IActivityManager mActivityManager;
     @GuardedBy("this")
     @Nullable private UserManager mUserManager;
+    @GuardedBy("this")
+    @Nullable private UserManagerInternal mUserManagerInternal;
 
     public SystemUserInfoHelper(Context context) {
         mContext = context;
     }
 
+    /** The function should be called when PHASE_SYSTEM_SERVICES_READY. */
+    public synchronized void onSystemReady() {
+        mUserManagerInternal =
+                Objects.requireNonNull(LocalServices.getService(UserManagerInternal.class));
+        mUserManagerInternal.addUserVisibilityListener(
+                (userId, visible) -> dispatchOnVisibleUserChanged(userId, visible));
+    }
+
     @Nullable
     protected final ActivityManagerInternal getActivityManagerInternal() {
         synchronized (this) {
@@ -136,6 +148,24 @@
     }
 
     @Override
+    public boolean isVisibleUserId(@UserIdInt int userId) {
+        synchronized (this) {
+            // if you're hitting this precondition then you are invoking this before the system is
+            // ready
+            Preconditions.checkState(mUserManagerInternal != null);
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                return mUserManagerInternal.isUserVisible(userId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     protected int[] getProfileIds(@UserIdInt int userId) {
         UserManager userManager = getUserManager();
 
diff --git a/services/core/java/com/android/server/location/injector/UserInfoHelper.java b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
index c835370..2b9db1c 100644
--- a/services/core/java/com/android/server/location/injector/UserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
@@ -22,6 +22,7 @@
 import static com.android.server.location.injector.UserInfoHelper.UserListener.CURRENT_USER_CHANGED;
 import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STARTED;
 import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STOPPED;
+import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_VISIBILITY_CHANGED;
 
 import android.annotation.IntDef;
 import android.annotation.UserIdInt;
@@ -47,8 +48,9 @@
         int CURRENT_USER_CHANGED = 1;
         int USER_STARTED = 2;
         int USER_STOPPED = 3;
+        int USER_VISIBILITY_CHANGED = 4;
 
-        @IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED})
+        @IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED, USER_VISIBILITY_CHANGED})
         @Retention(RetentionPolicy.SOURCE)
         @interface UserChange {}
 
@@ -121,6 +123,18 @@
         }
     }
 
+    protected final void dispatchOnVisibleUserChanged(@UserIdInt int userId, boolean visible) {
+        if (D) {
+            Log.d(TAG, "visibility of u" + userId + " changed to "
+                    + (visible ? "visible" : "invisible"));
+        }
+        EVENT_LOG.logUserVisibilityChanged(userId, visible);
+
+        for (UserListener listener : mListeners) {
+            listener.onUserChanged(userId, USER_VISIBILITY_CHANGED);
+        }
+    }
+
     /**
      * Returns an array of running user ids. This will include all running users, and will also
      * include any profiles of the running users. The caller must never mutate the returned
@@ -129,8 +143,8 @@
     public abstract int[] getRunningUserIds();
 
     /**
-     * Returns true if the given user id is either the current user or a profile of the current
-     * user.
+     * Returns {@code true} if the given user id is either the current user or a profile of the
+     * current user.
      */
     public abstract boolean isCurrentUserId(@UserIdInt int userId);
 
@@ -140,6 +154,13 @@
      */
     public abstract @UserIdInt int getCurrentUserId();
 
+    /**
+     * Returns {@code true} if the user is visible.
+     *
+     * <p>The visibility of a user is defined by {@link android.os.UserManager#isUserVisible()}.
+     */
+    public abstract boolean isVisibleUserId(@UserIdInt int userId);
+
     protected abstract int[] getProfileIds(@UserIdInt int userId);
 
     /**
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 338a995..7063cb8 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -661,6 +661,8 @@
                 if (!GPS_PROVIDER.equals(mName)) {
                     Log.e(TAG, "adas gnss bypass request received in non-gps provider");
                     adasGnssBypass = false;
+                } else if (!mUserHelper.isCurrentUserId(getIdentity().getUserId())) {
+                    adasGnssBypass = false;
                 } else if (!mLocationSettings.getUserSettings(
                         getIdentity().getUserId()).isAdasGnssLocationEnabled()) {
                     adasGnssBypass = false;
@@ -1712,6 +1714,8 @@
             if (!GPS_PROVIDER.equals(mName)) {
                 Log.e(TAG, "adas gnss bypass request received in non-gps provider");
                 adasGnssBypass = false;
+            } else if (!mUserHelper.isCurrentUserId(identity.getUserId())) {
+                adasGnssBypass = false;
             } else if (!mLocationSettings.getUserSettings(
                     identity.getUserId()).isAdasGnssLocationEnabled()) {
                 adasGnssBypass = false;
@@ -2193,7 +2197,7 @@
                 if (!isEnabled(identity.getUserId())) {
                     return false;
                 }
-                if (!mUserHelper.isCurrentUserId(identity.getUserId())) {
+                if (!mUserHelper.isVisibleUserId(identity.getUserId())) {
                     return false;
                 }
             }
@@ -2322,6 +2326,10 @@
 
             switch (change) {
                 case UserListener.CURRENT_USER_CHANGED:
+                    // current user changes affect whether system server location requests are
+                    // allowed to access location, and visibility changes affect whether any given
+                    // user may access location.
+                case UserListener.USER_VISIBILITY_CHANGED:
                     updateRegistrations(
                             registration -> registration.getIdentity().getUserId() == userId);
                     break;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 3bb0238..14d6d7b 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
@@ -226,9 +227,8 @@
 
             mBackAnimationInProgress = true;
             // We don't have an application callback, let's find the destination of the back gesture
-            Task finalTask = currentTask;
-            prevActivity = currentTask.getActivity(
-                    (r) -> !r.finishing && r.getTask() == finalTask && !r.isTopRunningActivity());
+            // The search logic should align with ActivityClientController#finishActivity
+            prevActivity = currentTask.topRunningActivity(currentActivity.token, INVALID_TASK_ID);
             // TODO Dialog window does not need to attach on activity, check
             // window.mAttrs.type != TYPE_BASE_APPLICATION
             if ((window.getParent().getChildCount() > 1
@@ -244,12 +244,14 @@
             } else if (currentTask.returnsToHomeRootTask()) {
                 // Our Task should bring back to home
                 removedWindowContainer = currentTask;
+                prevTask = currentTask.getDisplayArea().getRootHomeTask();
                 backType = BackNavigationInfo.TYPE_RETURN_TO_HOME;
                 mShowWallpaper = true;
             } else if (currentActivity.isRootOfTask()) {
                 // TODO(208789724): Create single source of truth for this, maybe in
                 //  RootWindowContainer
-                prevTask = currentTask.mRootWindowContainer.getTaskBelow(currentTask);
+                prevTask = currentTask.mRootWindowContainer.getTask(Task::showToCurrentUser,
+                        currentTask, false /*includeBoundary*/, true /*traverseTopToBottom*/);
                 removedWindowContainer = currentTask;
                 // If it reaches the top activity, we will check the below task from parent.
                 // If it's null or multi-window, fallback the type to TYPE_CALLBACK.
@@ -423,6 +425,11 @@
 
         void reset(@NonNull WindowContainer close, @NonNull WindowContainer open) {
             clearBackAnimateTarget(null);
+            if (close == null || open == null) {
+                Slog.e(TAG, "reset animation with null target close: "
+                        + close + " open: " + open);
+                return;
+            }
             if (close.asActivityRecord() != null && open.asActivityRecord() != null
                     && (close.asActivityRecord().getTask() == open.asActivityRecord().getTask())) {
                 mSwitchType = ACTIVITY_SWITCH;
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 30fcd06..d3b9e10 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -35,6 +35,7 @@
 import android.os.ICancellationSignal;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.credentials.BeginCreateCredentialRequest;
 import android.service.credentials.GetCredentialsRequest;
 import android.text.TextUtils;
 import android.util.Log;
@@ -199,7 +200,7 @@
             // Iterate over all provider sessions and invoke the request
             providerSessions.forEach(providerCreateSession -> {
                 providerCreateSession.getRemoteCredentialService().onCreateCredential(
-                        (android.service.credentials.CreateCredentialRequest)
+                        (BeginCreateCredentialRequest)
                                 providerCreateSession.getProviderRequest(),
                         /*callback=*/providerCreateSession);
             });
diff --git a/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java b/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
index 4cdc457..d0bc074 100644
--- a/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
+++ b/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
@@ -22,7 +22,7 @@
 import android.credentials.Credential;
 import android.credentials.ui.ProviderPendingIntentResponse;
 import android.service.credentials.CredentialProviderService;
-import android.service.credentials.CredentialsDisplayContent;
+import android.service.credentials.CredentialsResponseContent;
 
 /**
  * Helper class for setting up pending intent, and extracting objects from it.
@@ -37,14 +37,15 @@
         return pendingIntentResponse.getResultCode() == Activity.RESULT_OK;
     }
 
-    /** Extracts the {@link CredentialsDisplayContent} object added to the result data. */
-    public static CredentialsDisplayContent extractCredentialsDisplayContent(Intent resultData) {
+    /** Extracts the {@link CredentialsResponseContent} object added to the result data. */
+    public static CredentialsResponseContent extractResponseContent(Intent resultData) {
         if (resultData == null) {
             return null;
         }
         return resultData.getParcelableExtra(
-                CredentialProviderService.EXTRA_GET_CREDENTIALS_DISPLAY_CONTENT,
-                CredentialsDisplayContent.class);
+                CredentialProviderService
+                        .EXTRA_GET_CREDENTIALS_CONTENT_RESULT,
+                CredentialsResponseContent.class);
     }
 
     /** Extracts the {@link CreateCredentialResponse} object added to the result data. */
@@ -53,7 +54,7 @@
             return null;
         }
         return resultData.getParcelableExtra(
-                CredentialProviderService.EXTRA_CREATE_CREDENTIAL_RESPONSE,
+                CredentialProviderService.EXTRA_CREATE_CREDENTIAL_RESULT,
                 CreateCredentialResponse.class);
     }
 
@@ -63,7 +64,7 @@
             return null;
         }
         return resultData.getParcelableExtra(
-                CredentialProviderService.EXTRA_GET_CREDENTIAL,
+                CredentialProviderService.EXTRA_CREDENTIAL_RESULT,
                 Credential.class);
     }
 }
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index 6bb8c60..14fee78 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -26,11 +26,11 @@
 import android.credentials.ui.Entry;
 import android.credentials.ui.ProviderPendingIntentResponse;
 import android.os.Bundle;
-import android.service.credentials.CreateCredentialRequest;
-import android.service.credentials.CreateCredentialResponse;
+import android.service.credentials.BeginCreateCredentialRequest;
+import android.service.credentials.BeginCreateCredentialResponse;
+import android.service.credentials.CreateEntry;
 import android.service.credentials.CredentialProviderInfo;
 import android.service.credentials.CredentialProviderService;
-import android.service.credentials.SaveEntry;
 import android.util.Log;
 import android.util.Slog;
 
@@ -44,16 +44,16 @@
  * Will likely split this into remote response state and UI state.
  */
 public final class ProviderCreateSession extends ProviderSession<
-        CreateCredentialRequest, CreateCredentialResponse> {
+        BeginCreateCredentialRequest, BeginCreateCredentialResponse> {
     private static final String TAG = "ProviderCreateSession";
 
     // Key to be used as an entry key for a save entry
     private static final String SAVE_ENTRY_KEY = "save_entry_key";
 
     @NonNull
-    private final Map<String, SaveEntry> mUiSaveEntries = new HashMap<>();
+    private final Map<String, CreateEntry> mUiSaveEntries = new HashMap<>();
     /** The complete request to be used in the second round. */
-    private final CreateCredentialRequest mCompleteRequest;
+    private final BeginCreateCredentialRequest mCompleteRequest;
 
     /** Creates a new provider session to be used by the request session. */
     @Nullable public static ProviderCreateSession createNewSession(
@@ -62,7 +62,7 @@
             CredentialProviderInfo providerInfo,
             CreateRequestSession createRequestSession,
             RemoteCredentialService remoteCredentialService) {
-        CreateCredentialRequest providerRequest =
+        BeginCreateCredentialRequest providerRequest =
                 createProviderRequest(providerInfo.getCapabilities(),
                         createRequestSession.mClientRequest,
                         createRequestSession.mClientCallingPackage);
@@ -75,21 +75,23 @@
     }
 
     @Nullable
-    private static CreateCredentialRequest createProviderRequest(List<String> providerCapabilities,
+    private static BeginCreateCredentialRequest createProviderRequest(
+            List<String> providerCapabilities,
             android.credentials.CreateCredentialRequest clientRequest,
             String clientCallingPackage) {
         String capability = clientRequest.getType();
         if (providerCapabilities.contains(capability)) {
-            return new CreateCredentialRequest(clientCallingPackage, capability,
+            return new BeginCreateCredentialRequest(clientCallingPackage, capability,
                     clientRequest.getData());
         }
         Log.i(TAG, "Unable to create provider request - capabilities do not match");
         return null;
     }
 
-    private static CreateCredentialRequest getFirstRoundRequest(CreateCredentialRequest request) {
+    private static BeginCreateCredentialRequest getFirstRoundRequest(
+            BeginCreateCredentialRequest request) {
         // TODO: Replace with first round bundle from request when ready
-        return new CreateCredentialRequest(
+        return new BeginCreateCredentialRequest(
                 request.getCallingPackage(),
                 request.getType(),
                 new Bundle());
@@ -101,7 +103,7 @@
             @NonNull ProviderInternalCallback callbacks,
             @UserIdInt int userId,
             @NonNull RemoteCredentialService remoteCredentialService,
-            @NonNull CreateCredentialRequest request) {
+            @NonNull BeginCreateCredentialRequest request) {
         super(context, info, getFirstRoundRequest(request), callbacks, userId,
                 remoteCredentialService);
         // TODO : Replace with proper splitting of request
@@ -110,13 +112,13 @@
     }
 
     /** Returns the save entry maintained in state by this provider session. */
-    public SaveEntry getUiSaveEntry(String entryId) {
+    public CreateEntry getUiSaveEntry(String entryId) {
         return mUiSaveEntries.get(entryId);
     }
 
     @Override
     public void onProviderResponseSuccess(
-            @Nullable CreateCredentialResponse response) {
+            @Nullable BeginCreateCredentialResponse response) {
         Log.i(TAG, "in onProviderResponseSuccess");
         onUpdateResponse(response);
     }
@@ -138,7 +140,7 @@
         }
     }
 
-    private void onUpdateResponse(CreateCredentialResponse response) {
+    private void onUpdateResponse(BeginCreateCredentialResponse response) {
         Log.i(TAG, "updateResponse with save entries");
         mProviderResponse = response;
         updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
@@ -152,15 +154,15 @@
             Log.i(TAG, "In prepareUiData not in uiInvokingStatus");
             return null;
         }
-        final CreateCredentialResponse response = getProviderResponse();
+        final BeginCreateCredentialResponse response = getProviderResponse();
         if (response == null) {
             Log.i(TAG, "In prepareUiData response null");
             throw new IllegalStateException("Response must be in completion mode");
         }
-        if (response.getSaveEntries() != null) {
+        if (response.getCreateEntries() != null) {
             Log.i(TAG, "In prepareUiData save entries not null");
             return prepareUiProviderData(
-                    prepareUiSaveEntries(response.getSaveEntries()),
+                    prepareUiSaveEntries(response.getCreateEntries()),
                     null,
                     /*isDefaultProvider=*/false);
         }
@@ -192,24 +194,25 @@
         }
     }
 
-    private List<Entry> prepareUiSaveEntries(@NonNull List<SaveEntry> saveEntries) {
+    private List<Entry> prepareUiSaveEntries(@NonNull List<CreateEntry> saveEntries) {
         Log.i(TAG, "in populateUiSaveEntries");
         List<Entry> uiSaveEntries = new ArrayList<>();
 
         // Populate the save entries
-        for (SaveEntry saveEntry : saveEntries) {
+        for (CreateEntry createEntry : saveEntries) {
             String entryId = generateEntryId();
-            mUiSaveEntries.put(entryId, saveEntry);
+            mUiSaveEntries.put(entryId, createEntry);
             Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId);
-            uiSaveEntries.add(new Entry(SAVE_ENTRY_KEY, entryId, saveEntry.getSlice(),
-                    saveEntry.getPendingIntent(), setUpFillInIntent(saveEntry.getPendingIntent())));
+            uiSaveEntries.add(new Entry(SAVE_ENTRY_KEY, entryId, createEntry.getSlice(),
+                    createEntry.getPendingIntent(), setUpFillInIntent(
+                            createEntry.getPendingIntent())));
         }
         return uiSaveEntries;
     }
 
     private Intent setUpFillInIntent(PendingIntent pendingIntent) {
         Intent intent = pendingIntent.getIntent();
-        intent.putExtra(CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST_PARAMS,
+        intent.putExtra(CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST,
                 mCompleteRequest);
         return intent;
     }
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index d63cdeb..6cd011b 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -29,7 +29,7 @@
 import android.service.credentials.Action;
 import android.service.credentials.CredentialEntry;
 import android.service.credentials.CredentialProviderInfo;
-import android.service.credentials.CredentialsDisplayContent;
+import android.service.credentials.CredentialsResponseContent;
 import android.service.credentials.GetCredentialsRequest;
 import android.service.credentials.GetCredentialsResponse;
 import android.util.Log;
@@ -211,20 +211,20 @@
                     prepareUiAuthenticationAction(mProviderResponse.getAuthenticationAction()),
                     /*remoteEntry=*/null);
         }
-        if (mProviderResponse.getCredentialsDisplayContent() != null) {
-            Log.i(TAG, "In prepareUiData displayContent not null");
+        if (mProviderResponse.getCredentialsResponseContent() != null) {
+            Log.i(TAG, "In prepareUiData credentialsResponseContent not null");
             return prepareUiProviderData(prepareUiActionEntries(
-                            mProviderResponse.getCredentialsDisplayContent().getActions()),
-                    prepareUiCredentialEntries(mProviderResponse.getCredentialsDisplayContent()
+                            mProviderResponse.getCredentialsResponseContent().getActions()),
+                    prepareUiCredentialEntries(mProviderResponse.getCredentialsResponseContent()
                             .getCredentialEntries()),
                     /*authenticationAction=*/null,
                     prepareUiRemoteEntry(mProviderResponse
-                            .getCredentialsDisplayContent().getRemoteCredentialEntry()));
+                            .getCredentialsResponseContent().getRemoteCredentialEntry()));
         }
         return null;
     }
 
-    private Entry prepareUiRemoteEntry(Action remoteCredentialEntry) {
+    private Entry prepareUiRemoteEntry(CredentialEntry remoteCredentialEntry) {
         if (remoteCredentialEntry == null) {
             return null;
         }
@@ -316,11 +316,11 @@
             @Nullable ProviderPendingIntentResponse providerPendingIntentResponse) {
         if (providerPendingIntentResponse != null) {
             if (PendingIntentResultHandler.isSuccessfulResponse(providerPendingIntentResponse)) {
-                CredentialsDisplayContent content = PendingIntentResultHandler
-                        .extractCredentialsDisplayContent(providerPendingIntentResponse
+                CredentialsResponseContent content = PendingIntentResultHandler
+                        .extractResponseContent(providerPendingIntentResponse
                                 .getResultData());
                 if (content != null) {
-                    onUpdateResponse(GetCredentialsResponse.createWithDisplayContent(content));
+                    onUpdateResponse(GetCredentialsResponse.createWithResponseContent(content));
                     return;
                 }
             }
@@ -342,7 +342,7 @@
         if (response.getAuthenticationAction() != null) {
             Log.i(TAG , "updateResponse with authentication entry");
             updateStatusAndInvokeCallback(Status.REQUIRES_AUTHENTICATION);
-        } else if (response.getCredentialsDisplayContent() != null) {
+        } else if (response.getCredentialsResponseContent() != null) {
             Log.i(TAG , "updateResponse with credentialEntries");
             // TODO validate response
             updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java
index 4a07f0a..ac360bd 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java
@@ -23,7 +23,7 @@
 import android.credentials.Credential;
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.ProviderPendingIntentResponse;
-import android.service.credentials.Action;
+import android.service.credentials.CredentialEntry;
 import android.service.credentials.CredentialProviderException;
 import android.service.credentials.CredentialProviderInfo;
 import android.util.Pair;
@@ -50,7 +50,7 @@
     @Nullable protected Credential mFinalCredentialResponse;
     @NonNull protected final T mProviderRequest;
     @Nullable protected R mProviderResponse;
-    @Nullable protected Pair<String, Action> mUiRemoteEntry;
+    @Nullable protected Pair<String, CredentialEntry> mUiRemoteEntry;
 
     /**
      * Returns true if the given status reflects that the provider state is ready to be shown
diff --git a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
index c2464b5..e385bcb 100644
--- a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
+++ b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
@@ -24,14 +24,14 @@
 import android.os.Handler;
 import android.os.ICancellationSignal;
 import android.os.RemoteException;
-import android.service.credentials.CreateCredentialRequest;
-import android.service.credentials.CreateCredentialResponse;
+import android.service.credentials.BeginCreateCredentialRequest;
+import android.service.credentials.BeginCreateCredentialResponse;
 import android.service.credentials.CredentialProviderException;
 import android.service.credentials.CredentialProviderException.CredentialProviderError;
 import android.service.credentials.CredentialProviderService;
 import android.service.credentials.GetCredentialsRequest;
 import android.service.credentials.GetCredentialsResponse;
-import android.service.credentials.ICreateCredentialCallback;
+import android.service.credentials.IBeginCreateCredentialCallback;
 import android.service.credentials.ICredentialProviderService;
 import android.service.credentials.IGetCredentialsCallback;
 import android.text.format.DateUtils;
@@ -146,27 +146,27 @@
                 handleExecutionResponse(result, error, cancellationSink, callback)));
     }
 
-    /** Main entry point to be called for executing a createCredential call on the remote
+    /** Main entry point to be called for executing a beginCreateCredential call on the remote
      * provider service.
      * @param request the request to be sent to the provider
      * @param callback the callback to be used to send back the provider response to the
      *                 {@link ProviderCreateSession} class that maintains provider state
      */
-    public void onCreateCredential(@NonNull CreateCredentialRequest request,
-            ProviderCallbacks<CreateCredentialResponse> callback) {
+    public void onCreateCredential(@NonNull BeginCreateCredentialRequest request,
+            ProviderCallbacks<BeginCreateCredentialResponse> callback) {
         Log.i(TAG, "In onCreateCredential in RemoteCredentialService");
         AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
-        AtomicReference<CompletableFuture<CreateCredentialResponse>> futureRef =
+        AtomicReference<CompletableFuture<BeginCreateCredentialResponse>> futureRef =
                 new AtomicReference<>();
 
-        CompletableFuture<CreateCredentialResponse> connectThenExecute = postAsync(service -> {
-            CompletableFuture<CreateCredentialResponse> createCredentialFuture =
+        CompletableFuture<BeginCreateCredentialResponse> connectThenExecute = postAsync(service -> {
+            CompletableFuture<BeginCreateCredentialResponse> createCredentialFuture =
                     new CompletableFuture<>();
-            ICancellationSignal cancellationSignal = service.onCreateCredential(
-                    request, new ICreateCredentialCallback.Stub() {
+            ICancellationSignal cancellationSignal = service.onBeginCreateCredential(
+                    request, new IBeginCreateCredentialCallback.Stub() {
                         @Override
-                        public void onSuccess(CreateCredentialResponse response) {
-                            Log.i(TAG, "In onSuccess onCreateCredential "
+                        public void onSuccess(BeginCreateCredentialResponse response) {
+                            Log.i(TAG, "In onSuccess onBeginCreateCredential "
                                     + "in RemoteCredentialService");
                             createCredentialFuture.complete(response);
                         }
@@ -179,7 +179,7 @@
                             createCredentialFuture.completeExceptionally(
                                     new CredentialProviderException(errorCode, errorMsg));
                         }});
-            CompletableFuture<CreateCredentialResponse> future = futureRef.get();
+            CompletableFuture<BeginCreateCredentialResponse> future = futureRef.get();
             if (future != null && future.isCancelled()) {
                 dispatchCancellationSignal(cancellationSignal);
             } else {
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
index ac23d4e..014ef3d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
@@ -34,14 +34,16 @@
     public static final int DEFAULT_USERID = 0;
 
     private final IntArray mRunningUserIds;
+    private final IntArray mVisibleUserIds;
     private final SparseArray<IntArray> mProfiles;
 
     private int mCurrentUserId;
 
     public FakeUserInfoHelper() {
         mCurrentUserId = DEFAULT_USERID;
-        mRunningUserIds = IntArray.wrap(new int[]{DEFAULT_USERID});
+        mRunningUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
         mProfiles = new SparseArray<>();
+        mVisibleUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
     }
 
     public void startUser(int userId) {
@@ -65,6 +67,7 @@
             mRunningUserIds.remove(idx);
         }
 
+        setUserInvisibleInternal(userId);
         dispatchOnUserStopped(userId);
     }
 
@@ -82,16 +85,39 @@
         // ensure all profiles are started if they didn't exist before...
         for (int userId : currentProfileUserIds) {
             startUserInternal(userId, false);
+            setUserVisibleInternal(userId, true);
         }
 
         if (oldUserId != mCurrentUserId) {
             dispatchOnCurrentUserChanged(oldUserId, mCurrentUserId);
+            setUserVisibleInternal(mCurrentUserId, true);
         }
     }
 
-    @Override
-    public int[] getRunningUserIds() {
-        return mRunningUserIds.toArray();
+    private void setUserVisibleInternal(int userId, boolean alwaysDispatch) {
+        int idx = mVisibleUserIds.indexOf(userId);
+        if (idx < 0) {
+            mVisibleUserIds.add(userId);
+        } else if (!alwaysDispatch) {
+            return;
+        }
+        dispatchOnVisibleUserChanged(userId, true);
+    }
+
+    private void setUserInvisibleInternal(int userId) {
+        int idx = mVisibleUserIds.indexOf(userId);
+        if (idx >= 0) {
+            mVisibleUserIds.remove(userId);
+        }
+        dispatchOnVisibleUserChanged(userId, false);
+    }
+
+    public void setUserVisible(int userId, boolean visible) {
+        if (visible) {
+            setUserVisibleInternal(userId, true);
+        } else {
+            setUserInvisibleInternal(userId);
+        }
     }
 
     @Override
@@ -100,11 +126,21 @@
     }
 
     @Override
+    public int[] getRunningUserIds() {
+        return mRunningUserIds.toArray();
+    }
+
+    @Override
     public int getCurrentUserId() {
         return mCurrentUserId;
     }
 
     @Override
+    public boolean isVisibleUserId(int userId) {
+        return mVisibleUserIds.indexOf(userId) >= 0;
+    }
+
+    @Override
     protected int[] getProfileIds(int userId) {
         IntArray profiles = mProfiles.get(userId);
         if (profiles != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
index 490b2e8..d9aa232 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.location.injector;
 
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -31,6 +32,7 @@
 
 import com.android.server.LocalServices;
 import com.android.server.location.injector.UserInfoHelper.UserListener;
+import com.android.server.pm.UserManagerInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -45,13 +47,14 @@
 
     private static final int USER1_ID = 1;
     private static final int USER1_MANAGED_ID = 11;
-    private static final int[] USER1_PROFILES = new int[]{USER1_ID, USER1_MANAGED_ID};
+    private static final int[] USER1_PROFILES = new int[] {USER1_ID, USER1_MANAGED_ID};
     private static final int USER2_ID = 2;
     private static final int USER2_MANAGED_ID = 12;
-    private static final int[] USER2_PROFILES = new int[]{USER2_ID, USER2_MANAGED_ID};
+    private static final int[] USER2_PROFILES = new int[] {USER2_ID, USER2_MANAGED_ID};
 
     @Mock private Context mContext;
     @Mock private UserManager mUserManager;
+    @Mock private UserManagerInternal mUserManagerInternal;
 
     private SystemUserInfoHelper mHelper;
 
@@ -63,12 +66,15 @@
         doReturn(USER1_PROFILES).when(mUserManager).getEnabledProfileIds(USER1_ID);
         doReturn(USER2_PROFILES).when(mUserManager).getEnabledProfileIds(USER2_ID);
 
+        LocalServices.addService(UserManagerInternal.class, mUserManagerInternal);
+
         mHelper = new SystemUserInfoHelper(mContext);
     }
 
     @After
     public void tearDown() {
         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+        LocalServices.removeServiceForTest(UserManagerInternal.class);
     }
 
     @Test
@@ -77,11 +83,11 @@
         mHelper.addListener(listener);
 
         mHelper.dispatchOnCurrentUserChanged(USER1_ID, USER2_ID);
-        verify(listener, times(1)).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED);
-        verify(listener, times(1)).onUserChanged(USER1_MANAGED_ID,
+        verify(listener).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED);
+        verify(listener).onUserChanged(USER1_MANAGED_ID,
                 UserListener.CURRENT_USER_CHANGED);
-        verify(listener, times(1)).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED);
-        verify(listener, times(1)).onUserChanged(USER2_MANAGED_ID,
+        verify(listener).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED);
+        verify(listener).onUserChanged(USER2_MANAGED_ID,
                 UserListener.CURRENT_USER_CHANGED);
 
         mHelper.dispatchOnCurrentUserChanged(USER2_ID, USER1_ID);
@@ -94,6 +100,25 @@
     }
 
     @Test
+    public void testListener_UserVisibilityChanged() {
+        mHelper.onSystemReady();
+        verify(mUserManagerInternal).addUserVisibilityListener(any());
+
+        UserListener listener = mock(UserListener.class);
+        mHelper.addListener(listener);
+
+        mHelper.dispatchOnVisibleUserChanged(USER1_ID, false);
+        mHelper.dispatchOnVisibleUserChanged(USER2_ID, true);
+        verify(listener).onUserChanged(USER1_ID, UserListener.USER_VISIBILITY_CHANGED);
+        verify(listener).onUserChanged(USER2_ID, UserListener.USER_VISIBILITY_CHANGED);
+
+        mHelper.dispatchOnVisibleUserChanged(USER2_ID, false);
+        mHelper.dispatchOnVisibleUserChanged(USER1_ID, true);
+        verify(listener, times(2)).onUserChanged(USER2_ID, UserListener.USER_VISIBILITY_CHANGED);
+        verify(listener, times(2)).onUserChanged(USER1_ID, UserListener.USER_VISIBILITY_CHANGED);
+    }
+
+    @Test
     public void testListener_StartUser() {
         UserListener listener = mock(UserListener.class);
         mHelper.addListener(listener);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index 20e4e80..aa28ad4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -175,7 +175,9 @@
         doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
 
         mInjector = new TestInjector(mContext);
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
         mInjector.getUserInfoHelper().startUser(OTHER_USER);
+        mInjector.getUserInfoHelper().setUserVisible(OTHER_USER, true);
 
         mPassive = new PassiveLocationProviderManager(mContext, mInjector);
         mPassive.startManager(null);
@@ -331,6 +333,20 @@
     }
 
     @Test
+    public void testGetLastLocation_InvisibleUser() {
+        Location loc = createLocation(NAME, mRandom);
+        mProvider.setProviderLocation(loc);
+
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
+
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc);
+    }
+
+    @Test
     public void testGetLastLocation_Bypass() {
         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
                 new PackageTagsList.Builder().add(
@@ -569,6 +585,25 @@
     }
 
     @Test
+    public void testRegisterListener_InvisibleUser() throws Exception {
+        ILocationListener listener = createMockLocationListener();
+        LocationRequest request = new LocationRequest.Builder(0)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
+
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+        mProvider.setProviderLocation(createLocationResult(NAME, mRandom));
+        verify(listener, never()).onLocationChanged(any(List.class),
+                nullable(IRemoteCallback.class));
+
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
+        LocationResult loc = createLocationResult(NAME, mRandom);
+        mProvider.setProviderLocation(loc);
+        verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
+    }
+
+    @Test
     public void testRegisterListener_ExpiringAlarm() throws Exception {
         ILocationListener listener = createMockLocationListener();
         LocationRequest request = new LocationRequest.Builder(0)
@@ -799,6 +834,17 @@
     }
 
     @Test
+    public void testGetCurrentLocation_InvisibleUser() throws Exception {
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+
+        ILocationCallback listener = createMockGetCurrentLocationListener();
+        LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
+        mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
+
+        verify(listener).onLocation(isNull());
+    }
+
+    @Test
     public void testFlush() throws Exception {
         ILocationListener listener = createMockLocationListener();
         mManager.registerLocationRequest(
@@ -1008,6 +1054,21 @@
     }
 
     @Test
+    public void testProviderRequest_InvisibleUser() {
+        ILocationListener listener = createMockLocationListener();
+        LocationRequest request = new LocationRequest.Builder(5)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
+
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+        assertThat(mProvider.getRequest().isActive()).isFalse();
+
+        mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
+        assertThat(mProvider.getRequest().isActive()).isTrue();
+    }
+
+    @Test
     public void testProviderRequest_IgnoreLocationSettings() {
         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
                 new PackageTagsList.Builder().add(
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index f3f56e0..dc3515d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -114,6 +114,20 @@
     }
 
     @Test
+    public void backTypeBackToHomeDifferentUser() {
+        Task taskA = createTask(mDefaultDisplay);
+        ActivityRecord recordA = createActivityRecord(taskA);
+        Mockito.doNothing().when(recordA).reparentSurfaceControl(any(), any());
+        doReturn(false).when(taskA).showToCurrentUser();
+
+        withSystemCallback(createTopTaskWithActivity());
+        BackNavigationInfo backNavigationInfo = startBackNavigation();
+        assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
+        assertThat(typeToString(backNavigationInfo.getType()))
+                .isEqualTo(typeToString(BackNavigationInfo.TYPE_RETURN_TO_HOME));
+    }
+
+    @Test
     public void backTypeCrossActivityWhenBackToPreviousActivity() {
         CrossActivityTestCase testCase = createTopTaskWithTwoActivities();
         IOnBackInvokedCallback callback = withSystemCallback(testCase.task);
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 2435243..86b98f1 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -5,7 +5,6 @@
 import android.net.NetworkCapabilities;
 import android.telecom.Connection;
 import android.telephony.data.ApnSetting;
-import android.telephony.ims.ImsCallProfile;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -495,7 +494,7 @@
             PreciseCallState.PRECISE_CALL_STATE_HOLDING,
             PreciseCallState.PRECISE_CALL_STATE_DIALING,
             PreciseCallState.PRECISE_CALL_STATE_ALERTING,
-            PreciseCallState.PRECISE_CALL_STATE_INCOMING,
+            PreciseCallState. PRECISE_CALL_STATE_INCOMING,
             PreciseCallState.PRECISE_CALL_STATE_WAITING,
             PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
             PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
@@ -728,36 +727,6 @@
     })
     public @interface ValidationStatus {}
 
-    /**
-     * IMS call Service types
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "SERVICE_TYPE_" }, value = {
-            ImsCallProfile.SERVICE_TYPE_NONE,
-            ImsCallProfile.SERVICE_TYPE_NORMAL,
-            ImsCallProfile.SERVICE_TYPE_EMERGENCY,
-    })
-    public @interface ImsCallServiceType {}
-
-    /**
-     * IMS call types
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "CALL_TYPE_" }, value = {
-            ImsCallProfile.CALL_TYPE_NONE,
-            ImsCallProfile.CALL_TYPE_VOICE_N_VIDEO,
-            ImsCallProfile.CALL_TYPE_VOICE,
-            ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE,
-            ImsCallProfile.CALL_TYPE_VT,
-            ImsCallProfile.CALL_TYPE_VT_TX,
-            ImsCallProfile.CALL_TYPE_VT_RX,
-            ImsCallProfile.CALL_TYPE_VT_NODIR,
-            ImsCallProfile.CALL_TYPE_VS,
-            ImsCallProfile.CALL_TYPE_VS_TX,
-            ImsCallProfile.CALL_TYPE_VS_RX,
-    })
-    public @interface ImsCallType {}
-
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = { "NET_CAPABILITY_ENTERPRISE_SUB_LEVEL" }, value = {
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index 1dc64a9..b7bef39 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -29,10 +29,8 @@
  * Contains information about a call's attributes as passed up from the HAL. If there are multiple
  * ongoing calls, the CallAttributes will pertain to the call in the foreground.
  * @hide
- * @deprecated use {@link CallState} for call information for each call.
  */
 @SystemApi
-@Deprecated
 public final class CallAttributes implements Parcelable {
     private PreciseCallState mPreciseCallState;
     @NetworkType
diff --git a/telephony/java/android/telephony/CallState.aidl b/telephony/java/android/telephony/CallState.aidl
deleted file mode 100644
index dd5af8e..0000000
--- a/telephony/java/android/telephony/CallState.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-parcelable CallState;
-
diff --git a/telephony/java/android/telephony/CallState.java b/telephony/java/android/telephony/CallState.java
deleted file mode 100644
index 0a267cf..0000000
--- a/telephony/java/android/telephony/CallState.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.Annotation.ImsCallServiceType;
-import android.telephony.Annotation.ImsCallType;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.Annotation.PreciseCallStates;
-import android.telephony.ims.ImsCallProfile;
-import android.telephony.ims.ImsCallSession;
-
-import java.util.Objects;
-
-/**
- * Contains information about various states for a call.
- * @hide
- */
-@SystemApi
-public final class CallState implements Parcelable {
-
-    /**
-     * Call classifications are just used for backward compatibility of deprecated API {@link
-     * TelephonyCallback#CallAttributesListener#onCallAttributesChanged}, Since these will be
-     * removed when the deprecated API is removed, they should not be opened.
-     */
-    /**
-     * Call classification is not valid. It should not be opened.
-     * @hide
-     */
-    public static final int CALL_CLASSIFICATION_UNKNOWN = -1;
-
-    /**
-     * Call classification indicating foreground call
-     * @hide
-     */
-    public static final int CALL_CLASSIFICATION_RINGING = 0;
-
-    /**
-     * Call classification indicating background call
-     * @hide
-     */
-    public static final int CALL_CLASSIFICATION_FOREGROUND = 1;
-
-    /**
-     * Call classification indicating ringing call
-     * @hide
-     */
-    public static final int CALL_CLASSIFICATION_BACKGROUND = 2;
-
-    /**
-     * Call classification Max value.
-     * @hide
-     */
-    public static final int CALL_CLASSIFICATION_MAX = CALL_CLASSIFICATION_BACKGROUND + 1;
-
-    @PreciseCallStates
-    private final int mPreciseCallState;
-
-    @NetworkType
-    private final int mNetworkType; // TelephonyManager.NETWORK_TYPE_* ints
-    private final CallQuality mCallQuality;
-
-    private final int mCallClassification;
-    /**
-     * IMS call session ID. {@link ImsCallSession#getCallId()}
-     */
-    @Nullable
-    private String mImsCallId;
-
-    /**
-     * IMS call service type of this call
-     */
-    @ImsCallServiceType
-    private int mImsCallServiceType;
-
-    /**
-     * IMS call type of this call.
-     */
-    @ImsCallType
-    private int mImsCallType;
-
-    /**
-     * Constructor of CallAttributes
-     *
-     * @param callState call state defined in {@link PreciseCallState}
-     * @param networkType network type for this call attributes
-     * @param callQuality call quality for this call attributes, only CallState in
-     *                    {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE} will have valid call
-     *                    quality.
-     * @param callClassification call classification
-     * @param imsCallId IMS call session ID for this call attributes
-     * @param imsCallServiceType IMS call service type for this call attributes
-     * @param imsCallType IMS call type for this call attributes
-     */
-    private CallState(@PreciseCallStates int callState, @NetworkType int networkType,
-            @NonNull CallQuality callQuality, int callClassification, @Nullable String imsCallId,
-            @ImsCallServiceType int imsCallServiceType, @ImsCallType int imsCallType) {
-        this.mPreciseCallState = callState;
-        this.mNetworkType = networkType;
-        this.mCallQuality = callQuality;
-        this.mCallClassification = callClassification;
-        this.mImsCallId = imsCallId;
-        this.mImsCallServiceType = imsCallServiceType;
-        this.mImsCallType = imsCallType;
-    }
-
-    @NonNull
-    @Override
-    public String toString() {
-        return "mPreciseCallState=" + mPreciseCallState + " mNetworkType=" + mNetworkType
-                + " mCallQuality=" + mCallQuality + " mCallClassification" + mCallClassification
-                + " mImsCallId=" + mImsCallId + " mImsCallServiceType=" + mImsCallServiceType
-                + " mImsCallType=" + mImsCallType;
-    }
-
-    private CallState(Parcel in) {
-        this.mPreciseCallState = in.readInt();
-        this.mNetworkType = in.readInt();
-        this.mCallQuality = in.readParcelable(
-                CallQuality.class.getClassLoader(), CallQuality.class);
-        this.mCallClassification = in.readInt();
-        this.mImsCallId = in.readString();
-        this.mImsCallServiceType = in.readInt();
-        this.mImsCallType = in.readInt();
-    }
-
-    // getters
-    /**
-     * Returns the precise call state of the call.
-     */
-    @PreciseCallStates
-    public int getCallState() {
-        return mPreciseCallState;
-    }
-
-    /**
-     * Returns the {@link TelephonyManager#NetworkType} of the call.
-     *
-     * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
-     * @see TelephonyManager#NETWORK_TYPE_GPRS
-     * @see TelephonyManager#NETWORK_TYPE_EDGE
-     * @see TelephonyManager#NETWORK_TYPE_UMTS
-     * @see TelephonyManager#NETWORK_TYPE_CDMA
-     * @see TelephonyManager#NETWORK_TYPE_EVDO_0
-     * @see TelephonyManager#NETWORK_TYPE_EVDO_A
-     * @see TelephonyManager#NETWORK_TYPE_1xRTT
-     * @see TelephonyManager#NETWORK_TYPE_HSDPA
-     * @see TelephonyManager#NETWORK_TYPE_HSUPA
-     * @see TelephonyManager#NETWORK_TYPE_HSPA
-     * @see TelephonyManager#NETWORK_TYPE_IDEN
-     * @see TelephonyManager#NETWORK_TYPE_EVDO_B
-     * @see TelephonyManager#NETWORK_TYPE_LTE
-     * @see TelephonyManager#NETWORK_TYPE_EHRPD
-     * @see TelephonyManager#NETWORK_TYPE_HSPAP
-     * @see TelephonyManager#NETWORK_TYPE_GSM
-     * @see TelephonyManager#NETWORK_TYPE_TD_SCDMA
-     * @see TelephonyManager#NETWORK_TYPE_IWLAN
-     * @see TelephonyManager#NETWORK_TYPE_LTE_CA
-     * @see TelephonyManager#NETWORK_TYPE_NR
-     */
-    @NetworkType
-    public int getNetworkType() {
-        return mNetworkType;
-    }
-
-    /**
-     * Returns the {#link CallQuality} of the call.
-     * @return call quality for this call attributes, only CallState in {@link PreciseCallState#
-     *         PRECISE_CALL_STATE_ACTIVE} will have valid call quality. It will be null for the
-     *         call which is not in {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE}.
-     */
-    @Nullable
-    public CallQuality getCallQuality() {
-        return mCallQuality;
-    }
-
-    /**
-     * Returns the call classification.
-     * @hide
-     */
-    public int getCallClassification() {
-        return mCallClassification;
-    }
-
-    /**
-     * Returns the IMS call session ID.
-     */
-    @Nullable
-    public String getImsCallSessionId() {
-        return mImsCallId;
-    }
-
-    /**
-     * Returns the IMS call service type.
-     */
-    @ImsCallServiceType
-    public int getImsCallServiceType() {
-        return mImsCallServiceType;
-    }
-
-    /**
-     * Returns the IMS call type.
-     */
-    @ImsCallType
-    public int getImsCallType() {
-        return mImsCallType;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mPreciseCallState, mNetworkType, mCallQuality, mCallClassification,
-                mImsCallId, mImsCallServiceType, mImsCallType);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o == null || !(o instanceof CallState) || hashCode() != o.hashCode()) {
-            return false;
-        }
-
-        if (this == o) {
-            return true;
-        }
-
-        CallState s = (CallState) o;
-
-        return (Objects.equals(mPreciseCallState, s.mPreciseCallState)
-                && mPreciseCallState == s.mPreciseCallState
-                && mNetworkType == s.mNetworkType
-                && Objects.equals(mCallQuality, s.mCallQuality)
-                && mCallClassification == s.mCallClassification
-                && Objects.equals(mImsCallId, s.mImsCallId)
-                && mImsCallType == s.mImsCallType
-                && mImsCallServiceType == s.mImsCallServiceType);
-    }
-
-    /**
-     * {@link Parcelable#describeContents}
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * {@link Parcelable#writeToParcel}
-     */
-    public void writeToParcel(@Nullable Parcel dest, int flags) {
-        dest.writeInt(mPreciseCallState);
-        dest.writeInt(mNetworkType);
-        dest.writeParcelable(mCallQuality, flags);
-        dest.writeInt(mCallClassification);
-        dest.writeString(mImsCallId);
-        dest.writeInt(mImsCallServiceType);
-        dest.writeInt(mImsCallType);
-    }
-
-    public static final @NonNull Creator<CallState> CREATOR = new Creator() {
-        public CallState createFromParcel(Parcel in) {
-            return new CallState(in);
-        }
-
-        public CallState[] newArray(int size) {
-            return new CallState[size];
-        }
-    };
-
-    /**
-     * Builder of {@link CallState}
-     *
-     * <p>The example below shows how you might create a new {@code CallState}:
-     *
-     * <pre><code>
-     *
-     * CallState = new CallState.Builder()
-     *     .setCallState(3)
-     *     .setNetworkType({@link TelephonyManager#NETWORK_TYPE_LTE})
-     *     .setCallQuality({@link CallQuality})
-     *     .setImsCallSessionId({@link String})
-     *     .setImsCallServiceType({@link ImsCallProfile#SERVICE_TYPE_NORMAL})
-     *     .setImsCallType({@link ImsCallProfile#CALL_TYPE_VOICE})
-     *     .build();
-     * </code></pre>
-     */
-    public static final class Builder {
-        private @PreciseCallStates int mPreciseCallState;
-        private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        private CallQuality mCallQuality = null;
-        private int mCallClassification = CALL_CLASSIFICATION_UNKNOWN;
-        private String mImsCallId;
-        private @ImsCallServiceType int mImsCallServiceType = ImsCallProfile.SERVICE_TYPE_NONE;
-        private @ImsCallType int mImsCallType = ImsCallProfile.CALL_TYPE_NONE;
-
-
-        /**
-         * Default constructor for the Builder.
-         */
-        public Builder(@PreciseCallStates int preciseCallState) {
-            mPreciseCallState = preciseCallState;
-        }
-
-        /**
-         * Set network type of this call.
-         *
-         * @param networkType the transport type.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public CallState.Builder setNetworkType(@NetworkType int networkType) {
-            this.mNetworkType = networkType;
-            return this;
-        }
-
-        /**
-         * Set the call quality {@link CallQuality} of this call.
-         *
-         * @param callQuality call quality of active call.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public CallState.Builder setCallQuality(@Nullable CallQuality callQuality) {
-            this.mCallQuality = callQuality;
-            return this;
-        }
-
-        /**
-         * Set call classification for this call.
-         *
-         * @param classification call classification type defined in this class.
-         * @return The same instance of the builder.
-         * @hide
-         */
-        @NonNull
-        public CallState.Builder setCallClassification(int classification) {
-            this.mCallClassification = classification;
-            return this;
-        }
-
-        /**
-         * Set IMS call session ID of this call.
-         *
-         * @param imsCallId  IMS call session ID.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public CallState.Builder setImsCallSessionId(@Nullable String imsCallId) {
-            this.mImsCallId = imsCallId;
-            return this;
-        }
-
-        /**
-         * Set IMS call service type of this call.
-         *
-         * @param serviceType IMS call service type defined in {@link ImsCallProfile}.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public CallState.Builder setImsCallServiceType(@ImsCallServiceType int serviceType) {
-            this.mImsCallServiceType = serviceType;
-            return this;
-        }
-
-        /**
-         * Set IMS call type of this call.
-         *
-         * @param callType IMS call type defined in {@link ImsCallProfile}.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public CallState.Builder setImsCallType(@ImsCallType int callType) {
-            this.mImsCallType = callType;
-            return this;
-        }
-
-        /**
-         * Build the {@link CallState}
-         *
-         * @return the {@link CallState} object
-         */
-        @NonNull
-        public CallState build() {
-            return new CallState(
-                    mPreciseCallState,
-                    mNetworkType,
-                    mCallQuality,
-                    mCallClassification,
-                    mImsCallId,
-                    mImsCallServiceType,
-                    mImsCallType);
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 1ea7fdc..e6d7df3 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -78,9 +78,8 @@
     public static final int SERVICE_TYPE_EMERGENCY = 2;
 
     /**
-     * Call type none
+     * Call types
      */
-    public static final int CALL_TYPE_NONE = 0;
     /**
      * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
      */
diff --git a/tools/lint/common/Android.bp b/tools/lint/common/Android.bp
new file mode 100644
index 0000000..898f88b
--- /dev/null
+++ b/tools/lint/common/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2022 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_host {
+    name: "AndroidCommonLint",
+    srcs: ["src/main/java/**/*.kt"],
+    libs: ["lint_api"],
+    kotlincflags: ["-Xjvm-default=all"],
+}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/Constants.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
diff --git a/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt b/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt
new file mode 100644
index 0000000..720f835
--- /dev/null
+++ b/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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 com.google.android.lint
+
+import com.android.tools.lint.detector.api.getUMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.UParameter
+
+fun isPermissionMethodCall(callExpression: UCallExpression): Boolean {
+    val method = callExpression.resolve()?.getUMethod() ?: return false
+    return hasPermissionMethodAnnotation(method)
+}
+
+fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations
+        .any {
+            it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD)
+        }
+
+fun hasPermissionNameAnnotation(parameter: UParameter) = parameter.annotations.any {
+    it.hasQualifiedName(ANNOTATION_PERMISSION_NAME)
+}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/model/Method.kt b/tools/lint/common/src/main/java/com/google/android/lint/model/Method.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/model/Method.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/model/Method.kt
diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp
new file mode 100644
index 0000000..5f6c6f7
--- /dev/null
+++ b/tools/lint/fix/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+python_binary_host {
+    name: "lint_fix",
+    main: "lint_fix.py",
+    srcs: ["lint_fix.py"],
+}
diff --git a/tools/lint/Android.bp b/tools/lint/framework/Android.bp
similarity index 87%
rename from tools/lint/Android.bp
rename to tools/lint/framework/Android.bp
index 96618f4..7f27e8a 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/framework/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Android Open Source Project
+// Copyright (C) 2022 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.
@@ -29,6 +29,11 @@
         "auto_service_annotations",
         "lint_api",
     ],
+    static_libs: [
+        "AndroidCommonLint",
+        // TODO: remove once b/236558918 is resolved and the below checks actually run globally
+        "AndroidGlobalLintChecker",
+    ],
     kotlincflags: ["-Xjvm-default=all"],
 }
 
@@ -51,9 +56,3 @@
         unit_test: true,
     },
 }
-
-python_binary_host {
-    name: "lint_fix",
-    main: "fix/lint_fix.py",
-    srcs: ["fix/lint_fix.py"],
-}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
similarity index 97%
rename from tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
index 1b0f035..e12ec3d 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
@@ -26,7 +26,6 @@
 import com.android.tools.lint.detector.api.Severity
 import com.android.tools.lint.detector.api.SourceCodeScanner
 import com.android.tools.lint.detector.api.getUMethod
-import com.google.android.lint.aidl.hasPermissionMethodAnnotation
 import com.intellij.psi.PsiType
 import org.jetbrains.uast.UAnnotation
 import org.jetbrains.uast.UBlockExpression
@@ -193,5 +192,8 @@
                 else -> false
             }
         }
+
+        private fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations
+                .any { it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD) }
     }
 }
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/Method.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/Method.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
diff --git a/tools/lint/Android.bp b/tools/lint/global/Android.bp
similarity index 84%
copy from tools/lint/Android.bp
copy to tools/lint/global/Android.bp
index 96618f4..3756abe 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/global/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Android Open Source Project
+// Copyright (C) 2022 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.
@@ -22,18 +22,22 @@
 }
 
 java_library_host {
-    name: "AndroidFrameworkLintChecker",
+    name: "AndroidGlobalLintChecker",
     srcs: ["checks/src/main/java/**/*.kt"],
     plugins: ["auto_service_plugin"],
     libs: [
         "auto_service_annotations",
         "lint_api",
     ],
+    static_libs: ["AndroidCommonLint"],
     kotlincflags: ["-Xjvm-default=all"],
+    dist: {
+        targets: ["droid"],
+    },
 }
 
 java_test_host {
-    name: "AndroidFrameworkLintCheckerTest",
+    name: "AndroidGlobalLintCheckerTest",
     // TODO(b/239881504): Since this test was written, Android
     // Lint was updated, and now includes classes that were
     // compiled for java 15. The soong build doesn't support
@@ -42,7 +46,7 @@
     enabled: false,
     srcs: ["checks/src/test/java/**/*.kt"],
     static_libs: [
-        "AndroidFrameworkLintChecker",
+        "AndroidGlobalLintChecker",
         "junit",
         "lint",
         "lint_tests",
@@ -51,9 +55,3 @@
         unit_test: true,
     },
 }
-
-python_binary_host {
-    name: "lint_fix",
-    main: "fix/lint_fix.py",
-    srcs: ["fix/lint_fix.py"],
-}
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
new file mode 100644
index 0000000..b377d50
--- /dev/null
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 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 com.google.android.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.aidl.EnforcePermissionDetector
+import com.google.android.lint.aidl.EnforcePermissionHelperDetector
+import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class AndroidGlobalIssueRegistry : IssueRegistry() {
+    override val issues = listOf(
+            EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
+            EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
+            EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+            SimpleManualPermissionEnforcementDetector.ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION,
+    )
+
+    override val api: Int
+        get() = CURRENT_API
+
+    override val minApi: Int
+        get() = 8
+
+    override val vendor: Vendor = Vendor(
+            vendorName = "Android",
+            feedbackUrl = "http://b/issues/new?component=315013",
+            contact = "repsonsible-apis@google.com"
+    )
+}
\ No newline at end of file
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
similarity index 97%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
index d120e1d..f1b6348 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
@@ -19,6 +19,8 @@
 import com.android.tools.lint.detector.api.JavaContext
 import com.android.tools.lint.detector.api.Location
 import com.android.tools.lint.detector.api.getUMethod
+import com.google.android.lint.hasPermissionNameAnnotation
+import com.google.android.lint.isPermissionMethodCall
 import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
 import org.jetbrains.uast.UCallExpression
 import org.jetbrains.uast.evaluateString
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
similarity index 69%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
index edbdd8d..250ca78 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
@@ -16,14 +16,9 @@
 
 package com.google.android.lint.aidl
 
-import com.android.tools.lint.detector.api.getUMethod
-import com.google.android.lint.ANNOTATION_PERMISSION_METHOD
-import com.google.android.lint.ANNOTATION_PERMISSION_NAME
 import com.google.android.lint.CLASS_STUB
 import com.intellij.psi.PsiAnonymousClass
-import org.jetbrains.uast.UCallExpression
 import org.jetbrains.uast.UMethod
-import org.jetbrains.uast.UParameter
 
 /**
  * Given a UMethod, determine if this method is
@@ -51,17 +46,3 @@
         it.referenceName == CLASS_STUB
     } ?: false
 }
-
-fun isPermissionMethodCall(callExpression: UCallExpression): Boolean {
-    val method = callExpression.resolve()?.getUMethod() ?: return false
-    return hasPermissionMethodAnnotation(method)
-}
-
-fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations
-    .any {
-        it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD)
-    }
-
-fun hasPermissionNameAnnotation(parameter: UParameter) = parameter.annotations.any {
-    it.hasQualifiedName(ANNOTATION_PERMISSION_NAME)
-}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt