summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-07-13 18:00:37 -0700
committerDianne Hackborn <hackbod@google.com>2015-07-14 18:33:08 -0700
commitfd854ee58c5d56f84047007ead9f88a767ae956f (patch)
tree8cd12e57928f2984b2da6c9a0872fcb795c5fa94
parent987241265b77542f45ce95838c25beeaf3ae6849 (diff)
downloadframeworks_base-fd854ee58c5d56f84047007ead9f88a767ae956f.zip
frameworks_base-fd854ee58c5d56f84047007ead9f88a767ae956f.tar.gz
frameworks_base-fd854ee58c5d56f84047007ead9f88a767ae956f.tar.bz2
Fix issue #21626564: MMS should be receivied while Dozing
We now place whoever is receiving the MMS on the temporary whitelist while doing so, so they can get network access to download it. There was also an issue that needed to be fixed where we were no longer updating the list of allowed uids while dozing based on their proc states... we now do that. Also did a bit of optimization of the temp white list update path do the network policy manager, instead of going through a broadcast we now directly call in to the network policy manager. This also allows us to have a synchronous version of updating the list, so we can know the app has network access before we tell it to do anything. Finally added battery stats events for things going on and off the whitelist so we can diagnose the behavior there. Change-Id: Ic7fe010af680034d9f8cb014bb135b2addef7455
-rw-r--r--core/java/android/app/ContextImpl.java19
-rw-r--r--core/java/android/content/Context.java11
-rw-r--r--core/java/android/content/ContextWrapper.java12
-rw-r--r--core/java/android/os/BatteryStats.java12
-rw-r--r--core/java/android/os/IDeviceIdleController.aidl3
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java117
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java22
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java71
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java6
-rw-r--r--test-runner/src/android/test/mock/MockContext.java10
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java8
11 files changed, 227 insertions, 64 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index c07140c..235f294 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -960,14 +960,21 @@ class ContextImpl extends Context {
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) {
sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
- resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
- Handler scheduler,
- int initialCode, String initialData, Bundle initialExtras) {
+ Handler scheduler, 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;
if (resultReceiver != null) {
if (mPackageInfo != null) {
@@ -981,8 +988,8 @@ class ContextImpl extends Context {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
- rd = new LoadedApk.ReceiverDispatcher(
- resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
+ rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
+ scheduler, null, false).getIIntentReceiver();
}
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
@@ -993,7 +1000,7 @@ class ContextImpl extends Context {
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, receiverPermissions,
- appOp, null, true, false, user.getIdentifier());
+ appOp, options, true, false, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0bfe108..4c7dd10 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1809,6 +1809,17 @@ public abstract class Context {
@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
* Intent you are sending stays around after the broadcast is complete,
* so that others can quickly retrieve that data through the return
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 8ad3d21..8359edf 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -489,12 +489,20 @@ public class ContextWrapper extends Context {
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
- Handler scheduler,
- int initialCode, String initialData, Bundle initialExtras) {
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, resultReceiver,
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
@Deprecated
public void sendStickyBroadcast(Intent intent) {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index adc84bc..452e4d5 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1193,9 +1193,11 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
// Event for a package becoming active due to an interaction.
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.
- 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.
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;
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_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.
public int eventCode;
@@ -1852,12 +1858,12 @@ public abstract class BatteryStats implements Parcelable {
public static final String[] HISTORY_EVENT_NAMES = new String[] {
"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[] {
"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"
};
/**
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index fe4aa13..b768852 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -27,6 +27,7 @@ interface IDeviceIdleController {
int[] getAppIdWhitelist();
int[] getAppIdTempWhitelist();
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);
}
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index fde1490..08b2332 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -36,6 +36,7 @@ import android.hardware.TriggerEventListener;
import android.hardware.display.DisplayManager;
import android.net.INetworkPolicyManager;
import android.net.Uri;
+import android.os.BatteryStats;
import android.os.Binder;
import android.os.Environment;
import android.os.FileUtils;
@@ -54,9 +55,11 @@ import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.KeyValueListParser;
+import android.util.MutableLong;
+import android.util.Pair;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseBooleanArray;
-import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.Xml;
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
* 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.
@@ -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_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
@@ -339,6 +350,13 @@ public class DeviceIdleController extends SystemService
*/
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 KeyValueListParser mParser = new KeyValueListParser(',');
@@ -388,8 +406,10 @@ public class DeviceIdleController extends SystemService
2f);
MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM,
!COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
- MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(KEY_MAX_TEMP_APP_WHITELIST_DURATION,
- 5 * 60 * 1000L);
+ MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
+ 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("=");
TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
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,
- int userId) throws RemoteException {
+ int userId, String reason) throws RemoteException {
getContext().enforceCallingPermission(
Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
"No permission to change device idle whitelist");
@@ -580,12 +604,19 @@ public class DeviceIdleController extends SystemService
final long token = Binder.clearCallingIdentity();
try {
DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(callingUid,
- packageName, duration, userId);
+ packageName, duration, userId, true, reason);
} finally {
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) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
@@ -598,8 +629,13 @@ public class DeviceIdleController extends SystemService
}
public final class LocalService {
- public void addPowerSaveTempWhitelistAppDirect(int appId, long duration) {
- addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration);
+ public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
+ 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.
*/
public void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
- long duration, int userId) {
+ long duration, int userId, boolean sync, String reason) {
try {
int uid = getContext().getPackageManager().getPackageUid(packageName, userId);
int appId = UserHandle.getAppId(uid);
- addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration);
+ addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
} catch (NameNotFoundException e) {
}
}
@@ -791,8 +827,9 @@ public class DeviceIdleController extends SystemService
* app an exemption to access network and acquire wakelocks.
*/
public void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
- long duration) {
+ long duration, boolean sync, String reason) {
final long timeNow = SystemClock.elapsedRealtime();
+ Runnable networkPolicyTempWhitelistCallback = null;
synchronized (this) {
int callingAppId = UserHandle.getAppId(callingUid);
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);
- long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId);
+ Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
+ final boolean newEntry = entry == null;
// 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) {
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
+ try {
+ mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
+ reason, appId);
+ } catch (RemoteException e) {
+ }
postTempActiveTimeoutMessage(appId, duration);
updateTempWhitelistAppIdsLocked();
+ if (mNetworkPolicyTempWhitelistCallback != null) {
+ if (!sync) {
+ mHandler.post(mNetworkPolicyTempWhitelistCallback);
+ } else {
+ networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback;
+ }
+ }
reportTempWhitelistChangedLocked();
}
}
+ if (networkPolicyTempWhitelistCallback != null) {
+ networkPolicyTempWhitelistCallback.run();
+ }
+ }
+
+ public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) {
+ synchronized (this) {
+ mNetworkPolicyTempWhitelistCallback = callback;
+ }
}
private void postTempActiveTimeoutMessage(int uid, long delay) {
@@ -825,21 +888,26 @@ public class DeviceIdleController extends SystemService
void checkTempAppWhitelistTimeout(int uid) {
final long timeNow = SystemClock.elapsedRealtime();
synchronized (this) {
- long endTime = mTempWhitelistAppIdEndTimes.get(uid);
- if (endTime == 0) {
+ Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
+ if (entry == null) {
// Nothing to do
return;
}
- if (timeNow >= endTime) {
+ if (timeNow >= entry.first.value) {
mTempWhitelistAppIdEndTimes.delete(uid);
if (DEBUG) {
Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
}
updateTempWhitelistAppIdsLocked();
reportTempWhitelistChangedLocked();
+ try {
+ mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
+ entry.second, uid);
+ } catch (RemoteException e) {
+ }
} else {
// Need more time
- postTempActiveTimeoutMessage(uid, endTime - timeNow);
+ postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
}
}
}
@@ -1101,7 +1169,7 @@ public class DeviceIdleController extends SystemService
}
void readConfigFileLocked() {
- Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
+ if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
mPowerSaveWhitelistUserApps.clear();
FileInputStream stream;
try {
@@ -1370,11 +1438,14 @@ public class DeviceIdleController extends SystemService
while (i < args.length) {
arg = args[i];
i++;
- addPowerSaveTempWhitelistAppInternal(0, arg, 10000L, userId);
+ addPowerSaveTempWhitelistAppInternal(0, arg, 10000L, userId, true,
+ "shell");
+ pw.println("Added: " + arg);
}
} finally {
Binder.restoreCallingIdentity(token);
}
+ return;
} else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg);
return;
@@ -1421,8 +1492,10 @@ public class DeviceIdleController extends SystemService
pw.print(" UID=");
pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
pw.print(": ");
- TimeUtils.formatDuration(mTempWhitelistAppIdEndTimes.valueAt(i), timeNow, pw);
- pw.println();
+ Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
+ TimeUtils.formatDuration(entry.first.value, timeNow, pw);
+ pw.print(" - ");
+ pw.println(entry.second);
}
}
size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 7766539..91d97ef 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -175,7 +175,7 @@ public final class BroadcastQueue {
DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController;
if (dic != null) {
dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1),
- msg.arg2);
+ msg.arg2, true, (String)msg.obj);
}
} 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) {
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
// 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.
- 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) {
@@ -822,7 +834,7 @@ public final class BroadcastQueue {
} else {
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(filter.owningUid,
- brOptions.getTemporaryAppWhitelistDuration());
+ brOptions.getTemporaryAppWhitelistDuration(), r);
}
}
return;
@@ -1005,7 +1017,7 @@ public final class BroadcastQueue {
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(receiverUid,
- brOptions.getTemporaryAppWhitelistDuration());
+ brOptions.getTemporaryAppWhitelistDuration(), r);
}
// Broadcast is being executed, its package can't be stopped.
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f8f00ef..395aa27 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -147,6 +147,7 @@ import android.util.SparseIntArray;
import android.util.TrustedTime;
import android.util.Xml;
+import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags;
import libcore.io.IoUtils;
@@ -462,9 +463,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// listen for changes to power save whitelist
final IntentFilter whitelistFilter = new IntentFilter(
PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
- whitelistFilter.addAction(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
+ DeviceIdleController.LocalService deviceIdleService
+ = LocalServices.getService(DeviceIdleController.LocalService.class);
+ deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback);
+
// watch for network interfaces to be claimed
final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
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 {
synchronized (mRulesLock) {
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
public void onReceive(Context context, Intent intent) {
// on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
synchronized (mRulesLock) {
- if (PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED.equals(intent.getAction())) {
- updatePowerSaveWhitelistLocked();
- updateRulesForGlobalChangeLocked(false);
- } else {
- updatePowerSaveTempWhitelistLocked();
- updateRulesForTempWhitelistChangeLocked();
- purgePowerSaveTempWhitelistLocked();
- }
+ updatePowerSaveWhitelistLocked();
+ updateRulesForGlobalChangeLocked(false);
}
}
};
- private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
+ final private Runnable mTempPowerSaveChangedCallback = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mRulesLock) {
+ updatePowerSaveTempWhitelistLocked();
+ updateRulesForTempWhitelistChangeLocked();
+ purgePowerSaveTempWhitelistLocked();
+ }
+ }
+ };
+
+ final private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 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
public void onReceive(Context context, Intent intent) {
// 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
public void onReceive(Context context, Intent intent) {
// 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
public void onReceive(Context context, Intent intent) {
// 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
* use to check against {@link NetworkPolicy#warningBytes}.
*/
- private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
+ final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified
@@ -637,7 +646,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Receiver that watches for {@link Notification} control of
* {@link #mRestrictBackground}.
*/
- private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
+ final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 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
* {@link NetworkPolicy#lastWarningSnooze}.
*/
- private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
+ final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 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.
*/
- private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
+ final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 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
* state. Ignores hints when policy is user-defined.
*/
- private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
+ final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 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.
*/
- private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
+ final private INetworkManagementEventObserver mAlertObserver
+ = new BaseNetworkObserver() {
@Override
public void limitReached(String limitName, String iface) {
// only someone like NMS should be calling us
@@ -1985,6 +1995,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// state changed, push updated rules
mUidState.put(uid, 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) {
updateRulesForUidStateChangeLocked(uid, oldUidState,
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() {
if (mDeviceIdleMode) {
// sync the whitelists before enable dozable chain. We don't care about the rules if
// we are disabling the chain.
SparseIntArray uidRules = new SparseIntArray();
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--) {
int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
int uid = UserHandle.getUid(user.id, appId);
@@ -2051,6 +2073,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
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);
}
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index c49a5f9..b0a14c8 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1177,7 +1177,11 @@ public class UsageStatsService extends SystemService implements
@Override
public void whitelistAppTemporarily(String packageName, long duration, int userId)
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
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index e5ea562..e09d124 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -395,13 +395,19 @@ public class MockContext extends Context {
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
- Handler scheduler,
- int initialCode, String initialData, Bundle initialExtras) {
+ Handler scheduler, 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();
+ }
+ @Override
public void sendStickyBroadcast(Intent intent) {
throw new UnsupportedOperationException();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 933420f..1f3802e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1586,6 +1586,14 @@ public final class BridgeContext extends Context {
}
@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
public void sendStickyBroadcast(Intent arg0) {
// pass