summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java42
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java11
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java11
-rw-r--r--services/core/java/com/android/server/am/UserController.java2
4 files changed, 65 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bdb5d9356a0d..ef67cbe5024b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -77,8 +77,10 @@ import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
+import static android.os.PowerExemptionManager.REASON_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
+import static android.os.PowerExemptionManager.REASON_LOCKED_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.REASON_PROC_STATE_BTOP;
import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT;
import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI;
@@ -4840,6 +4842,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (!mConstants.mEnableWaitForFinishAttachApplication) {
finishAttachApplicationInner(startSeq, callingUid, pid);
}
+ maybeSendBootCompletedLocked(app);
} catch (Exception e) {
// We need kill the process group here. (b/148588589)
Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
@@ -5066,6 +5069,45 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ /**
+ * Send LOCKED_BOOT_COMPLETED and BOOT_COMPLETED to the package explicitly when unstopped
+ */
+ private void maybeSendBootCompletedLocked(ProcessRecord app) {
+ // Nothing to do if it wasn't previously stopped
+ if (!android.content.pm.Flags.stayStopped() || !app.wasForceStopped()) return;
+
+ // Send LOCKED_BOOT_COMPLETED, if necessary
+ if (app.getApplicationInfo().isEncryptionAware()) {
+ sendBootBroadcastToAppLocked(app, new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED),
+ REASON_LOCKED_BOOT_COMPLETED);
+ }
+ // Send BOOT_COMPLETED if the user is unlocked
+ if (StorageManager.isUserKeyUnlocked(app.userId)) {
+ sendBootBroadcastToAppLocked(app, new Intent(Intent.ACTION_BOOT_COMPLETED),
+ REASON_BOOT_COMPLETED);
+ }
+ app.setWasForceStopped(false);
+ }
+
+ /** Send a boot_completed broadcast to app */
+ private void sendBootBroadcastToAppLocked(ProcessRecord app, Intent intent,
+ @PowerExemptionManager.ReasonCode int reason) {
+ intent.setPackage(app.info.packageName);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, app.userId);
+ intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
+ final BroadcastOptions bOptions = mUserController.getTemporaryAppAllowlistBroadcastOptions(
+ reason);
+
+ broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null,
+ new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+ null, null, AppOpsManager.OP_NONE,
+ bOptions.toBundle(), true,
+ false, MY_PID, SYSTEM_UID,
+ SYSTEM_UID, MY_PID, app.userId);
+ }
+
@Override
public void showBootMessage(final CharSequence msg, final boolean always) {
if (Binder.getCallingUid() != myUid()) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 59d8e7e96ba6..f04198ed39ec 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -3257,6 +3257,17 @@ public final class ProcessList {
hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
final ProcessStateRecord state = r.mState;
+ // Check if we should mark the processrecord for first launch after force-stopping
+ if ((r.getApplicationInfo().flags & ApplicationInfo.FLAG_STOPPED) != 0) {
+ final boolean wasPackageEverLaunched = mService.getPackageManagerInternal()
+ .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId);
+ // If the package was launched in the past but is currently stopped, only then it
+ // should be considered as stopped after use. Do not mark it if it's the first launch.
+ if (wasPackageEverLaunched) {
+ r.setWasForceStopped(true);
+ }
+ }
+
if (!isolated && !isSdkSandbox
&& userId == UserHandle.USER_SYSTEM
&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f02b8c737f90..2c6e598ef0a4 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -438,6 +438,9 @@ class ProcessRecord implements WindowProcessListener {
final ProcessRecordNode[] mLinkedNodes = new ProcessRecordNode[NUM_NODE_TYPE];
+ /** Whether the app was launched from a stopped state and is being unstopped. */
+ volatile boolean mWasForceStopped;
+
void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
long startUptime, long startElapsedTime) {
this.mStartUid = startUid;
@@ -1602,4 +1605,12 @@ class ProcessRecord implements WindowProcessListener {
List<ProcessRecord> getLruProcessList() {
return mService.mProcessList.getLruProcessesLOSP();
}
+
+ public void setWasForceStopped(boolean stopped) {
+ mWasForceStopped = stopped;
+ }
+
+ public boolean wasForceStopped() {
+ return mWasForceStopped;
+ }
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index de4ad20bdccc..0dd579fd0b15 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -3387,7 +3387,7 @@ class UserController implements Handler.Callback {
}
- private BroadcastOptions getTemporaryAppAllowlistBroadcastOptions(
+ BroadcastOptions getTemporaryAppAllowlistBroadcastOptions(
@PowerWhitelistManager.ReasonCode int reasonCode) {
long duration = 10_000;
final ActivityManagerInternal amInternal =