summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-03-01 01:11:25 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-03-01 01:11:25 +0000
commit06b1df657a9fcc93a2541fca4495559dc950798e (patch)
tree7bd3a30056f3a3c758c9fbe233c6da6010fc4fc6
parent364eb306471fcdd4130b5899ddeb7978d8050b8c (diff)
parentf7b4725375dfb5f6b65433f1679c44501c2478e3 (diff)
Merge "Use start/finish app ops in window manager"
-rw-r--r--api/test-current.txt8
-rw-r--r--core/java/android/app/AppOpsManager.java109
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl3
-rw-r--r--services/core/java/com/android/server/AppOpsService.java57
-rw-r--r--services/core/java/com/android/server/VibratorService.java27
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java38
-rw-r--r--services/core/java/com/android/server/power/Notifier.java16
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java48
11 files changed, 201 insertions, 137 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index 21d12c357164..a2fead2b6a9d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -48,7 +48,10 @@ package android.app {
public class AppOpsManager {
method public static java.lang.String[] getOpStrs();
+ method public boolean isOperationActive(int, int, java.lang.String);
method public void setMode(int, int, java.lang.String, int);
+ method public void startWatchingActive(int[], android.app.AppOpsManager.OnOpActiveChangedListener);
+ method public void stopWatchingActive(android.app.AppOpsManager.OnOpActiveChangedListener);
field public static final java.lang.String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
field public static final java.lang.String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
field public static final java.lang.String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
@@ -90,6 +93,11 @@ package android.app {
field public static final java.lang.String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
field public static final java.lang.String OPSTR_WRITE_SMS = "android:write_sms";
field public static final java.lang.String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
+ field public static final int OP_SYSTEM_ALERT_WINDOW = 24; // 0x18
+ }
+
+ public static abstract interface AppOpsManager.OnOpActiveChangedListener {
+ method public abstract void onOpActiveChanged(int, int, java.lang.String, boolean);
}
public final class NotificationChannelGroup implements android.os.Parcelable {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index d76a4f9ff10e..0e126a3a02d4 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -31,7 +31,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -168,6 +167,7 @@ public class AppOpsManager {
/** @hide */
public static final int OP_WRITE_SETTINGS = 23;
/** @hide Required to draw on top of other apps. */
+ @TestApi
public static final int OP_SYSTEM_ALERT_WINDOW = 24;
/** @hide */
public static final int OP_ACCESS_NOTIFICATIONS = 25;
@@ -1540,6 +1540,7 @@ public class AppOpsManager {
*
* @hide
*/
+ @TestApi
public interface OnOpActiveChangedListener {
/**
* Called when the active state of an app op changes.
@@ -1731,7 +1732,7 @@ public class AppOpsManager {
* Monitor for changes to the operating mode for the given op in the given app package.
*
* <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
- * to watch changes only for your UID.
+ * you can watch changes only for your UID.
*
* @param op The operation to monitor, one of OP_*.
* @param packageName The name of the application to monitor.
@@ -1787,6 +1788,9 @@ public class AppOpsManager {
* watched ops for a registered callback you need to unregister and register it
* again.
*
+ * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
+ * you can watch changes only for your UID.
+ *
* @param ops The ops to watch.
* @param callback Where to report changes.
*
@@ -1797,7 +1801,9 @@ public class AppOpsManager {
*
* @hide
*/
- @RequiresPermission(Manifest.permission.WATCH_APPOPS)
+ @TestApi
+ // TODO: Uncomment below annotation once b/73559440 is fixed
+ // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
public void startWatchingActive(@NonNull int[] ops,
@NonNull OnOpActiveChangedListener callback) {
Preconditions.checkNotNull(ops, "ops cannot be null");
@@ -1835,6 +1841,7 @@ public class AppOpsManager {
*
* @hide
*/
+ @TestApi
public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
synchronized (mActiveWatchers) {
final IAppOpsActiveCallback cb = mActiveWatchers.get(callback);
@@ -2086,15 +2093,11 @@ public class AppOpsManager {
* @hide
*/
public int noteOp(int op, int uid, String packageName) {
- try {
- int mode = mService.noteOperation(op, uid, packageName);
- if (mode == MODE_ERRORED) {
- throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
- }
- return mode;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ final int mode = noteOpNoThrow(op, uid, packageName);
+ if (mode == MODE_ERRORED) {
+ throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
}
+ return mode;
}
/**
@@ -2173,6 +2176,11 @@ public class AppOpsManager {
}
}
+ /** @hide */
+ public int startOp(int op) {
+ return startOp(op, Process.myUid(), mContext.getOpPackageName());
+ }
+
/**
* Report that an application has started executing a long-running operation. Note that you
* must pass in both the uid and name of the application to be checked; this function will
@@ -2181,6 +2189,7 @@ public class AppOpsManager {
* the current time and the operation will be marked as "running". In this case you must
* later call {@link #finishOp(int, int, String)} to report when the application is no
* longer performing the operation.
+ *
* @param op The operation to start. One of the OP_* constants.
* @param uid The user id of the application attempting to perform the operation.
* @param packageName The name of the application attempting to perform the operation.
@@ -2191,15 +2200,34 @@ public class AppOpsManager {
* @hide
*/
public int startOp(int op, int uid, String packageName) {
- try {
- int mode = mService.startOperation(getToken(mService), op, uid, packageName);
- if (mode == MODE_ERRORED) {
- throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
- }
- return mode;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ return startOp(op, uid, packageName, false);
+ }
+
+ /**
+ * Report that an application has started executing a long-running operation. Similar
+ * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
+ * the operation should succeed since the caller has performed its standard permission
+ * checks which passed and would perform the protected operation for this mode.
+ *
+ * @param op The operation to start. One of the OP_* constants.
+ * @param uid The user id of the application attempting to perform the operation.
+ * @param packageName The name of the application attempting to perform the operation.
+ * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+ * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+ * causing the app to crash).
+ * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
+ *
+ * @throws SecurityException If the app has been configured to crash on this op or
+ * the package is not in the passed in UID.
+ *
+ * @hide
+ */
+ public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
+ final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
+ if (mode == MODE_ERRORED) {
+ throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
}
+ return mode;
}
/**
@@ -2208,18 +2236,32 @@ public class AppOpsManager {
* @hide
*/
public int startOpNoThrow(int op, int uid, String packageName) {
+ return startOpNoThrow(op, uid, packageName, false);
+ }
+
+ /**
+ * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
+ * {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ *
+ * @param op The operation to start. One of the OP_* constants.
+ * @param uid The user id of the application attempting to perform the operation.
+ * @param packageName The name of the application attempting to perform the operation.
+ * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+ * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+ * causing the app to crash).
+ * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
+ *
+ * @hide
+ */
+ public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
try {
- return mService.startOperation(getToken(mService), op, uid, packageName);
+ return mService.startOperation(getToken(mService), op, uid, packageName,
+ startIfModeDefault);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- /** @hide */
- public int startOp(int op) {
- return startOp(op, Process.myUid(), mContext.getOpPackageName());
- }
-
/**
* Report that an application is no longer performing an operation that had previously
* been started with {@link #startOp(int, int, String)}. There is no validation of input
@@ -2240,8 +2282,21 @@ public class AppOpsManager {
finishOp(op, Process.myUid(), mContext.getOpPackageName());
}
- /** @hide */
- @RequiresPermission(Manifest.permission.WATCH_APPOPS)
+ /**
+ * Checks whether the given op for a UID and package is active.
+ *
+ * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
+ * you can query only for your UID.
+ *
+ * @see #startWatchingActive(int[], OnOpActiveChangedListener)
+ * @see #stopWatchingMode(OnOpChangedListener)
+ * @see #finishOp(int)
+ * @see #startOp(int)
+ *
+ * @hide */
+ @TestApi
+ // TODO: Uncomment below annotation once b/73559440 is fixed
+ // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
public boolean isOperationActive(int code, int uid, String packageName) {
try {
return mService.isOperationActive(code, uid, packageName);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index fabda4a5c15e..2505ea5d448b 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -26,7 +26,8 @@ interface IAppOpsService {
// be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h
int checkOperation(int code, int uid, String packageName);
int noteOperation(int code, int uid, String packageName);
- int startOperation(IBinder token, int code, int uid, String packageName);
+ int startOperation(IBinder token, int code, int uid, String packageName,
+ boolean startIfModeDefault);
void finishOperation(IBinder token, int code, int uid, String packageName);
void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
void stopWatchingMode(IAppOpsCallback callback);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index ca67a34101d5..692b12f660d1 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -211,9 +211,11 @@ public class AppOpsService extends IAppOpsService.Stub {
public final class ActiveCallback implements DeathRecipient {
final IAppOpsActiveCallback mCallback;
+ final int mUid;
- public ActiveCallback(IAppOpsActiveCallback callback) {
+ public ActiveCallback(IAppOpsActiveCallback callback, int uid) {
mCallback = callback;
+ mUid = uid;
try {
mCallback.asBinder().linkToDeath(this, 0);
} catch (RemoteException e) {
@@ -233,21 +235,19 @@ public class AppOpsService extends IAppOpsService.Stub {
final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<IBinder, ClientState>();
public final class ClientState extends Binder implements DeathRecipient {
+ final ArrayList<Op> mStartedOps = new ArrayList<>();
final IBinder mAppToken;
final int mPid;
- final ArrayList<Op> mStartedOps;
public ClientState(IBinder appToken) {
mAppToken = appToken;
mPid = Binder.getCallingPid();
- if (appToken instanceof Binder) {
- // For local clients, there is no reason to track them.
- mStartedOps = null;
- } else {
- mStartedOps = new ArrayList<Op>();
+ // Watch only for remote processes dying
+ if (!(appToken instanceof Binder)) {
try {
mAppToken.linkToDeath(this, 0);
} catch (RemoteException e) {
+ /* do nothing */
}
}
}
@@ -256,7 +256,7 @@ public class AppOpsService extends IAppOpsService.Stub {
public String toString() {
return "ClientState{" +
"mAppToken=" + mAppToken +
- ", " + (mStartedOps != null ? ("pid=" + mPid) : "local") +
+ ", " + "pid=" + mPid +
'}';
}
@@ -1195,8 +1195,11 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public void startWatchingActive(int[] ops, IAppOpsActiveCallback callback) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS,
- "startWatchingActive");
+ int watchedUid = -1;
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS)
+ != PackageManager.PERMISSION_GRANTED) {
+ watchedUid = Binder.getCallingUid();
+ }
if (ops != null) {
Preconditions.checkArrayElementsInRange(ops, 0,
AppOpsManager._NUM_OP - 1, "Invalid op code in: " + Arrays.toString(ops));
@@ -1210,7 +1213,7 @@ public class AppOpsService extends IAppOpsService.Stub {
callbacks = new SparseArray<>();
mActiveWatchers.put(callback.asBinder(), callbacks);
}
- final ActiveCallback activeCallback = new ActiveCallback(callback);
+ final ActiveCallback activeCallback = new ActiveCallback(callback, watchedUid);
for (int op : ops) {
callbacks.put(op, activeCallback);
}
@@ -1239,7 +1242,8 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
- public int startOperation(IBinder token, int code, int uid, String packageName) {
+ public int startOperation(IBinder token, int code, int uid, String packageName,
+ boolean startIfModeDefault) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
String resolvedPackageName = resolvePackageName(uid, packageName);
@@ -1265,7 +1269,8 @@ public class AppOpsService extends IAppOpsService.Stub {
// non-default) it takes over, otherwise use the per package policy.
if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
final int uidMode = uidState.opModes.get(switchCode);
- if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ if (uidMode != AppOpsManager.MODE_ALLOWED
+ && (!startIfModeDefault || uidMode != AppOpsManager.MODE_DEFAULT)) {
if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ resolvedPackageName);
@@ -1274,7 +1279,8 @@ public class AppOpsService extends IAppOpsService.Stub {
}
} else {
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
- if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+ if (switchOp.mode != AppOpsManager.MODE_ALLOWED
+ && (!startIfModeDefault || switchOp.mode != AppOpsManager.MODE_DEFAULT)) {
if (DEBUG) Slog.d(TAG, "startOperation: reject #" + op.mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ resolvedPackageName);
@@ -1316,11 +1322,9 @@ public class AppOpsService extends IAppOpsService.Stub {
if (op == null) {
return;
}
- if (client.mStartedOps != null) {
- if (!client.mStartedOps.remove(op)) {
- throw new IllegalStateException("Operation not started: uid" + op.uid
- + " pkg=" + op.packageName + " op=" + op.op);
- }
+ if (!client.mStartedOps.remove(op)) {
+ throw new IllegalStateException("Operation not started: uid" + op.uid
+ + " pkg=" + op.packageName + " op=" + op.op);
}
finishOperationLocked(op);
if (op.nesting <= 0) {
@@ -1337,6 +1341,9 @@ public class AppOpsService extends IAppOpsService.Stub {
final SparseArray<ActiveCallback> callbacks = mActiveWatchers.valueAt(i);
ActiveCallback callback = callbacks.get(code);
if (callback != null) {
+ if (callback.mUid >= 0 && callback.mUid != uid) {
+ continue;
+ }
if (dispatchedCallbacks == null) {
dispatchedCallbacks = new ArraySet<>();
}
@@ -2420,7 +2427,7 @@ public class AppOpsService extends IAppOpsService.Stub {
pw.print(" "); pw.print(mClients.keyAt(i)); pw.println(":");
ClientState cs = mClients.valueAt(i);
pw.print(" "); pw.println(cs);
- if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) {
+ if (cs.mStartedOps.size() > 0) {
pw.println(" Started ops:");
for (int j=0; j<cs.mStartedOps.size(); j++) {
Op op = cs.mStartedOps.get(j);
@@ -2651,8 +2658,12 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public boolean isOperationActive(int code, int uid, String packageName) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS,
- "isOperationActive");
+ if (Binder.getCallingUid() != uid) {
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS)
+ != PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+ }
verifyIncomingOp(code);
final String resolvedPackageName = resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
@@ -2661,8 +2672,6 @@ public class AppOpsService extends IAppOpsService.Stub {
synchronized (AppOpsService.this) {
for (int i = mClients.size() - 1; i >= 0; i--) {
final ClientState client = mClients.valueAt(i);
- if (client.mStartedOps == null) continue;
-
for (int j = client.mStartedOps.size() - 1; j >= 0; j--) {
final Op op = client.mStartedOps.get(j);
if (op.op == code && op.uid == uid) return true;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 14c99b229962..752c44a6f59b 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -98,7 +98,7 @@ public class VibratorService extends IVibratorService.Stub
private final Context mContext;
private final PowerManager.WakeLock mWakeLock;
- private final IAppOpsService mAppOpsService;
+ private final AppOpsManager mAppOps;
private final IBatteryStats mBatteryStatsService;
private PowerManagerInternal mPowerManagerInternal;
private InputManager mIm;
@@ -265,8 +265,7 @@ public class VibratorService extends IVibratorService.Stub
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
mWakeLock.setReferenceCounted(true);
- mAppOpsService =
- IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE));
+ mAppOps = mContext.getSystemService(AppOpsManager.class);
mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
@@ -721,17 +720,10 @@ public class VibratorService extends IVibratorService.Stub
}
private int getAppOpMode(Vibration vib) {
- int mode;
- try {
- mode = mAppOpsService.checkAudioOperation(AppOpsManager.OP_VIBRATE,
- vib.usageHint, vib.uid, vib.opPkg);
- if (mode == AppOpsManager.MODE_ALLOWED) {
- mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
- AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to get appop mode for vibration!", e);
- mode = AppOpsManager.MODE_IGNORED;
+ int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
+ vib.usageHint, vib.uid, vib.opPkg);
+ if (mode == AppOpsManager.MODE_ALLOWED) {
+ mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
}
return mode;
}
@@ -741,11 +733,8 @@ public class VibratorService extends IVibratorService.Stub
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked");
try {
if (mCurrentVibration != null) {
- try {
- mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
- AppOpsManager.OP_VIBRATE, mCurrentVibration.uid,
- mCurrentVibration.opPkg);
- } catch (RemoteException e) { }
+ mAppOps.finishOp(AppOpsManager.OP_VIBRATE, mCurrentVibration.uid,
+ mCurrentVibration.opPkg);
unlinkVibration(mCurrentVibration);
mCurrentVibration = null;
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 5267f54b9cd5..729ac0c68662 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -459,7 +459,7 @@ public class GnssLocationProvider implements LocationProviderInterface {
private final PendingIntent mWakeupIntent;
private final PendingIntent mTimeoutIntent;
- private final IAppOpsService mAppOpsService;
+ private final AppOpsManager mAppOps;
private final IBatteryStats mBatteryStats;
// Current list of underlying location clients.
@@ -782,8 +782,7 @@ public class GnssLocationProvider implements LocationProviderInterface {
mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// App ops service to keep track of who is accessing the GPS
- mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(
- Context.APP_OPS_SERVICE));
+ mAppOps = mContext.getSystemService(AppOpsManager.class);
// Battery statistics service to be notified when GPS turns on or off
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
@@ -1490,26 +1489,16 @@ public class GnssLocationProvider implements LocationProviderInterface {
if (newChains != null) {
for (int i = 0; i < newChains.size(); ++i) {
final WorkChain newChain = newChains.get(i);
- try {
- mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
- AppOpsManager.OP_GPS, newChain.getAttributionUid(),
- newChain.getAttributionTag());
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException", e);
- }
+ mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
+ newChain.getAttributionTag());
}
}
if (goneChains != null) {
for (int i = 0; i < goneChains.size(); i++) {
final WorkChain goneChain = goneChains.get(i);
- try {
- mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
- AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
- goneChain.getAttributionTag());
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException", e);
- }
+ mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
+ goneChain.getAttributionTag());
}
}
@@ -1525,24 +1514,15 @@ public class GnssLocationProvider implements LocationProviderInterface {
// Update sources that were not previously tracked.
if (newWork != null) {
for (int i = 0; i < newWork.size(); i++) {
- try {
- mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
- AppOpsManager.OP_GPS, newWork.get(i), newWork.getName(i));
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException", e);
- }
+ mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
+ newWork.get(i), newWork.getName(i));
}
}
// Update sources that are no longer tracked.
if (goneWork != null) {
for (int i = 0; i < goneWork.size(); i++) {
- try {
- mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
- AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException", e);
- }
+ mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
}
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 3072f212d7c1..b729b6a0f47f 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -91,7 +91,7 @@ final class Notifier {
private final Context mContext;
private final IBatteryStats mBatteryStats;
- private final IAppOpsService mAppOps;
+ private final AppOpsManager mAppOps;
private final SuspendBlocker mSuspendBlocker;
private final WindowManagerPolicy mPolicy;
private final ActivityManagerInternal mActivityManagerInternal;
@@ -134,11 +134,10 @@ final class Notifier {
private boolean mUserActivityPending;
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
- IAppOpsService appOps, SuspendBlocker suspendBlocker,
- WindowManagerPolicy policy) {
+ SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
mContext = context;
mBatteryStats = batteryStats;
- mAppOps = appOps;
+ mAppOps = mContext.getSystemService(AppOpsManager.class);
mSuspendBlocker = suspendBlocker;
mPolicy = policy;
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -194,8 +193,7 @@ final class Notifier {
mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
monitorType, unimportantForLogging);
// XXX need to deal with disabled operations.
- mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
- AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
}
} catch (RemoteException ex) {
// Ignore
@@ -295,8 +293,7 @@ final class Notifier {
} else {
mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
historyTag, monitorType);
- mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
- AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
}
} catch (RemoteException ex) {
// Ignore
@@ -539,12 +536,11 @@ final class Notifier {
try {
mBatteryStats.noteWakeUp(reason, reasonUid);
if (opPackageName != null) {
- mAppOps.noteOperation(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
+ mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
}
} catch (RemoteException ex) {
// Ignore
}
-
}
/**
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d67acc481acf..f77b0ee59249 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -759,8 +759,7 @@ public final class PowerManagerService extends SystemService
// with the animations and other critical functions of the power manager.
mBatteryStats = BatteryStatsService.getService();
mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
- mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
- mPolicy);
+ createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy);
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 6356a3512e65..36d331da19e4 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -29,9 +29,7 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.os.UserHandle;
-import android.provider.Settings;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Slog;
@@ -50,9 +48,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.app.AppOpsManager.OP_NONE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
@@ -68,8 +63,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -427,12 +420,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
void updateAppOpsState() {
forAllWindows((w) -> {
- if (w.mAppOp == OP_NONE) {
- return;
- }
- final int mode = mService.mAppOps.noteOpNoThrow(w.mAppOp, w.getOwningUid(),
- w.getOwningPackage());
- w.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
+ w.updateAppOpsState();
}, false /* traverseTopToBottom */);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index bab4399d76ad..696eef1ac6ca 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1384,14 +1384,8 @@ public class WindowManagerService extends IWindowManager.Stub
win.attach();
mWindowMap.put(client.asBinder(), win);
- if (win.mAppOp != AppOpsManager.OP_NONE) {
- int startOpResult = mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(),
- win.getOwningPackage());
- if ((startOpResult != AppOpsManager.MODE_ALLOWED) &&
- (startOpResult != AppOpsManager.MODE_DEFAULT)) {
- win.setAppOpVisibilityLw(false);
- }
- }
+
+ win.initAppOpsState();
final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
@@ -1656,9 +1650,8 @@ public class WindowManagerService extends IWindowManager.Stub
void postWindowRemoveCleanupLocked(WindowState win) {
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win);
mWindowMap.remove(win.mClient.asBinder());
- if (win.mAppOp != AppOpsManager.OP_NONE) {
- mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
- }
+
+ win.resetAppOpsState();
if (mCurrentFocus == null) {
mWinRemovedSinceNullFocus.add(win);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b706096f3d0b..62664738a2c0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -17,6 +17,9 @@
package com.android.server.wm;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.OP_NONE;
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -2571,7 +2574,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
- public void setAppOpVisibilityLw(boolean state) {
+ private void setAppOpVisibilityLw(boolean state) {
if (mAppOpVisibility != state) {
mAppOpVisibility = state;
if (state) {
@@ -2588,6 +2591,49 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
+ void initAppOpsState() {
+ if (mAppOp == OP_NONE || !mAppOpVisibility) {
+ return;
+ }
+ // If the app op was MODE_DEFAULT we would have checked the permission
+ // and add the window only if the permission was granted. Therefore, if
+ // the mode is MODE_DEFAULT we want the op to succeed as the window is
+ // shown.
+ final int mode = mService.mAppOps.startOpNoThrow(mAppOp,
+ getOwningUid(), getOwningPackage(), true);
+ if (mode != MODE_ALLOWED && mode != MODE_DEFAULT) {
+ setAppOpVisibilityLw(false);
+ }
+ }
+
+ void resetAppOpsState() {
+ if (mAppOp != OP_NONE && mAppOpVisibility) {
+ mService.mAppOps.finishOp(mAppOp, getOwningUid(), getOwningPackage());
+ }
+ }
+
+ void updateAppOpsState() {
+ if (mAppOp == OP_NONE) {
+ return;
+ }
+ final int uid = getOwningUid();
+ final String packageName = getOwningPackage();
+ if (mAppOpVisibility) {
+ // There is a race between the check and the finish calls but this is fine
+ // as this would mean we will get another change callback and will reconcile.
+ int mode = mService.mAppOps.checkOpNoThrow(mAppOp, uid, packageName);
+ if (mode != MODE_ALLOWED && mode != MODE_DEFAULT) {
+ mService.mAppOps.finishOp(mAppOp, uid, packageName);
+ setAppOpVisibilityLw(false);
+ }
+ } else {
+ final int mode = mService.mAppOps.startOpNoThrow(mAppOp, uid, packageName);
+ if (mode == MODE_ALLOWED || mode == MODE_DEFAULT) {
+ setAppOpVisibilityLw(true);
+ }
+ }
+ }
+
public void hidePermanentlyLw() {
if (!mPermanentlyHidden) {
mPermanentlyHidden = true;