diff options
8 files changed, 79 insertions, 33 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 948210cc1336..32bb71e33388 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -104,8 +104,9 @@ public class AppOpsManager { public static final int OP_AUDIO_ALARM_VOLUME = 37; public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38; public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39; + public static final int OP_WAKE_LOCK = 40; /** @hide */ - public static final int _NUM_OP = 40; + public static final int _NUM_OP = 41; /** * This maps each operation to the operation that serves as the @@ -156,6 +157,7 @@ public class AppOpsManager { OP_AUDIO_ALARM_VOLUME, OP_AUDIO_NOTIFICATION_VOLUME, OP_AUDIO_BLUETOOTH_VOLUME, + OP_WAKE_LOCK, }; /** @@ -203,6 +205,7 @@ public class AppOpsManager { "AUDIO_ALARM_VOLUME", "AUDIO_NOTIFICATION_VOLUME", "AUDIO_BLUETOOTH_VOLUME", + "WAKE_LOCK", }; /** @@ -250,6 +253,7 @@ public class AppOpsManager { null, // no permission for changing alarm volume null, // no permission for changing notification volume null, // no permission for changing bluetooth volume + android.Manifest.permission.WAKE_LOCK, }; /** diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 6d6d147b8a5e..23492ff96340 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -25,7 +25,7 @@ interface IPowerManager { // WARNING: The first two methods must remain the first two methods because their // transaction numbers must not change unless IPowerManager.cpp is also updated. - void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws); + void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws); void releaseWakeLock(IBinder lock, int flags); void updateWakeLockWorkSource(IBinder lock, in WorkSource ws); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 736762f67ff3..52e5f38dc90f 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -224,7 +224,7 @@ public final class PowerManager { /** * Flag for {@link WakeLock#release release(int)} to defer releasing a - * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns + * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor returns * a negative value. * * {@hide} @@ -407,7 +407,7 @@ public final class PowerManager { */ public WakeLock newWakeLock(int levelAndFlags, String tag) { validateWakeLockParameters(levelAndFlags, tag); - return new WakeLock(levelAndFlags, tag); + return new WakeLock(levelAndFlags, tag, mContext.getBasePackageName()); } /** @hide */ @@ -624,6 +624,7 @@ public final class PowerManager { public final class WakeLock { private final int mFlags; private final String mTag; + private final String mPackageName; private final IBinder mToken; private int mCount; private boolean mRefCounted = true; @@ -636,9 +637,10 @@ public final class PowerManager { } }; - WakeLock(int flags, String tag) { + WakeLock(int flags, String tag, String packageName) { mFlags = flags; mTag = tag; + mPackageName = packageName; mToken = new Binder(); } @@ -714,7 +716,7 @@ public final class PowerManager { // been explicitly released by the keyguard. mHandler.removeCallbacks(mReleaser); try { - mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); + mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource); } catch (RemoteException e) { } mHeld = true; diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java index a402642bc0de..7a107e7760df 100644 --- a/services/java/com/android/server/AppOpsService.java +++ b/services/java/com/android/server/AppOpsService.java @@ -551,6 +551,9 @@ public class AppOpsService extends IAppOpsService.Stub { pkgUid = mContext.getPackageManager().getPackageUid(packageName, UserHandle.getUserId(uid)); } catch (NameNotFoundException e) { + if ("media".equals(packageName)) { + pkgUid = Process.MEDIA_UID; + } } if (pkgUid != uid) { // Oops! The package name is not valid for the uid they are calling diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 7d7aeec55dea..7c5959dbd08a 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -286,7 +286,8 @@ class ServerThread { // only initialize the power service after we have started the // lights service, content providers and the battery service. power.init(context, lights, ActivityManagerService.self(), battery, - BatteryStatsService.getService(), display); + BatteryStatsService.getService(), + ActivityManagerService.self().getAppOpsService(), display); Slog.i(TAG, "Alarm Manager"); alarm = new AlarmManagerService(context); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 601517178ce1..d1cc6ba49110 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -28,6 +28,7 @@ import android.app.AppOpsManager; import android.appwidget.AppWidgetManager; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.app.IAppOpsService; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.ProcessStats; import com.android.internal.util.FastXmlSerializer; @@ -1554,6 +1555,10 @@ public final class ActivityManagerService extends ActivityManagerNative return mSelf; } + public IAppOpsService getAppOpsService() { + return mAppOpsService; + } + static class AThread extends Thread { ActivityManagerService mService; Looper mLooper; diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java index d99d523f5cf5..e44cfe5018d1 100644 --- a/services/java/com/android/server/power/Notifier.java +++ b/services/java/com/android/server/power/Notifier.java @@ -16,6 +16,8 @@ package com.android.server.power; +import android.app.AppOpsManager; +import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.server.EventLogTags; @@ -75,6 +77,7 @@ final class Notifier { private final Context mContext; private final IBatteryStats mBatteryStats; + private final IAppOpsService mAppOps; private final SuspendBlocker mSuspendBlocker; private final ScreenOnBlocker mScreenOnBlocker; private final WindowManagerPolicy mPolicy; @@ -104,10 +107,11 @@ final class Notifier { private boolean mScreenOnBlockerAcquired; public Notifier(Looper looper, Context context, IBatteryStats batteryStats, - SuspendBlocker suspendBlocker, ScreenOnBlocker screenOnBlocker, + IAppOpsService appOps, SuspendBlocker suspendBlocker, ScreenOnBlocker screenOnBlocker, WindowManagerPolicy policy) { mContext = context; mBatteryStats = batteryStats; + mAppOps = appOps; mSuspendBlocker = suspendBlocker; mScreenOnBlocker = screenOnBlocker; mPolicy = policy; @@ -124,11 +128,12 @@ final class Notifier { /** * Called when a wake lock is acquired. */ - public void onWakeLockAcquired(int flags, String tag, int ownerUid, int ownerPid, - WorkSource workSource) { + public void onWakeLockAcquired(int flags, String tag, String packageName, + int ownerUid, int ownerPid, WorkSource workSource) { if (DEBUG) { Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag - + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + + "\", packageName=" + packageName + + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } @@ -138,6 +143,8 @@ final class Notifier { mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType); } else { mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType); + // XXX need to deal with disabled operations. + mAppOps.startOperation(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName); } } catch (RemoteException ex) { // Ignore @@ -147,11 +154,12 @@ final class Notifier { /** * Called when a wake lock is released. */ - public void onWakeLockReleased(int flags, String tag, int ownerUid, int ownerPid, - WorkSource workSource) { + public void onWakeLockReleased(int flags, String tag, String packageName, + int ownerUid, int ownerPid, WorkSource workSource) { if (DEBUG) { Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag - + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + + "\", packageName=" + packageName + + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } @@ -161,6 +169,7 @@ final class Notifier { mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, monitorType); } else { mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, monitorType); + mAppOps.finishOperation(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName); } } catch (RemoteException ex) { // Ignore diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index 6c283faf7934..5c81cde27809 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -16,6 +16,7 @@ package com.android.server.power; +import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.server.BatteryService; import com.android.server.EventLogTags; @@ -172,6 +173,7 @@ public final class PowerManagerService extends IPowerManager.Stub private BatteryService mBatteryService; private DisplayManagerService mDisplayManagerService; private IBatteryStats mBatteryStats; + private IAppOpsService mAppOps; private HandlerThread mHandlerThread; private PowerManagerHandler mHandler; private WindowManagerPolicy mPolicy; @@ -394,11 +396,12 @@ public final class PowerManagerService extends IPowerManager.Stub */ public void init(Context context, LightsService ls, ActivityManagerService am, BatteryService bs, IBatteryStats bss, - DisplayManagerService dm) { + IAppOpsService appOps, DisplayManagerService dm) { mContext = context; mLightsService = ls; mBatteryService = bs; mBatteryStats = bss; + mAppOps = appOps; mDisplayManagerService = dm; mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); @@ -437,7 +440,7 @@ public final class PowerManagerService extends IPowerManager.Stub // The notifier runs on the system server's main looper so as not to interfere // with the animations and other critical functions of the power manager. mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats, - createSuspendBlockerLocked("PowerManagerService.Broadcasts"), + mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mScreenOnBlocker, mPolicy); // The display power controller runs on the power manager service's @@ -572,10 +575,14 @@ public final class PowerManagerService extends IPowerManager.Stub } @Override // Binder call - public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) { + public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, + WorkSource ws) { if (lock == null) { throw new IllegalArgumentException("lock must not be null"); } + if (packageName == null) { + throw new IllegalArgumentException("packageName must not be null"); + } PowerManager.validateWakeLockParameters(flags, tag); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); @@ -590,14 +597,14 @@ public final class PowerManagerService extends IPowerManager.Stub final int pid = Binder.getCallingPid(); final long ident = Binder.clearCallingIdentity(); try { - acquireWakeLockInternal(lock, flags, tag, ws, uid, pid); + acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid); } finally { Binder.restoreCallingIdentity(ident); } } - private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws, - int uid, int pid) { + private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName, + WorkSource ws, int uid, int pid) { synchronized (mLock) { if (DEBUG_SPEW) { Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock) @@ -612,11 +619,11 @@ public final class PowerManagerService extends IPowerManager.Stub if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) { // Update existing wake lock. This shouldn't happen but is harmless. notifyWakeLockReleasedLocked(wakeLock); - wakeLock.updateProperties(flags, tag, ws, uid, pid); + wakeLock.updateProperties(flags, tag, packageName, ws, uid, pid); notifyWakeLockAcquiredLocked(wakeLock); } } else { - wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid); + wakeLock = new WakeLock(lock, flags, tag, packageName, ws, uid, pid); try { lock.linkToDeath(wakeLock, 0); } catch (RemoteException ex) { @@ -785,14 +792,16 @@ public final class PowerManagerService extends IPowerManager.Stub private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) { if (mSystemReady) { - mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, + wakeLock.mNotifiedAcquired = true; + mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource); } } private void notifyWakeLockReleasedLocked(WakeLock wakeLock) { - if (mSystemReady) { - mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag, + if (mSystemReady && wakeLock.mNotifiedAcquired) { + wakeLock.mNotifiedAcquired = false; + mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource); } } @@ -2428,15 +2437,18 @@ public final class PowerManagerService extends IPowerManager.Stub public final IBinder mLock; public int mFlags; public String mTag; + public final String mPackageName; public WorkSource mWorkSource; - public int mOwnerUid; - public int mOwnerPid; + public final int mOwnerUid; + public final int mOwnerPid; + public boolean mNotifiedAcquired; - public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource, - int ownerUid, int ownerPid) { + public WakeLock(IBinder lock, int flags, String tag, String packageName, + WorkSource workSource, int ownerUid, int ownerPid) { mLock = lock; mFlags = flags; mTag = tag; + mPackageName = packageName; mWorkSource = copyWorkSource(workSource); mOwnerUid = ownerUid; mOwnerPid = ownerPid; @@ -2456,13 +2468,23 @@ public final class PowerManagerService extends IPowerManager.Stub && mOwnerPid == ownerPid; } - public void updateProperties(int flags, String tag, WorkSource workSource, - int ownerUid, int ownerPid) { + public void updateProperties(int flags, String tag, String packageName, + WorkSource workSource, int ownerUid, int ownerPid) { + if (!mPackageName.equals(packageName)) { + throw new IllegalStateException("Existing wake lock package name changed: " + + mPackageName + " to " + packageName); + } + if (mOwnerUid != ownerUid) { + throw new IllegalStateException("Existing wake lock uid changed: " + + mOwnerUid + " to " + ownerUid); + } + if (mOwnerPid != ownerPid) { + throw new IllegalStateException("Existing wake lock pid changed: " + + mOwnerPid + " to " + ownerPid); + } mFlags = flags; mTag = tag; updateWorkSource(workSource); - mOwnerUid = ownerUid; - mOwnerPid = ownerPid; } public boolean hasSameWorkSource(WorkSource workSource) { |