Merge "Fix issue #21626564: MMS should be receivied while Dozing" into mnc-dev

This commit is contained in:
Dianne Hackborn
2015-07-15 01:45:30 +00:00
committed by Android (Google) Code Review
11 changed files with 228 additions and 65 deletions

View File

@ -960,14 +960,21 @@ class ContextImpl extends Context {
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) { int initialCode, String initialData, Bundle initialExtras) {
sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE, sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
resultReceiver, scheduler, initialCode, initialData, initialExtras); null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
} }
@Override @Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver, String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
Handler scheduler, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
int initialCode, String initialData, Bundle initialExtras) { sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
IIntentReceiver rd = null; IIntentReceiver rd = null;
if (resultReceiver != null) { if (resultReceiver != null) {
if (mPackageInfo != null) { if (mPackageInfo != null) {
@ -981,8 +988,8 @@ class ContextImpl extends Context {
if (scheduler == null) { if (scheduler == null) {
scheduler = mMainThread.getHandler(); scheduler = mMainThread.getHandler();
} }
rd = new LoadedApk.ReceiverDispatcher( rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); scheduler, null, false).getIIntentReceiver();
} }
} }
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
@ -993,7 +1000,7 @@ class ContextImpl extends Context {
ActivityManagerNative.getDefault().broadcastIntent( ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd, mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, receiverPermissions, initialCode, initialData, initialExtras, receiverPermissions,
appOp, null, true, false, user.getIdentifier()); appOp, options, true, false, user.getIdentifier());
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException("Failure from system", e); throw new RuntimeException("Failure from system", e);
} }

View File

