diff options
Diffstat (limited to 'android/os')
-rw-r--r-- | android/os/BatteryStats.java | 267 | ||||
-rw-r--r-- | android/os/Binder.java | 45 | ||||
-rw-r--r-- | android/os/IServiceManager.java | 27 | ||||
-rw-r--r-- | android/os/Parcel.java | 191 | ||||
-rw-r--r-- | android/os/ParcelableException.java | 6 | ||||
-rw-r--r-- | android/os/PowerManager.java | 36 | ||||
-rw-r--r-- | android/os/ServiceManager.java | 105 | ||||
-rw-r--r-- | android/os/ServiceManagerNative.java | 102 | ||||
-rw-r--r-- | android/os/StrictMode.java | 106 | ||||
-rw-r--r-- | android/os/UserManagerInternal.java | 12 |
10 files changed, 536 insertions, 361 deletions
diff --git a/android/os/BatteryStats.java b/android/os/BatteryStats.java index 66b6b478..98819279 100644 --- a/android/os/BatteryStats.java +++ b/android/os/BatteryStats.java @@ -19,6 +19,7 @@ package android.os; import android.app.job.JobParameters; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.service.batterystats.BatteryStatsServiceDumpProto; import android.telephony.SignalStrength; import android.text.format.DateFormat; import android.util.ArrayMap; @@ -29,11 +30,13 @@ import android.util.Printer; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TimeUtils; +import android.util.proto.ProtoOutputStream; import android.view.Display; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; +import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; @@ -78,17 +81,17 @@ public abstract class BatteryStats implements Parcelable { * A constant indicating a sensor timer. */ public static final int SENSOR = 3; - + /** * A constant indicating a a wifi running timer */ public static final int WIFI_RUNNING = 4; - + /** * A constant indicating a full wifi lock timer */ public static final int FULL_WIFI_LOCK = 5; - + /** * A constant indicating a wifi scan */ @@ -190,7 +193,7 @@ public abstract class BatteryStats implements Parcelable { public static final int STATS_SINCE_UNPLUGGED = 2; // NOTE: Update this list if you add/change any stats above. - // These characters are supposed to represent "total", "last", "current", + // These characters are supposed to represent "total", "last", "current", // and "unplugged". They were shortened for efficiency sake. private static final String[] STAT_NAMES = { "l", "c", "u" }; @@ -217,8 +220,10 @@ public abstract class BatteryStats implements Parcelable { * - Package wakeup alarms are now on screen-off timebase * New in version 26: * - Resource power manager (rpm) states [but screenOffRpm is disabled from working properly] + * New in version 27: + * - Always On Display (screen doze mode) time and power */ - static final String CHECKIN_VERSION = "26"; + static final int CHECKIN_VERSION = 27; /** * Old version, we hit 9 and ran out of room, need to remove. @@ -1381,12 +1386,12 @@ public abstract class BatteryStats implements Parcelable { public static final int STATE_PHONE_SCANNING_FLAG = 1<<21; public static final int STATE_SCREEN_ON_FLAG = 1<<20; // consider moving to states2 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2 - // empty slot + public static final int STATE_SCREEN_DOZE_FLAG = 1 << 18; // empty slot public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16; public static final int MOST_INTERESTING_STATES = - STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG; + STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG | STATE_SCREEN_DOZE_FLAG; public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES; @@ -1414,8 +1419,8 @@ public abstract class BatteryStats implements Parcelable { public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20; public static final int MOST_INTERESTING_STATES2 = - STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK - | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG; + STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK + | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG; public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2; @@ -1863,6 +1868,21 @@ public abstract class BatteryStats implements Parcelable { */ public abstract int getScreenOnCount(int which); + /** + * Returns the time in microseconds that the screen has been dozing while the device was + * running on battery. + * + * {@hide} + */ + public abstract long getScreenDozeTime(long elapsedRealtimeUs, int which); + + /** + * Returns the number of times the screen was turned dozing. + * + * {@hide} + */ + public abstract int getScreenDozeCount(int which); + public abstract long getInteractiveTime(long elapsedRealtimeUs, int which); public static final int SCREEN_BRIGHTNESS_DARK = 0; @@ -2116,8 +2136,7 @@ public abstract class BatteryStats implements Parcelable { "group", "compl", "dorm", "uninit" }; - public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS - = new BitDescription[] { + public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] { new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"), new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"), @@ -2131,6 +2150,7 @@ public abstract class BatteryStats implements Parcelable { new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"), new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"), new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"), + new BitDescription(HistoryItem.STATE_SCREEN_DOZE_FLAG, "screen_doze", "Sd"), new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn", DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES), @@ -2467,6 +2487,18 @@ public abstract class BatteryStats implements Parcelable { public abstract int getDischargeAmountScreenOffSinceCharge(); /** + * Get the amount the battery has discharged while the screen was doze, + * since the last time power was unplugged. + */ + public abstract int getDischargeAmountScreenDoze(); + + /** + * Get the amount the battery has discharged while the screen was doze, + * since the last time the device was charged. + */ + public abstract int getDischargeAmountScreenDozeSinceCharge(); + + /** * Returns the total, last, or current battery uptime in microseconds. * * @param curTime the elapsed realtime in microseconds. @@ -2483,7 +2515,7 @@ public abstract class BatteryStats implements Parcelable { public abstract long computeBatteryRealtime(long curTime, int which); /** - * Returns the total, last, or current battery screen off uptime in microseconds. + * Returns the total, last, or current battery screen off/doze uptime in microseconds. * * @param curTime the elapsed realtime in microseconds. * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. @@ -2491,7 +2523,7 @@ public abstract class BatteryStats implements Parcelable { public abstract long computeBatteryScreenOffUptime(long curTime, int which); /** - * Returns the total, last, or current battery screen off realtime in microseconds. + * Returns the total, last, or current battery screen off/doze realtime in microseconds. * * @param curTime the current elapsed realtime in microseconds. * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. @@ -2590,18 +2622,24 @@ public abstract class BatteryStats implements Parcelable { }; /** - * Return the counter keeping track of the amount of battery discharge while the screen was off, - * measured in micro-Ampere-hours. This will be non-zero only if the device's battery has + * Return the amount of battery discharge while the screen was off, measured in + * micro-Ampere-hours. This will be non-zero only if the device's battery has * a coulomb counter. */ - public abstract LongCounter getDischargeScreenOffCoulombCounter(); + public abstract long getMahDischargeScreenOff(int which); /** - * Return the counter keeping track of the amount of battery discharge measured in + * Return the amount of battery discharge while the screen was in doze mode, measured in * micro-Ampere-hours. This will be non-zero only if the device's battery has * a coulomb counter. */ - public abstract LongCounter getDischargeCoulombCounter(); + public abstract long getMahDischargeScreenDoze(int which); + + /** + * Return the amount of battery discharge measured in micro-Ampere-hours. This will be + * non-zero only if the device's battery has a coulomb counter. + */ + public abstract long getMahDischarge(int which); /** * Returns the estimated real battery capacity, which may be less than the capacity @@ -2953,6 +2991,31 @@ public abstract class BatteryStats implements Parcelable { } /** + * Dump a given timer stat to the proto stream. + * + * @param proto the ProtoOutputStream to log to + * @param fieldId type of data, the field to save to (e.g. AggregatedBatteryStats.WAKELOCK) + * @param timer a {@link Timer} to dump stats for + * @param rawRealtimeUs the current elapsed realtime of the system in microseconds + * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT + */ + private static void dumpTimer(ProtoOutputStream proto, long fieldId, + Timer timer, long rawRealtime, int which) { + if (timer == null) { + return; + } + // Convert from microseconds to milliseconds with rounding + final long totalTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; + final int count = timer.getCountLocked(which); + if (totalTimeMs != 0 || count != 0) { + final long token = proto.start(fieldId); + proto.write(TimerProto.DURATION_MS, totalTimeMs); + proto.write(TimerProto.COUNT, count); + proto.end(token); + } + } + + /** * Checks if the ControllerActivityCounter has any data worth dumping. */ private static boolean controllerActivityHasData(ControllerActivityCounter counter, int which) { @@ -3004,6 +3067,38 @@ public abstract class BatteryStats implements Parcelable { pw.println(); } + /** + * Dumps the ControllerActivityCounter if it has any data worth dumping. + */ + private static void dumpControllerActivityProto(ProtoOutputStream proto, long fieldId, + ControllerActivityCounter counter, + int which) { + if (!controllerActivityHasData(counter, which)) { + return; + } + + final long cToken = proto.start(fieldId); + + proto.write(ControllerActivityProto.IDLE_DURATION_MS, + counter.getIdleTimeCounter().getCountLocked(which)); + proto.write(ControllerActivityProto.RX_DURATION_MS, + counter.getRxTimeCounter().getCountLocked(which)); + proto.write(ControllerActivityProto.POWER_MAH, + counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60)); + + long tToken; + LongCounter[] txCounters = counter.getTxTimeCounters(); + for (int i = 0; i < txCounters.length; ++i) { + LongCounter c = txCounters[i]; + tToken = proto.start(ControllerActivityProto.TX); + proto.write(ControllerActivityProto.TxLevel.LEVEL, i); + proto.write(ControllerActivityProto.TxLevel.DURATION_MS, c.getCountLocked(which)); + proto.end(tToken); + } + + proto.end(cToken); + } + private final void printControllerActivityIfInteresting(PrintWriter pw, StringBuilder sb, String prefix, String controllerName, ControllerActivityCounter counter, @@ -3112,6 +3207,7 @@ public abstract class BatteryStats implements Parcelable { final long totalRealtime = computeRealtime(rawRealtime, which); final long totalUptime = computeUptime(rawUptime, which); final long screenOnTime = getScreenOnTime(rawRealtime, which); + final long screenDozeTime = getScreenDozeTime(rawRealtime, which); final long interactiveTime = getInteractiveTime(rawRealtime, which); final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which); final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, @@ -3124,9 +3220,9 @@ public abstract class BatteryStats implements Parcelable { rawRealtime, which); final int connChanges = getNumConnectivityChange(which); final long phoneOnTime = getPhoneOnTime(rawRealtime, which); - final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which); - final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter() - .getCountLocked(which); + final long dischargeCount = getMahDischarge(which); + final long dischargeScreenOffCount = getMahDischargeScreenOff(which); + final long dischargeScreenDozeCount = getMahDischargeScreenDoze(which); final StringBuilder sb = new StringBuilder(128); @@ -3143,7 +3239,8 @@ public abstract class BatteryStats implements Parcelable { getStartClockTime(), whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000, getEstimatedBatteryCapacity(), - getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity()); + getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity(), + screenDozeTime / 1000); // Calculate wakelock times across all uids. @@ -3295,13 +3392,15 @@ public abstract class BatteryStats implements Parcelable { getDischargeStartLevel()-getDischargeCurrentLevel(), getDischargeStartLevel()-getDischargeCurrentLevel(), getDischargeAmountScreenOn(), getDischargeAmountScreenOff(), - dischargeCount / 1000, dischargeScreenOffCount / 1000); + dischargeCount / 1000, dischargeScreenOffCount / 1000, + getDischargeAmountScreenDoze(), dischargeScreenDozeCount / 1000); } else { dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), getDischargeAmountScreenOnSinceCharge(), getDischargeAmountScreenOffSinceCharge(), - dischargeCount / 1000, dischargeScreenOffCount / 1000); + dischargeCount / 1000, dischargeScreenOffCount / 1000, + getDischargeAmountScreenDozeSinceCharge(), dischargeScreenDozeCount / 1000); } if (reqUid < 0) { @@ -3831,6 +3930,7 @@ public abstract class BatteryStats implements Parcelable { which); final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime); final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime); + final long screenDozeTime = getScreenDozeTime(rawRealtime, which); final StringBuilder sb = new StringBuilder(128); @@ -3868,25 +3968,35 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); sb.append(prefix); - sb.append(" Time on battery: "); - formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); - sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); - sb.append(") realtime, "); - formatTimeMs(sb, whichBatteryUptime / 1000); - sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); - sb.append(") uptime"); + sb.append(" Time on battery: "); + formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); + sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); + sb.append(") realtime, "); + formatTimeMs(sb, whichBatteryUptime / 1000); + sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, whichBatteryRealtime)); + sb.append(") uptime"); pw.println(sb.toString()); + sb.setLength(0); sb.append(prefix); - sb.append(" Time on battery screen off: "); - formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("("); - sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime)); - sb.append(") realtime, "); - formatTimeMs(sb, whichBatteryScreenOffUptime / 1000); - sb.append("("); - sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime)); - sb.append(") uptime"); + sb.append(" Time on battery screen off: "); + formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("("); + sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, whichBatteryRealtime)); + sb.append(") realtime, "); + formatTimeMs(sb, whichBatteryScreenOffUptime / 1000); + sb.append("("); + sb.append(formatRatioLocked(whichBatteryScreenOffUptime, whichBatteryRealtime)); + sb.append(") uptime"); + pw.println(sb.toString()); + + sb.setLength(0); + sb.append(prefix); + sb.append(" Time on battery screen doze: "); + formatTimeMs(sb, screenDozeTime / 1000); sb.append("("); + sb.append(formatRatioLocked(screenDozeTime, whichBatteryRealtime)); + sb.append(")"); pw.println(sb.toString()); + sb.setLength(0); sb.append(prefix); sb.append(" Total run time: "); @@ -3910,8 +4020,7 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } - final LongCounter dischargeCounter = getDischargeCoulombCounter(); - final long dischargeCount = dischargeCounter.getCountLocked(which); + final long dischargeCount = getMahDischarge(which); if (dischargeCount >= 0) { sb.setLength(0); sb.append(prefix); @@ -3921,8 +4030,7 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } - final LongCounter dischargeScreenOffCounter = getDischargeScreenOffCoulombCounter(); - final long dischargeScreenOffCount = dischargeScreenOffCounter.getCountLocked(which); + final long dischargeScreenOffCount = getMahDischargeScreenOff(which); if (dischargeScreenOffCount >= 0) { sb.setLength(0); sb.append(prefix); @@ -3932,7 +4040,18 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } - final long dischargeScreenOnCount = dischargeCount - dischargeScreenOffCount; + final long dischargeScreenDozeCount = getMahDischargeScreenDoze(which); + if (dischargeScreenDozeCount >= 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Screen doze discharge: "); + sb.append(BatteryStatsHelper.makemAh(dischargeScreenDozeCount / 1000.0)); + sb.append(" mAh"); + pw.println(sb.toString()); + } + + final long dischargeScreenOnCount = + dischargeCount - dischargeScreenOffCount - dischargeScreenDozeCount; if (dischargeScreenOnCount >= 0) { sb.setLength(0); sb.append(prefix); @@ -4340,20 +4459,24 @@ public abstract class BatteryStats implements Parcelable { pw.println(getDischargeCurrentLevel()); } pw.print(prefix); pw.print(" Amount discharged while screen on: "); - pw.println(getDischargeAmountScreenOn()); + pw.println(getDischargeAmountScreenOn()); pw.print(prefix); pw.print(" Amount discharged while screen off: "); - pw.println(getDischargeAmountScreenOff()); + pw.println(getDischargeAmountScreenOff()); + pw.print(prefix); pw.print(" Amount discharged while screen doze: "); + pw.println(getDischargeAmountScreenDoze()); pw.println(" "); } else { pw.print(prefix); pw.println(" Device battery use since last full charge"); pw.print(prefix); pw.print(" Amount discharged (lower bound): "); - pw.println(getLowDischargeAmountSinceCharge()); + pw.println(getLowDischargeAmountSinceCharge()); pw.print(prefix); pw.print(" Amount discharged (upper bound): "); - pw.println(getHighDischargeAmountSinceCharge()); + pw.println(getHighDischargeAmountSinceCharge()); pw.print(prefix); pw.print(" Amount discharged while screen on: "); - pw.println(getDischargeAmountScreenOnSinceCharge()); + pw.println(getDischargeAmountScreenOnSinceCharge()); pw.print(prefix); pw.print(" Amount discharged while screen off: "); - pw.println(getDischargeAmountScreenOffSinceCharge()); + pw.println(getDischargeAmountScreenOffSinceCharge()); + pw.print(prefix); pw.print(" Amount discharged while screen doze: "); + pw.println(getDischargeAmountScreenDozeSinceCharge()); pw.println(); } @@ -5426,8 +5549,9 @@ public abstract class BatteryStats implements Parcelable { } } } - + public void prepareForDumpLocked() { + // We don't need to require subclasses implement this. } public static class HistoryPrinter { @@ -6248,7 +6372,8 @@ public abstract class BatteryStats implements Parcelable { pw.println(); } } - + + // This is called from BatteryStatsService. @SuppressWarnings("unused") public void dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps, int flags, long histStart) { @@ -6260,10 +6385,7 @@ public abstract class BatteryStats implements Parcelable { long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); - final boolean filtering = (flags & - (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0; - - if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) { + if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) { if (startIteratingHistoryLocked()) { try { for (int i=0; i<getHistoryStringPoolSize(); i++) { @@ -6287,7 +6409,7 @@ public abstract class BatteryStats implements Parcelable { } } - if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) { + if ((flags & DUMP_HISTORY_ONLY) != 0) { return; } @@ -6320,7 +6442,7 @@ public abstract class BatteryStats implements Parcelable { } } } - if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { + if ((flags & DUMP_DAILY_ONLY) == 0) { dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true); String[] lineArgs = new String[1]; long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime() * 1000); @@ -6340,4 +6462,33 @@ public abstract class BatteryStats implements Parcelable { (flags&DUMP_DEVICE_WIFI_ONLY) != 0); } } + + /** Dump batterystats data to a proto. @hide */ + public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps, + int flags, long historyStart) { + final ProtoOutputStream proto = new ProtoOutputStream(fd); + final long bToken = proto.start(BatteryStatsServiceDumpProto.BATTERYSTATS); + prepareForDumpLocked(); + + proto.write(BatteryStatsProto.REPORT_VERSION, CHECKIN_VERSION); + proto.write(BatteryStatsProto.PARCEL_VERSION, getParcelVersion()); + proto.write(BatteryStatsProto.START_PLATFORM_VERSION, getStartPlatformVersion()); + proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion()); + + long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); + + if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) { + if (startIteratingHistoryLocked()) { + // TODO: implement dumpProtoHistoryLocked(proto); + } + } + + if ((flags & (DUMP_HISTORY_ONLY | DUMP_DAILY_ONLY)) == 0) { + // TODO: implement dumpProtoAppsLocked(proto, apps); + // TODO: implement dumpProtoSystemLocked(proto); + } + + proto.end(bToken); + proto.flush(); + } } diff --git a/android/os/Binder.java b/android/os/Binder.java index 0df6361d..e9e695bb 100644 --- a/android/os/Binder.java +++ b/android/os/Binder.java @@ -23,7 +23,6 @@ import android.util.Log; import android.util.Slog; import com.android.internal.util.FastPrintWriter; -import com.android.internal.util.FunctionalUtils; import com.android.internal.util.FunctionalUtils.ThrowingRunnable; import com.android.internal.util.FunctionalUtils.ThrowingSupplier; @@ -202,7 +201,7 @@ public class Binder implements IBinder { * then its own pid is returned. */ public static final native int getCallingPid(); - + /** * Return the Linux uid assigned to the process that sent you the * current transaction that is being processed. This uid can be used with @@ -335,7 +334,7 @@ public class Binder implements IBinder { * it needs to. */ public static final native void flushPendingCommands(); - + /** * Add the calling thread to the IPC thread pool. This function does * not return until the current process is exiting. @@ -372,7 +371,7 @@ public class Binder implements IBinder { } } } - + /** * Convenience method for associating a specific interface with the Binder. * After calling, queryLocalInterface() will be implemented for you @@ -383,7 +382,7 @@ public class Binder implements IBinder { mOwner = owner; mDescriptor = descriptor; } - + /** * Default implementation returns an empty interface name. */ @@ -408,7 +407,7 @@ public class Binder implements IBinder { public boolean isBinderAlive() { return true; } - + /** * Use information supplied to attachInterface() to return the * associated IInterface if it matches the requested @@ -630,7 +629,7 @@ public class Binder implements IBinder { } return r; } - + /** * Local implementation is a no-op. */ @@ -643,7 +642,7 @@ public class Binder implements IBinder { public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) { return true; } - + protected void finalize() throws Throwable { try { destroyBinder(); @@ -730,7 +729,15 @@ public class Binder implements IBinder { } } +/** + * Java proxy for a native IBinder object. + * Allocated and constructed by the native javaObjectforIBinder function. Never allocated + * directly from Java code. + */ final class BinderProxy implements IBinder { + // See android_util_Binder.cpp for the native half of this. + // TODO: Consider using NativeAllocationRegistry instead of finalization. + // Assume the process-wide default value when created volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking; @@ -789,7 +796,7 @@ final class BinderProxy implements IBinder { reply.recycle(); } } - + public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -826,7 +833,7 @@ final class BinderProxy implements IBinder { BinderProxy() { mSelf = new WeakReference(this); } - + @Override protected void finalize() throws Throwable { try { @@ -835,9 +842,9 @@ final class BinderProxy implements IBinder { super.finalize(); } } - + private native final void destroy(); - + private static final void sendDeathNotice(DeathRecipient recipient) { if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient); try { @@ -848,8 +855,20 @@ final class BinderProxy implements IBinder { exc); } } - + + // This WeakReference to "this" is used only by native code to "attach" to the + // native IBinder object. + // Using WeakGlobalRefs instead currently appears unsafe, in that they can yield a + // non-null value after the BinderProxy is enqueued for finalization. + // Used only once immediately after construction. + // TODO: Consider making the extra native-to-java call to compute this on the fly. final private WeakReference mSelf; + + // Native pointer to the wrapped native IBinder object. Counted as strong reference. private long mObject; + + // Native pointer to native DeathRecipientList. Counted as strong reference. + // Basically owned by the JavaProxy object. Reference counted only because DeathRecipients + // hold a weak reference that can be temporarily promoted. private long mOrgue; } diff --git a/android/os/IServiceManager.java b/android/os/IServiceManager.java index 7b11c283..87c65ecc 100644 --- a/android/os/IServiceManager.java +++ b/android/os/IServiceManager.java @@ -18,12 +18,12 @@ package android.os; /** * Basic interface for finding and publishing system services. - * + * * An implementation of this interface is usually published as the * global context object, which can be retrieved via * BinderNative.getContextObject(). An easy way to retrieve this * is with the static method BnServiceManager.getDefault(). - * + * * @hide */ public interface IServiceManager extends IInterface @@ -33,33 +33,33 @@ public interface IServiceManager extends IInterface * service manager. Blocks for a few seconds waiting for it to be * published if it does not already exist. */ - public IBinder getService(String name) throws RemoteException; - + IBinder getService(String name) throws RemoteException; + /** * Retrieve an existing service called @a name from the * service manager. Non-blocking. */ - public IBinder checkService(String name) throws RemoteException; + IBinder checkService(String name) throws RemoteException; /** * Place a new @a service called @a name into the service * manager. */ - public void addService(String name, IBinder service, boolean allowIsolated) + void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) throws RemoteException; /** * Return a list of all currently running services. */ - public String[] listServices() throws RemoteException; + String[] listServices(int dumpPriority) throws RemoteException; /** * Assign a permission controller to the service manager. After set, this * interface is checked before any services are added. */ - public void setPermissionController(IPermissionController controller) + void setPermissionController(IPermissionController controller) throws RemoteException; - + static final String descriptor = "android.os.IServiceManager"; int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; @@ -68,4 +68,13 @@ public interface IServiceManager extends IInterface int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3; int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4; int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5; + + /* + * Must update values in IServiceManager.h + */ + int DUMP_PRIORITY_CRITICAL = 1 << 0; + int DUMP_PRIORITY_HIGH = 1 << 1; + int DUMP_PRIORITY_NORMAL = 1 << 2; + int DUMP_PRIORITY_ALL = DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH + | DUMP_PRIORITY_NORMAL; } diff --git a/android/os/Parcel.java b/android/os/Parcel.java index 031ca91c..857e8a60 100644 --- a/android/os/Parcel.java +++ b/android/os/Parcel.java @@ -1340,6 +1340,13 @@ public final class Parcel { * @see Parcelable */ public final <T extends Parcelable> void writeTypedList(List<T> val) { + writeTypedList(val, 0); + } + + /** + * @hide + */ + public <T extends Parcelable> void writeTypedList(List<T> val, int parcelableFlags) { if (val == null) { writeInt(-1); return; @@ -1348,13 +1355,7 @@ public final class Parcel { int i=0; writeInt(N); while (i < N) { - T item = val.get(i); - if (item != null) { - writeInt(1); - item.writeToParcel(this, 0); - } else { - writeInt(0); - } + writeTypedObject(val.get(i), parcelableFlags); i++; } } @@ -1456,116 +1457,7 @@ public final class Parcel { int N = val.length; writeInt(N); for (int i = 0; i < N; i++) { - T item = val[i]; - if (item != null) { - writeInt(1); - item.writeToParcel(this, parcelableFlags); - } else { - writeInt(0); - } - } - } else { - writeInt(-1); - } - } - - /** - * Write a uniform (all items are null or the same class) array list of - * parcelables. - * - * @param list The list to write. - * - * @hide - */ - public final <T extends Parcelable> void writeTypedArrayList(@Nullable ArrayList<T> list, - int parcelableFlags) { - if (list != null) { - int N = list.size(); - writeInt(N); - boolean wroteCreator = false; - for (int i = 0; i < N; i++) { - T item = list.get(i); - if (item != null) { - writeInt(1); - if (!wroteCreator) { - writeParcelableCreator(item); - wroteCreator = true; - } - item.writeToParcel(this, parcelableFlags); - } else { - writeInt(0); - } - } - } else { - writeInt(-1); - } - } - - /** - * Reads a uniform (all items are null or the same class) array list of - * parcelables. - * - * @return The list or null. - * - * @hide - */ - public final @Nullable <T> ArrayList<T> readTypedArrayList(@Nullable ClassLoader loader) { - int N = readInt(); - if (N <= 0) { - return null; - } - Parcelable.Creator<?> creator = null; - ArrayList<T> result = new ArrayList<T>(N); - for (int i = 0; i < N; i++) { - if (readInt() != 0) { - if (creator == null) { - creator = readParcelableCreator(loader); - if (creator == null) { - return null; - } - } - final T parcelable; - if (creator instanceof Parcelable.ClassLoaderCreator<?>) { - Parcelable.ClassLoaderCreator<?> classLoaderCreator = - (Parcelable.ClassLoaderCreator<?>) creator; - parcelable = (T) classLoaderCreator.createFromParcel(this, loader); - } else { - parcelable = (T) creator.createFromParcel(this); - } - result.add(parcelable); - } else { - result.add(null); - } - } - return result; - } - - /** - * Write a uniform (all items are null or the same class) array set of - * parcelables. - * - * @param set The set to write. - * - * @hide - */ - public final <T extends Parcelable> void writeTypedArraySet(@Nullable ArraySet<T> set, - int parcelableFlags) { - if (set != null) { - int N = set.size(); - writeInt(N); - boolean wroteCreator = false; - for (int i = 0; i < N; i++) { - T item = set.valueAt(i); - if (item != null) { - writeInt(1); - if (!wroteCreator) { - writeParcelableCreator(item); - wroteCreator = true; - } - item.writeToParcel(this, parcelableFlags); - } else { - writeInt(0); - } + writeTypedObject(val[i], parcelableFlags); } } else { writeInt(-1); @@ -1573,43 +1465,6 @@ public final class Parcel { } /** - * Reads a uniform (all items are null or the same class) array set of - * parcelables. - * - * @return The set or null. - * - * @hide - */ - public final @Nullable <T> ArraySet<T> readTypedArraySet(@Nullable ClassLoader loader) { - int N = readInt(); - if (N <= 0) { - return null; - } - Parcelable.Creator<?> creator = null; - ArraySet<T> result = new ArraySet<T>(N); - for (int i = 0; i < N; i++) { - T parcelable = null; - if (readInt() != 0) { - if (creator == null) { - creator = readParcelableCreator(loader); - if (creator == null) { - return null; - } - } - if (creator instanceof Parcelable.ClassLoaderCreator<?>) { - Parcelable.ClassLoaderCreator<?> classLoaderCreator = - (Parcelable.ClassLoaderCreator<?>) creator; - parcelable = (T) classLoaderCreator.createFromParcel(this, loader); - } else { - parcelable = (T) creator.createFromParcel(this); - } - } - result.append(parcelable); - } - return result; - } - - /** * Flatten the Parcelable object into the parcel. * * @param val The Parcelable object to be written. @@ -2458,11 +2313,7 @@ public final class Parcel { } ArrayList<T> l = new ArrayList<T>(N); while (N > 0) { - if (readInt() != 0) { - l.add(c.createFromParcel(this)); - } else { - l.add(null); - } + l.add(readTypedObject(c)); N--; } return l; @@ -2485,18 +2336,10 @@ public final class Parcel { int N = readInt(); int i = 0; for (; i < M && i < N; i++) { - if (readInt() != 0) { - list.set(i, c.createFromParcel(this)); - } else { - list.set(i, null); - } + list.set(i, readTypedObject(c)); } for (; i<N; i++) { - if (readInt() != 0) { - list.add(c.createFromParcel(this)); - } else { - list.add(null); - } + list.add(readTypedObject(c)); } for (; i<M; i++) { list.remove(N); @@ -2641,9 +2484,7 @@ public final class Parcel { } T[] l = c.newArray(N); for (int i=0; i<N; i++) { - if (readInt() != 0) { - l[i] = c.createFromParcel(this); - } + l[i] = readTypedObject(c); } return l; } @@ -2652,11 +2493,7 @@ public final class Parcel { int N = readInt(); if (N == val.length) { for (int i=0; i<N; i++) { - if (readInt() != 0) { - val[i] = c.createFromParcel(this); - } else { - val[i] = null; - } + val[i] = readTypedObject(c); } } else { throw new RuntimeException("bad array lengths"); diff --git a/android/os/ParcelableException.java b/android/os/ParcelableException.java index d84d6299..7f71905d 100644 --- a/android/os/ParcelableException.java +++ b/android/os/ParcelableException.java @@ -52,10 +52,12 @@ public final class ParcelableException extends RuntimeException implements Parce final String msg = in.readString(); try { final Class<?> clazz = Class.forName(name, true, Parcelable.class.getClassLoader()); - return (Throwable) clazz.getConstructor(String.class).newInstance(msg); + if (Throwable.class.isAssignableFrom(clazz)) { + return (Throwable) clazz.getConstructor(String.class).newInstance(msg); + } } catch (ReflectiveOperationException e) { - throw new RuntimeException(name + ": " + msg); } + return new RuntimeException(name + ": " + msg); } /** {@hide} */ diff --git a/android/os/PowerManager.java b/android/os/PowerManager.java index 960c9f5c..7f4dee6e 100644 --- a/android/os/PowerManager.java +++ b/android/os/PowerManager.java @@ -443,6 +443,20 @@ public final class PowerManager { public static final String SHUTDOWN_USER_REQUESTED = "userrequested"; /** + * The value to pass as the 'reason' argument to android_reboot() when battery temperature + * is too high. + * @hide + */ + public static final String SHUTDOWN_BATTERY_THERMAL_STATE = "thermal,battery"; + + /** + * The value to pass as the 'reason' argument to android_reboot() when device is running + * critically low on battery. + * @hide + */ + public static final String SHUTDOWN_LOW_BATTERY = "battery"; + + /** * @hide */ @Retention(RetentionPolicy.SOURCE) @@ -451,7 +465,9 @@ public final class PowerManager { SHUTDOWN_REASON_SHUTDOWN, SHUTDOWN_REASON_REBOOT, SHUTDOWN_REASON_USER_REQUESTED, - SHUTDOWN_REASON_THERMAL_SHUTDOWN + SHUTDOWN_REASON_THERMAL_SHUTDOWN, + SHUTDOWN_REASON_LOW_BATTERY, + SHUTDOWN_REASON_BATTERY_THERMAL }) public @interface ShutdownReason {} @@ -485,6 +501,18 @@ public final class PowerManager { */ public static final int SHUTDOWN_REASON_THERMAL_SHUTDOWN = 4; + /** + * constant for shutdown reason being low battery. + * @hide + */ + public static final int SHUTDOWN_REASON_LOW_BATTERY = 5; + + /** + * constant for shutdown reason being critical battery thermal state. + * @hide + */ + public static final int SHUTDOWN_REASON_BATTERY_THERMAL = 6; + final Context mContext; final IPowerManager mService; final Handler mHandler; @@ -1384,7 +1412,11 @@ public final class PowerManager { */ public void release(int flags) { synchronized (mToken) { - mInternalCount--; + if (mInternalCount > 0) { + // internal count must only be decreased if it is > 0 or state of + // the WakeLock object is broken. + mInternalCount--; + } if ((flags & RELEASE_FLAG_TIMEOUT) == 0) { mExternalCount--; } diff --git a/android/os/ServiceManager.java b/android/os/ServiceManager.java index 34c78455..f41848fa 100644 --- a/android/os/ServiceManager.java +++ b/android/os/ServiceManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2007 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. @@ -16,9 +16,29 @@ package android.os; +import android.util.Log; + +import com.android.internal.os.BinderInternal; + +import java.util.HashMap; import java.util.Map; +/** @hide */ public final class ServiceManager { + private static final String TAG = "ServiceManager"; + private static IServiceManager sServiceManager; + private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>(); + + private static IServiceManager getIServiceManager() { + if (sServiceManager != null) { + return sServiceManager; + } + + // Find the service manager + sServiceManager = ServiceManagerNative + .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); + return sServiceManager; + } /** * Returns a reference to a service with the given name. @@ -27,14 +47,32 @@ public final class ServiceManager { * @return a reference to the service, or <code>null</code> if the service doesn't exist */ public static IBinder getService(String name) { + try { + IBinder service = sCache.get(name); + if (service != null) { + return service; + } else { + return Binder.allowBlocking(getIServiceManager().getService(name)); + } + } catch (RemoteException e) { + Log.e(TAG, "error in getService", e); + } return null; } /** - * Is not supposed to return null, but that is fine for layoutlib. + * Returns a reference to a service with the given name, or throws + * {@link NullPointerException} if none is found. + * + * @hide */ public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException { - throw new ServiceNotFoundException(name); + final IBinder binder = getService(name); + if (binder != null) { + return binder; + } else { + throw new ServiceNotFoundException(name); + } } /** @@ -45,7 +83,39 @@ public final class ServiceManager { * @param service the service object */ public static void addService(String name, IBinder service) { - // pass + addService(name, service, false, IServiceManager.DUMP_PRIORITY_NORMAL); + } + + /** + * Place a new @a service called @a name into the service + * manager. + * + * @param name the name of the new service + * @param service the service object + * @param allowIsolated set to true to allow isolated sandboxed processes + * to access this service + */ + public static void addService(String name, IBinder service, boolean allowIsolated) { + addService(name, service, allowIsolated, IServiceManager.DUMP_PRIORITY_NORMAL); + } + + /** + * Place a new @a service called @a name into the service + * manager. + * + * @param name the name of the new service + * @param service the service object + * @param allowIsolated set to true to allow isolated sandboxed processes + * @param dumpPriority supported dump priority levels as a bitmask + * to access this service + */ + public static void addService(String name, IBinder service, boolean allowIsolated, + int dumpPriority) { + try { + getIServiceManager().addService(name, service, allowIsolated, dumpPriority); + } catch (RemoteException e) { + Log.e(TAG, "error in addService", e); + } } /** @@ -53,7 +123,17 @@ public final class ServiceManager { * service manager. Non-blocking. */ public static IBinder checkService(String name) { - return null; + try { + IBinder service = sCache.get(name); + if (service != null) { + return service; + } else { + return Binder.allowBlocking(getIServiceManager().checkService(name)); + } + } catch (RemoteException e) { + Log.e(TAG, "error in checkService", e); + return null; + } } /** @@ -62,9 +142,12 @@ public final class ServiceManager { * case of an exception */ public static String[] listServices() { - // actual implementation returns null sometimes, so it's ok - // to return null instead of an empty list. - return null; + try { + return getIServiceManager().listServices(IServiceManager.DUMP_PRIORITY_ALL); + } catch (RemoteException e) { + Log.e(TAG, "error in listServices", e); + return null; + } } /** @@ -76,7 +159,10 @@ public final class ServiceManager { * @hide */ public static void initServiceCache(Map<String, IBinder> cache) { - // pass + if (sCache.size() != 0) { + throw new IllegalStateException("setServiceCache may only be called once"); + } + sCache.putAll(cache); } /** @@ -87,7 +173,6 @@ public final class ServiceManager { * @hide */ public static class ServiceNotFoundException extends Exception { - // identical to the original implementation public ServiceNotFoundException(String name) { super("No service published for: " + name); } diff --git a/android/os/ServiceManagerNative.java b/android/os/ServiceManagerNative.java index be244264..589b8c49 100644 --- a/android/os/ServiceManagerNative.java +++ b/android/os/ServiceManagerNative.java @@ -40,63 +40,65 @@ public abstract class ServiceManagerNative extends Binder implements IServiceMan if (in != null) { return in; } - + return new ServiceManagerProxy(obj); } - + public ServiceManagerNative() { attachInterface(this, descriptor); } - + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) { try { switch (code) { - case IServiceManager.GET_SERVICE_TRANSACTION: { - data.enforceInterface(IServiceManager.descriptor); - String name = data.readString(); - IBinder service = getService(name); - reply.writeStrongBinder(service); - return true; - } - - case IServiceManager.CHECK_SERVICE_TRANSACTION: { - data.enforceInterface(IServiceManager.descriptor); - String name = data.readString(); - IBinder service = checkService(name); - reply.writeStrongBinder(service); - return true; - } - - case IServiceManager.ADD_SERVICE_TRANSACTION: { - data.enforceInterface(IServiceManager.descriptor); - String name = data.readString(); - IBinder service = data.readStrongBinder(); - boolean allowIsolated = data.readInt() != 0; - addService(name, service, allowIsolated); - return true; - } - - case IServiceManager.LIST_SERVICES_TRANSACTION: { - data.enforceInterface(IServiceManager.descriptor); - String[] list = listServices(); - reply.writeStringArray(list); - return true; - } - - case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: { - data.enforceInterface(IServiceManager.descriptor); - IPermissionController controller - = IPermissionController.Stub.asInterface( - data.readStrongBinder()); - setPermissionController(controller); - return true; - } + case IServiceManager.GET_SERVICE_TRANSACTION: { + data.enforceInterface(IServiceManager.descriptor); + String name = data.readString(); + IBinder service = getService(name); + reply.writeStrongBinder(service); + return true; + } + + case IServiceManager.CHECK_SERVICE_TRANSACTION: { + data.enforceInterface(IServiceManager.descriptor); + String name = data.readString(); + IBinder service = checkService(name); + reply.writeStrongBinder(service); + return true; + } + + case IServiceManager.ADD_SERVICE_TRANSACTION: { + data.enforceInterface(IServiceManager.descriptor); + String name = data.readString(); + IBinder service = data.readStrongBinder(); + boolean allowIsolated = data.readInt() != 0; + int dumpPriority = data.readInt(); + addService(name, service, allowIsolated, dumpPriority); + return true; + } + + case IServiceManager.LIST_SERVICES_TRANSACTION: { + data.enforceInterface(IServiceManager.descriptor); + int dumpPriority = data.readInt(); + String[] list = listServices(dumpPriority); + reply.writeStringArray(list); + return true; + } + + case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: { + data.enforceInterface(IServiceManager.descriptor); + IPermissionController controller = + IPermissionController.Stub.asInterface( + data.readStrongBinder()); + setPermissionController(controller); + return true; + } } } catch (RemoteException e) { } - + return false; } @@ -110,11 +112,11 @@ class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { mRemote = remote; } - + public IBinder asBinder() { return mRemote; } - + public IBinder getService(String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -139,7 +141,7 @@ class ServiceManagerProxy implements IServiceManager { return binder; } - public void addService(String name, IBinder service, boolean allowIsolated) + public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -147,12 +149,13 @@ class ServiceManagerProxy implements IServiceManager { data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); + data.writeInt(dumpPriority); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); } - - public String[] listServices() throws RemoteException { + + public String[] listServices(int dumpPriority) throws RemoteException { ArrayList<String> services = new ArrayList<String>(); int n = 0; while (true) { @@ -160,6 +163,7 @@ class ServiceManagerProxy implements IServiceManager { Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeInt(n); + data.writeInt(dumpPriority); n++; try { boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0); diff --git a/android/os/StrictMode.java b/android/os/StrictMode.java index f02631c7..826ec1eb 100644 --- a/android/os/StrictMode.java +++ b/android/os/StrictMode.java @@ -16,6 +16,7 @@ package android.os; import android.animation.ValueAnimator; +import android.annotation.Nullable; import android.annotation.TestApi; import android.app.ActivityManager; import android.app.ActivityThread; @@ -153,12 +154,15 @@ public final class StrictMode { // Byte 1: Thread-policy /** @hide */ + @TestApi public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy /** @hide */ + @TestApi public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy /** @hide */ + @TestApi public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy /** @@ -166,6 +170,7 @@ public final class StrictMode { * * @hide */ + @TestApi public static final int DETECT_CUSTOM = 0x08; // for ThreadPolicy /** @@ -173,9 +178,11 @@ public final class StrictMode { * * @hide */ + @TestApi public static final int DETECT_RESOURCE_MISMATCH = 0x10; // for ThreadPolicy /** @hide */ + @TestApi public static final int DETECT_UNBUFFERED_IO = 0x20; // for ThreadPolicy private static final int ALL_THREAD_DETECT_BITS = @@ -193,6 +200,7 @@ public final class StrictMode { * * @hide */ + @TestApi public static final int DETECT_VM_CURSOR_LEAKS = 0x01 << 8; // for VmPolicy /** @@ -200,6 +208,7 @@ public final class StrictMode { * * @hide */ + @TestApi public static final int DETECT_VM_CLOSABLE_LEAKS = 0x02 << 8; // for VmPolicy /** @@ -207,25 +216,32 @@ public final class StrictMode { * * @hide */ + @TestApi public static final int DETECT_VM_ACTIVITY_LEAKS = 0x04 << 8; // for VmPolicy /** @hide */ - private static final int DETECT_VM_INSTANCE_LEAKS = 0x08 << 8; // for VmPolicy + @TestApi + public static final int DETECT_VM_INSTANCE_LEAKS = 0x08 << 8; // for VmPolicy /** @hide */ + @TestApi public static final int DETECT_VM_REGISTRATION_LEAKS = 0x10 << 8; // for VmPolicy /** @hide */ - private static final int DETECT_VM_FILE_URI_EXPOSURE = 0x20 << 8; // for VmPolicy + @TestApi + public static final int DETECT_VM_FILE_URI_EXPOSURE = 0x20 << 8; // for VmPolicy /** @hide */ - private static final int DETECT_VM_CLEARTEXT_NETWORK = 0x40 << 8; // for VmPolicy + @TestApi + public static final int DETECT_VM_CLEARTEXT_NETWORK = 0x40 << 8; // for VmPolicy /** @hide */ - private static final int DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION = 0x80 << 8; // for VmPolicy + @TestApi + public static final int DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION = 0x80 << 8; // for VmPolicy /** @hide */ - private static final int DETECT_VM_UNTAGGED_SOCKET = 0x80 << 24; // for VmPolicy + @TestApi + public static final int DETECT_VM_UNTAGGED_SOCKET = 0x80 << 24; // for VmPolicy private static final int ALL_VM_DETECT_BITS = DETECT_VM_CURSOR_LEAKS @@ -322,16 +338,36 @@ public final class StrictMode { /** {@hide} */ @TestApi - public interface ViolationListener { - public void onViolation(String message); + public interface ViolationLogger { + + /** Called when penaltyLog is enabled and a violation needs logging. */ + void log(ViolationInfo info); } - private static volatile ViolationListener sListener; + private static final ViolationLogger LOGCAT_LOGGER = + info -> { + String msg; + if (info.durationMillis != -1) { + msg = "StrictMode policy violation; ~duration=" + info.durationMillis + " ms:"; + } else { + msg = "StrictMode policy violation:"; + } + if (info.crashInfo != null) { + Log.d(TAG, msg + " " + info.crashInfo.stackTrace); + } else { + Log.d(TAG, msg + " missing stack trace!"); + } + }; + + private static volatile ViolationLogger sLogger = LOGCAT_LOGGER; /** {@hide} */ @TestApi - public static void setViolationListener(ViolationListener listener) { - sListener = listener; + public static void setViolationLogger(ViolationLogger listener) { + if (listener == null) { + listener = LOGCAT_LOGGER; + } + sLogger = listener; } /** @@ -1512,28 +1548,16 @@ public final class StrictMode { lastViolationTime = vtime; } } else { - mLastViolationTime = new ArrayMap<Integer, Long>(1); + mLastViolationTime = new ArrayMap<>(1); } long now = SystemClock.uptimeMillis(); mLastViolationTime.put(crashFingerprint, now); long timeSinceLastViolationMillis = lastViolationTime == 0 ? Long.MAX_VALUE : (now - lastViolationTime); - if ((info.policy & PENALTY_LOG) != 0 && sListener != null) { - sListener.onViolation(info.crashInfo.stackTrace); - } if ((info.policy & PENALTY_LOG) != 0 && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { - if (info.durationMillis != -1) { - Log.d( - TAG, - "StrictMode policy violation; ~duration=" - + info.durationMillis - + " ms: " - + info.crashInfo.stackTrace); - } else { - Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); - } + sLogger.log(info); } // The violationMaskSubset, passed to ActivityManager, is a @@ -1849,6 +1873,10 @@ public final class StrictMode { } /** @hide */ + public static final String CLEARTEXT_DETECTED_MSG = + "Detected cleartext network traffic from UID "; + + /** @hide */ public static void onCleartextNetworkDetected(byte[] firstPacket) { byte[] rawAddr = null; if (firstPacket != null) { @@ -1864,14 +1892,10 @@ public final class StrictMode { } final int uid = android.os.Process.myUid(); - String msg = "Detected cleartext network traffic from UID " + uid; + String msg = CLEARTEXT_DETECTED_MSG + uid; if (rawAddr != null) { try { - msg = - "Detected cleartext network traffic from UID " - + uid - + " to " - + InetAddress.getByAddress(rawAddr); + msg += " to " + InetAddress.getByAddress(rawAddr); } catch (UnknownHostException ignored) { } } @@ -1882,12 +1906,13 @@ public final class StrictMode { } /** @hide */ + public static final String UNTAGGED_SOCKET_VIOLATION_MESSAGE = + "Untagged socket detected; use" + + " TrafficStats.setThreadSocketTag() to track all network usage"; + + /** @hide */ public static void onUntaggedSocket() { - onVmPolicyViolation( - null, - new Throwable( - "Untagged socket detected; use" - + " TrafficStats.setThreadSocketTag() to track all network usage")); + onVmPolicyViolation(null, new Throwable(UNTAGGED_SOCKET_VIOLATION_MESSAGE)); } // Map from VM violation fingerprint to uptime millis. @@ -1925,11 +1950,11 @@ public final class StrictMode { } } - if (penaltyLog && sListener != null) { - sListener.onViolation(originStack.toString()); + if (penaltyLog && sLogger != null) { + sLogger.log(info); } if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { - Log.e(TAG, message, originStack); + sLogger.log(info); } int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicy.mask); @@ -2339,11 +2364,12 @@ public final class StrictMode { * * @hide */ - public static class ViolationInfo implements Parcelable { + @TestApi + public static final class ViolationInfo implements Parcelable { public final String message; /** Stack and other stuff info. */ - public final ApplicationErrorReport.CrashInfo crashInfo; + @Nullable public final ApplicationErrorReport.CrashInfo crashInfo; /** The strict mode policy mask at the time of violation. */ public final int policy; diff --git a/android/os/UserManagerInternal.java b/android/os/UserManagerInternal.java index 17f00c24..9369eebf 100644 --- a/android/os/UserManagerInternal.java +++ b/android/os/UserManagerInternal.java @@ -154,11 +154,21 @@ public abstract class UserManagerInternal { public abstract boolean isUserUnlocked(int userId); /** - * Return whether the given user is running + * Returns whether the given user is running */ public abstract boolean isUserRunning(int userId); /** + * Returns whether the given user is initialized + */ + public abstract boolean isUserInitialized(int userId); + + /** + * Returns whether the given user exists + */ + public abstract boolean exists(int userId); + + /** * Set user's running state */ public abstract void setUserState(int userId, int userState); |