RESTRICT AUTOMERGE

Add a hidden API to check if ambient display is suppressed for a token.

Added 1 method:
boolean isAmbientDisplaySuppressedForTokenByApp(String token, int appUid)

Context:
The Settings team is working on adding a string to the AOD settings page when ambient display is suppressed by Bedtime mode: b/168790245.

The current PowerManager#isAmbientDisplaySuppressedForToken(String token) method will only work if the calling app is also the app that suppressed the ambient display. That is, if Digital Wellbeing called suppressAmbientDisplay("winddown"), then isAmbientDisplaySuppressedForToken("winddown") will only return true for Digital Wellbeing. It will return false for Settings app

This CL adds a hidden API PowerManager#isAmbientDisplaySuppressedForTokenByApp(String token, int appUid) that will return true if the given app is suppressing ambient display with the given token. Settings can then call isAmbientDisplaySuppressedForTokenByApp("winddown", digitalWellbeingUid) to get whether ambient display is suppressed by Bedtime mode.

Test: atest FrameworksServicesTests:PowerManagerServiceTest
Bug: 169241595
Change-Id: I41aecc4ff0ab159d67e62193af27362a96c3174c
(cherry picked from commit 784b62a517)
This commit is contained in:
Yogisha Dixit
2020-09-25 13:15:00 +01:00
parent 34407ea59b
commit 4b1a1f1309
6 changed files with 114 additions and 0 deletions

View File

@@ -94,6 +94,8 @@ interface IPowerManager
boolean isAmbientDisplaySuppressedForToken(String token);
// returns whether ambient display is suppressed by any app with any token.
boolean isAmbientDisplaySuppressed();
// returns whether ambient display is suppressed by the given app with the given token.
boolean isAmbientDisplaySuppressedForTokenByApp(String token, int appUid);
// Forces the system to suspend even if there are held wakelocks.
boolean forceSuspend();

View File

@@ -2126,6 +2126,27 @@ public final class PowerManager {
}
}
/**
* Returns true if ambient display is suppressed by the given {@code appUid} with the given
* {@code token}.
*
* <p>This method will return false if {@link #isAmbientDisplayAvailable()} is false.
*
* @param token The identifier of the ambient display suppression.
* @param appUid The uid of the app that suppressed ambient display.
* @hide
*/
@RequiresPermission(allOf = {
android.Manifest.permission.READ_DREAM_STATE,
android.Manifest.permission.READ_DREAM_SUPPRESSION })
public boolean isAmbientDisplaySuppressedForTokenByApp(@NonNull String token, int appUid) {
try {
return mService.isAmbientDisplaySuppressedForTokenByApp(token, appUid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the reason the phone was last shutdown. Calling app must have the
* {@link android.Manifest.permission#DEVICE_POWER} permission to request this information.

View File

@@ -4295,6 +4295,10 @@
<permission android:name="android.permission.WRITE_DREAM_STATE"
android:protectionLevel="signature|privileged" />
<!-- @hide Allows applications to read whether ambient display is suppressed. -->
<permission android:name="android.permission.READ_DREAM_SUPPRESSION"
android:protectionLevel="signature" />
<!-- @SystemApi Allow an application to read and write the cache partition.
@hide -->
<permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"

View File

@@ -5304,6 +5304,22 @@ public final class PowerManagerService extends SystemService
}
}
@Override // Binder call
public boolean isAmbientDisplaySuppressedForTokenByApp(@NonNull String token, int appUid) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_DREAM_STATE, null);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_DREAM_SUPPRESSION, null);
final long ident = Binder.clearCallingIdentity();
try {
return isAmbientDisplayAvailable()
&& mAmbientDisplaySuppressionController.isSuppressed(token, appUid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override // Binder call
public boolean isAmbientDisplaySuppressed() {
mContext.enforceCallingOrSelfPermission(

View File

@@ -77,6 +77,7 @@
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
<uses-permission android:name="android.permission.DUMP"/>
<uses-permission android:name="android.permission.READ_DREAM_STATE"/>
<uses-permission android:name="android.permission.READ_DREAM_SUPPRESSION"/>
<uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/>

View File

@@ -77,6 +77,7 @@ import com.android.server.SystemService;
import com.android.server.lights.LightsManager;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.PowerManagerService.BatteryReceiver;
import com.android.server.power.PowerManagerService.BinderService;
import com.android.server.power.PowerManagerService.Injector;
import com.android.server.power.PowerManagerService.NativeWrapper;
import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
@@ -173,6 +174,7 @@ public class PowerManagerServiceTest {
when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(false);
when(mDisplayManagerInternalMock.requestPowerState(any(), anyBoolean())).thenReturn(true);
when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
mDisplayPowerRequest = new DisplayPowerRequest();
addLocalServiceMock(LightsManager.class, mLightsManagerMock);
@@ -967,4 +969,72 @@ public class PowerManagerServiceTest {
assertThat(mService.getBinderServiceInstance().isAmbientDisplaySuppressedForToken("test2"))
.isFalse();
}
@Test
public void testIsAmbientDisplaySuppressedForTokenByApp_ambientDisplayUnavailable()
throws Exception {
createService();
when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(false);
BinderService service = mService.getBinderServiceInstance();
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test", Binder.getCallingUid()))
.isFalse();
}
@Test
public void testIsAmbientDisplaySuppressedForTokenByApp_default()
throws Exception {
createService();
BinderService service = mService.getBinderServiceInstance();
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test", Binder.getCallingUid()))
.isFalse();
}
@Test
public void testIsAmbientDisplaySuppressedForTokenByApp_suppressedByCallingApp()
throws Exception {
createService();
BinderService service = mService.getBinderServiceInstance();
service.suppressAmbientDisplay("test", true);
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test", Binder.getCallingUid()))
.isTrue();
// Check that isAmbientDisplaySuppressedForTokenByApp doesn't return true for another app.
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test", /* appUid= */ 123))
.isFalse();
}
@Test
public void testIsAmbientDisplaySuppressedForTokenByApp_notSuppressedByCallingApp()
throws Exception {
createService();
BinderService service = mService.getBinderServiceInstance();
service.suppressAmbientDisplay("test", false);
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test", Binder.getCallingUid()))
.isFalse();
// Check that isAmbientDisplaySuppressedForTokenByApp doesn't return true for another app.
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test", /* appUid= */ 123))
.isFalse();
}
@Test
public void testIsAmbientDisplaySuppressedForTokenByApp_multipleTokensSuppressedByCallingApp()
throws Exception {
createService();
BinderService service = mService.getBinderServiceInstance();
service.suppressAmbientDisplay("test1", true);
service.suppressAmbientDisplay("test2", true);
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test1", Binder.getCallingUid()))
.isTrue();
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test2", Binder.getCallingUid()))
.isTrue();
// Check that isAmbientDisplaySuppressedForTokenByApp doesn't return true for another app.
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test1", /* appUid= */ 123))
.isFalse();
assertThat(service.isAmbientDisplaySuppressedForTokenByApp("test2", /* appUid= */ 123))
.isFalse();
}
}