Merge "Update framework from Jetpack." into sc-dev
diff --git a/service/java/com/android/server/appsearch/AppSearchManagerService.java b/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 3bbc945..271129b 100644
--- a/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -38,6 +38,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.util.Preconditions;
@@ -49,6 +50,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /** TODO(b/142567528): add comments when implement this class */
 public class AppSearchManagerService extends SystemService {
@@ -56,6 +58,9 @@
     private PackageManagerInternal mPackageManagerInternal;
     private ImplInstanceManager mImplInstanceManager;
 
+    // Cache of unlocked user ids so we don't have to query UserManager service each time.
+    private final Set<Integer> mUnlockedUserIds = new ArraySet<>();
+
     public AppSearchManagerService(Context context) {
         super(context);
     }
@@ -67,6 +72,11 @@
         mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
     }
 
+    @Override
+    public void onUserUnlocked(@NonNull TargetUser user) {
+        mUnlockedUserIds.add(user.getUserIdentifier());
+    }
+
     private class Stub extends IAppSearchManager.Stub {
         @Override
         public void setSchema(
@@ -86,6 +96,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
                 for (int i = 0; i < schemaBundles.size(); i++) {
@@ -133,6 +144,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -165,6 +177,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchBatchResult.Builder<String, Void> resultBuilder =
                         new AppSearchBatchResult.Builder<>();
@@ -207,6 +220,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
                         new AppSearchBatchResult.Builder<>();
@@ -253,6 +267,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -287,6 +302,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -318,6 +334,7 @@
             // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
             // opened it
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
@@ -337,6 +354,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 impl.invalidateNextPageToken(nextPageToken);
@@ -364,6 +382,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 impl.reportUsage(packageName, databaseName, namespace, uri, usageTimeMillis);
@@ -392,6 +411,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchBatchResult.Builder<String, Void> resultBuilder =
                         new AppSearchBatchResult.Builder<>();
@@ -431,6 +451,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -453,6 +474,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 impl.persistToDisk();
@@ -470,6 +492,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
             } catch (Throwable t) {
@@ -479,6 +502,13 @@
             }
         }
 
+        private void verifyUserUnlocked(int callingUserId) {
+            if (!mUnlockedUserIds.contains(callingUserId)) {
+                throw new IllegalStateException(
+                        "User " + callingUserId + " is locked or not running.");
+            }
+        }
+
         private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
             Preconditions.checkNotNull(callingPackage);
             if (mPackageManagerInternal.getPackageUid(
diff --git a/service/java/com/android/server/appsearch/ImplInstanceManager.java b/service/java/com/android/server/appsearch/ImplInstanceManager.java
index 97b1a8c..5ea2a02 100644
--- a/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -73,8 +73,8 @@
     /**
      * Gets an instance of AppSearchImpl for the given user.
      *
-     * <p>If no AppSearchImpl instance exists for this user, Icing will be initialized and one will
-     * be created.
+     * <p>If no AppSearchImpl instance exists for the unlocked user, Icing will be initialized and
+     * one will be created.
      *
      * @param context The context
      * @param userId The multi-user userId of the device user calling AppSearch