Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +152 −15 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Binder; Loading Loading @@ -250,8 +252,6 @@ public class JobSchedulerService extends com.android.server.SystemService */ private final List<RestrictingController> mRestrictiveControllers; /** Need direct access to this for testing. */ private final BatteryController mBatteryController; /** Need direct access to this for testing. */ private final StorageController mStorageController; /** Need directly for sending uid state changes */ private final DeviceIdleJobsController mDeviceIdleJobsController; Loading @@ -268,6 +268,9 @@ public class JobSchedulerService extends com.android.server.SystemService */ private final List<JobRestriction> mJobRestrictions; @GuardedBy("mLock") private final BatteryStateTracker mBatteryStateTracker; @NonNull private final String mSystemGalleryPackage; Loading Loading @@ -1697,6 +1700,9 @@ public class JobSchedulerService extends com.android.server.SystemService // Initialize the job store and set up any persisted jobs mJobs = JobStore.initAndGet(this); mBatteryStateTracker = new BatteryStateTracker(); mBatteryStateTracker.startTracking(); // Create the controllers. mControllers = new ArrayList<StateController>(); final ConnectivityController connectivityController = new ConnectivityController(this); Loading @@ -1704,8 +1710,8 @@ public class JobSchedulerService extends com.android.server.SystemService mControllers.add(new TimeController(this)); final IdleController idleController = new IdleController(this); mControllers.add(idleController); mBatteryController = new BatteryController(this); mControllers.add(mBatteryController); final BatteryController batteryController = new BatteryController(this); mControllers.add(batteryController); mStorageController = new StorageController(this); mControllers.add(mStorageController); final BackgroundJobsController backgroundJobsController = Loading @@ -1725,7 +1731,7 @@ public class JobSchedulerService extends com.android.server.SystemService mControllers.add(mTareController); mRestrictiveControllers = new ArrayList<>(); mRestrictiveControllers.add(mBatteryController); mRestrictiveControllers.add(batteryController); mRestrictiveControllers.add(connectivityController); mRestrictiveControllers.add(idleController); Loading Loading @@ -2818,6 +2824,129 @@ public class JobSchedulerService extends com.android.server.SystemService return adjustJobBias(bias, job); } private final class BatteryStateTracker extends BroadcastReceiver { /** * Track whether we're "charging", where charging means that we're ready to commit to * doing work. */ private boolean mCharging; /** Keep track of whether the battery is charged enough that we want to do work. */ private boolean mBatteryNotLow; /** Sequence number of last broadcast. */ private int mLastBatterySeq = -1; private BroadcastReceiver mMonitor; BatteryStateTracker() { } public void startTracking() { IntentFilter filter = new IntentFilter(); // Battery health. filter.addAction(Intent.ACTION_BATTERY_LOW); filter.addAction(Intent.ACTION_BATTERY_OKAY); // Charging/not charging. filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); getTestableContext().registerReceiver(this, filter); // Initialise tracker state. BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); mBatteryNotLow = !batteryManagerInternal.getBatteryLevelLow(); mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); } public void setMonitorBatteryLocked(boolean enabled) { if (enabled) { if (mMonitor == null) { mMonitor = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); getTestableContext().registerReceiver(mMonitor, filter); } } else if (mMonitor != null) { getTestableContext().unregisterReceiver(mMonitor); mMonitor = null; } } public boolean isCharging() { return mCharging; } public boolean isBatteryNotLow() { return mBatteryNotLow; } public boolean isMonitoring() { return mMonitor != null; } public int getSeq() { return mLastBatterySeq; } @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } @VisibleForTesting public void onReceiveInternal(Intent intent) { synchronized (mLock) { final String action = intent.getAction(); boolean changed = false; if (Intent.ACTION_BATTERY_LOW.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery life too low @ " + sElapsedRealtimeClock.millis()); } if (mBatteryNotLow) { mBatteryNotLow = false; changed = true; } } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery high enough @ " + sElapsedRealtimeClock.millis()); } if (!mBatteryNotLow) { mBatteryNotLow = true; changed = true; } } else if (BatteryManager.ACTION_CHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery charging @ " + sElapsedRealtimeClock.millis()); } if (!mCharging) { mCharging = true; changed = true; } } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Disconnected from power @ " + sElapsedRealtimeClock.millis()); } if (mCharging) { mCharging = false; changed = true; } } mLastBatterySeq = intent.getIntExtra(BatteryManager.EXTRA_SEQUENCE, mLastBatterySeq); if (changed) { for (int c = mControllers.size() - 1; c >= 0; --c) { mControllers.get(c).onBatteryStateChangedLocked(); } } } } } final class LocalService implements JobSchedulerInternal { /** Loading Loading @@ -3417,29 +3546,27 @@ public class JobSchedulerService extends com.android.server.SystemService void setMonitorBattery(boolean enabled) { synchronized (mLock) { if (mBatteryController != null) { mBatteryController.getTracker().setMonitorBatteryLocked(enabled); } mBatteryStateTracker.setMonitorBatteryLocked(enabled); } } int getBatterySeq() { synchronized (mLock) { return mBatteryController != null ? mBatteryController.getTracker().getSeq() : -1; return mBatteryStateTracker.getSeq(); } } boolean getBatteryCharging() { /** Return {@code true} if the device is currently charging. */ public boolean isBatteryCharging() { synchronized (mLock) { return mBatteryController != null ? mBatteryController.getTracker().isOnStablePower() : false; return mBatteryStateTracker.isCharging(); } } boolean getBatteryNotLow() { /** Return {@code true} if the battery is not low. */ public boolean isBatteryNotLow() { synchronized (mLock) { return mBatteryController != null ? mBatteryController.getTracker().isBatteryNotLow() : false; return mBatteryStateTracker.isBatteryNotLow(); } } Loading Loading @@ -3614,6 +3741,16 @@ public class JobSchedulerService extends com.android.server.SystemService mQuotaTracker.dump(pw); pw.println(); pw.print("Battery charging: "); pw.println(mBatteryStateTracker.isCharging()); pw.print("Battery not low: "); pw.println(mBatteryStateTracker.isBatteryNotLow()); if (mBatteryStateTracker.isMonitoring()) { pw.print("MONITORING: seq="); pw.println(mBatteryStateTracker.getSeq()); } pw.println(); pw.println("Started users: " + Arrays.toString(mStartedUsers)); pw.print("Registered "); pw.print(mJobs.size()); Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java +2 −2 Original line number Diff line number Diff line Loading @@ -293,13 +293,13 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { } private int getBatteryCharging(PrintWriter pw) { boolean val = mInternal.getBatteryCharging(); boolean val = mInternal.isBatteryCharging(); pw.println(val); return 0; } private int getBatteryNotLow(PrintWriter pw) { boolean val = mInternal.getBatteryNotLow(); boolean val = mInternal.isBatteryNotLow(); pw.println(val); return 0; } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +23 −152 Original line number Diff line number Diff line Loading @@ -18,12 +18,6 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.UserHandle; import android.util.ArraySet; import android.util.IndentingPrintWriter; Loading @@ -31,8 +25,8 @@ import android.util.Log; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.internal.annotations.GuardedBy; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.job.JobSchedulerService; import com.android.server.job.StateControllerProto; Loading @@ -49,17 +43,9 @@ public final class BatteryController extends RestrictingController { || Log.isLoggable(TAG, Log.DEBUG); private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>(); private ChargingTracker mChargeTracker; @VisibleForTesting public ChargingTracker getTracker() { return mChargeTracker; } public BatteryController(JobSchedulerService service) { super(service); mChargeTracker = new ChargingTracker(); mChargeTracker.startTracking(); } @Override Loading @@ -68,9 +54,9 @@ public final class BatteryController extends RestrictingController { final long nowElapsed = sElapsedRealtimeClock.millis(); mTrackedTasks.add(taskStatus); taskStatus.setTrackingController(JobStatus.TRACKING_BATTERY); taskStatus.setChargingConstraintSatisfied(nowElapsed, mChargeTracker.isOnStablePower()); taskStatus.setBatteryNotLowConstraintSatisfied( nowElapsed, mChargeTracker.isBatteryNotLow()); taskStatus.setChargingConstraintSatisfied(nowElapsed, mService.isBatteryCharging() && mService.isBatteryNotLow()); taskStatus.setBatteryNotLowConstraintSatisfied(nowElapsed, mService.isBatteryNotLow()); } } Loading @@ -93,9 +79,21 @@ public final class BatteryController extends RestrictingController { } } @Override @GuardedBy("mLock") public void onBatteryStateChangedLocked() { // Update job bookkeeping out of band. JobSchedulerBackgroundThread.getHandler().post(() -> { synchronized (mLock) { maybeReportNewChargingStateLocked(); } }); } @GuardedBy("mLock") private void maybeReportNewChargingStateLocked() { final boolean stablePower = mChargeTracker.isOnStablePower(); final boolean batteryNotLow = mChargeTracker.isBatteryNotLow(); final boolean stablePower = mService.isBatteryCharging() && mService.isBatteryNotLow(); final boolean batteryNotLow = mService.isBatteryNotLow(); if (DEBUG) { Slog.d(TAG, "maybeReportNewChargingStateLocked: " + stablePower); } Loading @@ -116,133 +114,11 @@ public final class BatteryController extends RestrictingController { } } public final class ChargingTracker extends BroadcastReceiver { /** * Track whether we're "charging", where charging means that we're ready to commit to * doing work. */ private boolean mCharging; /** Keep track of whether the battery is charged enough that we want to do work. */ private boolean mBatteryHealthy; /** Sequence number of last broadcast. */ private int mLastBatterySeq = -1; private BroadcastReceiver mMonitor; public ChargingTracker() { } public void startTracking() { IntentFilter filter = new IntentFilter(); // Battery health. filter.addAction(Intent.ACTION_BATTERY_LOW); filter.addAction(Intent.ACTION_BATTERY_OKAY); // Charging/not charging. filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(this, filter); // Initialise tracker state. BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); mBatteryHealthy = !batteryManagerInternal.getBatteryLevelLow(); mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); } public void setMonitorBatteryLocked(boolean enabled) { if (enabled) { if (mMonitor == null) { mMonitor = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ChargingTracker.this.onReceive(context, intent); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); mContext.registerReceiver(mMonitor, filter); } } else { if (mMonitor != null) { mContext.unregisterReceiver(mMonitor); mMonitor = null; } } } public boolean isOnStablePower() { return mCharging && mBatteryHealthy; } public boolean isBatteryNotLow() { return mBatteryHealthy; } public boolean isMonitoring() { return mMonitor != null; } public int getSeq() { return mLastBatterySeq; } @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } @VisibleForTesting public void onReceiveInternal(Intent intent) { synchronized (mLock) { final String action = intent.getAction(); if (Intent.ACTION_BATTERY_LOW.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery life too low to do work. @ " + sElapsedRealtimeClock.millis()); } // If we get this action, the battery is discharging => it isn't plugged in so // there's no work to cancel. We track this variable for the case where it is // charging, but hasn't been for long enough to be healthy. mBatteryHealthy = false; maybeReportNewChargingStateLocked(); } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery life healthy enough to do work. @ " + sElapsedRealtimeClock.millis()); } mBatteryHealthy = true; maybeReportNewChargingStateLocked(); } else if (BatteryManager.ACTION_CHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Received charging intent, fired @ " + sElapsedRealtimeClock.millis()); } mCharging = true; maybeReportNewChargingStateLocked(); } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Disconnected from power."); } mCharging = false; maybeReportNewChargingStateLocked(); } mLastBatterySeq = intent.getIntExtra(BatteryManager.EXTRA_SEQUENCE, mLastBatterySeq); } } } @Override public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) { pw.println("Stable power: " + mChargeTracker.isOnStablePower()); pw.println("Not low: " + mChargeTracker.isBatteryNotLow()); if (mChargeTracker.isMonitoring()) { pw.print("MONITORING: seq="); pw.println(mChargeTracker.getSeq()); } pw.println(); pw.println("Stable power: " + (mService.isBatteryCharging() && mService.isBatteryNotLow())); pw.println("Not low: " + mService.isBatteryNotLow()); for (int i = 0; i < mTrackedTasks.size(); i++) { final JobStatus js = mTrackedTasks.valueAt(i); Loading @@ -264,14 +140,9 @@ public final class BatteryController extends RestrictingController { final long mToken = proto.start(StateControllerProto.BATTERY); proto.write(StateControllerProto.BatteryController.IS_ON_STABLE_POWER, mChargeTracker.isOnStablePower()); mService.isBatteryCharging() && mService.isBatteryNotLow()); proto.write(StateControllerProto.BatteryController.IS_BATTERY_NOT_LOW, mChargeTracker.isBatteryNotLow()); proto.write(StateControllerProto.BatteryController.IS_MONITORING, mChargeTracker.isMonitoring()); proto.write(StateControllerProto.BatteryController.LAST_BROADCAST_SEQUENCE_NUMBER, mChargeTracker.getSeq()); mService.isBatteryNotLow()); for (int i = 0; i < mTrackedTasks.size(); i++) { final JobStatus js = mTrackedTasks.valueAt(i); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +13 −57 Original line number Diff line number Diff line Loading @@ -25,18 +25,12 @@ import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.job.JobInfo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; import android.net.NetworkRequest; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading @@ -55,6 +49,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; import com.android.server.job.JobSchedulerService.Constants; Loading Loading @@ -107,8 +102,6 @@ public final class ConnectivityController extends RestrictingController implemen private final ConnectivityManager mConnManager; private final NetworkPolicyManagerInternal mNetPolicyManagerInternal; private final ChargingTracker mChargingTracker; /** List of tracked jobs keyed by source UID. */ @GuardedBy("mLock") private final SparseArray<ArraySet<JobStatus>> mTrackedJobs = new SparseArray<>(); Loading Loading @@ -237,9 +230,6 @@ public final class ConnectivityController extends RestrictingController implemen // network changes against the active network for each UID with jobs. final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); mConnManager.registerNetworkCallback(request, mNetworkCallback); mChargingTracker = new ChargingTracker(); mChargingTracker.startTracking(); } @GuardedBy("mLock") Loading Loading @@ -535,6 +525,17 @@ public final class ConnectivityController extends RestrictingController implemen } } @Override @GuardedBy("mLock") public void onBatteryStateChangedLocked() { // Update job bookkeeping out of band to avoid blocking broadcast progress. JobSchedulerBackgroundThread.getHandler().post(() -> { synchronized (mLock) { updateTrackedJobsLocked(-1, null); } }); } private boolean isUsable(NetworkCapabilities capabilities) { return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED); Loading Loading @@ -591,7 +592,7 @@ public final class ConnectivityController extends RestrictingController implemen // Minimum chunk size isn't defined. Check using the estimated upload/download sizes. if (capabilities.hasCapability(NET_CAPABILITY_NOT_METERED) && mChargingTracker.isCharging()) { && mService.isBatteryCharging()) { // We're charging and on an unmetered network. We don't have to be as conservative about // making sure the job will run within its max execution time. Let's just hope the app // supports interruptible work. Loading Loading @@ -1072,51 +1073,6 @@ public final class ConnectivityController extends RestrictingController implemen } } private final class ChargingTracker extends BroadcastReceiver { /** * Track whether we're "charging", where charging means that we're ready to commit to * doing work. */ private boolean mCharging; ChargingTracker() {} public void startTracking() { IntentFilter filter = new IntentFilter(); filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(this, filter); // Initialise tracker state. final BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); } public boolean isCharging() { return mCharging; } @Override public void onReceive(Context context, Intent intent) { synchronized (mLock) { final String action = intent.getAction(); if (BatteryManager.ACTION_CHARGING.equals(action)) { if (mCharging) { return; } mCharging = true; } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) { if (!mCharging) { return; } mCharging = false; } updateTrackedJobsLocked(-1, null); } } } private final NetworkCallback mNetworkCallback = new NetworkCallback() { @Override public void onAvailable(Network network) { Loading apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +23 −68 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +152 −15 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Binder; Loading Loading @@ -250,8 +252,6 @@ public class JobSchedulerService extends com.android.server.SystemService */ private final List<RestrictingController> mRestrictiveControllers; /** Need direct access to this for testing. */ private final BatteryController mBatteryController; /** Need direct access to this for testing. */ private final StorageController mStorageController; /** Need directly for sending uid state changes */ private final DeviceIdleJobsController mDeviceIdleJobsController; Loading @@ -268,6 +268,9 @@ public class JobSchedulerService extends com.android.server.SystemService */ private final List<JobRestriction> mJobRestrictions; @GuardedBy("mLock") private final BatteryStateTracker mBatteryStateTracker; @NonNull private final String mSystemGalleryPackage; Loading Loading @@ -1697,6 +1700,9 @@ public class JobSchedulerService extends com.android.server.SystemService // Initialize the job store and set up any persisted jobs mJobs = JobStore.initAndGet(this); mBatteryStateTracker = new BatteryStateTracker(); mBatteryStateTracker.startTracking(); // Create the controllers. mControllers = new ArrayList<StateController>(); final ConnectivityController connectivityController = new ConnectivityController(this); Loading @@ -1704,8 +1710,8 @@ public class JobSchedulerService extends com.android.server.SystemService mControllers.add(new TimeController(this)); final IdleController idleController = new IdleController(this); mControllers.add(idleController); mBatteryController = new BatteryController(this); mControllers.add(mBatteryController); final BatteryController batteryController = new BatteryController(this); mControllers.add(batteryController); mStorageController = new StorageController(this); mControllers.add(mStorageController); final BackgroundJobsController backgroundJobsController = Loading @@ -1725,7 +1731,7 @@ public class JobSchedulerService extends com.android.server.SystemService mControllers.add(mTareController); mRestrictiveControllers = new ArrayList<>(); mRestrictiveControllers.add(mBatteryController); mRestrictiveControllers.add(batteryController); mRestrictiveControllers.add(connectivityController); mRestrictiveControllers.add(idleController); Loading Loading @@ -2818,6 +2824,129 @@ public class JobSchedulerService extends com.android.server.SystemService return adjustJobBias(bias, job); } private final class BatteryStateTracker extends BroadcastReceiver { /** * Track whether we're "charging", where charging means that we're ready to commit to * doing work. */ private boolean mCharging; /** Keep track of whether the battery is charged enough that we want to do work. */ private boolean mBatteryNotLow; /** Sequence number of last broadcast. */ private int mLastBatterySeq = -1; private BroadcastReceiver mMonitor; BatteryStateTracker() { } public void startTracking() { IntentFilter filter = new IntentFilter(); // Battery health. filter.addAction(Intent.ACTION_BATTERY_LOW); filter.addAction(Intent.ACTION_BATTERY_OKAY); // Charging/not charging. filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); getTestableContext().registerReceiver(this, filter); // Initialise tracker state. BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); mBatteryNotLow = !batteryManagerInternal.getBatteryLevelLow(); mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); } public void setMonitorBatteryLocked(boolean enabled) { if (enabled) { if (mMonitor == null) { mMonitor = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); getTestableContext().registerReceiver(mMonitor, filter); } } else if (mMonitor != null) { getTestableContext().unregisterReceiver(mMonitor); mMonitor = null; } } public boolean isCharging() { return mCharging; } public boolean isBatteryNotLow() { return mBatteryNotLow; } public boolean isMonitoring() { return mMonitor != null; } public int getSeq() { return mLastBatterySeq; } @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } @VisibleForTesting public void onReceiveInternal(Intent intent) { synchronized (mLock) { final String action = intent.getAction(); boolean changed = false; if (Intent.ACTION_BATTERY_LOW.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery life too low @ " + sElapsedRealtimeClock.millis()); } if (mBatteryNotLow) { mBatteryNotLow = false; changed = true; } } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery high enough @ " + sElapsedRealtimeClock.millis()); } if (!mBatteryNotLow) { mBatteryNotLow = true; changed = true; } } else if (BatteryManager.ACTION_CHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery charging @ " + sElapsedRealtimeClock.millis()); } if (!mCharging) { mCharging = true; changed = true; } } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Disconnected from power @ " + sElapsedRealtimeClock.millis()); } if (mCharging) { mCharging = false; changed = true; } } mLastBatterySeq = intent.getIntExtra(BatteryManager.EXTRA_SEQUENCE, mLastBatterySeq); if (changed) { for (int c = mControllers.size() - 1; c >= 0; --c) { mControllers.get(c).onBatteryStateChangedLocked(); } } } } } final class LocalService implements JobSchedulerInternal { /** Loading Loading @@ -3417,29 +3546,27 @@ public class JobSchedulerService extends com.android.server.SystemService void setMonitorBattery(boolean enabled) { synchronized (mLock) { if (mBatteryController != null) { mBatteryController.getTracker().setMonitorBatteryLocked(enabled); } mBatteryStateTracker.setMonitorBatteryLocked(enabled); } } int getBatterySeq() { synchronized (mLock) { return mBatteryController != null ? mBatteryController.getTracker().getSeq() : -1; return mBatteryStateTracker.getSeq(); } } boolean getBatteryCharging() { /** Return {@code true} if the device is currently charging. */ public boolean isBatteryCharging() { synchronized (mLock) { return mBatteryController != null ? mBatteryController.getTracker().isOnStablePower() : false; return mBatteryStateTracker.isCharging(); } } boolean getBatteryNotLow() { /** Return {@code true} if the battery is not low. */ public boolean isBatteryNotLow() { synchronized (mLock) { return mBatteryController != null ? mBatteryController.getTracker().isBatteryNotLow() : false; return mBatteryStateTracker.isBatteryNotLow(); } } Loading Loading @@ -3614,6 +3741,16 @@ public class JobSchedulerService extends com.android.server.SystemService mQuotaTracker.dump(pw); pw.println(); pw.print("Battery charging: "); pw.println(mBatteryStateTracker.isCharging()); pw.print("Battery not low: "); pw.println(mBatteryStateTracker.isBatteryNotLow()); if (mBatteryStateTracker.isMonitoring()) { pw.print("MONITORING: seq="); pw.println(mBatteryStateTracker.getSeq()); } pw.println(); pw.println("Started users: " + Arrays.toString(mStartedUsers)); pw.print("Registered "); pw.print(mJobs.size()); Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java +2 −2 Original line number Diff line number Diff line Loading @@ -293,13 +293,13 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler { } private int getBatteryCharging(PrintWriter pw) { boolean val = mInternal.getBatteryCharging(); boolean val = mInternal.isBatteryCharging(); pw.println(val); return 0; } private int getBatteryNotLow(PrintWriter pw) { boolean val = mInternal.getBatteryNotLow(); boolean val = mInternal.isBatteryNotLow(); pw.println(val); return 0; } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +23 −152 Original line number Diff line number Diff line Loading @@ -18,12 +18,6 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.UserHandle; import android.util.ArraySet; import android.util.IndentingPrintWriter; Loading @@ -31,8 +25,8 @@ import android.util.Log; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.internal.annotations.GuardedBy; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.job.JobSchedulerService; import com.android.server.job.StateControllerProto; Loading @@ -49,17 +43,9 @@ public final class BatteryController extends RestrictingController { || Log.isLoggable(TAG, Log.DEBUG); private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>(); private ChargingTracker mChargeTracker; @VisibleForTesting public ChargingTracker getTracker() { return mChargeTracker; } public BatteryController(JobSchedulerService service) { super(service); mChargeTracker = new ChargingTracker(); mChargeTracker.startTracking(); } @Override Loading @@ -68,9 +54,9 @@ public final class BatteryController extends RestrictingController { final long nowElapsed = sElapsedRealtimeClock.millis(); mTrackedTasks.add(taskStatus); taskStatus.setTrackingController(JobStatus.TRACKING_BATTERY); taskStatus.setChargingConstraintSatisfied(nowElapsed, mChargeTracker.isOnStablePower()); taskStatus.setBatteryNotLowConstraintSatisfied( nowElapsed, mChargeTracker.isBatteryNotLow()); taskStatus.setChargingConstraintSatisfied(nowElapsed, mService.isBatteryCharging() && mService.isBatteryNotLow()); taskStatus.setBatteryNotLowConstraintSatisfied(nowElapsed, mService.isBatteryNotLow()); } } Loading @@ -93,9 +79,21 @@ public final class BatteryController extends RestrictingController { } } @Override @GuardedBy("mLock") public void onBatteryStateChangedLocked() { // Update job bookkeeping out of band. JobSchedulerBackgroundThread.getHandler().post(() -> { synchronized (mLock) { maybeReportNewChargingStateLocked(); } }); } @GuardedBy("mLock") private void maybeReportNewChargingStateLocked() { final boolean stablePower = mChargeTracker.isOnStablePower(); final boolean batteryNotLow = mChargeTracker.isBatteryNotLow(); final boolean stablePower = mService.isBatteryCharging() && mService.isBatteryNotLow(); final boolean batteryNotLow = mService.isBatteryNotLow(); if (DEBUG) { Slog.d(TAG, "maybeReportNewChargingStateLocked: " + stablePower); } Loading @@ -116,133 +114,11 @@ public final class BatteryController extends RestrictingController { } } public final class ChargingTracker extends BroadcastReceiver { /** * Track whether we're "charging", where charging means that we're ready to commit to * doing work. */ private boolean mCharging; /** Keep track of whether the battery is charged enough that we want to do work. */ private boolean mBatteryHealthy; /** Sequence number of last broadcast. */ private int mLastBatterySeq = -1; private BroadcastReceiver mMonitor; public ChargingTracker() { } public void startTracking() { IntentFilter filter = new IntentFilter(); // Battery health. filter.addAction(Intent.ACTION_BATTERY_LOW); filter.addAction(Intent.ACTION_BATTERY_OKAY); // Charging/not charging. filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(this, filter); // Initialise tracker state. BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); mBatteryHealthy = !batteryManagerInternal.getBatteryLevelLow(); mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); } public void setMonitorBatteryLocked(boolean enabled) { if (enabled) { if (mMonitor == null) { mMonitor = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ChargingTracker.this.onReceive(context, intent); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); mContext.registerReceiver(mMonitor, filter); } } else { if (mMonitor != null) { mContext.unregisterReceiver(mMonitor); mMonitor = null; } } } public boolean isOnStablePower() { return mCharging && mBatteryHealthy; } public boolean isBatteryNotLow() { return mBatteryHealthy; } public boolean isMonitoring() { return mMonitor != null; } public int getSeq() { return mLastBatterySeq; } @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } @VisibleForTesting public void onReceiveInternal(Intent intent) { synchronized (mLock) { final String action = intent.getAction(); if (Intent.ACTION_BATTERY_LOW.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery life too low to do work. @ " + sElapsedRealtimeClock.millis()); } // If we get this action, the battery is discharging => it isn't plugged in so // there's no work to cancel. We track this variable for the case where it is // charging, but hasn't been for long enough to be healthy. mBatteryHealthy = false; maybeReportNewChargingStateLocked(); } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) { if (DEBUG) { Slog.d(TAG, "Battery life healthy enough to do work. @ " + sElapsedRealtimeClock.millis()); } mBatteryHealthy = true; maybeReportNewChargingStateLocked(); } else if (BatteryManager.ACTION_CHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Received charging intent, fired @ " + sElapsedRealtimeClock.millis()); } mCharging = true; maybeReportNewChargingStateLocked(); } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) { if (DEBUG) { Slog.d(TAG, "Disconnected from power."); } mCharging = false; maybeReportNewChargingStateLocked(); } mLastBatterySeq = intent.getIntExtra(BatteryManager.EXTRA_SEQUENCE, mLastBatterySeq); } } } @Override public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) { pw.println("Stable power: " + mChargeTracker.isOnStablePower()); pw.println("Not low: " + mChargeTracker.isBatteryNotLow()); if (mChargeTracker.isMonitoring()) { pw.print("MONITORING: seq="); pw.println(mChargeTracker.getSeq()); } pw.println(); pw.println("Stable power: " + (mService.isBatteryCharging() && mService.isBatteryNotLow())); pw.println("Not low: " + mService.isBatteryNotLow()); for (int i = 0; i < mTrackedTasks.size(); i++) { final JobStatus js = mTrackedTasks.valueAt(i); Loading @@ -264,14 +140,9 @@ public final class BatteryController extends RestrictingController { final long mToken = proto.start(StateControllerProto.BATTERY); proto.write(StateControllerProto.BatteryController.IS_ON_STABLE_POWER, mChargeTracker.isOnStablePower()); mService.isBatteryCharging() && mService.isBatteryNotLow()); proto.write(StateControllerProto.BatteryController.IS_BATTERY_NOT_LOW, mChargeTracker.isBatteryNotLow()); proto.write(StateControllerProto.BatteryController.IS_MONITORING, mChargeTracker.isMonitoring()); proto.write(StateControllerProto.BatteryController.LAST_BROADCAST_SEQUENCE_NUMBER, mChargeTracker.getSeq()); mService.isBatteryNotLow()); for (int i = 0; i < mTrackedTasks.size(); i++) { final JobStatus js = mTrackedTasks.valueAt(i); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +13 −57 Original line number Diff line number Diff line Loading @@ -25,18 +25,12 @@ import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.job.JobInfo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; import android.net.NetworkRequest; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading @@ -55,6 +49,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; import com.android.server.job.JobSchedulerService.Constants; Loading Loading @@ -107,8 +102,6 @@ public final class ConnectivityController extends RestrictingController implemen private final ConnectivityManager mConnManager; private final NetworkPolicyManagerInternal mNetPolicyManagerInternal; private final ChargingTracker mChargingTracker; /** List of tracked jobs keyed by source UID. */ @GuardedBy("mLock") private final SparseArray<ArraySet<JobStatus>> mTrackedJobs = new SparseArray<>(); Loading Loading @@ -237,9 +230,6 @@ public final class ConnectivityController extends RestrictingController implemen // network changes against the active network for each UID with jobs. final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); mConnManager.registerNetworkCallback(request, mNetworkCallback); mChargingTracker = new ChargingTracker(); mChargingTracker.startTracking(); } @GuardedBy("mLock") Loading Loading @@ -535,6 +525,17 @@ public final class ConnectivityController extends RestrictingController implemen } } @Override @GuardedBy("mLock") public void onBatteryStateChangedLocked() { // Update job bookkeeping out of band to avoid blocking broadcast progress. JobSchedulerBackgroundThread.getHandler().post(() -> { synchronized (mLock) { updateTrackedJobsLocked(-1, null); } }); } private boolean isUsable(NetworkCapabilities capabilities) { return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED); Loading Loading @@ -591,7 +592,7 @@ public final class ConnectivityController extends RestrictingController implemen // Minimum chunk size isn't defined. Check using the estimated upload/download sizes. if (capabilities.hasCapability(NET_CAPABILITY_NOT_METERED) && mChargingTracker.isCharging()) { && mService.isBatteryCharging()) { // We're charging and on an unmetered network. We don't have to be as conservative about // making sure the job will run within its max execution time. Let's just hope the app // supports interruptible work. Loading Loading @@ -1072,51 +1073,6 @@ public final class ConnectivityController extends RestrictingController implemen } } private final class ChargingTracker extends BroadcastReceiver { /** * Track whether we're "charging", where charging means that we're ready to commit to * doing work. */ private boolean mCharging; ChargingTracker() {} public void startTracking() { IntentFilter filter = new IntentFilter(); filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(this, filter); // Initialise tracker state. final BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class); mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); } public boolean isCharging() { return mCharging; } @Override public void onReceive(Context context, Intent intent) { synchronized (mLock) { final String action = intent.getAction(); if (BatteryManager.ACTION_CHARGING.equals(action)) { if (mCharging) { return; } mCharging = true; } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) { if (!mCharging) { return; } mCharging = false; } updateTrackedJobsLocked(-1, null); } } } private final NetworkCallback mNetworkCallback = new NetworkCallback() { @Override public void onAvailable(Network network) { Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +23 −68 File changed.Preview size limit exceeded, changes collapsed. Show changes