diff options
| author | 2023-12-07 00:47:10 +0000 | |
|---|---|---|
| committer | 2023-12-07 00:47:10 +0000 | |
| commit | 945bfb86b664756ced0cca1d6c0742b0bbb7f18a (patch) | |
| tree | 97d1245e7a348671a8c12897cac74e9d27dcb57f | |
| parent | 269a95d4a88a293405c1b85fca92c1c68101a728 (diff) | |
| parent | 1d21f7e97b880a0cd203fd55687658285bcede72 (diff) | |
Merge changes I0aa2a2ae,If98b481b into main
* changes:
Update SyncManager to use PackageMonitor instead of broadcasts.
Add PackageMonitor callback for PACKAGE_UNSTOPPED broadcast.
5 files changed, 78 insertions, 19 deletions
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java index d85227f1a0a8..c89cfc4b0191 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -199,6 +199,11 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { public void onPackageChangedWithExtras(String packageName, Bundle extras) { } + public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit, + Bundle extras) { + return onHandleForceStop(intent, packages, uid, doit); + } + public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { return false; } @@ -254,6 +259,15 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { public void onPackageModified(@NonNull String packageName) { } + /** + * Called when a package in the stopped state is started for some reason. + * + * @param packageName Name of the package that was unstopped + * @param uid UID of the package that was unstopped + */ + public void onPackageUnstopped(String packageName, int uid, Bundle extras) { + } + public boolean didSomePackagesChange() { return mSomePackagesChanged; } @@ -444,13 +458,13 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { mChangeType = PACKAGE_TEMPORARY_CHANGE; boolean canRestart = onHandleForceStop(intent, mDisappearingPackages, - intent.getIntExtra(Intent.EXTRA_UID, 0), false); + intent.getIntExtra(Intent.EXTRA_UID, 0), false, intent.getExtras()); if (canRestart) setResultCode(Activity.RESULT_OK); } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) { mDisappearingPackages = new String[] {getPackageName(intent)}; mChangeType = PACKAGE_TEMPORARY_CHANGE; onHandleForceStop(intent, mDisappearingPackages, - intent.getIntExtra(Intent.EXTRA_UID, 0), true); + intent.getIntExtra(Intent.EXTRA_UID, 0), true, intent.getExtras()); } else if (Intent.ACTION_UID_REMOVED.equals(action)) { onUidRemoved(intent.getIntExtra(Intent.EXTRA_UID, 0)); } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { @@ -485,6 +499,12 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); mSomePackagesChanged = true; onPackagesUnsuspended(pkgList); + } else if (Intent.ACTION_PACKAGE_UNSTOPPED.equals(action)) { + final String pkgName = getPackageName(intent); + mAppearingPackages = new String[] {pkgName}; + mChangeType = PACKAGE_TEMPORARY_CHANGE; + onPackageUnstopped(pkgName, intent.getIntExtra(Intent.EXTRA_UID, 0), + intent.getExtras()); } if (mSomePackagesChanged) { diff --git a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java index 8e653f5e828f..9cb91229ce58 100644 --- a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java +++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java @@ -30,6 +30,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.SystemClock; import android.os.UserHandle; import androidx.test.runner.AndroidJUnit4; @@ -38,6 +39,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -185,16 +187,44 @@ public class PackageMonitorTest { Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED); intent.putExtra(Intent.EXTRA_USER_HANDLE, FAKE_USER_ID); intent.putExtra(Intent.EXTRA_UID, FAKE_PACKAGE_UID); + final long elapsedRealtimeMs = SystemClock.elapsedRealtime(); + intent.putExtra(Intent.EXTRA_TIME, elapsedRealtimeMs); intent.setData(Uri.fromParts("package", FAKE_PACKAGE_NAME, null)); spyPackageMonitor.doHandlePackageEvent(intent); verify(spyPackageMonitor, times(1)).onBeginPackageChanges(); verify(spyPackageMonitor, times(1)).onHandleForceStop(eq(intent), - eq(new String[]{FAKE_PACKAGE_NAME}), eq(FAKE_PACKAGE_UID), eq(true)); + eq(new String[]{FAKE_PACKAGE_NAME}), eq(FAKE_PACKAGE_UID), eq(true), + eqTimestamp(elapsedRealtimeMs)); verify(spyPackageMonitor, times(1)).onFinishPackageChanges(); } @Test + public void testPackageMonitorDoHandlePackageEventPackageUnstopped() throws Exception { + PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor()); + + Intent intent = new Intent(Intent.ACTION_PACKAGE_UNSTOPPED); + intent.putExtra(Intent.EXTRA_USER_HANDLE, FAKE_USER_ID); + intent.putExtra(Intent.EXTRA_UID, FAKE_PACKAGE_UID); + final long elapsedRealtimeMs = SystemClock.elapsedRealtime(); + intent.putExtra(Intent.EXTRA_TIME, elapsedRealtimeMs); + intent.setData(Uri.fromParts("package", FAKE_PACKAGE_NAME, null)); + spyPackageMonitor.doHandlePackageEvent(intent); + + verify(spyPackageMonitor, times(1)).onBeginPackageChanges(); + verify(spyPackageMonitor, times(1)).onPackageUnstopped( + eq(FAKE_PACKAGE_NAME), eq(FAKE_PACKAGE_UID), eqTimestamp(elapsedRealtimeMs)); + verify(spyPackageMonitor, times(1)).onFinishPackageChanges(); + } + + private static Bundle eqTimestamp(long expectedRealtimeMs) { + return ArgumentMatchers.argThat(actualExtras -> { + final long actualRealtimeMs = actualExtras.getLong(Intent.EXTRA_TIME); + return expectedRealtimeMs == actualRealtimeMs; + }); + } + + @Test public void testPackageMonitorDoHandlePackageEventPackageQueryRestarted() throws Exception { PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor()); diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 575b30946fce..5a9f113e79df 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -105,6 +105,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; +import com.android.internal.content.PackageMonitor; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BackgroundThread; @@ -438,19 +439,23 @@ public class SyncManager { } }; - private final BroadcastReceiver mForceStoppedReceiver = new BroadcastReceiver() { + private class PackageMonitorImpl extends PackageMonitor { @Override - public void onReceive(Context context, Intent intent) { + public boolean onHandleForceStop(Intent intent, String[] packageNames, int uid, + boolean doit, Bundle extras) { final boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG); - // For now, just log when packages were force-stopped and unstopped for debugging. if (isLoggable) { - if (Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) { - Log.d(TAG, "Package force-stopped: " - + intent.getData().getSchemeSpecificPart()); - } else if (Intent.ACTION_PACKAGE_UNSTOPPED.equals(intent.getAction())) { - Log.d(TAG, "Package unstopped: " - + intent.getData().getSchemeSpecificPart()); - } + Log.d(TAG, "Package force-stopped: " + Arrays.toString(packageNames) + + ", uid: " + uid); + } + return false; + } + + @Override + public void onPackageUnstopped(String packageName, int uid, Bundle extras) { + final boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG); + if (isLoggable) { + Log.d(TAG, "Package unstopped: " + packageName + ", uid: " + uid); } } }; @@ -718,11 +723,10 @@ public class SyncManager { mContext.registerReceiverAsUser( mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null); - intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); - intentFilter.addAction(Intent.ACTION_PACKAGE_UNSTOPPED); - intentFilter.addDataScheme("package"); - context.registerReceiver(mForceStoppedReceiver, intentFilter); + + final PackageMonitor packageMonitor = new PackageMonitorImpl(); + packageMonitor.register(mContext, null /* thread */, UserHandle.ALL, + false /* externalStorage */); intentFilter = new IntentFilter(Intent.ACTION_TIME_CHANGED); context.registerReceiver(mOtherIntentsReceiver, intentFilter); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 968ea6688328..cce9eeebb816 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4604,6 +4604,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService userIds, null, broadcastAllowList, null, null); }); + mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_UNSTOPPED, + packageName, extras, userIds, null /* instantUserIds */, + broadcastAllowList, mHandler); } } } diff --git a/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java b/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java index fa9409f88a13..1bb0730cccb2 100644 --- a/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java +++ b/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java @@ -188,7 +188,9 @@ class PackageMonitorCallbackHelper { || TextUtils.equals(action, Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || TextUtils.equals(action, Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE) || TextUtils.equals(action, Intent.ACTION_PACKAGE_DATA_CLEARED) - || TextUtils.equals(action, Intent.ACTION_PACKAGE_RESTARTED); + || TextUtils.equals(action, Intent.ACTION_PACKAGE_RESTARTED) + || TextUtils.equals(action, Intent.ACTION_PACKAGE_UNSTOPPED); + } private void doNotifyCallbacksByIntent(Intent intent, int userId, |