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

Commit f23b64df authored by Svetoslav's avatar Svetoslav
Browse files

Perform idle maintenance when the device is charging.

Added the precondition that the device should be charging to the
existing ones of the device not being used for awhile and the
battery level being high enough. Note that even if the device is
charging, we have to check the battery level since the user can
unplug it at any time.

bug:8688454

Change-Id: I709b1620571301743dc3504a6a625e2018951bfa
parent 7c98c196
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -162,3 +162,15 @@ option java_package com.android.server
# IntentFirewall.java
# IntentFirewall.java
# ---------------------------
# ---------------------------
51400 ifw_intent_matched (Intent Type|1|5),(Component Name|3),(Caller Uid|1|5),(Caller Pkg Count|1|1),(Caller Pkgs|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5)
51400 ifw_intent_matched (Intent Type|1|5),(Component Name|3),(Caller Uid|1|5),(Caller Pkg Count|1|1),(Caller Pkgs|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5)

# ---------------------------
# IdleMaintenanceService.java
# ---------------------------
2753 idle_maintenance_window_start (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
2754 idle_maintenance_window_finish (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)

# ---------------------------
# MountService.java
# ---------------------------
2755 fstrim_start (time|2|3)
2756 fstrim_finish (time|2|3)
+36 −30
Original line number Original line Diff line number Diff line
@@ -30,9 +30,6 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.Log;
import android.util.Log;


import java.util.Calendar;
import java.util.TimeZone;

/**
/**
 * This service observes the device state and when applicable sends
 * This service observes the device state and when applicable sends
 * broadcasts at the beginning and at the end of a period during which
 * broadcasts at the beginning and at the end of a period during which
@@ -57,9 +54,15 @@ public class IdleMaintenanceService extends BroadcastReceiver {


    private static final int LAST_USER_ACTIVITY_TIME_INVALID = -1;
    private static final int LAST_USER_ACTIVITY_TIME_INVALID = -1;


    private static final int MIN_IDLE_MAINTENANCE_START_BATTERY_LEVEL = 20; // percent
    private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;

    private static final int MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_CHARGING = 30; // percent

    private static final int MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_NOT_CHARGING = 80; // percent


    private static final long MIN_IDLE_MAINTENANCE_START_USER_INACTIVITY = 60 * 60 * 1000; // 1 hour
    private static final int MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_RUNNING = 10; // percent

    private static final long MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START = 60 * 60 * 1000; // 1 hour


    private final Intent mIdleMaintenanceStartIntent =
    private final Intent mIdleMaintenanceStartIntent =
            new Intent(Intent.ACTION_IDLE_MAINTENANCE_START);
            new Intent(Intent.ACTION_IDLE_MAINTENANCE_START);
@@ -73,14 +76,14 @@ public class IdleMaintenanceService extends BroadcastReceiver {


    private final Handler mHandler;
    private final Handler mHandler;


    private final Calendar mTempCalendar = Calendar.getInstance();
    private long mLastIdleMaintenanceStartTimeMillis = SystemClock.elapsedRealtime();

    private final Calendar mLastIdleMaintenanceStartTime = Calendar.getInstance();


    private long mLastUserActivityElapsedTimeMillis = LAST_USER_ACTIVITY_TIME_INVALID;
    private long mLastUserActivityElapsedTimeMillis = LAST_USER_ACTIVITY_TIME_INVALID;


    private int mBatteryLevel;
    private int mBatteryLevel;


    private boolean mBatteryCharging;

    private boolean mIdleMaintenanceStarted;
    private boolean mIdleMaintenanceStarted;


    public IdleMaintenanceService(Context context) {
    public IdleMaintenanceService(Context context) {
@@ -91,10 +94,6 @@ public class IdleMaintenanceService extends BroadcastReceiver {


        mHandler = new Handler(mContext.getMainLooper());
        mHandler = new Handler(mContext.getMainLooper());


        // Move one day back so we can run maintenance the first day after starting.
        final int prevDayOfYear = mLastIdleMaintenanceStartTime.get(Calendar.DAY_OF_YEAR) - 1;
        mLastIdleMaintenanceStartTime.set(Calendar.DAY_OF_YEAR, prevDayOfYear);

        register(mContext.getMainLooper());
        register(mContext.getMainLooper());
    }
    }


@@ -120,15 +119,21 @@ public class IdleMaintenanceService extends BroadcastReceiver {
        if (mIdleMaintenanceStarted) {
        if (mIdleMaintenanceStarted) {
            // Idle maintenance can be interrupted only by
            // Idle maintenance can be interrupted only by
            // a change of the device state.
            // a change of the device state.
            if (!deviceStatePermitsIdleMaintenance()) {
            if (!deviceStatePermitsIdleMaintenanceRunning()) {
                mIdleMaintenanceStarted = false;
                mIdleMaintenanceStarted = false;
                EventLogTags.writeIdleMaintenanceWindowFinish(SystemClock.elapsedRealtime(),
                        mLastUserActivityElapsedTimeMillis, mBatteryLevel,
                        mBatteryCharging ? 1 : 0);
                sendIdleMaintenanceEndIntent();
                sendIdleMaintenanceEndIntent();
            }
            }
        } else if (deviceStatePermitsIdleMaintenance()
        } else if (deviceStatePermitsIdleMaintenanceStart()
                && lastUserActivityPermitsIdleMaintenanceStart()
                && lastUserActivityPermitsIdleMaintenanceStart()
                && lastRunPermitsIdleMaintenanceStart()) {
                && lastRunPermitsIdleMaintenanceStart()) {
            mIdleMaintenanceStarted = true;
            mIdleMaintenanceStarted = true;
            mLastIdleMaintenanceStartTime.setTimeInMillis(System.currentTimeMillis());
            EventLogTags.writeIdleMaintenanceWindowStart(SystemClock.elapsedRealtime(),
                    mLastUserActivityElapsedTimeMillis, mBatteryLevel,
                    mBatteryCharging ? 1 : 0);
            mLastIdleMaintenanceStartTimeMillis = SystemClock.elapsedRealtime();
            sendIdleMaintenanceStartIntent();
            sendIdleMaintenanceStartIntent();
        }
        }
    }
    }
@@ -151,29 +156,26 @@ public class IdleMaintenanceService extends BroadcastReceiver {
                null, this, mHandler, Activity.RESULT_OK, null, null);
                null, this, mHandler, Activity.RESULT_OK, null, null);
    }
    }


    private boolean deviceStatePermitsIdleMaintenance() {
    private boolean deviceStatePermitsIdleMaintenanceStart() {
        final int minBatteryLevel = mBatteryCharging
                ? MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_CHARGING
                : MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_NOT_CHARGING;
        return (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
                && mBatteryLevel > minBatteryLevel);
    }

    private boolean deviceStatePermitsIdleMaintenanceRunning() {
        return (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
        return (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
                && mBatteryLevel > MIN_IDLE_MAINTENANCE_START_BATTERY_LEVEL);
                && mBatteryLevel > MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_RUNNING);
    }
    }


    private boolean lastUserActivityPermitsIdleMaintenanceStart() {
    private boolean lastUserActivityPermitsIdleMaintenanceStart() {
        return (SystemClock.elapsedRealtime() - mLastUserActivityElapsedTimeMillis
        return (SystemClock.elapsedRealtime() - mLastUserActivityElapsedTimeMillis
                > MIN_IDLE_MAINTENANCE_START_USER_INACTIVITY);
                > MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START);
    }
    }


    private boolean lastRunPermitsIdleMaintenanceStart() {
    private boolean lastRunPermitsIdleMaintenanceStart() {
        Calendar now = mTempCalendar;
        return SystemClock.elapsedRealtime() - mLastIdleMaintenanceStartTimeMillis > MILLIS_IN_DAY;
        // Not setting the Locale since we do not care of locale
        // specific properties such as the first day of the week.
        now.setTimeZone(TimeZone.getDefault());
        now.setTimeInMillis(System.currentTimeMillis());

        Calendar lastRun = mLastIdleMaintenanceStartTime;
        // Not setting the Locale since we do not care of locale
        // specific properties such as the first day of the week.
        lastRun.setTimeZone(TimeZone.getDefault());

        return now.get(Calendar.DAY_OF_YEAR) != lastRun.get(Calendar.DAY_OF_YEAR);
    }
    }


    @Override
    @Override
@@ -186,6 +188,10 @@ public class IdleMaintenanceService extends BroadcastReceiver {
            final int maxBatteryLevel = intent.getExtras().getInt(BatteryManager.EXTRA_SCALE);
            final int maxBatteryLevel = intent.getExtras().getInt(BatteryManager.EXTRA_SCALE);
            final int currBatteryLevel = intent.getExtras().getInt(BatteryManager.EXTRA_LEVEL);
            final int currBatteryLevel = intent.getExtras().getInt(BatteryManager.EXTRA_LEVEL);
            mBatteryLevel = (int) (((float) maxBatteryLevel / 100) * currBatteryLevel);
            mBatteryLevel = (int) (((float) maxBatteryLevel / 100) * currBatteryLevel);
            final int pluggedState = intent.getExtras().getInt(BatteryManager.EXTRA_PLUGGED);
            final int chargerState = intent.getExtras().getInt(
                    BatteryManager.EXTRA_INVALID_CHARGER, 0);
            mBatteryCharging = (pluggedState > 0 && chargerState == 0);
        } else if (Intent.ACTION_SCREEN_ON.equals(action)
        } else if (Intent.ACTION_SCREEN_ON.equals(action)
                || Intent.ACTION_DREAMING_STOPPED.equals(action)) {
                || Intent.ACTION_DREAMING_STOPPED.equals(action)) {
            mLastUserActivityElapsedTimeMillis = LAST_USER_ACTIVITY_TIME_INVALID;
            mLastUserActivityElapsedTimeMillis = LAST_USER_ACTIVITY_TIME_INVALID;
+12 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Binder;
import android.os.Environment;
import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.Environment.UserEnvironment;
import android.os.Build;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IBinder;
@@ -43,6 +44,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.storage.IMountService;
import android.os.storage.IMountService;
@@ -173,6 +175,11 @@ class MountService extends IMountService.Stub
        public static final int VolumeDiskInserted             = 630;
        public static final int VolumeDiskInserted             = 630;
        public static final int VolumeDiskRemoved              = 631;
        public static final int VolumeDiskRemoved              = 631;
        public static final int VolumeBadRemoval               = 632;
        public static final int VolumeBadRemoval               = 632;

        /*
         * 700 series - fstrim
         */
        public static final int FstrimCompleted                = 700;
    }
    }


    private Context mContext;
    private Context mContext;
