Merge "Undo the jobscheduler / device idle initialization with callbacks"

This commit is contained in:
Makoto Onuki
2019-11-01 22:08:50 +00:00
committed by Android (Google) Code Review
8 changed files with 51 additions and 83 deletions

View File

@@ -19,14 +19,8 @@ package android.app;
import android.content.Context;
import android.os.DeviceIdleManager;
import android.os.IDeviceIdleController;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
/**
* This class needs to be pre-loaded by zygote. This is where the device idle manager wrapper
* is registered.
*
* @hide
*/
public class DeviceIdleFrameworkInitializer {
@@ -37,18 +31,5 @@ public class DeviceIdleFrameworkInitializer {
Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
(context, b) -> new DeviceIdleManager(
context, IDeviceIdleController.Stub.asInterface(b)));
PowerManager.setIsIgnoringBatteryOptimizationsCallback((packageName) -> {
// No need for synchronization on sIDeviceIdleController; worst case
// we just initialize it twice.
if (sIDeviceIdleController == null) {
sIDeviceIdleController = IDeviceIdleController.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
}
try {
return sIDeviceIdleController.isPowerSaveWhitelistApp(packageName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
});
}
}

View File

@@ -68,7 +68,11 @@ public class JobParameters implements Parcelable {
REASON_DEVICE_THERMAL,
};
/** @hide */
/**
* @hide
* @deprecated use {@link #getReasonCodeDescription(int)}
*/
@Deprecated
public static String getReasonName(int reason) {
switch (reason) {
case REASON_CANCELED: return "canceled";
@@ -81,6 +85,20 @@ public class JobParameters implements Parcelable {
}
}
/** @hide */
// @SystemApi TODO make it a system api for mainline
@NonNull
public static int[] getJobStopReasonCodes() {
return JOB_STOP_REASON_CODES;
}
/** @hide */
// @SystemApi TODO make it a system api for mainline
@NonNull
public static String getReasonCodeDescription(int reasonCode) {
return getReasonName(reasonCode);
}
@UnsupportedAppUsage
private final int jobId;
private final PersistableBundle extras;

View File

@@ -19,12 +19,8 @@ package android.app.job;
import android.app.JobSchedulerImpl;
import android.app.SystemServiceRegistry;
import android.content.Context;
import android.os.BatteryStats;
/**
* This class needs to be pre-loaded by zygote. This is where the job scheduler service wrapper
* is registered.
*
* @hide
*/
public class JobSchedulerFrameworkInitializer {
@@ -32,8 +28,5 @@ public class JobSchedulerFrameworkInitializer {
SystemServiceRegistry.registerStaticService(
Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
(b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b)));
BatteryStats.setJobStopReasons(JobParameters.JOB_STOP_REASON_CODES,
JobParameters::getReasonName);
}
}

View File

@@ -84,4 +84,17 @@ public class DeviceIdleManager {
return 0;
}
}
/**
* Return whether a given package is in the power-save whitelist or not.
* @hide
*/
public boolean isApplicationWhitelisted(@NonNull String packageName) {
try {
return mService.isPowerSaveWhitelistApp(packageName);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
return false;
}
}
}

View File

@@ -200,7 +200,6 @@ android.app.ContentProviderHolder
android.app.ContextImpl$1
android.app.ContextImpl$ApplicationContentResolver
android.app.ContextImpl
android.app.DeviceIdleFrameworkInitializer
android.app.DexLoadReporter
android.app.Dialog$ListenersHandler
android.app.Dialog

View File

@@ -1,7 +1,3 @@
# JobSchedulerFrameworkInitializer must always be preloaded because it registers the job scheduler
# service wrapper to SystemServiceRegistry.
android.app.DeviceIdleFrameworkInitializer
android.app.job.JobSchedulerFrameworkInitializer
android.icu.impl.coll.CollationRoot
android.icu.impl.IDNA2003
android.icu.impl.number.Parse

View File

