Loading core/java/android/app/usage/UsageStatsManagerInternal.java +9 −2 Original line number Diff line number Diff line Loading @@ -76,6 +76,12 @@ public abstract class UsageStatsManagerInternal { */ public abstract boolean isAppIdle(String packageName, int userId); /** * @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. */ public abstract boolean isAppIdleParoleOn(); /** * Sets up a listener for changes to packages being accessed. * @param listener A listener within the system process. Loading @@ -90,8 +96,9 @@ public abstract class UsageStatsManagerInternal { public abstract void removeAppIdleStateChangeListener( AppIdleStateChangeListener listener); public interface AppIdleStateChangeListener { void onAppIdleStateChanged(String packageName, int userId, boolean idle); public static abstract class AppIdleStateChangeListener { public abstract void onAppIdleStateChanged(String packageName, int userId, boolean idle); public abstract void onParoleStateChanged(boolean isParoleOn); } } services/core/java/com/android/server/NetworkManagementService.java +80 −63 Original line number Diff line number Diff line Loading @@ -214,9 +214,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub */ @GuardedBy("mQuotaLock") private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); private boolean mStandbyChainEnabled = false; private boolean mDozableChainEnabled = false; /** Set of states for the child firewall chains. True if the chain is active. */ @GuardedBy("mQuotaLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); private Object mIdleTimerLock = new Object(); /** Set of interfaces with active idle timers. */ Loading Loading @@ -307,9 +307,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub } public void systemReady() { // init firewall states mDozableChainEnabled = false; mStandbyChainEnabled = true; prepareNativeDaemon(); if (DBG) Slog.d(TAG, "Prepared"); } Loading Loading @@ -611,7 +608,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub uidFirewallRules.valueAt(i)); } } if (mStandbyChainEnabled) { if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)) { setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true); } Loading @@ -625,7 +622,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub uidFirewallRules.valueAt(i)); } } if (mDozableChainEnabled) { if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)) { setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true); } } Loading Loading @@ -2013,17 +2010,23 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setFirewallChainEnabled(int chain, boolean enable) { enforceSystemUid(); synchronized (mQuotaLock) { if (mFirewallChainStates.indexOfKey(chain) >= 0 && mFirewallChainStates.get(chain) == enable) { // All is the same, nothing to do. return; } mFirewallChainStates.put(chain, enable); final String operation = enable ? "enable_chain" : "disable_chain"; try { String chainName; switch(chain) { case FIREWALL_CHAIN_STANDBY: chainName = FIREWALL_CHAIN_NAME_STANDBY; mStandbyChainEnabled = enable; break; case FIREWALL_CHAIN_DOZABLE: chainName = FIREWALL_CHAIN_NAME_DOZABLE; mDozableChainEnabled = enable; break; default: throw new IllegalArgumentException("Bad child chain: " + chain); Loading @@ -2033,6 +2036,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub throw e.rethrowAsParcelableException(); } } } private int getFirewallType(int chain) { switch (chain) { Loading @@ -2048,6 +2052,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setFirewallUidRules(int chain, int[] uids, int[] rules) { enforceSystemUid(); synchronized (mQuotaLock) { SparseIntArray uidFirewallRules = getUidFirewallRules(chain); SparseIntArray newRules = new SparseIntArray(); // apply new set of rules Loading @@ -2071,6 +2076,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT); } } } @Override public void setFirewallUidRule(int chain, int uid, int rule) { Loading @@ -2094,6 +2100,26 @@ public class NetworkManagementService extends INetworkManagementService.Stub } try { String ruleName = getFirewallRuleName(chain, rule); String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule); if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { uidFirewallRules.delete(uid); } else { uidFirewallRules.put(uid, rule); } if (!ruleName.equals(oldRuleName)) { mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, ruleName); } } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } } private @NonNull String getFirewallRuleName(int chain, int rule) { String ruleName; if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { Loading @@ -2108,18 +2134,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub ruleName = "allow"; } } if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { uidFirewallRules.delete(uid); } else { uidFirewallRules.put(uid, rule); } mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, ruleName); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } return ruleName; } private @NonNull SparseIntArray getUidFirewallRules(int chain) { Loading Loading @@ -2272,7 +2287,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } pw.println("UID firewall standby chain enabled: " + mStandbyChainEnabled); pw.println("UID firewall standby chain enabled: " + mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)); synchronized (mUidFirewallStandbyRules) { pw.print("UID firewall standby rule: ["); final int size = mUidFirewallStandbyRules.size(); Loading @@ -2285,7 +2301,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } pw.println("UID firewall dozable chain enabled: " + mDozableChainEnabled); pw.println("UID firewall dozable chain enabled: " + mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)); synchronized (mUidFirewallDozableRules) { pw.print("UID firewall dozable rule: ["); final int size = mUidFirewallDozableRules.size(); Loading services/core/java/com/android/server/content/AppIdleMonitor.java +15 −36 Original line number Diff line number Diff line Loading @@ -18,11 +18,6 @@ package com.android.server.content; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.UserHandle; import com.android.server.LocalServices; Loading @@ -31,53 +26,32 @@ import com.android.server.LocalServices; * Helper to listen for app idle and charging status changes and restart backed off * sync operations. */ class AppIdleMonitor implements AppIdleStateChangeListener { class AppIdleMonitor extends AppIdleStateChangeListener { private final SyncManager mSyncManager; private final UsageStatsManagerInternal mUsageStats; final BatteryManager mBatteryManager; /** Is the device currently plugged into power. */ private boolean mPluggedIn; private boolean mAppIdleParoleOn; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { onPluggedIn(mBatteryManager.isCharging()); } }; AppIdleMonitor(SyncManager syncManager, Context context) { AppIdleMonitor(SyncManager syncManager) { mSyncManager = syncManager; mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); mUsageStats.addAppIdleStateChangeListener(this); mBatteryManager = context.getSystemService(BatteryManager.class); mPluggedIn = isPowered(); registerReceivers(context); } mAppIdleParoleOn = mUsageStats.isAppIdleParoleOn(); private void registerReceivers(Context context) { // Monitor battery charging state IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); context.registerReceiver(mReceiver, filter); } private boolean isPowered() { return mBatteryManager.isCharging(); mUsageStats.addAppIdleStateChangeListener(this); } void onPluggedIn(boolean pluggedIn) { if (mPluggedIn == pluggedIn) { void setAppIdleParoleOn(boolean appIdleParoleOn) { if (mAppIdleParoleOn == appIdleParoleOn) { return; } mPluggedIn = pluggedIn; if (mPluggedIn) { mAppIdleParoleOn = appIdleParoleOn; if (mAppIdleParoleOn) { mSyncManager.onAppNotIdle(null, UserHandle.USER_ALL); } } boolean isAppIdle(String packageName, int userId) { return !mPluggedIn && mUsageStats.isAppIdle(packageName, userId); return !mAppIdleParoleOn && mUsageStats.isAppIdle(packageName, userId); } @Override Loading @@ -86,4 +60,9 @@ class AppIdleMonitor implements AppIdleStateChangeListener { if (idle) return; mSyncManager.onAppNotIdle(packageName, userId); } @Override public void onParoleStateChanged(boolean isParoleOn) { setAppIdleParoleOn(isParoleOn); } } services/core/java/com/android/server/content/SyncManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.content; import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.AppGlobals; Loading Loading @@ -461,7 +462,7 @@ public class SyncManager { mSyncAlarmIntent = PendingIntent.getBroadcast( mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0); mAppIdleMonitor = new AppIdleMonitor(this, mContext); mAppIdleMonitor = new AppIdleMonitor(this); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); context.registerReceiver(mConnectivityIntentReceiver, intentFilter); Loading Loading @@ -1271,7 +1272,7 @@ public class SyncManager { * @param userId The user for which the package has become active. Can be USER_ALL if * the device just plugged in. */ void onAppNotIdle(String packageName, int userId) { void onAppNotIdle(@Nullable String packageName, int userId) { synchronized (mSyncQueue) { // For all sync operations in sync queue, if marked as idle, compare with package name // and unmark. And clear backoff for the operation. Loading services/core/java/com/android/server/job/controllers/AppIdleController.java +48 −61 Original line number Diff line number Diff line Loading @@ -17,12 +17,7 @@ package com.android.server.job.controllers; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.util.Slog; import com.android.server.LocalServices; Loading @@ -38,8 +33,7 @@ import java.util.ArrayList; * for a certain amount of time (maybe hours or days) are considered idle. When the app comes * out of idle state, it will be allowed to run scheduled jobs. */ public class AppIdleController extends StateController implements UsageStatsManagerInternal.AppIdleStateChangeListener { public class AppIdleController extends StateController { private static final String LOG_TAG = "AppIdleController"; private static final boolean DEBUG = false; Loading @@ -49,14 +43,7 @@ public class AppIdleController extends StateController private static volatile AppIdleController sController; final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>(); private final UsageStatsManagerInternal mUsageStatsInternal; private final BatteryManager mBatteryManager; private boolean mPluggedIn; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { onPluggedIn(mBatteryManager.isCharging()); } }; boolean mAppIdleParoleOn; public static AppIdleController get(JobSchedulerService service) { synchronized (sCreationLock) { Loading @@ -70,17 +57,8 @@ public class AppIdleController extends StateController private AppIdleController(StateChangedListener stateChangedListener, Context context) { super(stateChangedListener, context); mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class); mBatteryManager = context.getSystemService(BatteryManager.class); mPluggedIn = mBatteryManager.isCharging(); mUsageStatsInternal.addAppIdleStateChangeListener(this); registerReceivers(); } private void registerReceivers() { // Monitor battery charging state IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(mReceiver, filter); mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn(); mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); } @Override Loading @@ -88,7 +66,7 @@ public class AppIdleController extends StateController synchronized (mTrackedTasks) { mTrackedTasks.add(jobStatus); String packageName = jobStatus.job.getService().getPackageName(); final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName, final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName, jobStatus.getUserId()); if (DEBUG) { Slog.d(LOG_TAG, "Start tracking, setting idle state of " Loading @@ -108,7 +86,7 @@ public class AppIdleController extends StateController @Override public void dumpControllerState(PrintWriter pw) { pw.println("AppIdle"); pw.println("Plugged In: " + mPluggedIn); pw.println("Parole On: " + mAppIdleParoleOn); synchronized (mTrackedTasks) { for (JobStatus task : mTrackedTasks) { pw.print(task.job.getService().getPackageName()); Loading @@ -119,57 +97,66 @@ public class AppIdleController extends StateController } } @Override public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { void setAppIdleParoleOn(boolean isAppIdleParoleOn) { // Flag if any app's idle state has changed boolean changed = false; synchronized (mTrackedTasks) { // If currently plugged in, we don't care about app idle state if (mPluggedIn) { if (mAppIdleParoleOn == isAppIdleParoleOn) { return; } mAppIdleParoleOn = isAppIdleParoleOn; for (JobStatus task : mTrackedTasks) { if (task.job.getService().getPackageName().equals(packageName) && task.getUserId() == userId) { if (task.appNotIdleConstraintSatisfied.get() != !idle) { String packageName = task.job.getService().getPackageName(); final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName, task.getUserId()); if (DEBUG) { Slog.d(LOG_TAG, "App Idle state changed, setting idle state of " + packageName + " to " + idle); Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle); } task.appNotIdleConstraintSatisfied.set(!idle); if (task.appNotIdleConstraintSatisfied.get() == appIdle) { task.appNotIdleConstraintSatisfied.set(!appIdle); changed = true; } } } } if (changed) { mStateChangedListener.onControllerStateChanged(); } } void onPluggedIn(boolean pluggedIn) { // Flag if any app's idle state has changed private class AppIdleStateChangeListener extends UsageStatsManagerInternal.AppIdleStateChangeListener { @Override public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { boolean changed = false; synchronized (mTrackedTasks) { if (mPluggedIn == pluggedIn) { if (mAppIdleParoleOn) { return; } mPluggedIn = pluggedIn; for (JobStatus task : mTrackedTasks) { String packageName = task.job.getService().getPackageName(); final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName, task.getUserId()); if (task.job.getService().getPackageName().equals(packageName) && task.getUserId() == userId) { if (task.appNotIdleConstraintSatisfied.get() != !idle) { if (DEBUG) { Slog.d(LOG_TAG, "Plugged in " + pluggedIn + ", setting idle state of " + packageName + " to " + appIdle); Slog.d(LOG_TAG, "App Idle state changed, setting idle state of " + packageName + " to " + idle); } if (task.appNotIdleConstraintSatisfied.get() == appIdle) { task.appNotIdleConstraintSatisfied.set(!appIdle); task.appNotIdleConstraintSatisfied.set(!idle); changed = true; } } } } if (changed) { mStateChangedListener.onControllerStateChanged(); } } @Override public void onParoleStateChanged(boolean isParoleOn) { if (DEBUG) { Slog.d(LOG_TAG, "Parole on: " + isParoleOn); } setAppIdleParoleOn(isParoleOn); } } } Loading
core/java/android/app/usage/UsageStatsManagerInternal.java +9 −2 Original line number Diff line number Diff line Loading @@ -76,6 +76,12 @@ public abstract class UsageStatsManagerInternal { */ public abstract boolean isAppIdle(String packageName, int userId); /** * @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. */ public abstract boolean isAppIdleParoleOn(); /** * Sets up a listener for changes to packages being accessed. * @param listener A listener within the system process. Loading @@ -90,8 +96,9 @@ public abstract class UsageStatsManagerInternal { public abstract void removeAppIdleStateChangeListener( AppIdleStateChangeListener listener); public interface AppIdleStateChangeListener { void onAppIdleStateChanged(String packageName, int userId, boolean idle); public static abstract class AppIdleStateChangeListener { public abstract void onAppIdleStateChanged(String packageName, int userId, boolean idle); public abstract void onParoleStateChanged(boolean isParoleOn); } }
services/core/java/com/android/server/NetworkManagementService.java +80 −63 Original line number Diff line number Diff line Loading @@ -214,9 +214,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub */ @GuardedBy("mQuotaLock") private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); private boolean mStandbyChainEnabled = false; private boolean mDozableChainEnabled = false; /** Set of states for the child firewall chains. True if the chain is active. */ @GuardedBy("mQuotaLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); private Object mIdleTimerLock = new Object(); /** Set of interfaces with active idle timers. */ Loading Loading @@ -307,9 +307,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub } public void systemReady() { // init firewall states mDozableChainEnabled = false; mStandbyChainEnabled = true; prepareNativeDaemon(); if (DBG) Slog.d(TAG, "Prepared"); } Loading Loading @@ -611,7 +608,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub uidFirewallRules.valueAt(i)); } } if (mStandbyChainEnabled) { if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)) { setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true); } Loading @@ -625,7 +622,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub uidFirewallRules.valueAt(i)); } } if (mDozableChainEnabled) { if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)) { setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true); } } Loading Loading @@ -2013,17 +2010,23 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setFirewallChainEnabled(int chain, boolean enable) { enforceSystemUid(); synchronized (mQuotaLock) { if (mFirewallChainStates.indexOfKey(chain) >= 0 && mFirewallChainStates.get(chain) == enable) { // All is the same, nothing to do. return; } mFirewallChainStates.put(chain, enable); final String operation = enable ? "enable_chain" : "disable_chain"; try { String chainName; switch(chain) { case FIREWALL_CHAIN_STANDBY: chainName = FIREWALL_CHAIN_NAME_STANDBY; mStandbyChainEnabled = enable; break; case FIREWALL_CHAIN_DOZABLE: chainName = FIREWALL_CHAIN_NAME_DOZABLE; mDozableChainEnabled = enable; break; default: throw new IllegalArgumentException("Bad child chain: " + chain); Loading @@ -2033,6 +2036,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub throw e.rethrowAsParcelableException(); } } } private int getFirewallType(int chain) { switch (chain) { Loading @@ -2048,6 +2052,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setFirewallUidRules(int chain, int[] uids, int[] rules) { enforceSystemUid(); synchronized (mQuotaLock) { SparseIntArray uidFirewallRules = getUidFirewallRules(chain); SparseIntArray newRules = new SparseIntArray(); // apply new set of rules Loading @@ -2071,6 +2076,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT); } } } @Override public void setFirewallUidRule(int chain, int uid, int rule) { Loading @@ -2094,6 +2100,26 @@ public class NetworkManagementService extends INetworkManagementService.Stub } try { String ruleName = getFirewallRuleName(chain, rule); String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule); if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { uidFirewallRules.delete(uid); } else { uidFirewallRules.put(uid, rule); } if (!ruleName.equals(oldRuleName)) { mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, ruleName); } } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } } private @NonNull String getFirewallRuleName(int chain, int rule) { String ruleName; if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { Loading @@ -2108,18 +2134,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub ruleName = "allow"; } } if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { uidFirewallRules.delete(uid); } else { uidFirewallRules.put(uid, rule); } mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, ruleName); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } return ruleName; } private @NonNull SparseIntArray getUidFirewallRules(int chain) { Loading Loading @@ -2272,7 +2287,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } pw.println("UID firewall standby chain enabled: " + mStandbyChainEnabled); pw.println("UID firewall standby chain enabled: " + mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)); synchronized (mUidFirewallStandbyRules) { pw.print("UID firewall standby rule: ["); final int size = mUidFirewallStandbyRules.size(); Loading @@ -2285,7 +2301,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } pw.println("UID firewall dozable chain enabled: " + mDozableChainEnabled); pw.println("UID firewall dozable chain enabled: " + mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)); synchronized (mUidFirewallDozableRules) { pw.print("UID firewall dozable rule: ["); final int size = mUidFirewallDozableRules.size(); Loading
services/core/java/com/android/server/content/AppIdleMonitor.java +15 −36 Original line number Diff line number Diff line Loading @@ -18,11 +18,6 @@ package com.android.server.content; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.UserHandle; import com.android.server.LocalServices; Loading @@ -31,53 +26,32 @@ import com.android.server.LocalServices; * Helper to listen for app idle and charging status changes and restart backed off * sync operations. */ class AppIdleMonitor implements AppIdleStateChangeListener { class AppIdleMonitor extends AppIdleStateChangeListener { private final SyncManager mSyncManager; private final UsageStatsManagerInternal mUsageStats; final BatteryManager mBatteryManager; /** Is the device currently plugged into power. */ private boolean mPluggedIn; private boolean mAppIdleParoleOn; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { onPluggedIn(mBatteryManager.isCharging()); } }; AppIdleMonitor(SyncManager syncManager, Context context) { AppIdleMonitor(SyncManager syncManager) { mSyncManager = syncManager; mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); mUsageStats.addAppIdleStateChangeListener(this); mBatteryManager = context.getSystemService(BatteryManager.class); mPluggedIn = isPowered(); registerReceivers(context); } mAppIdleParoleOn = mUsageStats.isAppIdleParoleOn(); private void registerReceivers(Context context) { // Monitor battery charging state IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); context.registerReceiver(mReceiver, filter); } private boolean isPowered() { return mBatteryManager.isCharging(); mUsageStats.addAppIdleStateChangeListener(this); } void onPluggedIn(boolean pluggedIn) { if (mPluggedIn == pluggedIn) { void setAppIdleParoleOn(boolean appIdleParoleOn) { if (mAppIdleParoleOn == appIdleParoleOn) { return; } mPluggedIn = pluggedIn; if (mPluggedIn) { mAppIdleParoleOn = appIdleParoleOn; if (mAppIdleParoleOn) { mSyncManager.onAppNotIdle(null, UserHandle.USER_ALL); } } boolean isAppIdle(String packageName, int userId) { return !mPluggedIn && mUsageStats.isAppIdle(packageName, userId); return !mAppIdleParoleOn && mUsageStats.isAppIdle(packageName, userId); } @Override Loading @@ -86,4 +60,9 @@ class AppIdleMonitor implements AppIdleStateChangeListener { if (idle) return; mSyncManager.onAppNotIdle(packageName, userId); } @Override public void onParoleStateChanged(boolean isParoleOn) { setAppIdleParoleOn(isParoleOn); } }
services/core/java/com/android/server/content/SyncManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.content; import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.AppGlobals; Loading Loading @@ -461,7 +462,7 @@ public class SyncManager { mSyncAlarmIntent = PendingIntent.getBroadcast( mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0); mAppIdleMonitor = new AppIdleMonitor(this, mContext); mAppIdleMonitor = new AppIdleMonitor(this); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); context.registerReceiver(mConnectivityIntentReceiver, intentFilter); Loading Loading @@ -1271,7 +1272,7 @@ public class SyncManager { * @param userId The user for which the package has become active. Can be USER_ALL if * the device just plugged in. */ void onAppNotIdle(String packageName, int userId) { void onAppNotIdle(@Nullable String packageName, int userId) { synchronized (mSyncQueue) { // For all sync operations in sync queue, if marked as idle, compare with package name // and unmark. And clear backoff for the operation. Loading
services/core/java/com/android/server/job/controllers/AppIdleController.java +48 −61 Original line number Diff line number Diff line Loading @@ -17,12 +17,7 @@ package com.android.server.job.controllers; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.util.Slog; import com.android.server.LocalServices; Loading @@ -38,8 +33,7 @@ import java.util.ArrayList; * for a certain amount of time (maybe hours or days) are considered idle. When the app comes * out of idle state, it will be allowed to run scheduled jobs. */ public class AppIdleController extends StateController implements UsageStatsManagerInternal.AppIdleStateChangeListener { public class AppIdleController extends StateController { private static final String LOG_TAG = "AppIdleController"; private static final boolean DEBUG = false; Loading @@ -49,14 +43,7 @@ public class AppIdleController extends StateController private static volatile AppIdleController sController; final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>(); private final UsageStatsManagerInternal mUsageStatsInternal; private final BatteryManager mBatteryManager; private boolean mPluggedIn; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { onPluggedIn(mBatteryManager.isCharging()); } }; boolean mAppIdleParoleOn; public static AppIdleController get(JobSchedulerService service) { synchronized (sCreationLock) { Loading @@ -70,17 +57,8 @@ public class AppIdleController extends StateController private AppIdleController(StateChangedListener stateChangedListener, Context context) { super(stateChangedListener, context); mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class); mBatteryManager = context.getSystemService(BatteryManager.class); mPluggedIn = mBatteryManager.isCharging(); mUsageStatsInternal.addAppIdleStateChangeListener(this); registerReceivers(); } private void registerReceivers() { // Monitor battery charging state IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(mReceiver, filter); mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn(); mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); } @Override Loading @@ -88,7 +66,7 @@ public class AppIdleController extends StateController synchronized (mTrackedTasks) { mTrackedTasks.add(jobStatus); String packageName = jobStatus.job.getService().getPackageName(); final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName, final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName, jobStatus.getUserId()); if (DEBUG) { Slog.d(LOG_TAG, "Start tracking, setting idle state of " Loading @@ -108,7 +86,7 @@ public class AppIdleController extends StateController @Override public void dumpControllerState(PrintWriter pw) { pw.println("AppIdle"); pw.println("Plugged In: " + mPluggedIn); pw.println("Parole On: " + mAppIdleParoleOn); synchronized (mTrackedTasks) { for (JobStatus task : mTrackedTasks) { pw.print(task.job.getService().getPackageName()); Loading @@ -119,57 +97,66 @@ public class AppIdleController extends StateController } } @Override public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { void setAppIdleParoleOn(boolean isAppIdleParoleOn) { // Flag if any app's idle state has changed boolean changed = false; synchronized (mTrackedTasks) { // If currently plugged in, we don't care about app idle state if (mPluggedIn) { if (mAppIdleParoleOn == isAppIdleParoleOn) { return; } mAppIdleParoleOn = isAppIdleParoleOn; for (JobStatus task : mTrackedTasks) { if (task.job.getService().getPackageName().equals(packageName) && task.getUserId() == userId) { if (task.appNotIdleConstraintSatisfied.get() != !idle) { String packageName = task.job.getService().getPackageName(); final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName, task.getUserId()); if (DEBUG) { Slog.d(LOG_TAG, "App Idle state changed, setting idle state of " + packageName + " to " + idle); Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle); } task.appNotIdleConstraintSatisfied.set(!idle); if (task.appNotIdleConstraintSatisfied.get() == appIdle) { task.appNotIdleConstraintSatisfied.set(!appIdle); changed = true; } } } } if (changed) { mStateChangedListener.onControllerStateChanged(); } } void onPluggedIn(boolean pluggedIn) { // Flag if any app's idle state has changed private class AppIdleStateChangeListener extends UsageStatsManagerInternal.AppIdleStateChangeListener { @Override public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { boolean changed = false; synchronized (mTrackedTasks) { if (mPluggedIn == pluggedIn) { if (mAppIdleParoleOn) { return; } mPluggedIn = pluggedIn; for (JobStatus task : mTrackedTasks) { String packageName = task.job.getService().getPackageName(); final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName, task.getUserId()); if (task.job.getService().getPackageName().equals(packageName) && task.getUserId() == userId) { if (task.appNotIdleConstraintSatisfied.get() != !idle) { if (DEBUG) { Slog.d(LOG_TAG, "Plugged in " + pluggedIn + ", setting idle state of " + packageName + " to " + appIdle); Slog.d(LOG_TAG, "App Idle state changed, setting idle state of " + packageName + " to " + idle); } if (task.appNotIdleConstraintSatisfied.get() == appIdle) { task.appNotIdleConstraintSatisfied.set(!appIdle); task.appNotIdleConstraintSatisfied.set(!idle); changed = true; } } } } if (changed) { mStateChangedListener.onControllerStateChanged(); } } @Override public void onParoleStateChanged(boolean isParoleOn) { if (DEBUG) { Slog.d(LOG_TAG, "Parole on: " + isParoleOn); } setAppIdleParoleOn(isParoleOn); } } }