@ -1808,6 +1808,17 @@ public abstract class Context {
@Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
@Nullable Bundle initialExtras); @Nullable Bundle initialExtras);
/**
* Similar to above but takes an appOp as well, to enforce restrictions, and an options Bundle.
* @see #sendOrderedBroadcastAsUser(Intent, UserHandle, String,
* BroadcastReceiver, Handler, int, String, Bundle)
* @hide
*/
public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
@Nullable String receiverPermission, int appOp, @Nullable Bundle options,
BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode,
@Nullable String initialData, @Nullable Bundle initialExtras);
/** /**
* <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the * <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
* Intent you are sending stays around after the broadcast is complete, * Intent you are sending stays around after the broadcast is complete,

View File

@ -489,12 +489,20 @@ public class ContextWrapper extends Context {
@Override @Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver, String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
Handler scheduler, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
int initialCode, String initialData, Bundle initialExtras) {
mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, resultReceiver, mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, resultReceiver,
scheduler, initialCode, initialData, initialExtras); scheduler, initialCode, initialData, initialExtras);
} }
/** @hide */
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
@Override @Override
@Deprecated @Deprecated
public void sendStickyBroadcast(Intent intent) { public void sendStickyBroadcast(Intent intent) {

View File

@ -1193,9 +1193,11 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_PACKAGE_INACTIVE = 0x000f; public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
// Event for a package becoming active due to an interaction. // Event for a package becoming active due to an interaction.
public static final int EVENT_PACKAGE_ACTIVE = 0x0010; public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
// Event for a package being on the temporary whitelist.
public static final int EVENT_TEMP_WHITELIST = 0x0011;
// Number of event types. // Number of event types.
public static final int EVENT_COUNT = 0x0011; public static final int EVENT_COUNT = 0x0012;
// Mask to extract out only the type part of the event. // Mask to extract out only the type part of the event.
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH); public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
@ -1219,6 +1221,10 @@ public abstract class BatteryStats implements Parcelable {
EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH; EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START; public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH; public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
public static final int EVENT_TEMP_WHITELIST_START =
EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
public static final int EVENT_TEMP_WHITELIST_FINISH =
EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
// For CMD_EVENT. // For CMD_EVENT.
public int eventCode; public int eventCode;
@ -1852,12 +1858,12 @@ public abstract class BatteryStats implements Parcelable {
public static final String[] HISTORY_EVENT_NAMES = new String[] { public static final String[] HISTORY_EVENT_NAMES = new String[] {
"null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn", "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
"active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active" "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active", "tmpwhitelist"
}; };
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] { public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
"Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn", "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
"Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa" "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw"
}; };
/** /**

View File

@ -27,6 +27,7 @@ interface IDeviceIdleController {
int[] getAppIdWhitelist(); int[] getAppIdWhitelist();
int[] getAppIdTempWhitelist(); int[] getAppIdTempWhitelist();
boolean isPowerSaveWhitelistApp(String name); boolean isPowerSaveWhitelistApp(String name);
void addPowerSaveTempWhitelistApp(String name, long duration, int userId); void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
void exitIdle(String reason); void exitIdle(String reason);
} }

View File

@ -36,6 +36,7 @@ import android.hardware.TriggerEventListener;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager;
import android.net.Uri; import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder; import android.os.Binder;
import android.os.Environment; import android.os.Environment;
import android.os.FileUtils; import android.os.FileUtils;
@ -54,9 +55,11 @@ import android.provider.Settings;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.KeyValueListParser; import android.util.KeyValueListParser;
import android.util.MutableLong;
import android.util.Pair;
import android.util.Slog; import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import android.util.SparseLongArray;
import android.util.TimeUtils; import android.util.TimeUtils;
import android.util.Xml; import android.util.Xml;
import android.view.Display; import android.view.Display;
@ -177,7 +180,13 @@ public class DeviceIdleController extends SystemService
* List of end times for UIDs that are temporarily marked as being allowed to access * List of end times for UIDs that are temporarily marked as being allowed to access
* the network and acquire wakelocks. Times are in milliseconds. * the network and acquire wakelocks. Times are in milliseconds.
*/ */
private final SparseLongArray mTempWhitelistAppIdEndTimes = new SparseLongArray(); private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
= new SparseArray<>();
/**
* Callback to the NetworkPolicyManagerService to tell it that the temp whitelist has changed.
*/
Runnable mNetworkPolicyTempWhitelistCallback;
/** /**
* Current app IDs of temporarily whitelist apps for high-priority messages. * Current app IDs of temporarily whitelist apps for high-priority messages.
@ -242,6 +251,8 @@ public class DeviceIdleController extends SystemService
private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm"; private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION = private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
"max_temp_app_whitelist_duration"; "max_temp_app_whitelist_duration";
private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
"mms_temp_app_whitelist_duration";
/** /**
* This is the time, after becoming inactive, at which we start looking at the * This is the time, after becoming inactive, at which we start looking at the
@ -339,6 +350,13 @@ public class DeviceIdleController extends SystemService
*/ */
public long MAX_TEMP_APP_WHITELIST_DURATION; public long MAX_TEMP_APP_WHITELIST_DURATION;
/**
* Amount of time we would like to whitelist an app that is receiving an MMS.
* @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
*/
public long MMS_TEMP_APP_WHITELIST_DURATION;
private final ContentResolver mResolver; private final ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(','); private final KeyValueListParser mParser = new KeyValueListParser(',');
@ -388,8 +406,10 @@ public class DeviceIdleController extends SystemService
2f); 2f);
MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM, MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM,
!COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L); !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(KEY_MAX_TEMP_APP_WHITELIST_DURATION, MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
5 * 60 * 1000L); KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
KEY_MMS_TEMP_APP_WHITELIST_DURATION, 30 * 1000L);
} }
} }
@ -441,6 +461,10 @@ public class DeviceIdleController extends SystemService
pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("="); pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw); TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
pw.println(); pw.println();
pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
pw.println();
} }
} }
@ -565,7 +589,7 @@ public class DeviceIdleController extends SystemService
} }
@Override public void addPowerSaveTempWhitelistApp(String packageName, long duration, @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
int userId) throws RemoteException { int userId, String reason) throws RemoteException {
getContext().enforceCallingPermission( getContext().enforceCallingPermission(
Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
"No permission to change device idle whitelist"); "No permission to change device idle whitelist");
@ -580,12 +604,19 @@ public class DeviceIdleController extends SystemService
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
try { try {
DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(callingUid, DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(callingUid,
packageName, duration, userId); packageName, duration, userId, true, reason);
} finally { } finally {
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
} }
} }
@Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
int userId, String reason) throws RemoteException {
long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
addPowerSaveTempWhitelistApp(packageName, duration, userId, reason);
return duration;
}
@Override public void exitIdle(String reason) { @Override public void exitIdle(String reason) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null); null);
@ -598,8 +629,13 @@ public class DeviceIdleController extends SystemService
} }
public final class LocalService { public final class LocalService {
public void addPowerSaveTempWhitelistAppDirect(int appId, long duration) { public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration); String reason) {
addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
}
public void setNetworkPolicyTempWhitelistCallback(Runnable callback) {
setNetworkPolicyTempWhitelistCallbackInternal(callback);
} }
} }
@ -777,11 +813,11 @@ public class DeviceIdleController extends SystemService
* app an exemption to access network and acquire wakelocks. * app an exemption to access network and acquire wakelocks.
*/ */
public void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName, public void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
long duration, int userId) { long duration, int userId, boolean sync, String reason) {
try { try {
int uid = getContext().getPackageManager().getPackageUid(packageName, userId); int uid = getContext().getPackageManager().getPackageUid(packageName, userId);
int appId = UserHandle.getAppId(uid); int appId = UserHandle.getAppId(uid);
addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration); addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
} }
} }
@ -791,8 +827,9 @@ public class DeviceIdleController extends SystemService
* app an exemption to access network and acquire wakelocks. * app an exemption to access network and acquire wakelocks.
*/ */
public void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId, public void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
long duration) { long duration, boolean sync, String reason) {
final long timeNow = SystemClock.elapsedRealtime(); final long timeNow = SystemClock.elapsedRealtime();
Runnable networkPolicyTempWhitelistCallback = null;
synchronized (this) { synchronized (this) {
int callingAppId = UserHandle.getAppId(callingUid); int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId >= Process.FIRST_APPLICATION_UID) { if (callingAppId >= Process.FIRST_APPLICATION_UID) {
@ -802,19 +839,45 @@ public class DeviceIdleController extends SystemService
} }
} }
duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId); Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
final boolean newEntry = entry == null;
// Set the new end time // Set the new end time
mTempWhitelistAppIdEndTimes.put(appId, timeNow + duration); if (newEntry) {
entry = new Pair<>(new MutableLong(0), reason);
mTempWhitelistAppIdEndTimes.put(appId, entry);
}
entry.first.value = timeNow + duration;
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist"); Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist");
} }
if (currentEndTime == 0) { if (newEntry) {
// No pending timeout for the app id, post a delayed message // No pending timeout for the app id, post a delayed message
try {
mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
reason, appId);
} catch (RemoteException e) {
}
postTempActiveTimeoutMessage(appId, duration); postTempActiveTimeoutMessage(appId, duration);
updateTempWhitelistAppIdsLocked(); updateTempWhitelistAppIdsLocked();
if (mNetworkPolicyTempWhitelistCallback != null) {
if (!sync) {
mHandler.post(mNetworkPolicyTempWhitelistCallback);
} else {
networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback;
}
}
reportTempWhitelistChangedLocked(); reportTempWhitelistChangedLocked();
} }
} }
if (networkPolicyTempWhitelistCallback != null) {
networkPolicyTempWhitelistCallback.run();
}
}
public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) {
synchronized (this) {
mNetworkPolicyTempWhitelistCallback = callback;
}
} }
private void postTempActiveTimeoutMessage(int uid, long delay) { private void postTempActiveTimeoutMessage(int uid, long delay) {
@ -825,21 +888,26 @@ public class DeviceIdleController extends SystemService
void checkTempAppWhitelistTimeout(int uid) { void checkTempAppWhitelistTimeout(int uid) {
final long timeNow = SystemClock.elapsedRealtime(); final long timeNow = SystemClock.elapsedRealtime();
synchronized (this) { synchronized (this) {
long endTime = mTempWhitelistAppIdEndTimes.get(uid); Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
if (endTime == 0) { if (entry == null) {
// Nothing to do // Nothing to do
return; return;
} }
if (timeNow >= endTime) { if (timeNow >= entry.first.value) {
mTempWhitelistAppIdEndTimes.delete(uid); mTempWhitelistAppIdEndTimes.delete(uid);
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Removing UID " + uid + " from temp whitelist"); Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
} }
updateTempWhitelistAppIdsLocked(); updateTempWhitelistAppIdsLocked();
reportTempWhitelistChangedLocked(); reportTempWhitelistChangedLocked();
try {
mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
entry.second, uid);
} catch (RemoteException e) {
}
} else { } else {
// Need more time // Need more time
postTempActiveTimeoutMessage(uid, endTime - timeNow); postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
} }
} }
} }
@ -1101,7 +1169,7 @@ public class DeviceIdleController extends SystemService
} }
void readConfigFileLocked() { void readConfigFileLocked() {
Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
mPowerSaveWhitelistUserApps.clear(); mPowerSaveWhitelistUserApps.clear();
FileInputStream stream; FileInputStream stream;
try { try {
@ -1370,11 +1438,14 @@ public class DeviceIdleController extends SystemService
while (i < args.length) { while (i < args.length) {
arg = args[i]; arg = args[i];
i++; i++;
addPowerSaveTempWhitelistAppInternal(0, arg, 10000L, userId); addPowerSaveTempWhitelistAppInternal(0, arg, 10000L, userId, true,
"shell");
pw.println("Added: " + arg);
} }
} finally { } finally {
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
} }
return;
} else if (arg.length() > 0 && arg.charAt(0) == '-'){ } else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg); pw.println("Unknown option: " + arg);
return; return;
@ -1421,8 +1492,10 @@ public class DeviceIdleController extends SystemService
pw.print(" UID="); pw.print(" UID=");
pw.print(mTempWhitelistAppIdEndTimes.keyAt(i)); pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
pw.print(": "); pw.print(": ");
TimeUtils.formatDuration(mTempWhitelistAppIdEndTimes.valueAt(i), timeNow, pw); Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
pw.println(); TimeUtils.formatDuration(entry.first.value, timeNow, pw);
pw.print(" - ");
pw.println(entry.second);
} }
} }
size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;