@@ -21,6 +21,7 @@ import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import android.annotation.IntDef;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.job.JobParameters;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.server.ServerProtoEnums;
@@ -44,7 +45,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.location.gnssmetrics.GnssMetrics;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -58,7 +58,6 @@ import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* A class providing access to battery usage statistics, including information on
@@ -418,40 +417,6 @@ public abstract class BatteryStats implements Parcelable {
Long.MAX_VALUE
};
/**
* "Job stop reason codes" from the job scheduler subsystem, which we can't refer to from this
* class, so we initialize it from the job scheduler side at runtime using
* {@link #setJobStopReasons}.
*/
private static int[] sJobStopReasonCodes = {0};
/**
* A function that converts the "job stop reason codes" to their names.
*
* Similarly to {@link #sJobStopReasonCodes} it's initialized by the job scheduler subsystem
* using {@link #setJobStopReasons}.
*/
private static Function<Integer, String> sJobStopReasonNameConverter = (x) -> "unknown";
/**
* Set by the job scheduler subsystem to "push" job stop reasons, and a function that returns
* the "name" of each code. We do it this way to remove a build time dependency from this
* class to the job scheduler framework code.
*
* Note the passed array will be used as-is, without copying. The caller must not change
* the array it passed to it.
*
* @hide
*/
public static void setJobStopReasons(int[] reasonCodes,
Function<Integer, String> jobStopReasonNameConverter) {
Preconditions.checkArgument(reasonCodes.length > 0);
Preconditions.checkArgument(jobStopReasonNameConverter != null);
sJobStopReasonCodes = reasonCodes;
sJobStopReasonNameConverter = jobStopReasonNameConverter;
}
/**
* State for keeping track of counting information.
*/
@@ -4339,15 +4304,16 @@ public abstract class BatteryStats implements Parcelable {
}
}
final Object[] jobCompletionArgs = new Object[sJobStopReasonCodes.length + 1];
final int[] jobStopReasonCodes = JobParameters.getJobStopReasonCodes();
final Object[] jobCompletionArgs = new Object[jobStopReasonCodes.length + 1];
final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
for (int ic=completions.size()-1; ic>=0; ic--) {
SparseIntArray types = completions.valueAt(ic);
if (types != null) {
jobCompletionArgs[0] = "\"" + completions.keyAt(ic) + "\"";
for (int i = 0; i < sJobStopReasonCodes.length; i++) {
jobCompletionArgs[i + 1] = types.get(sJobStopReasonCodes[i], 0);
for (int i = 0; i < jobStopReasonCodes.length; i++) {
jobCompletionArgs[i + 1] = types.get(jobStopReasonCodes[i], 0);
}
dumpLine(pw, uid, category, JOB_COMPLETION_DATA, jobCompletionArgs);
@@ -5967,7 +5933,7 @@ public abstract class BatteryStats implements Parcelable {
pw.print(":");
for (int it=0; it<types.size(); it++) {
pw.print(" ");
pw.print(sJobStopReasonNameConverter.apply(types.keyAt(it)));
pw.print(JobParameters.getReasonCodeDescription(types.keyAt(it)));
pw.print("(");
pw.print(types.valueAt(it));
pw.print("x)");
@@ -7565,7 +7531,7 @@ public abstract class BatteryStats implements Parcelable {
proto.write(UidProto.JobCompletion.NAME, completions.keyAt(ic));
for (int r : sJobStopReasonCodes) {
for (int r : JobParameters.getJobStopReasonCodes()) {
long rToken = proto.start(UidProto.JobCompletion.REASON_COUNT);
proto.write(UidProto.JobCompletion.ReasonCount.NAME, r);
proto.write(UidProto.JobCompletion.ReasonCount.COUNT, types.get(r, 0));

View File

@@ -37,7 +37,6 @@ import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
import java.util.function.Function;
/**
* This class gives you control of the power state of the device.
@@ -828,13 +827,13 @@ public final class PowerManager {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
final Handler mHandler;
/** We lazily initialize it.*/
private DeviceIdleManager mDeviceIdleManager;
IThermalService mThermalService;
private final ArrayMap<OnThermalStatusChangedListener, IThermalStatusListener>
mListenerMap = new ArrayMap<>();
private static Function<String, Boolean> sIsIgnoringBatteryOptimizationsCallback =
(packageName) -> false;
/**
* {@hide}
*/
@@ -844,6 +843,14 @@ public final class PowerManager {
mHandler = handler;
}
private DeviceIdleManager getDeviceIdleManager() {
if (mDeviceIdleManager == null) {
// No need for synchronization; getSystemService() will return the same object anyway.
mDeviceIdleManager = mContext.getSystemService(DeviceIdleManager.class);
}
return mDeviceIdleManager;
}
/**
* Gets the minimum supported screen brightness setting.
* The screen may be allowed to become dimmer than this value but
@@ -1662,12 +1669,7 @@ public final class PowerManager {
* {@link android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}.
*/
public boolean isIgnoringBatteryOptimizations(String packageName) {
return sIsIgnoringBatteryOptimizationsCallback.apply(packageName);
}
/** @hide */
public static void setIsIgnoringBatteryOptimizationsCallback(Function<String, Boolean> f) {
sIsIgnoringBatteryOptimizationsCallback = f;
return getDeviceIdleManager().isApplicationWhitelisted(packageName);
}
/**