Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -33312,6 +33312,7 @@ package android.os { field public static final int LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF = 1; // 0x1 field public static final int LOCATION_MODE_NO_CHANGE = 0; // 0x0 field public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4; // 0x4 field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 2; // 0x2 field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1; // 0x1 field public static final String LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN = "com.android.lowpowerstandby.WAKE_ON_LAN"; field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000 core/java/android/os/PowerManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -2994,6 +2994,7 @@ public final class PowerManager { */ @IntDef(prefix = { "LOW_POWER_STANDBY_ALLOWED_REASON_" }, flag = true, value = { LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST, }) @Retention(RetentionPolicy.SOURCE) public @interface LowPowerStandbyAllowedReason { Loading @@ -3006,6 +3007,13 @@ public final class PowerManager { */ public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1 << 0; /** * Exempts apps on the temporary powersave allowlist. * * @see #isAllowedInLowPowerStandby(int) */ public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 1 << 1; /** @hide */ public static String lowPowerStandbyAllowedReasonsToString( @LowPowerStandbyAllowedReason int allowedReasons) { Loading @@ -3014,6 +3022,10 @@ public final class PowerManager { allowedStrings.add("ALLOWED_REASON_VOICE_INTERACTION"); allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION; } if ((allowedReasons & LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST) != 0) { allowedStrings.add("ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST"); allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST; } if (allowedReasons != 0) { allowedStrings.add(String.valueOf(allowedReasons)); } Loading services/core/java/com/android/server/power/LowPowerStandbyController.java +32 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.power; import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST; import static android.os.PowerManager.lowPowerStandbyAllowedReasonsToString; import android.Manifest; Loading Loading @@ -59,6 +60,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.server.LocalServices; import com.android.server.PowerAllowlistInternal; import com.android.server.net.NetworkPolicyManagerInternal; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -134,7 +136,7 @@ public class LowPowerStandbyController { @GuardedBy("mLock") private boolean mEnableCustomPolicy; private final BroadcastReceiver mIdleBroadcastReceiver = new BroadcastReceiver() { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { Loading @@ -150,6 +152,8 @@ public class LowPowerStandbyController { } } }; private final TempAllowlistChangeListener mTempAllowlistChangeListener = new TempAllowlistChangeListener(); private final BroadcastReceiver mPackageBroadcastReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -318,7 +322,7 @@ public class LowPowerStandbyController { updateSettingsLocked(); if (mIsEnabled) { registerBroadcastReceiver(); registerListeners(); } } Loading Loading @@ -594,7 +598,7 @@ public class LowPowerStandbyController { onNonInteractive(); } registerBroadcastReceiver(); registerListeners(); } @GuardedBy("mLock") Loading @@ -604,7 +608,7 @@ public class LowPowerStandbyController { } cancelStandbyTimeoutAlarmLocked(); unregisterBroadcastReceiver(); unregisterListeners(); updateActiveLocked(); } Loading @@ -629,13 +633,13 @@ public class LowPowerStandbyController { } } private void registerBroadcastReceiver() { private void registerListeners() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); mContext.registerReceiver(mIdleBroadcastReceiver, intentFilter); mContext.registerReceiver(mBroadcastReceiver, intentFilter); IntentFilter packageFilter = new IntentFilter(); packageFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE); Loading @@ -648,12 +652,18 @@ public class LowPowerStandbyController { userFilter.addAction(Intent.ACTION_USER_ADDED); userFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class); pai.registerTempAllowlistChangeListener(mTempAllowlistChangeListener); } private void unregisterBroadcastReceiver() { mContext.unregisterReceiver(mIdleBroadcastReceiver); private void unregisterListeners() { mContext.unregisterReceiver(mBroadcastReceiver); mContext.unregisterReceiver(mPackageBroadcastReceiver); mContext.unregisterReceiver(mUserReceiver); PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class); pai.unregisterTempAllowlistChangeListener(mTempAllowlistChangeListener); } @GuardedBy("mLock") Loading Loading @@ -1197,4 +1207,18 @@ public class LowPowerStandbyController { onSettingsChanged(); } } final class TempAllowlistChangeListener implements PowerAllowlistInternal.TempAllowlistChangeListener { @Override public void onAppAdded(int uid) { addToAllowlistInternal(uid, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST); } @Override public void onAppRemoved(int uid) { removeFromAllowlistInternal(uid, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST); } } } services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java +42 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.power; import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST; import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION; import static android.os.PowerManager.LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN; Loading Loading @@ -62,6 +63,8 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.LocalServices; import com.android.server.PowerAllowlistInternal; import com.android.server.PowerAllowlistInternal.TempAllowlistChangeListener; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.power.LowPowerStandbyController.DeviceConfigWrapper; import com.android.server.testutils.OffsettableClock; Loading Loading @@ -117,6 +120,8 @@ public class LowPowerStandbyControllerTest { private PowerManagerInternal mPowerManagerInternalMock; @Mock private NetworkPolicyManagerInternal mNetworkPolicyManagerInternalMock; @Mock private PowerAllowlistInternal mPowerAllowlistInternalMock; @Before public void setUp() throws Exception { Loading @@ -130,6 +135,7 @@ public class LowPowerStandbyControllerTest { when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager); addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock); addLocalServiceMock(NetworkPolicyManagerInternal.class, mNetworkPolicyManagerInternalMock); addLocalServiceMock(PowerAllowlistInternal.class, mPowerAllowlistInternalMock); when(mIPowerManagerMock.isInteractive()).thenReturn(true); Loading Loading @@ -169,6 +175,7 @@ public class LowPowerStandbyControllerTest { LocalServices.removeServiceForTest(PowerManagerInternal.class); LocalServices.removeServiceForTest(LowPowerStandbyControllerInternal.class); LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); LocalServices.removeServiceForTest(PowerAllowlistInternal.class); mTestPolicyFile.delete(); } Loading Loading @@ -663,6 +670,39 @@ public class LowPowerStandbyControllerTest { assertFalse(mController.isPackageExempt(TEST_PKG1_APP_ID)); } @Test public void testAllowReason_tempPowerSaveAllowlist() throws Exception { mController.systemReady(); mController.setEnabled(true); mController.setPolicy(policyWithAllowedReasons( LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST)); mTestLooper.dispatchAll(); ArgumentCaptor<TempAllowlistChangeListener> tempAllowlistChangeListenerArgumentCaptor = ArgumentCaptor.forClass(TempAllowlistChangeListener.class); verify(mPowerAllowlistInternalMock).registerTempAllowlistChangeListener( tempAllowlistChangeListenerArgumentCaptor.capture()); TempAllowlistChangeListener tempAllowlistChangeListener = tempAllowlistChangeListenerArgumentCaptor.getValue(); tempAllowlistChangeListener.onAppAdded(TEST_PKG1_APP_ID); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{TEST_PKG1_APP_ID}); tempAllowlistChangeListener.onAppAdded(TEST_PKG2_APP_ID); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist( new int[]{TEST_PKG1_APP_ID, TEST_PKG2_APP_ID}); tempAllowlistChangeListener.onAppRemoved(TEST_PKG1_APP_ID); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{TEST_PKG2_APP_ID}); mController.setPolicy(EMPTY_POLICY); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[0]); } private void setInteractive() throws Exception { when(mIPowerManagerMock.isInteractive()).thenReturn(true); mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -33312,6 +33312,7 @@ package android.os { field public static final int LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF = 1; // 0x1 field public static final int LOCATION_MODE_NO_CHANGE = 0; // 0x0 field public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4; // 0x4 field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 2; // 0x2 field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1; // 0x1 field public static final String LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN = "com.android.lowpowerstandby.WAKE_ON_LAN"; field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
core/java/android/os/PowerManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -2994,6 +2994,7 @@ public final class PowerManager { */ @IntDef(prefix = { "LOW_POWER_STANDBY_ALLOWED_REASON_" }, flag = true, value = { LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST, }) @Retention(RetentionPolicy.SOURCE) public @interface LowPowerStandbyAllowedReason { Loading @@ -3006,6 +3007,13 @@ public final class PowerManager { */ public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1 << 0; /** * Exempts apps on the temporary powersave allowlist. * * @see #isAllowedInLowPowerStandby(int) */ public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 1 << 1; /** @hide */ public static String lowPowerStandbyAllowedReasonsToString( @LowPowerStandbyAllowedReason int allowedReasons) { Loading @@ -3014,6 +3022,10 @@ public final class PowerManager { allowedStrings.add("ALLOWED_REASON_VOICE_INTERACTION"); allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION; } if ((allowedReasons & LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST) != 0) { allowedStrings.add("ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST"); allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST; } if (allowedReasons != 0) { allowedStrings.add(String.valueOf(allowedReasons)); } Loading
services/core/java/com/android/server/power/LowPowerStandbyController.java +32 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.power; import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST; import static android.os.PowerManager.lowPowerStandbyAllowedReasonsToString; import android.Manifest; Loading Loading @@ -59,6 +60,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.server.LocalServices; import com.android.server.PowerAllowlistInternal; import com.android.server.net.NetworkPolicyManagerInternal; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -134,7 +136,7 @@ public class LowPowerStandbyController { @GuardedBy("mLock") private boolean mEnableCustomPolicy; private final BroadcastReceiver mIdleBroadcastReceiver = new BroadcastReceiver() { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { Loading @@ -150,6 +152,8 @@ public class LowPowerStandbyController { } } }; private final TempAllowlistChangeListener mTempAllowlistChangeListener = new TempAllowlistChangeListener(); private final BroadcastReceiver mPackageBroadcastReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -318,7 +322,7 @@ public class LowPowerStandbyController { updateSettingsLocked(); if (mIsEnabled) { registerBroadcastReceiver(); registerListeners(); } } Loading Loading @@ -594,7 +598,7 @@ public class LowPowerStandbyController { onNonInteractive(); } registerBroadcastReceiver(); registerListeners(); } @GuardedBy("mLock") Loading @@ -604,7 +608,7 @@ public class LowPowerStandbyController { } cancelStandbyTimeoutAlarmLocked(); unregisterBroadcastReceiver(); unregisterListeners(); updateActiveLocked(); } Loading @@ -629,13 +633,13 @@ public class LowPowerStandbyController { } } private void registerBroadcastReceiver() { private void registerListeners() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); mContext.registerReceiver(mIdleBroadcastReceiver, intentFilter); mContext.registerReceiver(mBroadcastReceiver, intentFilter); IntentFilter packageFilter = new IntentFilter(); packageFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE); Loading @@ -648,12 +652,18 @@ public class LowPowerStandbyController { userFilter.addAction(Intent.ACTION_USER_ADDED); userFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class); pai.registerTempAllowlistChangeListener(mTempAllowlistChangeListener); } private void unregisterBroadcastReceiver() { mContext.unregisterReceiver(mIdleBroadcastReceiver); private void unregisterListeners() { mContext.unregisterReceiver(mBroadcastReceiver); mContext.unregisterReceiver(mPackageBroadcastReceiver); mContext.unregisterReceiver(mUserReceiver); PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class); pai.unregisterTempAllowlistChangeListener(mTempAllowlistChangeListener); } @GuardedBy("mLock") Loading Loading @@ -1197,4 +1207,18 @@ public class LowPowerStandbyController { onSettingsChanged(); } } final class TempAllowlistChangeListener implements PowerAllowlistInternal.TempAllowlistChangeListener { @Override public void onAppAdded(int uid) { addToAllowlistInternal(uid, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST); } @Override public void onAppRemoved(int uid) { removeFromAllowlistInternal(uid, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST); } } }
services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java +42 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.power; import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST; import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION; import static android.os.PowerManager.LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN; Loading Loading @@ -62,6 +63,8 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.LocalServices; import com.android.server.PowerAllowlistInternal; import com.android.server.PowerAllowlistInternal.TempAllowlistChangeListener; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.power.LowPowerStandbyController.DeviceConfigWrapper; import com.android.server.testutils.OffsettableClock; Loading Loading @@ -117,6 +120,8 @@ public class LowPowerStandbyControllerTest { private PowerManagerInternal mPowerManagerInternalMock; @Mock private NetworkPolicyManagerInternal mNetworkPolicyManagerInternalMock; @Mock private PowerAllowlistInternal mPowerAllowlistInternalMock; @Before public void setUp() throws Exception { Loading @@ -130,6 +135,7 @@ public class LowPowerStandbyControllerTest { when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager); addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock); addLocalServiceMock(NetworkPolicyManagerInternal.class, mNetworkPolicyManagerInternalMock); addLocalServiceMock(PowerAllowlistInternal.class, mPowerAllowlistInternalMock); when(mIPowerManagerMock.isInteractive()).thenReturn(true); Loading Loading @@ -169,6 +175,7 @@ public class LowPowerStandbyControllerTest { LocalServices.removeServiceForTest(PowerManagerInternal.class); LocalServices.removeServiceForTest(LowPowerStandbyControllerInternal.class); LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); LocalServices.removeServiceForTest(PowerAllowlistInternal.class); mTestPolicyFile.delete(); } Loading Loading @@ -663,6 +670,39 @@ public class LowPowerStandbyControllerTest { assertFalse(mController.isPackageExempt(TEST_PKG1_APP_ID)); } @Test public void testAllowReason_tempPowerSaveAllowlist() throws Exception { mController.systemReady(); mController.setEnabled(true); mController.setPolicy(policyWithAllowedReasons( LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST)); mTestLooper.dispatchAll(); ArgumentCaptor<TempAllowlistChangeListener> tempAllowlistChangeListenerArgumentCaptor = ArgumentCaptor.forClass(TempAllowlistChangeListener.class); verify(mPowerAllowlistInternalMock).registerTempAllowlistChangeListener( tempAllowlistChangeListenerArgumentCaptor.capture()); TempAllowlistChangeListener tempAllowlistChangeListener = tempAllowlistChangeListenerArgumentCaptor.getValue(); tempAllowlistChangeListener.onAppAdded(TEST_PKG1_APP_ID); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{TEST_PKG1_APP_ID}); tempAllowlistChangeListener.onAppAdded(TEST_PKG2_APP_ID); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist( new int[]{TEST_PKG1_APP_ID, TEST_PKG2_APP_ID}); tempAllowlistChangeListener.onAppRemoved(TEST_PKG1_APP_ID); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{TEST_PKG2_APP_ID}); mController.setPolicy(EMPTY_POLICY); mTestLooper.dispatchAll(); verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[0]); } private void setInteractive() throws Exception { when(mIPowerManagerMock.isInteractive()).thenReturn(true); mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); Loading