Merge "Restrict device wakeup via PowerManager.ACQUIRE_CAUSES_WAKEUP." into tm-dev

This commit is contained in:
Philip Junker
2022-03-24 10:02:49 +00:00
committed by Android (Google) Code Review

View File

@@ -40,12 +40,14 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission; import android.annotation.RequiresPermission;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.SynchronousUserSwitchObserver; import android.app.SynchronousUserSwitchObserver;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.database.ContentObserver; 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, private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag,
String packageName, WorkSource ws, String historyTag, int uid, int pid, String packageName, WorkSource ws, String historyTag, int uid, int pid,
@Nullable IWakeLockCallback callback) { @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) { synchronized (mLock) {
if (displayId != Display.INVALID_DISPLAY) { if (displayId != Display.INVALID_DISPLAY) {
final DisplayInfo displayInfo = final DisplayInfo displayInfo =
@@ -1500,7 +1511,7 @@ public final class PowerManagerService extends SystemService
notifyAcquire = true; notifyAcquire = true;
} }
applyWakeLockFlagsOnAcquireLocked(wakeLock, uid); applyWakeLockFlagsOnAcquireLocked(wakeLock, isCallerPrivileged);
mDirty |= DIRTY_WAKE_LOCKS; mDirty |= DIRTY_WAKE_LOCKS;
updatePowerStateLocked(); updatePowerStateLocked();
if (notifyAcquire) { if (notifyAcquire) {
@@ -1539,8 +1550,34 @@ public final class PowerManagerService extends SystemService
return null; 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") @GuardedBy("mLock")
private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) { private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, boolean isCallerPrivileged) {
if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0 if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0
&& isScreenLock(wakeLock)) { && isScreenLock(wakeLock)) {
String opPackageName; String opPackageName;
@@ -1560,10 +1597,30 @@ public final class PowerManagerService extends SystemService
opPackageName = wakeLock.mPackageName; opPackageName = wakeLock.mPackageName;
opUid = wakeLock.mOwnerUid; opUid = wakeLock.mOwnerUid;
} }
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++) { for (int idx = 0; idx < mPowerGroups.size(); idx++) {
wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(), wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid, opPackageName, PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid,
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);
}
} }
} }
} }