Require TURN_SCREEN_ON permission for ACQUIRE_CAUSES_WAKEUP flag.
Bug: 237045954 Test: atest PowerManagerServiceTest Test: manually verified that app without permission can't turn screen on Change-Id: I525f824c74be77b93e3035ec76ca26202a2ab637
This commit is contained in:
@@ -42,8 +42,6 @@ import android.annotation.UserIdInt;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.SynchronousUserSwitchObserver;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@@ -64,7 +62,6 @@ import android.os.BatteryManager;
|
||||
import android.os.BatteryManagerInternal;
|
||||
import android.os.BatterySaverPolicyConfig;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.IBinder;
|
||||
@@ -127,7 +124,6 @@ import com.android.server.UiThread;
|
||||
import com.android.server.UserspaceRebootLogger;
|
||||
import com.android.server.Watchdog;
|
||||
import com.android.server.am.BatteryStatsService;
|
||||
import com.android.server.compat.PlatformCompat;
|
||||
import com.android.server.lights.LightsManager;
|
||||
import com.android.server.lights.LogicalLight;
|
||||
import com.android.server.policy.WindowManagerPolicy;
|
||||
@@ -283,17 +279,6 @@ public final class PowerManagerService extends SystemService
|
||||
*/
|
||||
private static final long ENHANCED_DISCHARGE_PREDICTION_BROADCAST_MIN_DELAY_MS = 60 * 1000L;
|
||||
|
||||
/**
|
||||
* Apps targeting Android U and above need to define
|
||||
* {@link android.Manifest.permission#TURN_SCREEN_ON} in their manifest for
|
||||
* {@link android.os.PowerManager#ACQUIRE_CAUSES_WAKEUP} to have any effect.
|
||||
* Note that most applications should use {@link android.R.attr#turnScreenOn} or
|
||||
* {@link android.app.Activity#setTurnScreenOn(boolean)} instead, as this prevents the
|
||||
* previous foreground app from being resumed first when the screen turns on.
|
||||
*/
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
public static final long REQUIRE_TURN_SCREEN_ON_PERMISSION = 216114297L;
|
||||
/** Reason ID for holding display suspend blocker. */
|
||||
private static final String HOLDING_DISPLAY_SUSPEND_BLOCKER = "holding display";
|
||||
|
||||
@@ -317,7 +302,6 @@ public final class PowerManagerService extends SystemService
|
||||
private final SystemPropertiesWrapper mSystemProperties;
|
||||
private final Clock mClock;
|
||||
private final Injector mInjector;
|
||||
private final PlatformCompat mPlatformCompat;
|
||||
|
||||
private AppOpsManager mAppOpsManager;
|
||||
private LightsManager mLightsManager;
|
||||
@@ -1005,11 +989,6 @@ public final class PowerManagerService extends SystemService
|
||||
public void set(String key, String val) {
|
||||
SystemProperties.set(key, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String key, boolean def) {
|
||||
return SystemProperties.getBoolean(key, def);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1046,10 +1025,6 @@ public final class PowerManagerService extends SystemService
|
||||
AppOpsManager createAppOpsManager(Context context) {
|
||||
return context.getSystemService(AppOpsManager.class);
|
||||
}
|
||||
|
||||
PlatformCompat createPlatformCompat(Context context) {
|
||||
return context.getSystemService(PlatformCompat.class);
|
||||
}
|
||||
}
|
||||
|
||||
final Constants mConstants;
|
||||
@@ -1106,8 +1081,6 @@ public final class PowerManagerService extends SystemService
|
||||
|
||||
mAppOpsManager = injector.createAppOpsManager(mContext);
|
||||
|
||||
mPlatformCompat = injector.createPlatformCompat(mContext);
|
||||
|
||||
mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener();
|
||||
|
||||
// Save brightness values:
|
||||
@@ -1614,28 +1587,14 @@ public final class PowerManagerService extends SystemService
|
||||
}
|
||||
if (mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName)
|
||||
== AppOpsManager.MODE_ALLOWED) {
|
||||
if (mPlatformCompat.isChangeEnabledByPackageName(REQUIRE_TURN_SCREEN_ON_PERMISSION,
|
||||
opPackageName, UserHandle.getUserId(opUid))) {
|
||||
if (mContext.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.TURN_SCREEN_ON)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Allowing device wake-up from app " + opPackageName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// android.permission.TURN_SCREEN_ON has only been introduced in Android U, only
|
||||
// check for appOp for apps targeting lower SDK versions
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Allowing device wake-up from app with "
|
||||
+ "REQUIRE_TURN_SCREEN_ON_PERMISSION disabled " + opPackageName);
|
||||
}
|
||||
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TURN_SCREEN_ON)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
Slog.i(TAG, "Allowing device wake-up from app " + opPackageName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (PowerProperties.permissionless_turn_screen_on().orElse(true)) {
|
||||
Slog.d(TAG, "Device wake-up will be denied without android.permission.TURN_SCREEN_ON");
|
||||
if (PowerProperties.permissionless_turn_screen_on().orElse(false)) {
|
||||
Slog.d(TAG, "Device wake-up allowed by debug.power.permissionless_turn_screen_on");
|
||||
return true;
|
||||
}
|
||||
Slog.w(TAG, "Not allowing device wake-up for " + opPackageName);
|
||||
|
||||
@@ -48,19 +48,4 @@ interface SystemPropertiesWrapper {
|
||||
* SELinux. libc will log the underlying reason.
|
||||
*/
|
||||
void set(@NonNull String key, @Nullable String val);
|
||||
|
||||
/**
|
||||
* Get the value for the given {@code key}, returned as a boolean.
|
||||
* Values 'n', 'no', '0', 'false' or 'off' are considered false.
|
||||
* Values 'y', 'yes', '1', 'true' or 'on' are considered true.
|
||||
* (case sensitive).
|
||||
* If the key does not exist, or has any other value, then the default
|
||||
* result is returned.
|
||||
*
|
||||
* @param key the key to lookup
|
||||
* @param def a default value to return
|
||||
* @return the key parsed as a boolean, or def if the key isn't found or is
|
||||
* not able to be parsed as a boolean.
|
||||
*/
|
||||
boolean getBoolean(@NonNull String key, boolean def);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.compat.PlatformCompat;
|
||||
import com.android.server.lights.LightsManager;
|
||||
import com.android.server.policy.WindowManagerPolicy;
|
||||
import com.android.server.power.PowerManagerService.BatteryReceiver;
|
||||
@@ -147,7 +146,6 @@ public class PowerManagerServiceTest {
|
||||
@Mock private SystemPropertiesWrapper mSystemPropertiesMock;
|
||||
@Mock private AppOpsManager mAppOpsManagerMock;
|
||||
@Mock private LowPowerStandbyController mLowPowerStandbyControllerMock;
|
||||
@Mock private PlatformCompat mPlatformCompat;
|
||||
|
||||
@Mock
|
||||
private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
|
||||
@@ -321,11 +319,6 @@ public class PowerManagerServiceTest {
|
||||
AppOpsManager createAppOpsManager(Context context) {
|
||||
return mAppOpsManagerMock;
|
||||
}
|
||||
|
||||
@Override
|
||||
PlatformCompat createPlatformCompat(Context context) {
|
||||
return mPlatformCompat;
|
||||
}
|
||||
});
|
||||
return mService;
|
||||
}
|
||||
@@ -499,9 +492,6 @@ public class PowerManagerServiceTest {
|
||||
String packageName = "pkg.name";
|
||||
when(mAppOpsManagerMock.checkOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON,
|
||||
Binder.getCallingUid(), packageName)).thenReturn(MODE_ALLOWED);
|
||||
when(mPlatformCompat.isChangeEnabledByPackageName(
|
||||
eq(PowerManagerService.REQUIRE_TURN_SCREEN_ON_PERMISSION), anyString(),
|
||||
anyInt())).thenReturn(true);
|
||||
when(mContextSpy.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.TURN_SCREEN_ON)).thenReturn(
|
||||
PackageManager.PERMISSION_GRANTED);
|
||||
@@ -526,23 +516,6 @@ public class PowerManagerServiceTest {
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
|
||||
|
||||
// Verify that on older platforms only the appOp is necessary and the permission isn't
|
||||
// checked
|
||||
when(mPlatformCompat.isChangeEnabledByPackageName(
|
||||
eq(PowerManagerService.REQUIRE_TURN_SCREEN_ON_PERMISSION), anyString(),
|
||||
anyInt())).thenReturn(false);
|
||||
when(mContextSpy.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.TURN_SCREEN_ON)).thenReturn(
|
||||
PackageManager.PERMISSION_DENIED);
|
||||
forceSleep();
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
|
||||
flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -562,7 +535,7 @@ public class PowerManagerServiceTest {
|
||||
int flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
|
||||
if (PowerProperties.permissionless_turn_screen_on().orElse(true)) {
|
||||
if (PowerProperties.permissionless_turn_screen_on().orElse(false)) {
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
} else {
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
@@ -571,9 +544,6 @@ public class PowerManagerServiceTest {
|
||||
|
||||
when(mAppOpsManagerMock.checkOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON,
|
||||
Binder.getCallingUid(), packageName)).thenReturn(MODE_ALLOWED);
|
||||
when(mPlatformCompat.isChangeEnabledByPackageName(
|
||||
eq(PowerManagerService.REQUIRE_TURN_SCREEN_ON_PERMISSION), anyString(),
|
||||
anyInt())).thenReturn(true);
|
||||
when(mContextSpy.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.TURN_SCREEN_ON)).thenReturn(
|
||||
PackageManager.PERMISSION_DENIED);
|
||||
@@ -583,7 +553,7 @@ public class PowerManagerServiceTest {
|
||||
flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
|
||||
if (PowerProperties.permissionless_turn_screen_on().orElse(true)) {
|
||||
if (PowerProperties.permissionless_turn_screen_on().orElse(false)) {
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
} else {
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
|
||||
Reference in New Issue
Block a user