From 777d87f91b23aa245d6c0807cd52365a713f340f Mon Sep 17 00:00:00 2001 From: Varun Shah Date: Tue, 17 Aug 2021 13:49:06 -0700 Subject: Dismiss the suspend dialog if conditions have been modified. Whenever suspension conditions change, if there is a user-visible suspension-related dialog, dismiss it to ensure the user is never looking at stale information. Bug: 169137795 Test: atest SuspendPackagesBroadcastTest#sendPackagesSuspendModifiedForUser Test: manual (steps below) -enable EBS, tap on suspended app to see dialog -enable Focus mode, ensure dialog is dismissed -tap on suspended app again to see relevent dialog, disable Focus mode, ensure dialog is dismissed -tap on suspended app again to see relevant dialog, disable EBS, ensure dialog is dismissed correctly -can permute enable/disable steps to further verify Change-Id: Ib1650f910f7441498424ab4bc92185ce432ac405 (cherry picked from commit 25e73a8b9e81a40c725463d8de9f27e911fe484b) --- core/java/android/content/Intent.java | 16 +++++++++++++++ .../android/internal/app/SuspendedAppActivity.java | 23 ++++++++++++---------- 2 files changed, 29 insertions(+), 10 deletions(-) (limited to 'core/java') diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 9e35a32638a8..35794d79b49d 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2738,6 +2738,22 @@ public class Intent implements Parcelable, Cloneable { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED"; + /** + * Broadcast Action: One of the suspend conditions have been modified for the packages. + *

Includes the following extras: + *

+ * + *

