Loading Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -372,6 +372,7 @@ java_library { "devicepolicyprotosnano", "com.android.sysprop.apex", "com.android.sysprop.init", "PlatformProperties", ], sdk_version: "core_platform", Loading cmds/statsd/src/atoms.proto +1 −1 Original line number Diff line number Diff line Loading @@ -378,7 +378,7 @@ message Atom { 240 [(module) = "framework"]; BootTimeEventUtcTime boot_time_event_utc_time_reported = 241; BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"]; UserspaceRebootReported userspace_reboot_reported = 243; UserspaceRebootReported userspace_reboot_reported = 243 [(module) = "framework"]; NotificationReported notification_reported = 244 [(module) = "framework"]; NotificationPanelReported notification_panel_reported = 245; NotificationChannelModified notification_panel_modified = 246; Loading services/core/java/com/android/server/UserspaceRebootLogger.java 0 → 100644 +136 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__OUTCOME_UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__LOCKED; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__UNLOCKED; import android.os.SystemClock; import android.os.SystemProperties; import android.util.Slog; import com.android.internal.util.FrameworkStatsLog; import java.util.concurrent.Executor; /** * Utility class to help abstract logging {@code UserspaceRebootReported} atom. */ public final class UserspaceRebootLogger { private static final String TAG = "UserspaceRebootLogger"; private static final String USERSPACE_REBOOT_SHOULD_LOG_PROPERTY = "persist.sys.userspace_reboot.log.should_log"; private static final String USERSPACE_REBOOT_LAST_STARTED_PROPERTY = "sys.userspace_reboot.log.last_started"; private static final String USERSPACE_REBOOT_LAST_FINISHED_PROPERTY = "sys.userspace_reboot.log.last_finished"; private static final String BOOT_REASON_PROPERTY = "sys.boot.reason"; private UserspaceRebootLogger() {} /** * Modifies internal state to note that {@code UserspaceRebootReported} atom needs to be * logged on the next successful boot. */ public static void noteUserspaceRebootWasRequested() { SystemProperties.set(USERSPACE_REBOOT_SHOULD_LOG_PROPERTY, "1"); SystemProperties.set(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, String.valueOf(SystemClock.elapsedRealtime())); } /** * Updates internal state on boot after successful userspace reboot. * * <p>Should be called right before framework sets {@code sys.boot_completed} property. */ public static void noteUserspaceRebootSuccess() { SystemProperties.set(USERSPACE_REBOOT_LAST_FINISHED_PROPERTY, String.valueOf(SystemClock.elapsedRealtime())); } /** * Returns {@code true} if {@code UserspaceRebootReported} atom should be logged. */ public static boolean shouldLogUserspaceRebootEvent() { return SystemProperties.getBoolean(USERSPACE_REBOOT_SHOULD_LOG_PROPERTY, false); } /** * Asynchronously logs {@code UserspaceRebootReported} on the given {@code executor}. * * <p>Should be called in the end of {@link * com.android.server.am.ActivityManagerService#finishBooting()} method, after framework have * tried to proactivelly unlock storage of the primary user. */ public static void logEventAsync(boolean userUnlocked, Executor executor) { final int outcome = computeOutcome(); final long durationMillis; if (outcome == USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS) { durationMillis = SystemProperties.getLong(USERSPACE_REBOOT_LAST_FINISHED_PROPERTY, 0) - SystemProperties.getLong(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, 0); } else { durationMillis = 0; } final int encryptionState = userUnlocked ? USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__UNLOCKED : USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__LOCKED; executor.execute( () -> { Slog.i(TAG, "Logging UserspaceRebootReported atom: { outcome: " + outcome + " durationMillis: " + durationMillis + " encryptionState: " + encryptionState + " }"); FrameworkStatsLog.write(FrameworkStatsLog.USERSPACE_REBOOT_REPORTED, outcome, durationMillis, encryptionState); SystemProperties.set(USERSPACE_REBOOT_SHOULD_LOG_PROPERTY, ""); }); } private static int computeOutcome() { if (SystemProperties.getLong(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, -1) != -1) { return USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS; } String reason = SystemProperties.get(BOOT_REASON_PROPERTY, ""); if (reason.startsWith("reboot,")) { reason = reason.substring("reboot".length()); } switch (reason) { case "userspace_failed,watchdog_fork": // Since fork happens before shutdown sequence, attribute it to // USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED. case "userspace_failed,shutdown_aborted": return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED; case "userspace_failed,init_user0_failed": // init_user0 will fail if userdata wasn't remounted correctly, attribute to // USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT. case "mount_userdata_failed": return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT; case "userspace_failed,watchdog_triggered": return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED; default: return USERSPACE_REBOOT_REPORTED__OUTCOME__OUTCOME_UNKNOWN; } } } services/core/java/com/android/server/am/ActivityManagerService.java +23 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,7 @@ import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.provider.Settings; import android.server.ServerProtoEnums; import android.sysprop.InitProperties; import android.sysprop.VoldProperties; import android.telephony.TelephonyManager; import android.text.TextUtils; Loading Loading @@ -347,6 +348,7 @@ import com.android.server.SystemConfig; import com.android.server.SystemService; import com.android.server.SystemServiceManager; import com.android.server.ThreadPriorityBooster; import com.android.server.UserspaceRebootLogger; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto; import com.android.server.appop.AppOpsService; Loading Loading @@ -2282,6 +2284,20 @@ public class ActivityManagerService extends IActivityManager.Stub } } private void maybeLogUserspaceRebootEvent() { if (!UserspaceRebootLogger.shouldLogUserspaceRebootEvent()) { return; } final int userId = mUserController.getCurrentUserId(); if (userId != UserHandle.USER_SYSTEM) { // Only log for user0. return; } // TODO(b/148767783): should we check all profiles under user0? UserspaceRebootLogger.logEventAsync(StorageManager.isUserKeyUnlocked(userId), BackgroundThread.getExecutor()); } /** * Encapsulates global settings related to hidden API enforcement behaviour, including tracking * the latest value via a content observer. Loading Loading @@ -5361,6 +5377,12 @@ public class ActivityManagerService extends IActivityManager.Stub // Start looking for apps that are abusing wake locks. Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); // Check if we are performing userspace reboot before setting sys.boot_completed to // avoid race with init reseting sys.init.userspace_reboot.in_progress once sys // .boot_completed is 1. if (InitProperties.userspace_reboot_in_progress().orElse(false)) { UserspaceRebootLogger.noteUserspaceRebootSuccess(); } // Tell anyone interested that we are done booting! SystemProperties.set("sys.boot_completed", "1"); Loading @@ -5381,6 +5403,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } }); maybeLogUserspaceRebootEvent(); mUserController.scheduleStartProfiles(); } // UART is on if init's console service is running, send a warning notification. Loading services/core/java/com/android/server/power/PowerManagerService.java +7 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.SynchronousUserSwitchObserver; Loading Loading @@ -95,6 +96,7 @@ import com.android.server.RescueParty; import com.android.server.ServiceThread; import com.android.server.SystemService; import com.android.server.UiThread; import com.android.server.UserspaceRebootLogger; import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; import com.android.server.lights.LightsManager; Loading Loading @@ -3154,7 +3156,10 @@ public final class PowerManagerService extends SystemService } private void shutdownOrRebootInternal(final @HaltMode int haltMode, final boolean confirm, final String reason, boolean wait) { @Nullable final String reason, boolean wait) { if (PowerManager.REBOOT_USERSPACE.equals(reason)) { UserspaceRebootLogger.noteUserspaceRebootWasRequested(); } if (mHandler == null || !mSystemReady) { if (RescueParty.isAttemptingFactoryReset()) { // If we're stuck in a really low-level reboot loop, and a Loading Loading @@ -5039,7 +5044,7 @@ public final class PowerManagerService extends SystemService * @param wait If true, this call waits for the reboot to complete and does not return. */ @Override // Binder call public void reboot(boolean confirm, String reason, boolean wait) { public void reboot(boolean confirm, @Nullable String reason, boolean wait) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); if (PowerManager.REBOOT_RECOVERY.equals(reason) || PowerManager.REBOOT_RECOVERY_UPDATE.equals(reason)) { Loading Loading
Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -372,6 +372,7 @@ java_library { "devicepolicyprotosnano", "com.android.sysprop.apex", "com.android.sysprop.init", "PlatformProperties", ], sdk_version: "core_platform", Loading
cmds/statsd/src/atoms.proto +1 −1 Original line number Diff line number Diff line Loading @@ -378,7 +378,7 @@ message Atom { 240 [(module) = "framework"]; BootTimeEventUtcTime boot_time_event_utc_time_reported = 241; BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"]; UserspaceRebootReported userspace_reboot_reported = 243; UserspaceRebootReported userspace_reboot_reported = 243 [(module) = "framework"]; NotificationReported notification_reported = 244 [(module) = "framework"]; NotificationPanelReported notification_panel_reported = 245; NotificationChannelModified notification_panel_modified = 246; Loading
services/core/java/com/android/server/UserspaceRebootLogger.java 0 → 100644 +136 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__OUTCOME_UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__LOCKED; import static com.android.internal.util.FrameworkStatsLog.USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__UNLOCKED; import android.os.SystemClock; import android.os.SystemProperties; import android.util.Slog; import com.android.internal.util.FrameworkStatsLog; import java.util.concurrent.Executor; /** * Utility class to help abstract logging {@code UserspaceRebootReported} atom. */ public final class UserspaceRebootLogger { private static final String TAG = "UserspaceRebootLogger"; private static final String USERSPACE_REBOOT_SHOULD_LOG_PROPERTY = "persist.sys.userspace_reboot.log.should_log"; private static final String USERSPACE_REBOOT_LAST_STARTED_PROPERTY = "sys.userspace_reboot.log.last_started"; private static final String USERSPACE_REBOOT_LAST_FINISHED_PROPERTY = "sys.userspace_reboot.log.last_finished"; private static final String BOOT_REASON_PROPERTY = "sys.boot.reason"; private UserspaceRebootLogger() {} /** * Modifies internal state to note that {@code UserspaceRebootReported} atom needs to be * logged on the next successful boot. */ public static void noteUserspaceRebootWasRequested() { SystemProperties.set(USERSPACE_REBOOT_SHOULD_LOG_PROPERTY, "1"); SystemProperties.set(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, String.valueOf(SystemClock.elapsedRealtime())); } /** * Updates internal state on boot after successful userspace reboot. * * <p>Should be called right before framework sets {@code sys.boot_completed} property. */ public static void noteUserspaceRebootSuccess() { SystemProperties.set(USERSPACE_REBOOT_LAST_FINISHED_PROPERTY, String.valueOf(SystemClock.elapsedRealtime())); } /** * Returns {@code true} if {@code UserspaceRebootReported} atom should be logged. */ public static boolean shouldLogUserspaceRebootEvent() { return SystemProperties.getBoolean(USERSPACE_REBOOT_SHOULD_LOG_PROPERTY, false); } /** * Asynchronously logs {@code UserspaceRebootReported} on the given {@code executor}. * * <p>Should be called in the end of {@link * com.android.server.am.ActivityManagerService#finishBooting()} method, after framework have * tried to proactivelly unlock storage of the primary user. */ public static void logEventAsync(boolean userUnlocked, Executor executor) { final int outcome = computeOutcome(); final long durationMillis; if (outcome == USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS) { durationMillis = SystemProperties.getLong(USERSPACE_REBOOT_LAST_FINISHED_PROPERTY, 0) - SystemProperties.getLong(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, 0); } else { durationMillis = 0; } final int encryptionState = userUnlocked ? USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__UNLOCKED : USERSPACE_REBOOT_REPORTED__USER_ENCRYPTION_STATE__LOCKED; executor.execute( () -> { Slog.i(TAG, "Logging UserspaceRebootReported atom: { outcome: " + outcome + " durationMillis: " + durationMillis + " encryptionState: " + encryptionState + " }"); FrameworkStatsLog.write(FrameworkStatsLog.USERSPACE_REBOOT_REPORTED, outcome, durationMillis, encryptionState); SystemProperties.set(USERSPACE_REBOOT_SHOULD_LOG_PROPERTY, ""); }); } private static int computeOutcome() { if (SystemProperties.getLong(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, -1) != -1) { return USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS; } String reason = SystemProperties.get(BOOT_REASON_PROPERTY, ""); if (reason.startsWith("reboot,")) { reason = reason.substring("reboot".length()); } switch (reason) { case "userspace_failed,watchdog_fork": // Since fork happens before shutdown sequence, attribute it to // USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED. case "userspace_failed,shutdown_aborted": return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED; case "userspace_failed,init_user0_failed": // init_user0 will fail if userdata wasn't remounted correctly, attribute to // USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT. case "mount_userdata_failed": return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT; case "userspace_failed,watchdog_triggered": return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED; default: return USERSPACE_REBOOT_REPORTED__OUTCOME__OUTCOME_UNKNOWN; } } }
services/core/java/com/android/server/am/ActivityManagerService.java +23 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,7 @@ import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.provider.Settings; import android.server.ServerProtoEnums; import android.sysprop.InitProperties; import android.sysprop.VoldProperties; import android.telephony.TelephonyManager; import android.text.TextUtils; Loading Loading @@ -347,6 +348,7 @@ import com.android.server.SystemConfig; import com.android.server.SystemService; import com.android.server.SystemServiceManager; import com.android.server.ThreadPriorityBooster; import com.android.server.UserspaceRebootLogger; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto; import com.android.server.appop.AppOpsService; Loading Loading @@ -2282,6 +2284,20 @@ public class ActivityManagerService extends IActivityManager.Stub } } private void maybeLogUserspaceRebootEvent() { if (!UserspaceRebootLogger.shouldLogUserspaceRebootEvent()) { return; } final int userId = mUserController.getCurrentUserId(); if (userId != UserHandle.USER_SYSTEM) { // Only log for user0. return; } // TODO(b/148767783): should we check all profiles under user0? UserspaceRebootLogger.logEventAsync(StorageManager.isUserKeyUnlocked(userId), BackgroundThread.getExecutor()); } /** * Encapsulates global settings related to hidden API enforcement behaviour, including tracking * the latest value via a content observer. Loading Loading @@ -5361,6 +5377,12 @@ public class ActivityManagerService extends IActivityManager.Stub // Start looking for apps that are abusing wake locks. Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); // Check if we are performing userspace reboot before setting sys.boot_completed to // avoid race with init reseting sys.init.userspace_reboot.in_progress once sys // .boot_completed is 1. if (InitProperties.userspace_reboot_in_progress().orElse(false)) { UserspaceRebootLogger.noteUserspaceRebootSuccess(); } // Tell anyone interested that we are done booting! SystemProperties.set("sys.boot_completed", "1"); Loading @@ -5381,6 +5403,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } }); maybeLogUserspaceRebootEvent(); mUserController.scheduleStartProfiles(); } // UART is on if init's console service is running, send a warning notification. Loading
services/core/java/com/android/server/power/PowerManagerService.java +7 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.SynchronousUserSwitchObserver; Loading Loading @@ -95,6 +96,7 @@ import com.android.server.RescueParty; import com.android.server.ServiceThread; import com.android.server.SystemService; import com.android.server.UiThread; import com.android.server.UserspaceRebootLogger; import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; import com.android.server.lights.LightsManager; Loading Loading @@ -3154,7 +3156,10 @@ public final class PowerManagerService extends SystemService } private void shutdownOrRebootInternal(final @HaltMode int haltMode, final boolean confirm, final String reason, boolean wait) { @Nullable final String reason, boolean wait) { if (PowerManager.REBOOT_USERSPACE.equals(reason)) { UserspaceRebootLogger.noteUserspaceRebootWasRequested(); } if (mHandler == null || !mSystemReady) { if (RescueParty.isAttemptingFactoryReset()) { // If we're stuck in a really low-level reboot loop, and a Loading Loading @@ -5039,7 +5044,7 @@ public final class PowerManagerService extends SystemService * @param wait If true, this call waits for the reboot to complete and does not return. */ @Override // Binder call public void reboot(boolean confirm, String reason, boolean wait) { public void reboot(boolean confirm, @Nullable String reason, boolean wait) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); if (PowerManager.REBOOT_RECOVERY.equals(reason) || PowerManager.REBOOT_RECOVERY_UPDATE.equals(reason)) { Loading