diff options
| -rw-r--r-- | services/core/java/com/android/server/power/PowerManagerService.java | 69 |
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); + } } } } |