diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java index 5809769cfbacd..55a5f725f90b0 100644 --- a/services/core/java/com/android/server/pm/InstantAppRegistry.java +++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java @@ -117,7 +117,13 @@ class InstantAppRegistry { public byte[] getInstantAppCookieLPw(@NonNull String packageName, @UserIdInt int userId) { - byte[] pendingCookie = mCookiePersistence.getPendingPersistCookie(userId, packageName); + // Only installed packages can get their own cookie + PackageParser.Package pkg = mService.mPackages.get(packageName); + if (pkg == null) { + return null; + } + + byte[] pendingCookie = mCookiePersistence.getPendingPersistCookieLPr(pkg, userId); if (pendingCookie != null) { return pendingCookie; } @@ -144,14 +150,13 @@ class InstantAppRegistry { } } + // Only an installed package can set its own cookie PackageParser.Package pkg = mService.mPackages.get(packageName); if (pkg == null) { return false; } - File cookieFile = computeInstantCookieFile(pkg, userId); - - mCookiePersistence.schedulePersist(userId, packageName, cookieFile, cookie); + mCookiePersistence.schedulePersistLPw(userId, pkg, cookie); return true; } @@ -172,12 +177,11 @@ class InstantAppRegistry { if (cookie == null || cookie.length <= 0) { return; } - - try (FileOutputStream fos = new FileOutputStream(cookieFile)) { - fos.write(cookie, 0, cookie.length); - } catch (IOException e) { - Slog.e(LOG_TAG, "Error writing instant app cookie file: " + cookieFile, e); - } + } + try (FileOutputStream fos = new FileOutputStream(cookieFile)) { + fos.write(cookie, 0, cookie.length); + } catch (IOException e) { + Slog.e(LOG_TAG, "Error writing instant app cookie file: " + cookieFile, e); } } @@ -242,6 +246,8 @@ class InstantAppRegistry { if (!currentCookieFile.equals(expectedCookeFile)) { Slog.i(LOG_TAG, "Signature for package " + pkg.packageName + " changed - dropping cookie"); + // Make sure a pending write for the old signed app is cancelled + mCookiePersistence.cancelPendingPersistLPw(pkg, userId); currentCookieFile.delete(); } } @@ -894,75 +900,88 @@ class InstantAppRegistry { // Handler allows removing messages by id and tag where 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 - // with a way to cancel persisting the cookie for a user - // and package. - private final SparseArray> mPendingPersistCookies = - new SparseArray<>(); + // the fact that package are cached by the system so the == + // comparison would match and we end up with a way to cancel + // persisting the cookie for a user and package. + private final SparseArray> mPendingPersistCookies + = new SparseArray<>(); public CookiePersistence(Looper looper) { super(looper); } - public void schedulePersist(@UserIdInt int userId, @NonNull String packageName, - @NonNull File cookieFile, @NonNull byte[] cookie) { - cancelPendingPersist(userId, packageName); - addPendingPersistCookie(userId, packageName, cookie); - SomeArgs args = SomeArgs.obtain(); - args.arg1 = packageName; - args.arg2 = cookieFile; - sendMessageDelayed(obtainMessage(userId, args), + public void schedulePersistLPw(@UserIdInt int userId, @NonNull PackageParser.Package pkg, + @NonNull byte[] cookie) { + File cookieFile = computeInstantCookieFile(pkg, userId); + cancelPendingPersistLPw(pkg, userId); + addPendingPersistCookieLPw(userId, pkg, cookie, cookieFile); + sendMessageDelayed(obtainMessage(userId, pkg), PERSIST_COOKIE_DELAY_MILLIS); } - public @Nullable byte[] getPendingPersistCookie(@UserIdInt int userId, - @NonNull String packageName) { - ArrayMap pendingWorkForUser = mPendingPersistCookies.get(userId); + public @Nullable byte[] getPendingPersistCookieLPr(@NonNull PackageParser.Package pkg, + @UserIdInt int userId) { + ArrayMap pendingWorkForUser = + mPendingPersistCookies.get(userId); if (pendingWorkForUser != null) { - return pendingWorkForUser.remove(packageName); + SomeArgs state = pendingWorkForUser.get(pkg); + if (state != null) { + return (byte[]) state.arg1; + } } return null; } - private void cancelPendingPersist(@UserIdInt int userId, - @NonNull String packageName) { - removePendingPersistCookie(userId, packageName); - removeMessages(userId, packageName); + public void cancelPendingPersistLPw(@NonNull PackageParser.Package pkg, + @UserIdInt int userId) { + removeMessages(userId, pkg); + SomeArgs state = removePendingPersistCookieLPr(pkg, userId); + if (state != null) { + state.recycle(); + } } - private void addPendingPersistCookie(@UserIdInt int userId, - @NonNull String packageName, @NonNull byte[] cookie) { - ArrayMap pendingWorkForUser = mPendingPersistCookies.get(userId); + private void addPendingPersistCookieLPw(@UserIdInt int userId, + @NonNull PackageParser.Package pkg, @NonNull byte[] cookie, + @NonNull File cookieFile) { + ArrayMap pendingWorkForUser = + mPendingPersistCookies.get(userId); if (pendingWorkForUser == null) { pendingWorkForUser = new ArrayMap<>(); mPendingPersistCookies.put(userId, pendingWorkForUser); } - pendingWorkForUser.put(packageName, cookie); + SomeArgs args = SomeArgs.obtain(); + args.arg1 = cookie; + args.arg2 = cookieFile; + pendingWorkForUser.put(pkg, args); } - private byte[] removePendingPersistCookie(@UserIdInt int userId, - @NonNull String packageName) { - ArrayMap pendingWorkForUser = mPendingPersistCookies.get(userId); - byte[] cookie = null; + private SomeArgs removePendingPersistCookieLPr(@NonNull PackageParser.Package pkg, + @UserIdInt int userId) { + ArrayMap pendingWorkForUser = + mPendingPersistCookies.get(userId); + SomeArgs state = null; if (pendingWorkForUser != null) { - cookie = pendingWorkForUser.remove(packageName); + state = pendingWorkForUser.remove(pkg); if (pendingWorkForUser.isEmpty()) { mPendingPersistCookies.remove(userId); } } - return cookie; + return state; } @Override public void handleMessage(Message message) { int userId = message.what; - 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, cookieFile, userId); + PackageParser.Package pkg = (PackageParser.Package) message.obj; + SomeArgs state = removePendingPersistCookieLPr(pkg, userId); + if (state == null) { + return; + } + byte[] cookie = (byte[]) state.arg1; + File cookieFile = (File) state.arg2; + state.recycle(); + persistInstantApplicationCookie(cookie, pkg.packageName, cookieFile, userId); } } }