Restrict device wakeup via PowerManager.ACQUIRE_CAUSES_WAKEUP.
The default value of OP_TURN_SCREEN_ON is still MODE_ALLOWED, which means the user needs to actively disallow the special app access for an app to lose the functionality of turning the screen on via wakelock. Only wake the power group linked to the wake lock if valid power group id is provided. Bug: 216114297 Bug: 219568783 Test: manual Change-Id: Ib6df6e6c4f71adbb9bc8fd3db80708e4af0c40cc
This commit is contained in:
@@ -40,12 +40,14 @@ import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.SynchronousUserSwitchObserver;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
@@ -1454,6 +1456,15 @@ public final class PowerManagerService extends SystemService
|
||||
private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag,
|
||||
String packageName, WorkSource ws, String historyTag, int uid, int pid,
|
||||
@Nullable IWakeLockCallback callback) {
|
||||
|
||||
boolean isCallerPrivileged = false;
|
||||
try {
|
||||
ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0));
|
||||
isCallerPrivileged = appInfo.uid == uid && appInfo.isPrivilegedApp();
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// assume app is not privileged
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (displayId != Display.INVALID_DISPLAY) {
|
||||
final DisplayInfo displayInfo =
|
||||
@@ -1500,7 +1511,7 @@ public final class PowerManagerService extends SystemService
|
||||
notifyAcquire = true;
|
||||
}
|
||||
|
||||
applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);
|
||||
applyWakeLockFlagsOnAcquireLocked(wakeLock, isCallerPrivileged);
|
||||
mDirty |= DIRTY_WAKE_LOCKS;
|
||||
updatePowerStateLocked();
|
||||
if (notifyAcquire) {
|
||||
@@ -1539,8 +1550,34 @@ public final class PowerManagerService extends SystemService
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isAcquireCausesWakeupFlagAllowed(String opPackageName, int opUid,
|
||||
boolean isCallerPrivileged) {
|
||||
if (opPackageName == null) {
|
||||
return false;
|
||||
}
|
||||
if (isCallerPrivileged) {
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Allowing device wake-up for privileged app, call attributed to "
|
||||
+ opPackageName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (mContext.getSystemService(AppOpsManager.class).checkOpNoThrow(
|
||||
AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName)
|
||||
== AppOpsManager.MODE_ALLOWED) {
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Allowing device wake-up for app with special access " + opPackageName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Not allowing device wake-up for " + opPackageName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) {
|
||||
private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, boolean isCallerPrivileged) {
|
||||
if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0
|
||||
&& isScreenLock(wakeLock)) {
|
||||
String opPackageName;
|
||||
@@ -1560,10 +1597,30 @@ public final class PowerManagerService extends SystemService
|
||||
opPackageName = wakeLock.mPackageName;
|
||||
opUid = wakeLock.mOwnerUid;
|
||||
}
|
||||
for (int idx = 0; idx < mPowerGroups.size(); idx++) {
|
||||
wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
|
||||
PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid, opPackageName,
|
||||
opUid);
|
||||
Integer powerGroupId = wakeLock.getPowerGroupId();
|
||||
// powerGroupId is null if the wakelock associated display is no longer available
|
||||
if (powerGroupId != null && isAcquireCausesWakeupFlagAllowed(opPackageName, opUid,
|
||||
isCallerPrivileged)) {
|
||||
if (powerGroupId == Display.INVALID_DISPLAY_GROUP) {
|
||||
// wake up all display groups
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Waking up all power groups");
|
||||
}
|
||||
for (int idx = 0; idx < mPowerGroups.size(); idx++) {
|
||||
wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
|
||||
PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid,
|
||||
opPackageName, opUid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mPowerGroups.contains(powerGroupId)) {
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Waking up power group " + powerGroupId);
|
||||
}
|
||||
wakePowerGroupLocked(mPowerGroups.get(powerGroupId), mClock.uptimeMillis(),
|
||||
PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid,
|
||||
opPackageName, opUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user