This is a protected intent that can only be sent + * by the system. It is only sent to registered receivers. + * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGES_SUSPENSION_CHANGED = + "android.intent.action.PACKAGES_SUSPENSION_CHANGED"; /** * Broadcast Action: Distracting packages have been changed. diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java index 84354d90b5f3..ec224e50eb8d 100644 --- a/core/java/com/android/internal/app/SuspendedAppActivity.java +++ b/core/java/com/android/internal/app/SuspendedAppActivity.java @@ -72,17 +72,19 @@ public class SuspendedAppActivity extends AlertActivity private Resources mSuspendingAppResources; private SuspendDialogInfo mSuppliedDialogInfo; private Bundle mOptions; - private BroadcastReceiver mUnsuspendReceiver = new BroadcastReceiver() { + private BroadcastReceiver mSuspendModifiedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(intent.getAction())) { - final String[] unsuspended = intent.getStringArrayExtra( + if (Intent.ACTION_PACKAGES_SUSPENSION_CHANGED.equals(intent.getAction())) { + // Suspension conditions were modified, dismiss any related visible dialogs. + final String[] modified = intent.getStringArrayExtra( Intent.EXTRA_CHANGED_PACKAGE_LIST); - if (ArrayUtils.contains(unsuspended, mSuspendedPackage)) { + if (ArrayUtils.contains(modified, mSuspendedPackage)) { if (!isFinishing()) { - Slog.w(TAG, "Package " + mSuspendedPackage - + " got unsuspended while the dialog was visible. Finishing."); + Slog.w(TAG, "Package " + mSuspendedPackage + " has modified" + + " suspension conditions while dialog was visible. Finishing."); SuspendedAppActivity.this.finish(); + // TODO (b/198201994): reload the suspend dialog to show most relevant info } } } @@ -245,15 +247,16 @@ public class SuspendedAppActivity extends AlertActivity setupAlert(); - final IntentFilter unsuspendFilter = new IntentFilter(Intent.ACTION_PACKAGES_UNSUSPENDED); - registerReceiverAsUser(mUnsuspendReceiver, UserHandle.of(mUserId), unsuspendFilter, null, - null); + final IntentFilter suspendModifiedFilter = + new IntentFilter(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED); + registerReceiverAsUser(mSuspendModifiedReceiver, UserHandle.of(mUserId), + suspendModifiedFilter, null, null); } @Override protected void onDestroy() { super.onDestroy(); - unregisterReceiver(mUnsuspendReceiver); + unregisterReceiver(mSuspendModifiedReceiver); } private void requestDismissKeyguardIfNeeded(CharSequence dismissMessage) { -- cgit v1.2.3 From 6cc84a14159577b3b2e899e1040ce3f7c47bbee9 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Mon, 6 Sep 2021 11:15:08 +0200 Subject: Fix race condition around CE storage becoming available. This fixes a race condition that exists around preparing CE storage, and a package being reinstalled at the same time. The normal CE data unlock procedure is something like this: 1. User state is RUNNING_LOCKED 2. UserController calls onBeforeUnlockUser() 3. onBeforeUnlockUser() prepares CE storage 4. onBeforeUnlockUser() calls PackageManagerService.reconcileAppsData() 5. reconcileAppsData() prepares app CE data directories, creating dirs when needed 6. UserController changes state to RUNNING_UNLOCKING The race comes into the picture when an app is installed right between step 5 and step 6; when a new app is installed, PMS does have a function to create the CE app data directory; but that function only creates CE data directories when the user state is RUNNING_UNLOCKING (or later); so even though technically CE storage became available in step 3, other parts of PMS will only use it after step 6 has completed. To fix this, we use StorageManagerService to record the fact that CE storage for a particular user is prepared; then, PackageManagerService can query StorageManager to ask whether CE storage is prepared. That in combination with the user key being unlocked is then used as a condition for creating CE data directories from PackageManagerService. Bug: 187103629 Test: manual Change-Id: Ice81ae98441b9ed287e8db4196a041c3d47afce9 Merged-In: Ice81ae98441b9ed287e8db4196a041c3d47afce9 --- core/java/android/os/storage/StorageManagerInternal.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'core/java') diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index 54905ec6eaeb..8928a423c6cb 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -18,6 +18,7 @@ package android.os.storage; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.os.IVold; import java.util.List; @@ -135,4 +136,19 @@ public abstract class StorageManagerInternal { * {@link VolumeInfo#isPrimary()} */ public abstract List getPrimaryVolumeIds(); + + /** + * Tells StorageManager that CE storage for this user has been prepared. + * + * @param userId userId for which CE storage has been prepared + */ + public abstract void markCeStoragePrepared(@UserIdInt int userId); + + /** + * Returns true when CE storage for this user has been prepared. + * + * When the user key is unlocked and CE storage has been prepared, + * it's ok to access and modify CE directories on volumes for this user. + */ + public abstract boolean isCeStoragePrepared(@UserIdInt int userId); } -- cgit v1.2.3 From a381ebd20500bcb6d79e24bbaa9096e3464e7008 Mon Sep 17 00:00:00 2001 From: Ahan Wu Date: Wed, 15 Sep 2021 17:35:04 +0800 Subject: Use longer timeout for reportShown call If the system is under somewhat pressure, the one second timeout might not be enough, let's use a longer timeout to mitigate it. Bug: 194080642 Test: see b/199700573#comment10 Change-Id: I8b9f40b332138b771d0892917b3f737caa2311a0 --- core/java/android/service/wallpaper/WallpaperService.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'core/java') diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index c198a492d4c9..c9a0121936dc 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -548,12 +548,16 @@ public abstract class WallpaperService extends Service { */ public void reportEngineShown(boolean waitForEngineShown) { if (mIWallpaperEngine.mShownReported) return; - Message message = mCaller.obtainMessage(MSG_REPORT_SHOWN); if (!waitForEngineShown) { + Message message = mCaller.obtainMessage(MSG_REPORT_SHOWN); mCaller.removeMessages(MSG_REPORT_SHOWN); mCaller.sendMessage(message); } else { - mCaller.sendMessageDelayed(message, TimeUnit.SECONDS.toMillis(1)); + // if we are already waiting, no need to reset the timeout. + if (!mCaller.hasMessages(MSG_REPORT_SHOWN)) { + Message message = mCaller.obtainMessage(MSG_REPORT_SHOWN); + mCaller.sendMessageDelayed(message, TimeUnit.SECONDS.toMillis(5)); + } } } @@ -2078,6 +2082,8 @@ public abstract class WallpaperService extends Service { mShownReported = true; try { mConnection.engineShown(this); + Log.d(TAG, "Wallpaper has updated the surface:" + + mWallpaperManager.getWallpaperInfo()); } catch (RemoteException e) { Log.w(TAG, "Wallpaper host disappeared", e); return; -- cgit v1.2.3 From 7d2da2c2d23301c2bc9a0db8fcc7d28b6e91a747 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Fri, 3 Sep 2021 18:05:44 +0200 Subject: Run a GC after killing a UID due to binder proxy limit. After we hit the per-UID proxy limit and kill the originating process, there's actually no guarantee that the proxies to the (now dead) processes are cleaned up immediately; if the processes get restarted and start accumulating proxies again, we may go over the global proxy limit (25k with this CL). Do a GC to make sure we clean them up. Note that the GC here might not actually clean up all the proxies, because the binder reference decrements will come in asynchronously; but if new processes belonging to the UID keep adding proxies, we will get another callback here, and run the GC again - this time cleaning up the old proxies. Because of this potential delay, an app may temporarily have many more outstanding proxies than the high watermark, so also increase the global proxy limit to 25k proxies. Bug: 198340142 Test: Manual Change-Id: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b Merged-In: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b --- core/java/android/os/BinderProxy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/java') diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java index 3d466a0bf007..c6466235e5d1 100644 --- a/core/java/android/os/BinderProxy.java +++ b/core/java/android/os/BinderProxy.java @@ -74,7 +74,7 @@ public final class BinderProxy implements IBinder { private static final int MAIN_INDEX_SIZE = 1 << LOG_MAIN_INDEX_SIZE; private static final int MAIN_INDEX_MASK = MAIN_INDEX_SIZE - 1; // Debuggable builds will throw an AssertionError if the number of map entries exceeds: - private static final int CRASH_AT_SIZE = 20_000; + private static final int CRASH_AT_SIZE = 25_000; /** * We next warn when we exceed this bucket size. -- cgit v1.2.3