diff options
8 files changed, 65 insertions, 26 deletions
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig index 4c97dbbb4d01..4d61f418af10 100644 --- a/core/java/android/app/activity_manager.aconfig +++ b/core/java/android/app/activity_manager.aconfig @@ -106,6 +106,17 @@ flag { flag { namespace: "backstage_power" + name: "use_app_info_not_launched" + description: "Use the notLaunched state from ApplicationInfo instead of current value" + is_fixed_read_only: true + bug: "362516211" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + namespace: "backstage_power" name: "cache_get_current_user_id" description: "Add caching for getCurrentUserId" is_fixed_read_only: true diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 495ae6026805..34bea1a4df6f 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -849,6 +849,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_EXT_CPU_OVERRIDE = 1 << 5; + /** + * Whether the app has been previously not launched + * @hide + */ + public static final int PRIVATE_FLAG_EXT_NOT_LAUNCHED = 1 << 6; + /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_EXT_" }, value = { PRIVATE_FLAG_EXT_PROFILEABLE, @@ -857,6 +863,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK, PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS, PRIVATE_FLAG_EXT_CPU_OVERRIDE, + PRIVATE_FLAG_EXT_NOT_LAUNCHED, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoPrivateFlagsExt {} @@ -2664,6 +2671,22 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } /** + * Returns whether the app in the STOPPED state. + * @hide + */ + public boolean isStopped() { + return (flags & ApplicationInfo.FLAG_STOPPED) != 0; + } + + /** + * Returns whether the app was never launched (any process started) before. + * @hide + */ + public boolean isNotLaunched() { + return (privateFlagsExt & ApplicationInfo.PRIVATE_FLAG_EXT_NOT_LAUNCHED) != 0; + } + + /** * Checks if a changeId is enabled for the current user * @param changeId The changeId to verify * @return True of the changeId is enabled diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index d4f729cfbaf6..36665240c16b 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1516,9 +1516,8 @@ public final class ActiveServices { serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START); mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName); final ProcessRecord hostApp = r.app; - final boolean wasStopped = hostApp == null ? wasStopped(r) : false; - final boolean firstLaunch = - hostApp == null ? !mAm.wasPackageEverLaunched(r.packageName, r.userId) : false; + final boolean wasStopped = hostApp == null ? r.appInfo.isStopped() : false; + final boolean firstLaunch = hostApp == null ? r.appInfo.isNotLaunched() : false; String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false /* whileRestarting */, @@ -4308,9 +4307,8 @@ public final class ActiveServices { true, UNKNOWN_ADJ); } - final boolean wasStopped = hostApp == null ? wasStopped(s) : false; - final boolean firstLaunch = - hostApp == null ? !mAm.wasPackageEverLaunched(s.packageName, s.userId) : false; + final boolean wasStopped = hostApp == null ? s.appInfo.isStopped() : false; + final boolean firstLaunch = hostApp == null ? s.appInfo.isNotLaunched() : false; boolean needOomAdj = false; if (c.hasFlag(Context.BIND_AUTO_CREATE)) { @@ -9350,8 +9348,4 @@ public final class ActiveServices { return mCachedDeviceProvisioningPackage != null && mCachedDeviceProvisioningPackage.equals(packageName); } - - private boolean wasStopped(ServiceRecord serviceRecord) { - return (serviceRecord.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; - } } diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java index 1b00cec90bc4..6aadcdc74870 100644 --- a/services/core/java/com/android/server/am/AppStartInfoTracker.java +++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java @@ -33,6 +33,7 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.icu.text.SimpleDateFormat; import android.os.Binder; +import android.os.Debug; import android.os.FileUtils; import android.os.Handler; import android.os.IBinder.DeathRecipient; @@ -495,6 +496,10 @@ public final class AppStartInfoTracker { private void addBaseFieldsFromProcessRecord(ApplicationStartInfo start, ProcessRecord app) { if (app == null) { + if (DEBUG) { + Slog.w(TAG, + "app is null in addBaseFieldsFromProcessRecord: " + Debug.getCallers(4)); + } return; } final int definingUid = app.getHostingRecord() != null diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 8fe33d18152c..9e4666cca140 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -1005,13 +1005,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final ApplicationInfo info = ((ResolveInfo) receiver).activityInfo.applicationInfo; final ComponentName component = ((ResolveInfo) receiver).activityInfo.getComponentName(); - if ((info.flags & ApplicationInfo.FLAG_STOPPED) != 0) { - queue.setActiveWasStopped(true); - } - final int intentFlags = r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND; - final boolean firstLaunch = !mService.wasPackageEverLaunched(info.packageName, r.userId); - queue.setActiveFirstLaunch(firstLaunch); + queue.setActiveWasStopped(info.isStopped()); + queue.setActiveFirstLaunch(info.isNotLaunched()); + final int intentFlags = r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND; final HostingRecord hostingRecord = new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST, component, r.intent.getAction(), r.getHostingRecordTriggerType()); final boolean isActivityCapable = (r.options != null diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java index 13145214c1c1..da408266bfac 100644 --- a/services/core/java/com/android/server/am/ContentProviderHelper.java +++ b/services/core/java/com/android/server/am/ContentProviderHelper.java @@ -554,13 +554,11 @@ public class ContentProviderHelper { callingProcessState, proc.mState.getCurProcState(), false, 0L); } else { - final boolean stopped = - (cpr.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; + final boolean stopped = cpr.appInfo.isStopped(); final int packageState = stopped ? PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED : PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; - final boolean firstLaunch = !mService.wasPackageEverLaunched( - cpi.packageName, userId); + final boolean firstLaunch = cpr.appInfo.isNotLaunched(); checkTime(startTime, "getContentProviderImpl: before start process"); proc = mService.startProcessLocked( cpi.processName, cpr.appInfo, false, 0, diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index bb0c24b4f8c6..5b4e57350c40 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -3394,24 +3394,33 @@ public final class ProcessList { hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName()); final ProcessStateRecord state = r.mState; - final boolean wasStopped = (info.flags & ApplicationInfo.FLAG_STOPPED) != 0; + final boolean wasStopped = info.isStopped(); // Check if we should mark the processrecord for first launch after force-stopping if (wasStopped) { + boolean wasEverLaunched; + if (android.app.Flags.useAppInfoNotLaunched()) { + wasEverLaunched = !info.isNotLaunched(); + } else { + wasEverLaunched = mService.getPackageManagerInternal() + .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId); + } // Check if the hosting record is for an activity or not. Since the stopped // state tracking is handled differently to avoid WM calling back into AM, // store the state in the correct record if (hostingRecord.isTypeActivity()) { - final boolean wasPackageEverLaunched = mService - .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId); // If the package was launched in the past but is currently stopped, only then // should it be considered as force-stopped. - @WindowProcessController.StoppedState int stoppedState = wasPackageEverLaunched + @WindowProcessController.StoppedState int stoppedState = wasEverLaunched ? STOPPED_STATE_FORCE_STOPPED : STOPPED_STATE_FIRST_LAUNCH; r.getWindowProcessController().setStoppedState(stoppedState); } else { - r.setWasForceStopped(true); - // first launch is computed just before logging, for non-activity types + if (android.app.Flags.useAppInfoNotLaunched()) { + // If it was launched before, then it must be a force-stop + r.setWasForceStopped(wasEverLaunched); + } else { + r.setWasForceStopped(true); + } } } diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index 1c70af0a56ea..5ca5fda19b2f 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -397,6 +397,8 @@ public class PackageInfoUtils { ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT) | flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD) | flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN); + ai.privateFlagsExt |= + flag(state.isNotLaunched(), ApplicationInfo.PRIVATE_FLAG_EXT_NOT_LAUNCHED); if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { ai.enabled = true; } else if (state.getEnabledState() |