Merge "Fix issue #22989030: Separate battery whitelists" into mnc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f0e5501e09
@ -76,6 +76,13 @@ public abstract class UsageStatsManagerInternal {
|
|||||||
*/
|
*/
|
||||||
public abstract boolean isAppIdle(String packageName, int userId);
|
public abstract boolean isAppIdle(String packageName, int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all of the uids for a given user where all packages associating with that uid
|
||||||
|
* are in the app idle state -- there are no associated apps that are not idle. This means
|
||||||
|
* all of the returned uids can be safely considered app idle.
|
||||||
|
*/
|
||||||
|
public abstract int[] getIdleUidsForUser(int userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if currently app idle parole mode is on. This means all idle apps are allow to
|
* @return True if currently app idle parole mode is on. This means all idle apps are allow to
|
||||||
* run for a short period of time.
|
* run for a short period of time.
|
||||||
|
@ -22,10 +22,14 @@ import android.os.UserHandle;
|
|||||||
interface IDeviceIdleController {
|
interface IDeviceIdleController {
|
||||||
void addPowerSaveWhitelistApp(String name);
|
void addPowerSaveWhitelistApp(String name);
|
||||||
void removePowerSaveWhitelistApp(String name);
|
void removePowerSaveWhitelistApp(String name);
|
||||||
|
String[] getSystemPowerWhitelistExceptIdle();
|
||||||
String[] getSystemPowerWhitelist();
|
String[] getSystemPowerWhitelist();
|
||||||
|
String[] getFullPowerWhitelistExceptIdle();
|
||||||
String[] getFullPowerWhitelist();
|
String[] getFullPowerWhitelist();
|
||||||
|
int[] getAppIdWhitelistExceptIdle();
|
||||||
int[] getAppIdWhitelist();
|
int[] getAppIdWhitelist();
|
||||||
int[] getAppIdTempWhitelist();
|
int[] getAppIdTempWhitelist();
|
||||||
|
boolean isPowerSaveWhitelistExceptIdleApp(String name);
|
||||||
boolean isPowerSaveWhitelistApp(String name);
|
boolean isPowerSaveWhitelistApp(String name);
|
||||||
void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
|
void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
|
||||||
long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
|
long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
|
||||||
|
@ -183,6 +183,14 @@ public class SparseIntArray implements Cloneable {
|
|||||||
return mValues[index];
|
return mValues[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly set the value at a particular index.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setValueAt(int index, int value) {
|
||||||
|
mValues[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index for which {@link #keyAt} would return the
|
* Returns the index for which {@link #keyAt} would return the
|
||||||
* specified key, or a negative number if the specified
|
* specified key, or a negative number if the specified
|
||||||
|
@ -141,6 +141,6 @@
|
|||||||
|
|
||||||
<!-- These are the standard packages that are white-listed to always have internet
|
<!-- These are the standard packages that are white-listed to always have internet
|
||||||
access while in power save mode, even if they aren't in the foreground. -->
|
access while in power save mode, even if they aren't in the foreground. -->
|
||||||
<allow-in-power-save package="com.android.providers.downloads" />
|
<allow-in-power-save-except-idle package="com.android.providers.downloads" />
|
||||||
|
|
||||||
</permissions>
|
</permissions>
|
||||||
|
@ -113,6 +113,7 @@ public class DeviceIdleController extends SystemService
|
|||||||
private Display mCurDisplay;
|
private Display mCurDisplay;
|
||||||
private AnyMotionDetector mAnyMotionDetector;
|
private AnyMotionDetector mAnyMotionDetector;
|
||||||
private boolean mEnabled;
|
private boolean mEnabled;
|
||||||
|
private boolean mForceIdle;
|
||||||
private boolean mScreenOn;
|
private boolean mScreenOn;
|
||||||
private boolean mCharging;
|
private boolean mCharging;
|
||||||
private boolean mSigMotionActive;
|
private boolean mSigMotionActive;
|
||||||
@ -151,7 +152,14 @@ public class DeviceIdleController extends SystemService
|
|||||||
public final AtomicFile mConfigFile;
|
public final AtomicFile mConfigFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package names the system has white-listed to opt out of power save restrictions.
|
* Package names the system has white-listed to opt out of power save restrictions,
|
||||||
|
* except for device idle mode.
|
||||||
|
*/
|
||||||
|
private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package names the system has white-listed to opt out of power save restrictions for
|
||||||
|
* all modes.
|
||||||
*/
|
*/
|
||||||
private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
|
private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
|
||||||
|
|
||||||
@ -160,11 +168,30 @@ public class DeviceIdleController extends SystemService
|
|||||||
*/
|
*/
|
||||||
private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
|
private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App IDs of built-in system apps that have been white-listed except for idle modes.
|
||||||
|
*/
|
||||||
|
private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
|
||||||
|
= new SparseBooleanArray();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App IDs of built-in system apps that have been white-listed.
|
* App IDs of built-in system apps that have been white-listed.
|
||||||
*/
|
*/
|
||||||
private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
|
private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App IDs that have been white-listed to opt out of power save restrictions, except
|
||||||
|
* for device idle modes.
|
||||||
|
*/
|
||||||
|
private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current app IDs that are in the complete power save white list, but shouldn't be
|
||||||
|
* excluded from idle modes. This array can be shared with others because it will not be
|
||||||
|
* modified once set.
|
||||||
|
*/
|
||||||
|
private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App IDs that have been white-listed to opt out of power save restrictions.
|
* App IDs that have been white-listed to opt out of power save restrictions.
|
||||||
*/
|
*/
|
||||||
@ -583,14 +610,26 @@ public class DeviceIdleController extends SystemService
|
|||||||
removePowerSaveWhitelistAppInternal(name);
|
removePowerSaveWhitelistAppInternal(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public String[] getSystemPowerWhitelistExceptIdle() {
|
||||||
|
return getSystemPowerWhitelistExceptIdleInternal();
|
||||||
|
}
|
||||||
|
|
||||||
@Override public String[] getSystemPowerWhitelist() {
|
@Override public String[] getSystemPowerWhitelist() {
|
||||||
return getSystemPowerWhitelistInternal();
|
return getSystemPowerWhitelistInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public String[] getFullPowerWhitelistExceptIdle() {
|
||||||
|
return getFullPowerWhitelistExceptIdleInternal();
|
||||||
|
}
|
||||||
|
|
||||||
@Override public String[] getFullPowerWhitelist() {
|
@Override public String[] getFullPowerWhitelist() {
|
||||||
return getFullPowerWhitelistInternal();
|
return getFullPowerWhitelistInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public int[] getAppIdWhitelistExceptIdle() {
|
||||||
|
return getAppIdWhitelistExceptIdleInternal();
|
||||||
|
}
|
||||||
|
|
||||||
@Override public int[] getAppIdWhitelist() {
|
@Override public int[] getAppIdWhitelist() {
|
||||||
return getAppIdWhitelistInternal();
|
return getAppIdWhitelistInternal();
|
||||||
}
|
}
|
||||||
@ -599,6 +638,10 @@ public class DeviceIdleController extends SystemService
|
|||||||
return getAppIdTempWhitelistInternal();
|
return getAppIdTempWhitelistInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
|
||||||
|
return isPowerSaveWhitelistExceptIdleAppInternal(name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override public boolean isPowerSaveWhitelistApp(String name) {
|
@Override public boolean isPowerSaveWhitelistApp(String name) {
|
||||||
return isPowerSaveWhitelistAppInternal(name);
|
return isPowerSaveWhitelistAppInternal(name);
|
||||||
}
|
}
|
||||||
@ -679,6 +722,19 @@ public class DeviceIdleController extends SystemService
|
|||||||
mEnabled = getContext().getResources().getBoolean(
|
mEnabled = getContext().getResources().getBoolean(
|
||||||
com.android.internal.R.bool.config_enableAutoPowerModes);
|
com.android.internal.R.bool.config_enableAutoPowerModes);
|
||||||
SystemConfig sysConfig = SystemConfig.getInstance();
|
SystemConfig sysConfig = SystemConfig.getInstance();
|
||||||
|
ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
|
||||||
|
for (int i=0; i<allowPowerExceptIdle.size(); i++) {
|
||||||
|
String pkg = allowPowerExceptIdle.valueAt(i);
|
||||||
|
try {
|
||||||
|
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
|
||||||
|
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||||
|
int appid = UserHandle.getAppId(ai.uid);
|
||||||
|
mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
|
||||||
|
mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
|
ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
|
||||||
for (int i=0; i<allowPower.size(); i++) {
|
for (int i=0; i<allowPower.size(); i++) {
|
||||||
String pkg = allowPower.valueAt(i);
|
String pkg = allowPower.valueAt(i);
|
||||||
@ -686,6 +742,10 @@ public class DeviceIdleController extends SystemService
|
|||||||
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
|
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
|
||||||
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
|
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||||
int appid = UserHandle.getAppId(ai.uid);
|
int appid = UserHandle.getAppId(ai.uid);
|
||||||
|
// These apps are on both the whitelist-except-idle as well
|
||||||
|
// as the full whitelist, so they apply in all cases.
|
||||||
|
mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
|
||||||
|
mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
|
||||||
mPowerSaveWhitelistApps.put(ai.packageName, appid);
|
mPowerSaveWhitelistApps.put(ai.packageName, appid);
|
||||||
mPowerSaveWhitelistSystemAppIds.put(appid, true);
|
mPowerSaveWhitelistSystemAppIds.put(appid, true);
|
||||||
}
|
}
|
||||||
@ -783,17 +843,45 @@ public class DeviceIdleController extends SystemService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getSystemPowerWhitelistExceptIdleInternal() {
|
||||||
|
synchronized (this) {
|
||||||
|
int size = mPowerSaveWhitelistAppsExceptIdle.size();
|
||||||
|
String[] apps = new String[size];
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
|
||||||
|
}
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String[] getSystemPowerWhitelistInternal() {
|
public String[] getSystemPowerWhitelistInternal() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
int size = mPowerSaveWhitelistApps.size();
|
int size = mPowerSaveWhitelistApps.size();
|
||||||
String[] apps = new String[size];
|
String[] apps = new String[size];
|
||||||
for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
apps[i] = mPowerSaveWhitelistApps.keyAt(i);
|
apps[i] = mPowerSaveWhitelistApps.keyAt(i);
|
||||||
}
|
}
|
||||||
return apps;
|
return apps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getFullPowerWhitelistExceptIdleInternal() {
|
||||||
|
synchronized (this) {
|
||||||
|
int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
|
||||||
|
String[] apps = new String[size];
|
||||||
|
int cur = 0;
|
||||||
|
for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
|
||||||
|
apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
|
||||||
|
apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String[] getFullPowerWhitelistInternal() {
|
public String[] getFullPowerWhitelistInternal() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
|
int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
|
||||||
@ -811,6 +899,13 @@ public class DeviceIdleController extends SystemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
|
||||||
|
synchronized (this) {
|
||||||
|
return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
|
||||||
|
|| mPowerSaveWhitelistUserApps.containsKey(packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPowerSaveWhitelistAppInternal(String packageName) {
|
public boolean isPowerSaveWhitelistAppInternal(String packageName) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return mPowerSaveWhitelistApps.containsKey(packageName)
|
return mPowerSaveWhitelistApps.containsKey(packageName)
|
||||||
@ -818,6 +913,12 @@ public class DeviceIdleController extends SystemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int[] getAppIdWhitelistExceptIdleInternal() {
|
||||||
|
synchronized (this) {
|
||||||
|
return mPowerSaveWhitelistExceptIdleAppIdArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int[] getAppIdWhitelistInternal() {
|
public int[] getAppIdWhitelistInternal() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return mPowerSaveWhitelistAllAppIdArray;
|
return mPowerSaveWhitelistAllAppIdArray;
|
||||||
@ -921,6 +1022,9 @@ public class DeviceIdleController extends SystemService
|
|||||||
Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
|
Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
|
||||||
}
|
}
|
||||||
updateTempWhitelistAppIdsLocked();
|
updateTempWhitelistAppIdsLocked();
|
||||||
|
if (mNetworkPolicyTempWhitelistCallback != null) {
|
||||||
|
mHandler.post(mNetworkPolicyTempWhitelistCallback);
|
||||||
|
}
|
||||||
reportTempWhitelistChangedLocked();
|
reportTempWhitelistChangedLocked();
|
||||||
try {
|
try {
|
||||||
mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
|
mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
|
||||||
@ -949,10 +1053,14 @@ public class DeviceIdleController extends SystemService
|
|||||||
if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
|
if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
|
||||||
if (!screenOn && mScreenOn) {
|
if (!screenOn && mScreenOn) {
|
||||||
mScreenOn = false;
|
mScreenOn = false;
|
||||||
becomeInactiveIfAppropriateLocked();
|
if (!mForceIdle) {
|
||||||
|
becomeInactiveIfAppropriateLocked();
|
||||||
|
}
|
||||||
} else if (screenOn) {
|
} else if (screenOn) {
|
||||||
mScreenOn = true;
|
mScreenOn = true;
|
||||||
becomeActiveLocked("screen", Process.myUid());
|
if (!mForceIdle) {
|
||||||
|
becomeActiveLocked("screen", Process.myUid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,10 +1068,14 @@ public class DeviceIdleController extends SystemService
|
|||||||
if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
|
if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
|
||||||
if (!charging && mCharging) {
|
if (!charging && mCharging) {
|
||||||
mCharging = false;
|
mCharging = false;
|
||||||
becomeInactiveIfAppropriateLocked();
|
if (!mForceIdle) {
|
||||||
|
becomeInactiveIfAppropriateLocked();
|
||||||
|
}
|
||||||
} else if (charging) {
|
} else if (charging) {
|
||||||
mCharging = charging;
|
mCharging = charging;
|
||||||
becomeActiveLocked("charging", Process.myUid());
|
if (!mForceIdle) {
|
||||||
|
becomeActiveLocked("charging", Process.myUid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +1101,7 @@ public class DeviceIdleController extends SystemService
|
|||||||
|
|
||||||
void becomeInactiveIfAppropriateLocked() {
|
void becomeInactiveIfAppropriateLocked() {
|
||||||
if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
|
if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
|
||||||
if (!mScreenOn && !mCharging && mEnabled && mState == STATE_ACTIVE) {
|
if (((!mScreenOn && !mCharging) || mForceIdle) && mEnabled && mState == STATE_ACTIVE) {
|
||||||
// Screen has turned off; we are now going to become inactive and start
|
// Screen has turned off; we are now going to become inactive and start
|
||||||
// waiting to see if we will ultimately go idle.
|
// waiting to see if we will ultimately go idle.
|
||||||
mState = STATE_INACTIVE;
|
mState = STATE_INACTIVE;
|
||||||
@ -1010,6 +1122,15 @@ public class DeviceIdleController extends SystemService
|
|||||||
becomeInactiveIfAppropriateLocked();
|
becomeInactiveIfAppropriateLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exitForceIdleLocked() {
|
||||||
|
if (mForceIdle) {
|
||||||
|
mForceIdle = false;
|
||||||
|
if (mScreenOn || mCharging) {
|
||||||
|
becomeActiveLocked("exit-force-idle", Process.myUid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void stepIdleStateLocked() {
|
void stepIdleStateLocked() {
|
||||||
if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
|
if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
|
||||||
EventLogTags.writeDeviceIdleStep();
|
EventLogTags.writeDeviceIdleStep();
|
||||||
@ -1138,20 +1259,28 @@ public class DeviceIdleController extends SystemService
|
|||||||
mNextAlarmTime, mSensingAlarmIntent);
|
mNextAlarmTime, mSensingAlarmIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateWhitelistAppIdsLocked() {
|
private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
|
||||||
mPowerSaveWhitelistAllAppIds.clear();
|
ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
|
||||||
for (int i=0; i<mPowerSaveWhitelistApps.size(); i++) {
|
outAppIds.clear();
|
||||||
mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistApps.valueAt(i), true);
|
for (int i=0; i<systemApps.size(); i++) {
|
||||||
|
outAppIds.put(systemApps.valueAt(i), true);
|
||||||
}
|
}
|
||||||
for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
|
for (int i=0; i<userApps.size(); i++) {
|
||||||
mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true);
|
outAppIds.put(userApps.valueAt(i), true);
|
||||||
}
|
}
|
||||||
int size = mPowerSaveWhitelistAllAppIds.size();
|
int size = outAppIds.size();
|
||||||
int[] appids = new int[size];
|
int[] appids = new int[size];
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
appids[i] = mPowerSaveWhitelistAllAppIds.keyAt(i);
|
appids[i] = outAppIds.keyAt(i);
|
||||||
}
|
}
|
||||||
mPowerSaveWhitelistAllAppIdArray = appids;
|
return appids;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWhitelistAppIdsLocked() {
|
||||||
|
mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
|
||||||
|
mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
|
||||||
|
mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
|
||||||
|
mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
|
||||||
if (mLocalPowerManager != null) {
|
if (mLocalPowerManager != null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Setting wakelock whitelist to "
|
Slog.d(TAG, "Setting wakelock whitelist to "
|
||||||
@ -1320,6 +1449,9 @@ public class DeviceIdleController extends SystemService
|
|||||||
pw.println("Commands:");
|
pw.println("Commands:");
|
||||||
pw.println(" step");
|
pw.println(" step");
|
||||||
pw.println(" Immediately step to next state, without waiting for alarm.");
|
pw.println(" Immediately step to next state, without waiting for alarm.");
|
||||||
|
pw.println(" force-idle");
|
||||||
|
pw.println(" Force directly into idle mode, regardless of other device state.");
|
||||||
|
pw.println(" Use \"step\" to get out.");
|
||||||
pw.println(" disable");
|
pw.println(" disable");
|
||||||
pw.println(" Completely disable device idle mode.");
|
pw.println(" Completely disable device idle mode.");
|
||||||
pw.println(" enable");
|
pw.println(" enable");
|
||||||
@ -1362,6 +1494,7 @@ public class DeviceIdleController extends SystemService
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
long token = Binder.clearCallingIdentity();
|
long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
|
exitForceIdleLocked();
|
||||||
stepIdleStateLocked();
|
stepIdleStateLocked();
|
||||||
pw.print("Stepped to: "); pw.println(stateToString(mState));
|
pw.print("Stepped to: "); pw.println(stateToString(mState));
|
||||||
} finally {
|
} finally {
|
||||||
@ -1369,6 +1502,33 @@ public class DeviceIdleController extends SystemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if ("force-idle".equals(arg)) {
|
||||||
|
synchronized (this) {
|
||||||
|
long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
if (!mEnabled) {
|
||||||
|
pw.println("Unable to go idle; not enabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mForceIdle = true;
|
||||||
|
becomeInactiveIfAppropriateLocked();
|
||||||
|
int curState = mState;
|
||||||
|
while (curState != STATE_IDLE) {
|
||||||
|
stepIdleStateLocked();
|
||||||
|
if (curState == mState) {
|
||||||
|
pw.print("Unable to go idle; stopped at ");
|
||||||
|
pw.println(stateToString(mState));
|
||||||
|
exitForceIdleLocked();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
curState = mState;
|
||||||
|
}
|
||||||
|
pw.println("Now forced in to idle mode");
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
} else if ("disable".equals(arg)) {
|
} else if ("disable".equals(arg)) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
long token = Binder.clearCallingIdentity();
|
long token = Binder.clearCallingIdentity();
|
||||||
@ -1387,6 +1547,7 @@ public class DeviceIdleController extends SystemService
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
long token = Binder.clearCallingIdentity();
|
long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
|
exitForceIdleLocked();
|
||||||
if (!mEnabled) {
|
if (!mEnabled) {
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
becomeInactiveIfAppropriateLocked();
|
becomeInactiveIfAppropriateLocked();
|
||||||
@ -1431,6 +1592,12 @@ public class DeviceIdleController extends SystemService
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
|
||||||
|
pw.print("system-excidle,");
|
||||||
|
pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
|
||||||
|
pw.print(",");
|
||||||
|
pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
|
||||||
|
}
|
||||||
for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
|
for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
|
||||||
pw.print("system,");
|
pw.print("system,");
|
||||||
pw.print(mPowerSaveWhitelistApps.keyAt(j));
|
pw.print(mPowerSaveWhitelistApps.keyAt(j));
|
||||||
@ -1481,7 +1648,15 @@ public class DeviceIdleController extends SystemService
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mConstants.dump(pw);
|
mConstants.dump(pw);
|
||||||
|
|
||||||
int size = mPowerSaveWhitelistApps.size();
|
int size = mPowerSaveWhitelistAppsExceptIdle.size();
|
||||||
|
if (size > 0) {
|
||||||
|
pw.println(" Whitelist (except idle) system apps:");
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
pw.print(" ");
|
||||||
|
pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = mPowerSaveWhitelistApps.size();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
pw.println(" Whitelist system apps:");
|
pw.println(" Whitelist system apps:");
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
@ -1497,6 +1672,15 @@ public class DeviceIdleController extends SystemService
|
|||||||
pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
|
pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size = mPowerSaveWhitelistExceptIdleAppIds.size();
|
||||||
|
if (size > 0) {
|
||||||
|
pw.println(" Whitelist (except idle) all app ids:");
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
pw.print(" ");
|
||||||
|
pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
|
||||||
|
pw.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
size = mPowerSaveWhitelistAllAppIds.size();
|
size = mPowerSaveWhitelistAllAppIds.size();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
pw.println(" Whitelist all app ids:");
|
pw.println(" Whitelist all app ids:");
|
||||||
@ -1531,6 +1715,7 @@ public class DeviceIdleController extends SystemService
|
|||||||
}
|
}
|
||||||
|
|
||||||
pw.print(" mEnabled="); pw.println(mEnabled);
|
pw.print(" mEnabled="); pw.println(mEnabled);
|
||||||
|
pw.print(" mForceIdle="); pw.println(mForceIdle);
|
||||||
pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor);
|
pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor);
|
||||||
pw.print(" mCurDisplay="); pw.println(mCurDisplay);
|
pw.print(" mCurDisplay="); pw.println(mCurDisplay);
|
||||||
pw.print(" mScreenOn="); pw.println(mScreenOn);
|
pw.print(" mScreenOn="); pw.println(mScreenOn);
|
||||||
|
@ -83,6 +83,11 @@ public class SystemConfig {
|
|||||||
// system configuration files.
|
// system configuration files.
|
||||||
final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>();
|
final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>();
|
||||||
|
|
||||||
|
// These are the packages that are white-listed to be able to run in the
|
||||||
|
// background while in power save mode (but not whitelisted from device idle modes),
|
||||||
|
// as read from the configuration files.
|
||||||
|
final ArraySet<String> mAllowInPowerSaveExceptIdle = new ArraySet<>();
|
||||||
|
|
||||||
// These are the packages that are white-listed to be able to run in the
|
// These are the packages that are white-listed to be able to run in the
|
||||||
// background while in power save mode, as read from the configuration files.
|
// background while in power save mode, as read from the configuration files.
|
||||||
final ArraySet<String> mAllowInPowerSave = new ArraySet<>();
|
final ArraySet<String> mAllowInPowerSave = new ArraySet<>();
|
||||||
@ -123,6 +128,10 @@ public class SystemConfig {
|
|||||||
return mPermissions;
|
return mPermissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArraySet<String> getAllowInPowerSaveExceptIdle() {
|
||||||
|
return mAllowInPowerSaveExceptIdle;
|
||||||
|
}
|
||||||
|
|
||||||
public ArraySet<String> getAllowInPowerSave() {
|
public ArraySet<String> getAllowInPowerSave() {
|
||||||
return mAllowInPowerSave;
|
return mAllowInPowerSave;
|
||||||
}
|
}
|
||||||
@ -329,6 +338,17 @@ public class SystemConfig {
|
|||||||
XmlUtils.skipCurrentTag(parser);
|
XmlUtils.skipCurrentTag(parser);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
} else if ("allow-in-power-save-except-idle".equals(name) && !onlyFeatures) {
|
||||||
|
String pkgname = parser.getAttributeValue(null, "package");
|
||||||
|
if (pkgname == null) {
|
||||||
|
Slog.w(TAG, "<allow-in-power-save-except-idle> without package in "
|
||||||
|
+ permFile + " at " + parser.getPositionDescription());
|
||||||
|
} else {
|
||||||
|
mAllowInPowerSaveExceptIdle.add(pkgname);
|
||||||
|
}
|
||||||
|
XmlUtils.skipCurrentTag(parser);
|
||||||
|
continue;
|
||||||
|
|
||||||
} else if ("allow-in-power-save".equals(name) && !onlyFeatures) {
|
} else if ("allow-in-power-save".equals(name) && !onlyFeatures) {
|
||||||
String pkgname = parser.getAttributeValue(null, "package");
|
String pkgname = parser.getAttributeValue(null, "package");
|
||||||
if (pkgname == null) {
|
if (pkgname == null) {
|
||||||
|
@ -39,6 +39,7 @@ import static android.net.NetworkPolicy.WARNING_DISABLED;
|
|||||||
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
|
||||||
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
|
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
|
||||||
@ -46,7 +47,6 @@ import static android.net.NetworkPolicyManager.POLICY_NONE;
|
|||||||
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
||||||
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
|
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
|
||||||
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
|
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
|
||||||
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
|
|
||||||
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
|
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
|
||||||
import static android.net.NetworkPolicyManager.dumpPolicy;
|
import static android.net.NetworkPolicyManager.dumpPolicy;
|
||||||
import static android.net.NetworkPolicyManager.dumpRules;
|
import static android.net.NetworkPolicyManager.dumpRules;
|
||||||
@ -282,6 +282,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
/** Set of states for the child firewall chains. True if the chain is active. */
|
/** Set of states for the child firewall chains. True if the chain is active. */
|
||||||
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
|
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UIDs that have been white-listed to always be able to have network access
|
||||||
|
* in power save mode, except device idle (doze) still applies.
|
||||||
|
* TODO: An int array might be sufficient
|
||||||
|
*/
|
||||||
|
private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UIDs that have been white-listed to always be able to have network access
|
* UIDs that have been white-listed to always be able to have network access
|
||||||
* in power save mode.
|
* in power save mode.
|
||||||
@ -302,9 +309,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
/** Foreground at UID granularity. */
|
/** Foreground at UID granularity. */
|
||||||
final SparseIntArray mUidState = new SparseIntArray();
|
final SparseIntArray mUidState = new SparseIntArray();
|
||||||
|
|
||||||
/** The current maximum process state that we are considering to be foreground. */
|
|
||||||
private int mCurForegroundState = ActivityManager.PROCESS_STATE_TOP;
|
|
||||||
|
|
||||||
private final RemoteCallbackList<INetworkPolicyListener>
|
private final RemoteCallbackList<INetworkPolicyListener>
|
||||||
mListeners = new RemoteCallbackList<>();
|
mListeners = new RemoteCallbackList<>();
|
||||||
|
|
||||||
@ -365,7 +369,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
|
|
||||||
void updatePowerSaveWhitelistLocked() {
|
void updatePowerSaveWhitelistLocked() {
|
||||||
try {
|
try {
|
||||||
final int[] whitelist = mDeviceIdleController.getAppIdWhitelist();
|
int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
|
||||||
|
mPowerSaveWhitelistExceptIdleAppIds.clear();
|
||||||
|
if (whitelist != null) {
|
||||||
|
for (int uid : whitelist) {
|
||||||
|
mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
whitelist = mDeviceIdleController.getAppIdWhitelist();
|
||||||
mPowerSaveWhitelistAppIds.clear();
|
mPowerSaveWhitelistAppIds.clear();
|
||||||
if (whitelist != null) {
|
if (whitelist != null) {
|
||||||
for (int uid : whitelist) {
|
for (int uid : whitelist) {
|
||||||
@ -425,7 +436,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
if (mRestrictPower != enabled) {
|
if (mRestrictPower != enabled) {
|
||||||
mRestrictPower = enabled;
|
mRestrictPower = enabled;
|
||||||
updateRulesForGlobalChangeLocked(true);
|
updateRulesForGlobalChangeLocked(true);
|
||||||
updateRulesForTempWhitelistChangeLocked();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,9 +447,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
readPolicyLocked();
|
readPolicyLocked();
|
||||||
|
|
||||||
if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) {
|
if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) {
|
||||||
updateRulesForGlobalChangeLocked(true);
|
updateRulesForGlobalChangeLocked(false);
|
||||||
updateRulesForTempWhitelistChangeLocked();
|
|
||||||
updateNotificationsLocked();
|
updateNotificationsLocked();
|
||||||
|
} else {
|
||||||
|
// If we are not in any special mode, we just need to make sure the current
|
||||||
|
// app idle state is updated.
|
||||||
|
updateRulesForAppIdleLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1907,7 +1920,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
fout.print("Restrict background: "); fout.println(mRestrictBackground);
|
fout.print("Restrict background: "); fout.println(mRestrictBackground);
|
||||||
fout.print("Restrict power: "); fout.println(mRestrictPower);
|
fout.print("Restrict power: "); fout.println(mRestrictPower);
|
||||||
fout.print("Device idle: "); fout.println(mDeviceIdleMode);
|
fout.print("Device idle: "); fout.println(mDeviceIdleMode);
|
||||||
fout.print("Current foreground state: "); fout.println(mCurForegroundState);
|
|
||||||
fout.println("Network policies:");
|
fout.println("Network policies:");
|
||||||
fout.increaseIndent();
|
fout.increaseIndent();
|
||||||
for (int i = 0; i < mNetworkPolicy.size(); i++) {
|
for (int i = 0; i < mNetworkPolicy.size(); i++) {
|
||||||
@ -1931,6 +1943,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
fout.decreaseIndent();
|
fout.decreaseIndent();
|
||||||
|
|
||||||
|
size = mPowerSaveWhitelistExceptIdleAppIds.size();
|
||||||
|
if (size > 0) {
|
||||||
|
fout.println("Power save whitelist (except idle) app ids:");
|
||||||
|
fout.increaseIndent();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
fout.print("UID=");
|
||||||
|
fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
|
||||||
|
fout.print(": ");
|
||||||
|
fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
|
||||||
|
fout.println();
|
||||||
|
}
|
||||||
|
fout.decreaseIndent();
|
||||||
|
}
|
||||||
|
|
||||||
size = mPowerSaveWhitelistAppIds.size();
|
size = mPowerSaveWhitelistAppIds.size();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
fout.println("Power save whitelist app ids:");
|
fout.println("Power save whitelist app ids:");
|
||||||
@ -1960,7 +1986,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
|
int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
|
||||||
fout.print(" state=");
|
fout.print(" state=");
|
||||||
fout.print(state);
|
fout.print(state);
|
||||||
fout.print(state <= mCurForegroundState ? " (fg)" : " (bg)");
|
fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)");
|
||||||
|
|
||||||
fout.print(" rules=");
|
fout.print(" rules=");
|
||||||
final int rulesIndex = mUidRules.indexOfKey(uid);
|
final int rulesIndex = mUidRules.indexOfKey(uid);
|
||||||
@ -1988,7 +2014,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
boolean isUidForegroundLocked(int uid) {
|
boolean isUidForegroundLocked(int uid) {
|
||||||
// only really in foreground when screen is also on
|
// only really in foreground when screen is also on
|
||||||
return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)
|
return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)
|
||||||
<= mCurForegroundState;
|
<= ActivityManager.PROCESS_STATE_TOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2024,8 +2050,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
|
void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
|
||||||
final boolean oldForeground = oldUidState <= mCurForegroundState;
|
final boolean oldForeground = oldUidState <= ActivityManager.PROCESS_STATE_TOP;
|
||||||
final boolean newForeground = newUidState <= mCurForegroundState;
|
final boolean newForeground = newUidState <= ActivityManager.PROCESS_STATE_TOP;
|
||||||
if (oldForeground != newForeground) {
|
if (oldForeground != newForeground) {
|
||||||
updateRulesForUidLocked(uid);
|
updateRulesForUidLocked(uid);
|
||||||
}
|
}
|
||||||
@ -2049,7 +2075,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
// only update rules for anyone with foreground activities
|
// only update rules for anyone with foreground activities
|
||||||
final int size = mUidState.size();
|
final int size = mUidState.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (mUidState.valueAt(i) <= mCurForegroundState) {
|
if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_TOP) {
|
||||||
final int uid = mUidState.keyAt(i);
|
final int uid = mUidState.keyAt(i);
|
||||||
updateRulesForUidLocked(uid);
|
updateRulesForUidLocked(uid);
|
||||||
}
|
}
|
||||||
@ -2069,9 +2095,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
for (int ui = users.size() - 1; ui >= 0; ui--) {
|
for (int ui = users.size() - 1; ui >= 0; ui--) {
|
||||||
UserInfo user = users.get(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);
|
if (mPowerSaveTempWhitelistAppIds.valueAt(i)) {
|
||||||
int uid = UserHandle.getUid(user.id, appId);
|
int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
|
||||||
uidRules.put(uid, FIREWALL_RULE_ALLOW);
|
int uid = UserHandle.getUid(user.id, appId);
|
||||||
|
uidRules.put(uid, FIREWALL_RULE_ALLOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
|
for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
|
||||||
int appId = mPowerSaveWhitelistAppIds.keyAt(i);
|
int appId = mPowerSaveWhitelistAppIds.keyAt(i);
|
||||||
@ -2089,6 +2117,45 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
|
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateRuleForDeviceIdleLocked(int uid) {
|
||||||
|
if (mDeviceIdleMode) {
|
||||||
|
int appId = UserHandle.getAppId(uid);
|
||||||
|
if (mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId)
|
||||||
|
|| isProcStateAllowedWhileIdle(mUidState.get(uid))) {
|
||||||
|
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_ALLOW);
|
||||||
|
} else {
|
||||||
|
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateRulesForAppIdleLocked() {
|
||||||
|
// Fully update the app idle firewall chain.
|
||||||
|
SparseIntArray uidRules = new SparseIntArray();
|
||||||
|
final List<UserInfo> users = mUserManager.getUsers();
|
||||||
|
for (int ui = users.size() - 1; ui >= 0; ui--) {
|
||||||
|
UserInfo user = users.get(ui);
|
||||||
|
int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
|
||||||
|
for (int uid : idleUids) {
|
||||||
|
if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
|
||||||
|
uidRules.put(uid, FIREWALL_RULE_DENY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateRuleForAppIdleLocked(int uid) {
|
||||||
|
if (!isUidValidForRules(uid)) return;
|
||||||
|
|
||||||
|
int appId = UserHandle.getAppId(uid);
|
||||||
|
if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)) {
|
||||||
|
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
|
||||||
|
} else {
|
||||||
|
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updateRulesForAppIdleParoleLocked() {
|
void updateRulesForAppIdleParoleLocked() {
|
||||||
boolean enableChain = !mUsageStats.isAppIdleParoleOn();
|
boolean enableChain = !mUsageStats.isAppIdleParoleOn();
|
||||||
enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
|
enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
|
||||||
@ -2101,14 +2168,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) {
|
void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) {
|
||||||
final PackageManager pm = mContext.getPackageManager();
|
final PackageManager pm = mContext.getPackageManager();
|
||||||
|
|
||||||
// If we are in restrict power mode, we allow all important apps
|
|
||||||
// to have data access. Otherwise, we restrict data access to only
|
|
||||||
// the top apps.
|
|
||||||
mCurForegroundState = (!mRestrictBackground && mRestrictPower)
|
|
||||||
? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
|
|
||||||
: ActivityManager.PROCESS_STATE_TOP;
|
|
||||||
|
|
||||||
updateRulesForDeviceIdleLocked();
|
updateRulesForDeviceIdleLocked();
|
||||||
|
updateRulesForAppIdleLocked();
|
||||||
|
|
||||||
// update rules for all installed applications
|
// update rules for all installed applications
|
||||||
final List<UserInfo> users = mUserManager.getUsers();
|
final List<UserInfo> users = mUserManager.getUsers();
|
||||||
@ -2138,10 +2199,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
for (UserInfo user : users) {
|
for (UserInfo user : users) {
|
||||||
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);
|
||||||
boolean isAllow = mPowerSaveTempWhitelistAppIds.valueAt(i);
|
|
||||||
int uid = UserHandle.getUid(user.id, appId);
|
int uid = UserHandle.getUid(user.id, appId);
|
||||||
updateRulesForUidLocked(uid);
|
updateRuleForAppIdleLocked(uid);
|
||||||
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, !isAllow);
|
updateRuleForDeviceIdleLocked(uid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2188,16 +2248,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
|
|
||||||
final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
|
final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
|
||||||
final boolean uidForeground = isUidForegroundLocked(uid);
|
final boolean uidForeground = isUidForegroundLocked(uid);
|
||||||
final boolean uidIdle = isUidIdle(uid);
|
|
||||||
|
|
||||||
// derive active rules based on policy and active state
|
// derive active rules based on policy and active state
|
||||||
|
|
||||||
int appId = UserHandle.getAppId(uid);
|
int appId = UserHandle.getAppId(uid);
|
||||||
int uidRules = RULE_ALLOW_ALL;
|
int uidRules = RULE_ALLOW_ALL;
|
||||||
if (uidIdle && !mPowerSaveWhitelistAppIds.get(appId)
|
if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
|
||||||
&& !mPowerSaveTempWhitelistAppIds.get(appId)) {
|
|
||||||
uidRules = RULE_REJECT_ALL;
|
|
||||||
} else if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
|
|
||||||
// uid in background, and policy says to block metered data
|
// uid in background, and policy says to block metered data
|
||||||
uidRules = RULE_REJECT_METERED;
|
uidRules = RULE_REJECT_METERED;
|
||||||
} else if (mRestrictBackground) {
|
} else if (mRestrictBackground) {
|
||||||
@ -2206,7 +2262,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
uidRules = RULE_REJECT_METERED;
|
uidRules = RULE_REJECT_METERED;
|
||||||
}
|
}
|
||||||
} else if (mRestrictPower) {
|
} else if (mRestrictPower) {
|
||||||
final boolean whitelisted = mPowerSaveWhitelistAppIds.get(appId)
|
final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId)
|
||||||
|| mPowerSaveTempWhitelistAppIds.get(appId);
|
|| mPowerSaveTempWhitelistAppIds.get(appId);
|
||||||
if (!whitelisted && !uidForeground
|
if (!whitelisted && !uidForeground
|
||||||
&& (uidPolicy & POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) == 0) {
|
&& (uidPolicy & POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) == 0) {
|
||||||
@ -2232,13 +2288,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
setUidNetworkRules(uid, rejectMetered);
|
setUidNetworkRules(uid, rejectMetered);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update firewall rules if necessary
|
|
||||||
final boolean oldFirewallReject = (oldRules & RULE_REJECT_ALL) != 0;
|
|
||||||
final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0;
|
|
||||||
if (oldFirewallReject != firewallReject) {
|
|
||||||
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, firewallReject);
|
|
||||||
}
|
|
||||||
|
|
||||||
// dispatch changed rule to existing listeners
|
// dispatch changed rule to existing listeners
|
||||||
if (oldRules != uidRules) {
|
if (oldRules != uidRules) {
|
||||||
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget();
|
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget();
|
||||||
@ -2260,7 +2309,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
try {
|
try {
|
||||||
int uid = mContext.getPackageManager().getPackageUid(packageName, userId);
|
int uid = mContext.getPackageManager().getPackageUid(packageName, userId);
|
||||||
synchronized (mRulesLock) {
|
synchronized (mRulesLock) {
|
||||||
updateRulesForUidLocked(uid);
|
updateRuleForAppIdleLocked(uid);
|
||||||
}
|
}
|
||||||
} catch (NameNotFoundException nnfe) {
|
} catch (NameNotFoundException nnfe) {
|
||||||
}
|
}
|
||||||
@ -2422,10 +2471,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
/**
|
/**
|
||||||
* Add or remove a uid to the firewall blacklist for all network ifaces.
|
* Add or remove a uid to the firewall blacklist for all network ifaces.
|
||||||
*/
|
*/
|
||||||
private void setUidFirewallRule(int chain, int uid, boolean rejectOnAll) {
|
private void setUidFirewallRule(int chain, int uid, int rule) {
|
||||||
try {
|
try {
|
||||||
mNetworkManager.setFirewallUidRule(chain, uid,
|
mNetworkManager.setFirewallUidRule(chain, uid, rule);
|
||||||
rejectOnAll ? FIREWALL_RULE_DENY : FIREWALL_RULE_ALLOW);
|
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
Log.wtf(TAG, "problem setting firewall uid rules", e);
|
Log.wtf(TAG, "problem setting firewall uid rules", e);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
@ -35,6 +35,7 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ParceledListSlice;
|
import android.content.pm.ParceledListSlice;
|
||||||
@ -65,6 +66,7 @@ import android.util.AtomicFile;
|
|||||||
import android.util.KeyValueListParser;
|
import android.util.KeyValueListParser;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
|
|
||||||
@ -799,7 +801,10 @@ public class UsageStatsService extends SystemService implements
|
|||||||
}
|
}
|
||||||
if (packageName.equals("android")) return false;
|
if (packageName.equals("android")) return false;
|
||||||
try {
|
try {
|
||||||
if (mDeviceIdleController.isPowerSaveWhitelistApp(packageName)) {
|
// We allow all whitelisted apps, including those that don't want to be whitelisted
|
||||||
|
// for idle mode, because app idle (aka app standby) is really not as big an issue
|
||||||
|
// for controlling who participates vs. doze mode.
|
||||||
|
if (mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
@ -825,6 +830,72 @@ public class UsageStatsService extends SystemService implements
|
|||||||
return isAppIdleUnfiltered(packageName, userService, timeNow, screenOnTime);
|
return isAppIdleUnfiltered(packageName, userService, timeNow, screenOnTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int[] getIdleUidsForUser(int userId) {
|
||||||
|
if (!mAppIdleEnabled) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
final long timeNow;
|
||||||
|
final UserUsageStatsService userService;
|
||||||
|
final long screenOnTime;
|
||||||
|
synchronized (mLock) {
|
||||||
|
timeNow = checkAndGetTimeLocked();
|
||||||
|
userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
|
||||||
|
screenOnTime = getScreenOnTimeLocked(timeNow);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ApplicationInfo> apps;
|
||||||
|
try {
|
||||||
|
ParceledListSlice<ApplicationInfo> slice
|
||||||
|
= AppGlobals.getPackageManager().getInstalledApplications(0, userId);
|
||||||
|
apps = slice.getList();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// State of each uid. Key is the uid. Value lower 16 bits is the number of apps
|
||||||
|
// associated with that uid, upper 16 bits is the number of those apps that is idle.
|
||||||
|
SparseIntArray uidStates = new SparseIntArray();
|
||||||
|
|
||||||
|
// Now resolve all app state. Iterating over all apps, keeping track of how many
|
||||||
|
// we find for each uid and how many of those are idle.
|
||||||
|
for (int i = apps.size()-1; i >= 0; i--) {
|
||||||
|
ApplicationInfo ai = apps.get(i);
|
||||||
|
|
||||||
|
// Check whether this app is idle.
|
||||||
|
boolean idle = isAppIdleFiltered(ai.packageName, userId, userService, timeNow,
|
||||||
|
screenOnTime);
|
||||||
|
|
||||||
|
int index = uidStates.indexOfKey(ai.uid);
|
||||||
|
if (index < 0) {
|
||||||
|
uidStates.put(ai.uid, 1 + (idle ? 1<<16 : 0));
|
||||||
|
} else {
|
||||||
|
int value = uidStates.valueAt(index);
|
||||||
|
uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int numIdle = 0;
|
||||||
|
for (int i = uidStates.size() - 1; i >= 0; i--) {
|
||||||
|
int value = uidStates.valueAt(i);
|
||||||
|
if ((value&0x7fff) == (value>>16)) {
|
||||||
|
numIdle++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] res = new int[numIdle];
|
||||||
|
numIdle = 0;
|
||||||
|
for (int i = uidStates.size() - 1; i >= 0; i--) {
|
||||||
|
int value = uidStates.valueAt(i);
|
||||||
|
if ((value&0x7fff) == (value>>16)) {
|
||||||
|
res[numIdle] = uidStates.keyAt(i);
|
||||||
|
numIdle++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void setAppIdle(String packageName, boolean idle, int userId) {
|
void setAppIdle(String packageName, boolean idle, int userId) {
|
||||||
if (packageName == null) return;
|
if (packageName == null) return;
|
||||||
|
|
||||||
@ -1283,6 +1354,11 @@ public class UsageStatsService extends SystemService implements
|
|||||||
return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
|
return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getIdleUidsForUser(int userId) {
|
||||||
|
return UsageStatsService.this.getIdleUidsForUser(userId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAppIdleParoleOn() {
|
public boolean isAppIdleParoleOn() {
|
||||||
return mAppIdleParoled;
|
return mAppIdleParoled;
|
||||||
|
Reference in New Issue
Block a user