Fix a race when persisting cookie data

bug:34983226

Test: CTS passes

Change-Id: I457154fecdc15c057e276358e443d3c941128ab2
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index 42934a4..53f664a 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -42,6 +42,7 @@
 import android.util.Xml;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 import libcore.io.IoUtils;
@@ -115,7 +116,7 @@
     }
 
     public byte[] getInstantAppCookieLPw(@NonNull String packageName,
-                                         @UserIdInt int userId) {
+            @UserIdInt int userId) {
         byte[] pendingCookie = mCookiePersistence.getPendingPersistCookie(userId, packageName);
         if (pendingCookie != null) {
             return pendingCookie;
@@ -132,7 +133,7 @@
     }
 
     public boolean setInstantAppCookieLPw(@NonNull String packageName,
-                                          @Nullable byte[] cookie, @UserIdInt int userId) {
+            @Nullable byte[] cookie, @UserIdInt int userId) {
         if (cookie != null && cookie.length > 0) {
             final int maxCookieSize = mService.mContext.getPackageManager()
                     .getInstantAppCookieMaxSize();
@@ -143,25 +144,26 @@
             }
         }
 
-        mCookiePersistence.schedulePersist(userId, packageName, cookie);
+        PackageParser.Package pkg = mService.mPackages.get(packageName);
+        if (pkg == null) {
+            return false;
+        }
+
+        File cookieFile = computeInstantCookieFile(pkg, userId);
+
+        mCookiePersistence.schedulePersist(userId, packageName, cookieFile, cookie);
         return true;
     }
 
     private void persistInstantApplicationCookie(@Nullable byte[] cookie,
-            @NonNull String packageName, @UserIdInt int userId) {
+            @NonNull String packageName, @NonNull File cookieFile, @UserIdInt int userId) {
         synchronized (mService.mPackages) {
-            PackageParser.Package pkg = mService.mPackages.get(packageName);
-            if (pkg == null) {
-                return;
-            }
-
             File appDir = getInstantApplicationDir(packageName, userId);
             if (!appDir.exists() && !appDir.mkdirs()) {
                 Slog.e(LOG_TAG, "Cannot create instant app cookie directory");
                 return;
             }
 
-            File cookieFile = computeInstantCookieFile(pkg, userId);
             if (cookieFile.exists() && !cookieFile.delete()) {
                 Slog.e(LOG_TAG, "Cannot delete instant app cookie file");
             }
@@ -889,7 +891,7 @@
         // In case you wonder why we stash the cookies aside, we use
         // the user id for the message id and the package for the payload.
         // Handler allows removing messages by id and tag where the
-        // tag is is compared using ==. So to allow cancelling the
+        // tag is compared using ==. So to allow cancelling the
         // pending persistence for an app under a given user we use
         // the fact that package names are interned in the system
         // process so the == comparison would match and we end up
@@ -902,11 +904,14 @@
             super(looper);
         }
 
-        public void schedulePersist(@UserIdInt int userId,
-                @NonNull String packageName, @NonNull byte[] cookie) {
+        public void schedulePersist(@UserIdInt int userId, @NonNull String packageName,
+                @NonNull File cookieFile, @NonNull byte[] cookie) {
             cancelPendingPersist(userId, packageName);
             addPendingPersistCookie(userId, packageName, cookie);
-            sendMessageDelayed(obtainMessage(userId, packageName),
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = packageName;
+            args.arg2 = cookieFile;
+            sendMessageDelayed(obtainMessage(userId, args),
                     PERSIST_COOKIE_DELAY_MILLIS);
         }
 
@@ -951,9 +956,12 @@
         @Override
         public void handleMessage(Message message) {
             int userId = message.what;
-            String packageName = (String) message.obj;
+            SomeArgs args = (SomeArgs) message.obj;
+            String packageName = (String) args.arg1;
+            File cookieFile = (File) args.arg2;
+            args.recycle();
             byte[] cookie = removePendingPersistCookie(userId, packageName);
-            persistInstantApplicationCookie(cookie, packageName, userId);
+            persistInstantApplicationCookie(cookie, packageName, cookieFile, userId);
         }
     }
 }