From c6d6347fc303919de73c16f1245633552f9a0ce4 Mon Sep 17 00:00:00 2001
From: Dmitry Dementyev <dementyev@google.com>
Date: Wed, 7 Jun 2023 11:39:04 -0700
Subject: [PATCH] Prevent crash in AccountManager after profile removal.

When user profile is removed AccountManagerService.purgeUserData may be
called after a delay. Until it happens other methods may try to access
database for a removed profile which causes a crash.

Bug: 281980345
Test: N/A
(cherry picked from commit 1fb0fb38ee44552a64962cb0e9e3d0a2cf2464a8)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:012998e4be23975d5cdae6438cdccb19f0ec5105)
Merged-In: Idb9840a5b9f9fdc84516149066cbb2a945c083a7
Change-Id: Idb9840a5b9f9fdc84516149066cbb2a945c083a7
---
 .../server/accounts/AccountManagerService.java  | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 8e1e3d86146f..fb7a81baba56 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -71,6 +71,7 @@ import android.content.pm.Signature;
 import android.content.pm.SigningDetails.CertCapabilities;
 import android.content.pm.UserInfo;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteCantOpenDatabaseException;
 import android.database.sqlite.SQLiteFullException;
 import android.database.sqlite.SQLiteStatement;
 import android.os.Binder;
@@ -1415,7 +1416,13 @@ public class AccountManagerService
     private void purgeOldGrants(UserAccounts accounts) {
         synchronized (accounts.dbLock) {
             synchronized (accounts.cacheLock) {
-                List<Integer> uids = accounts.accountsDb.findAllUidGrants();
+                List<Integer> uids;
+                try {
+                    uids = accounts.accountsDb.findAllUidGrants();
+                } catch (SQLiteCantOpenDatabaseException e) {
+                    Log.w(TAG, "Could not delete grants for user = " + accounts.userId);
+                    return;
+                }
                 for (int uid : uids) {
                     final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
                     if (packageExists) {
@@ -1441,7 +1448,13 @@ public class AccountManagerService
                     mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
                 } catch (NameNotFoundException e) {
                     // package does not exist - remove visibility values
-                    accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+                    try {
+                        accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+                    } catch (SQLiteCantOpenDatabaseException sqlException) {
+                        Log.w(TAG, "Could not delete account visibility for user = "
+                                + accounts.userId, sqlException);
+                        continue;
+                    }
                     synchronized (accounts.dbLock) {
                         synchronized (accounts.cacheLock) {
                             for (Account account : accounts.visibilityCache.keySet()) {
-- 
GitLab