summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java69
1 files changed, 63 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 048f8d6a04fa..97c743598833 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -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);
+ }
}
}
}