summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/AppOpsManager.java6
-rw-r--r--core/java/android/os/IPowerManager.aidl2
-rw-r--r--core/java/android/os/PowerManager.java10
-rw-r--r--services/java/com/android/server/AppOpsService.java3
-rw-r--r--services/java/com/android/server/SystemServer.java3
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java5
-rw-r--r--services/java/com/android/server/power/Notifier.java23
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java60
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) {