View File

@ -175,7 +175,7 @@ public final class BroadcastQueue {
DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController; DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController;
if (dic != null) { if (dic != null) {
dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1), dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1),
msg.arg2); msg.arg2, true, (String)msg.obj);
} }
} break; } break;
} }
@ -612,7 +612,7 @@ public final class BroadcastQueue {
} }
} }
final void scheduleTempWhitelistLocked(int uid, long duration) { final void scheduleTempWhitelistLocked(int uid, long duration, BroadcastRecord r) {
if (duration > Integer.MAX_VALUE) { if (duration > Integer.MAX_VALUE) {
duration = Integer.MAX_VALUE; duration = Integer.MAX_VALUE;
} }
@ -622,7 +622,19 @@ public final class BroadcastQueue {
// not that big a deal, however, because the main purpose here is to allow apps // not that big a deal, however, because the main purpose here is to allow apps
// to hold wake locks, and they will be able to acquire their wake lock immediately // to hold wake locks, and they will be able to acquire their wake lock immediately
// it just won't be enabled until we get through this work. // it just won't be enabled until we get through this work.
mHandler.obtainMessage(SCHEDULE_TEMP_WHITELIST_MSG, uid, (int)duration).sendToTarget(); StringBuilder b = new StringBuilder();
b.append("broadcast:");
UserHandle.formatUid(b, r.callingUid);
b.append(":");
if (r.intent.getAction() != null) {
b.append(r.intent.getAction());
} else if (r.intent.getComponent() != null) {
b.append(r.intent.getComponent().flattenToShortString());
} else if (r.intent.getData() != null) {
b.append(r.intent.getData());
}
mHandler.obtainMessage(SCHEDULE_TEMP_WHITELIST_MSG, uid, (int)duration, b.toString())
.sendToTarget();
} }
final void processNextBroadcast(boolean fromMsg) { final void processNextBroadcast(boolean fromMsg) {
@ -822,7 +834,7 @@ public final class BroadcastQueue {
} else { } else {
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(filter.owningUid, scheduleTempWhitelistLocked(filter.owningUid,
brOptions.getTemporaryAppWhitelistDuration()); brOptions.getTemporaryAppWhitelistDuration(), r);
} }
} }
return; return;
@ -1005,7 +1017,7 @@ public final class BroadcastQueue {
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(receiverUid, scheduleTempWhitelistLocked(receiverUid,
brOptions.getTemporaryAppWhitelistDuration()); brOptions.getTemporaryAppWhitelistDuration(), r);
} }
// Broadcast is being executed, its package can't be stopped. // Broadcast is being executed, its package can't be stopped.

