Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ea4289b authored by Tej Singh's avatar Tej Singh
Browse files

Atom: Shutdown sequence event

Records start and duration of shutdown, along with reason and if it was
a reboot.

Test: manually verified statsd received atom. CTS test for this will be
difficult, and I will investigate further later.

Change-Id: I0f6b595e0e251fd0a8b38127182d055885460a55
parent af2397da
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ message Atom {
        WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53;
        LmkStateChanged lmk_state_changed = 54;
        AppStartMemoryStateCaptured app_start_memory_state_captured = 55;
        ShutdownSequenceReported shutdown_sequence_reported = 56;
        // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
    }

@@ -668,6 +669,27 @@ message WifiMulticastLockStateChanged {
    optional State state = 2;
}

/**
 * Logs shutdown reason and duration on next boot.
 *
 * Logged from:
 *   frameworks/base/core/java/com/android/server/BootReceiver.java
 */
message ShutdownSequenceReported {
    // True if shutdown is for a reboot. Default: false if we do not know.
    optional bool reboot = 1;

    // Reason for shutdown. Eg: userrequested. Default: "<EMPTY>".
    optional string reason = 2;

    // Beginning of shutdown time in ms using wall clock time since unix epoch.
    // Default: 0 if no start time received.
    optional int64 start_time_ms = 3;

    // Duration of shutdown in ms. Default: 0 if no duration received.
    optional int64 duration_ms = 4;
}

/**
 * Logs phone signal strength changes.
 *
+64 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.text.TextUtils;
import android.util.AtomicFile;
import android.util.EventLog;
import android.util.Slog;
import android.util.StatsLog;
import android.util.Xml;

import com.android.internal.annotations.VisibleForTesting;
@@ -112,6 +113,8 @@ public class BootReceiver extends BroadcastReceiver {
    private static final String SHUTDOWN_METRICS_FILE = "/data/system/shutdown-metrics.txt";

    private static final String SHUTDOWN_TRON_METRICS_PREFIX = "shutdown_";
    private static final String METRIC_SYSTEM_SERVER = "shutdown_system_server";
    private static final String METRIC_SHUTDOWN_TIME_START = "begin_shutdown";

    @Override
    public void onReceive(final Context context, Intent intent) {
@@ -401,6 +404,10 @@ public class BootReceiver extends BroadcastReceiver {
            }
        }
        if (!TextUtils.isEmpty(metricsStr)) {
            String reboot = null;
            String reason = null;
            String start_time = null;
            String duration = null;
            String[] array = metricsStr.split(",");
            for (String keyValueStr : array) {
                String[] keyValue = keyValueStr.split(":");
@@ -411,8 +418,19 @@ public class BootReceiver extends BroadcastReceiver {
                // Ignore keys that are not indended for tron
                if (keyValue[0].startsWith(SHUTDOWN_TRON_METRICS_PREFIX)) {
                    logTronShutdownMetric(keyValue[0], keyValue[1]);
                    if (keyValue[0].equals(METRIC_SYSTEM_SERVER)) {
                        duration = keyValue[1];
                    }
                }
                if (keyValue[0].equals("reboot")) {
                    reboot = keyValue[1];
                } else if (keyValue[0].equals("reason")) {
                    reason = keyValue[1];
                } else if (keyValue[0].equals(METRIC_SHUTDOWN_TIME_START)) {
                    start_time = keyValue[1];
                }
            }
            logStatsdShutdownAtom(reboot, reason, start_time, duration);
        }
        metricsFile.delete();
    }
@@ -430,6 +448,52 @@ public class BootReceiver extends BroadcastReceiver {
        }
    }

    private static void logStatsdShutdownAtom(
            String rebootStr, String reasonStr, String startStr, String durationStr) {
        boolean reboot = false;
        String reason = "<EMPTY>";
        long start = 0;
        long duration = 0;

        if (rebootStr != null) {
            if (rebootStr.equals("y")) {
                reboot = true;
            } else if (!rebootStr.equals("n")) {
                Slog.e(TAG, "Unexpected value for reboot : " + rebootStr);
            }
        } else {
            Slog.e(TAG, "No value received for reboot");
        }

        if (reasonStr != null) {
            reason = reasonStr;
        } else {
            Slog.e(TAG, "No value received for shutdown reason");
        }

        if (startStr != null) {
            try {
                start = Long.parseLong(startStr);
            } catch (NumberFormatException e) {
                Slog.e(TAG, "Cannot parse shutdown start time: " + startStr);
            }
        } else {
            Slog.e(TAG, "No value received for shutdown start time");
        }

        if (durationStr != null) {
            try {
                duration = Long.parseLong(durationStr);
            } catch (NumberFormatException e) {
                Slog.e(TAG, "Cannot parse shutdown duration: " + startStr);
            }
        } else {
            Slog.e(TAG, "No value received for shutdown duration");
        }

        StatsLog.write(StatsLog.SHUTDOWN_SEQUENCE_REPORTED, reboot, reason, start, duration);
    }

    private static void logFsShutdownTime() {
        File f = null;
        for (String fileName : LAST_KMSG_FILES) {
+11 −2
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ public final class ShutdownThread extends Thread {
    private static String METRIC_PM = "shutdown_package_manager";
    private static String METRIC_RADIOS = "shutdown_radios";
    private static String METRIC_RADIO = "shutdown_radio";
    private static String METRIC_SHUTDOWN_TIME_START = "begin_shutdown";

    private final Object mActionDoneSync = new Object();
    private boolean mActionDone;
@@ -410,6 +411,7 @@ public final class ShutdownThread extends Thread {
    public void run() {
        TimingsTraceLog shutdownTimingLog = newTimingsLog();
        shutdownTimingLog.traceBegin("SystemServerShutdown");
        metricShutdownStart();
        metricStarted(METRIC_SYSTEM_SERVER);

        BroadcastReceiver br = new BroadcastReceiver() {
@@ -525,7 +527,7 @@ public final class ShutdownThread extends Thread {

        shutdownTimingLog.traceEnd(); // SystemServerShutdown
        metricEnded(METRIC_SYSTEM_SERVER);
        saveMetrics(mReboot);
        saveMetrics(mReboot, mReason);
        // Remaining work will be done by init, including vold shutdown
        rebootOrShutdown(mContext, mReboot, mReason);
    }
@@ -547,6 +549,12 @@ public final class ShutdownThread extends Thread {
        }
    }

    private static void metricShutdownStart() {
        synchronized (TRON_METRICS) {
            TRON_METRICS.put(METRIC_SHUTDOWN_TIME_START, System.currentTimeMillis());
        }
    }

    private void setRebootProgress(final int progress, final CharSequence message) {
        mHandler.post(new Runnable() {
            @Override
@@ -668,10 +676,11 @@ public final class ShutdownThread extends Thread {
        PowerManagerService.lowLevelShutdown(reason);
    }

    private static void saveMetrics(boolean reboot) {
    private static void saveMetrics(boolean reboot, String reason) {
        StringBuilder metricValue = new StringBuilder();
        metricValue.append("reboot:");
        metricValue.append(reboot ? "y" : "n");
        metricValue.append(",").append("reason:").append(reason);
        final int metricsSize = TRON_METRICS.size();
        for (int i = 0; i < metricsSize; i++) {
            final String name = TRON_METRICS.keyAt(i);