diff options
4 files changed, 59 insertions, 4 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/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c0c98dedfae3..b7f918fe18d7 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, |