View File

@ -147,6 +147,7 @@ import android.util.SparseIntArray;
import android.util.TrustedTime; import android.util.TrustedTime;
import android.util.Xml; import android.util.Xml;
import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags; import com.android.server.EventLogTags;
import libcore.io.IoUtils; import libcore.io.IoUtils;
@ -462,9 +463,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// listen for changes to power save whitelist // listen for changes to power save whitelist
final IntentFilter whitelistFilter = new IntentFilter( final IntentFilter whitelistFilter = new IntentFilter(
PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
whitelistFilter.addAction(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
DeviceIdleController.LocalService deviceIdleService
= LocalServices.getService(DeviceIdleController.LocalService.class);
deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback);
// watch for network interfaces to be claimed // watch for network interfaces to be claimed
final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
@ -512,7 +516,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
private IUidObserver mUidObserver = new IUidObserver.Stub() { final private IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState) throws RemoteException { @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
synchronized (mRulesLock) { synchronized (mRulesLock) {
updateUidStateLocked(uid, procState); updateUidStateLocked(uid, procState);
@ -526,24 +530,29 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
}; };
private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
synchronized (mRulesLock) { synchronized (mRulesLock) {
if (PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED.equals(intent.getAction())) {
updatePowerSaveWhitelistLocked(); updatePowerSaveWhitelistLocked();
updateRulesForGlobalChangeLocked(false); updateRulesForGlobalChangeLocked(false);
} else { }
}
};
final private Runnable mTempPowerSaveChangedCallback = new Runnable() {
@Override
public void run() {
synchronized (mRulesLock) {
updatePowerSaveTempWhitelistLocked(); updatePowerSaveTempWhitelistLocked();
updateRulesForTempWhitelistChangeLocked(); updateRulesForTempWhitelistChangeLocked();
purgePowerSaveTempWhitelistLocked(); purgePowerSaveTempWhitelistLocked();
} }
} }
}
}; };
private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { final private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// screen-related broadcasts are protected by system, no need // screen-related broadcasts are protected by system, no need
@ -552,7 +561,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
}; };
private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and PACKAGE_ADDED is protected // on background handler thread, and PACKAGE_ADDED is protected
@ -572,7 +581,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
}; };
private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and UID_REMOVED is protected // on background handler thread, and UID_REMOVED is protected
@ -590,7 +599,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
}; };
private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and USER_ADDED and USER_REMOVED // on background handler thread, and USER_ADDED and USER_REMOVED
@ -619,7 +628,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Receiver that watches for {@link INetworkStatsService} updates, which we * Receiver that watches for {@link INetworkStatsService} updates, which we
* use to check against {@link NetworkPolicy#warningBytes}. * use to check against {@link NetworkPolicy#warningBytes}.
*/ */
private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified // on background handler thread, and verified
@ -637,7 +646,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Receiver that watches for {@link Notification} control of * Receiver that watches for {@link Notification} control of
* {@link #mRestrictBackground}. * {@link #mRestrictBackground}.
*/ */
private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified MANAGE_NETWORK_POLICY // on background handler thread, and verified MANAGE_NETWORK_POLICY
@ -651,7 +660,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Receiver that watches for {@link Notification} control of * Receiver that watches for {@link Notification} control of
* {@link NetworkPolicy#lastWarningSnooze}. * {@link NetworkPolicy#lastWarningSnooze}.
*/ */
private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() { final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified MANAGE_NETWORK_POLICY // on background handler thread, and verified MANAGE_NETWORK_POLICY
@ -665,7 +674,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** /**
* Receiver that watches for {@link WifiConfiguration} to be changed. * Receiver that watches for {@link WifiConfiguration} to be changed.
*/ */
private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() { final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified CONNECTIVITY_INTERNAL // on background handler thread, and verified CONNECTIVITY_INTERNAL
@ -692,7 +701,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Receiver that watches {@link WifiInfo} state changes to infer metered * Receiver that watches {@link WifiInfo} state changes to infer metered
* state. Ignores hints when policy is user-defined. * state. Ignores hints when policy is user-defined.
*/ */
private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified CONNECTIVITY_INTERNAL // on background handler thread, and verified CONNECTIVITY_INTERNAL
@ -732,7 +741,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** /**
* Observer that watches for {@link INetworkManagementService} alerts. * Observer that watches for {@link INetworkManagementService} alerts.
*/ */
private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() { final private INetworkManagementEventObserver mAlertObserver
= new BaseNetworkObserver() {
@Override @Override
public void limitReached(String limitName, String iface) { public void limitReached(String limitName, String iface) {
// only someone like NMS should be calling us // only someone like NMS should be calling us
@ -1985,6 +1995,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// state changed, push updated rules // state changed, push updated rules
mUidState.put(uid, uidState); mUidState.put(uid, uidState);
updateRulesForUidStateChangeLocked(uid, oldUidState, uidState); updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState)
!= isProcStateAllowedWhileIdle(uidState)) {
updateRulesForDeviceIdleLocked();
}
} }
} }
@ -1996,6 +2010,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) { if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
updateRulesForUidStateChangeLocked(uid, oldUidState, updateRulesForUidStateChangeLocked(uid, oldUidState,
ActivityManager.PROCESS_STATE_CACHED_EMPTY); ActivityManager.PROCESS_STATE_CACHED_EMPTY);
if (mDeviceIdleMode) {
updateRulesForDeviceIdleLocked();
}
} }
} }
} }
@ -2033,13 +2050,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
} }
static boolean isProcStateAllowedWhileIdle(int procState) {
return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
}
void updateRulesForDeviceIdleLocked() { void updateRulesForDeviceIdleLocked() {
if (mDeviceIdleMode) { if (mDeviceIdleMode) {
// sync the whitelists before enable dozable chain. We don't care about the rules if // sync the whitelists before enable dozable chain. We don't care about the rules if
// we are disabling the chain. // we are disabling the chain.
SparseIntArray uidRules = new SparseIntArray(); SparseIntArray uidRules = new SparseIntArray();
final List<UserInfo> users = mUserManager.getUsers(); final List<UserInfo> users = mUserManager.getUsers();
for (UserInfo user : users) { for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
int uid = UserHandle.getUid(user.id, appId); int uid = UserHandle.getUid(user.id, appId);
@ -2051,6 +2073,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
uidRules.put(uid, FIREWALL_RULE_ALLOW); uidRules.put(uid, FIREWALL_RULE_ALLOW);
} }
} }
for (int i = mUidState.size() - 1; i >= 0; i--) {
if (isProcStateAllowedWhileIdle(mUidState.valueAt(i))) {
uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
}
}
setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules); setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
} }
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode); enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);

View File

@ -1177,7 +1177,11 @@ public class UsageStatsService extends SystemService implements
@Override @Override
public void whitelistAppTemporarily(String packageName, long duration, int userId) public void whitelistAppTemporarily(String packageName, long duration, int userId)
throws RemoteException { throws RemoteException {
mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName, duration, userId); StringBuilder reason = new StringBuilder(32);
reason.append("from:");
UserHandle.formatUid(reason, Binder.getCallingUid());
mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName, duration, userId,
reason.toString());
} }
@Override @Override

View File

@ -395,13 +395,19 @@ public class MockContext extends Context {
@Override @Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver, String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
Handler scheduler, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
int initialCode, String initialData, Bundle initialExtras) { throw new UnsupportedOperationException();
}
/** @hide */
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void sendStickyBroadcast(Intent intent) { public void sendStickyBroadcast(Intent intent) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -1585,6 +1585,14 @@ public final class BridgeContext extends Context {
// pass // pass
} }
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) {
// pass
}
@Override @Override
public void sendStickyBroadcast(Intent arg0) { public void sendStickyBroadcast(Intent arg0) {
// pass // pass