diff options
| author | 2023-06-27 19:26:01 -0700 | |
|---|---|---|
| committer | 2023-07-12 21:49:59 +0000 | |
| commit | 557d4c0f9c2d12cf584b1bb363536e288bfaa7ea (patch) | |
| tree | d1b50e6572f2507db21d8540a849ab2f3c2d9363 | |
| parent | 8658bbe31eb292bc2279838308ac9225a36351f3 (diff) | |
Add pending restoration for default browser.
By keeping the restored default browser package name in the original
Settings field, and applying it post package install. A little bit of
renaming is done to make this more evident.
Setting the default browser is also changed to async since there's no
reason to block system server main thread for that.
Also simplified DefaultAppProvider.setDefaultBrowser() since we no
longer have any API that requires the operation to complete
synchronously.
Fixes: 271337188
Test: manual
Change-Id: I197e8b523f9f7f99bffe2e3c3608507e754ff60a
Merged-In: I197e8b523f9f7f99bffe2e3c3608507e754ff60a
(cherry picked from commit a9ad2c2a562360df7550f2c842305f6f6eeb9131)
4 files changed, 49 insertions, 39 deletions
diff --git a/services/core/java/com/android/server/pm/DefaultAppProvider.java b/services/core/java/com/android/server/pm/DefaultAppProvider.java index c18d0e9ef35e..fc61451b0289 100644 --- a/services/core/java/com/android/server/pm/DefaultAppProvider.java +++ b/services/core/java/com/android/server/pm/DefaultAppProvider.java @@ -24,14 +24,10 @@ import android.os.Binder; import android.os.UserHandle; import android.util.Slog; -import com.android.internal.infra.AndroidFuture; import com.android.internal.util.CollectionUtils; import com.android.server.FgThread; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.function.Supplier; @@ -70,27 +66,19 @@ public class DefaultAppProvider { * Set the package name of the default browser. * * @param packageName package name of the default browser, or {@code null} to unset - * @param async whether the operation should be asynchronous * @param userId the user ID - * @return whether the default browser was successfully set. */ - public boolean setDefaultBrowser(@Nullable String packageName, boolean async, - @UserIdInt int userId) { - if (userId == UserHandle.USER_ALL) { - return false; - } + public void setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) { final RoleManager roleManager = mRoleManagerSupplier.get(); if (roleManager == null) { - return false; + return; } final UserHandle user = UserHandle.of(userId); final Executor executor = FgThread.getExecutor(); - final AndroidFuture<Void> future = new AndroidFuture<>(); final Consumer<Boolean> callback = successful -> { - if (successful) { - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); + if (!successful) { + Slog.e(PackageManagerService.TAG, "Failed to set default browser to " + + packageName); } }; final long identity = Binder.clearCallingIdentity(); @@ -102,19 +90,9 @@ public class DefaultAppProvider { roleManager.clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, user, executor, callback); } - if (!async) { - try { - future.get(5, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Slog.e(PackageManagerService.TAG, "Exception while setting default browser: " - + packageName, e); - return false; - } - } } finally { Binder.restoreCallingIdentity(identity); } - return true; } /** diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index e328d64dd0d6..dbc2fd89e58c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3535,6 +3535,18 @@ public class PackageManagerService implements PackageSender, TestUtilityService // within these users. mPermissionManager.restoreDelayedRuntimePermissions(packageName, userId); + // Restore default browser setting if it is now installed. + String defaultBrowser; + synchronized (mLock) { + defaultBrowser = mSettings.getPendingDefaultBrowserLPr(userId); + } + if (Objects.equals(packageName, defaultBrowser)) { + mDefaultAppProvider.setDefaultBrowser(packageName, userId); + synchronized (mLock) { + mSettings.removePendingDefaultBrowserLPw(userId); + } + } + // Persistent preferred activity might have came into effect due to this // install. mPreferredActivityHelper.updateDefaultHomeNotLocked(snapshotComputer(), userId); @@ -6732,7 +6744,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService @Override public String removeLegacyDefaultBrowserPackageName(int userId) { synchronized (mLock) { - return mSettings.removeDefaultBrowserPackageNameLPw(userId); + return mSettings.removePendingDefaultBrowserLPw(userId); } } @@ -7574,8 +7586,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService return mDefaultAppProvider.getDefaultBrowser(userId); } - void setDefaultBrowser(@Nullable String packageName, boolean async, @UserIdInt int userId) { - mDefaultAppProvider.setDefaultBrowser(packageName, async, userId); + void setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) { + mDefaultAppProvider.setDefaultBrowser(packageName, userId); } PackageUsage getPackageUsage() { diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java index 9ff83929a609..76e7070bd3fe 100644 --- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java +++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java @@ -585,7 +585,17 @@ final class PreferredActivityHelper { (parser1, userId1) -> { final String defaultBrowser = Settings.readDefaultApps(parser1); if (defaultBrowser != null) { - mPm.setDefaultBrowser(defaultBrowser, false, userId1); + final PackageStateInternal packageState = mPm.snapshotComputer() + .getPackageStateInternal(defaultBrowser); + if (packageState != null + && packageState.getUserStateOrDefault(userId1).isInstalled()) { + mPm.setDefaultBrowser(defaultBrowser, userId1); + } else { + synchronized (mPm.mLock) { + mPm.mSettings.setPendingDefaultBrowserLPw(defaultBrowser, + userId1); + } + } } }); } catch (Exception e) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 5811f11b20c5..677a5d11cc6b 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -517,9 +517,11 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile private final WatchedArrayMap<String, String> mRenamedPackages = new WatchedArrayMap<String, String>(); - // For every user, it is used to find the package name of the default Browser App. + // For every user, it is used to find the package name of the default browser app pending to be + // applied, either on first boot after upgrade, or after backup & restore but before app is + // installed. @Watched - final WatchedSparseArray<String> mDefaultBrowserApp = new WatchedSparseArray<String>(); + final WatchedSparseArray<String> mPendingDefaultBrowser = new WatchedSparseArray<>(); // TODO(b/161161364): This seems unused, and is probably not relevant in the new API, but should // verify. @@ -592,7 +594,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile mAppIds.registerObserver(mObserver); mRenamedPackages.registerObserver(mObserver); mNextAppLinkGeneration.registerObserver(mObserver); - mDefaultBrowserApp.registerObserver(mObserver); + mPendingDefaultBrowser.registerObserver(mObserver); mPendingPackages.registerObserver(mObserver); mPastSignatures.registerObserver(mObserver); mKeySetRefs.registerObserver(mObserver); @@ -787,7 +789,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile mRenamedPackages.snapshot(r.mRenamedPackages); mNextAppLinkGeneration.snapshot(r.mNextAppLinkGeneration); - mDefaultBrowserApp.snapshot(r.mDefaultBrowserApp); + mPendingDefaultBrowser.snapshot(r.mPendingDefaultBrowser); // mReadMessages mPendingPackages = r.mPendingPackagesSnapshot.snapshot(); mPendingPackagesSnapshot = new SnapshotCache.Sealed<>(); @@ -1504,8 +1506,16 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile return cpir; } - String removeDefaultBrowserPackageNameLPw(int userId) { - return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId); + String getPendingDefaultBrowserLPr(int userId) { + return mPendingDefaultBrowser.get(userId); + } + + void setPendingDefaultBrowserLPw(String defaultBrowser, int userId) { + mPendingDefaultBrowser.put(userId, defaultBrowser); + } + + String removePendingDefaultBrowserLPw(int userId) { + return mPendingDefaultBrowser.removeReturnOld(userId); } private File getUserSystemDirectory(int userId) { @@ -1690,7 +1700,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile throws XmlPullParserException, IOException { String defaultBrowser = readDefaultApps(parser); if (defaultBrowser != null) { - mDefaultBrowserApp.put(userId, defaultBrowser); + mPendingDefaultBrowser.put(userId, defaultBrowser); } } @@ -2100,7 +2110,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile void writeDefaultAppsLPr(XmlSerializer serializer, int userId) throws IllegalArgumentException, IllegalStateException, IOException { - String defaultBrowser = mDefaultBrowserApp.get(userId); + String defaultBrowser = mPendingDefaultBrowser.get(userId); writeDefaultApps(serializer, defaultBrowser); } |