@@ -609,6 +616,7 @@ class MountService extends IMountService.Stub
                    // This method runs on the handler thread,
                    // This method runs on the handler thread,
                    // so it is safe to directly call into vold.
                    // so it is safe to directly call into vold.
                    mConnector.execute("fstrim", "dotrim");
                    mConnector.execute("fstrim", "dotrim");
                    EventLogTags.writeFstrimStart(SystemClock.elapsedRealtime());
                } catch (NativeDaemonConnectorException ndce) {
                } catch (NativeDaemonConnectorException ndce) {
                    Slog.e(TAG, "Failed to run fstrim!");
                    Slog.e(TAG, "Failed to run fstrim!");
                }
                }
@@ -857,6 +865,10 @@ class MountService extends IMountService.Stub
                if (DEBUG_EVENTS) Slog.i(TAG, "Sending media bad removal");
                if (DEBUG_EVENTS) Slog.i(TAG, "Sending media bad removal");
                updatePublicVolumeState(volume, Environment.MEDIA_BAD_REMOVAL);
                updatePublicVolumeState(volume, Environment.MEDIA_BAD_REMOVAL);
                action = Intent.ACTION_MEDIA_BAD_REMOVAL;
                action = Intent.ACTION_MEDIA_BAD_REMOVAL;
            } else if (code == VoldResponseCode.FstrimCompleted) {
                if (Build.IS_DEBUGGABLE) {
                    EventLogTags.writeFstrimFinish(SystemClock.elapsedRealtime());
                }
            } else {
            } else {
                Slog.e(TAG, String.format("Unknown code {%d}", code));
                Slog.e(TAG, String.format("Unknown code {%d}", code));
            }
            }