Loading Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -356,6 +356,7 @@ java_library { "core/java/android/speech/IRecognitionService.aidl", "core/java/android/speech/tts/ITextToSpeechCallback.aidl", "core/java/android/speech/tts/ITextToSpeechService.aidl", "core/java/com/android/internal/app/IAppOpsActiveCallback.aidl", "core/java/com/android/internal/app/IAppOpsCallback.aidl", "core/java/com/android/internal/app/IAppOpsService.aidl", "core/java/com/android/internal/app/IBatteryStats.aidl", Loading core/java/android/app/AppOpsManager.java +100 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; Loading @@ -34,8 +35,10 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import com.android.internal.app.IAppOpsActiveCallback; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Arrays; Loading Loading @@ -74,8 +77,9 @@ public class AppOpsManager { final Context mContext; final IAppOpsService mService; final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = new ArrayMap<OnOpChangedListener, IAppOpsCallback>(); final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = new ArrayMap<>(); final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers = new ArrayMap<>(); static IBinder sToken; Loading Loading @@ -1531,6 +1535,23 @@ public class AppOpsManager { public void onOpChanged(String op, String packageName); } /** * Callback for notification of changes to operation active state. * * @hide */ public interface OnOpActiveChangedListener { /** * Called when the active state of an app op changes. * * @param code The op code. * @param uid The UID performing the operation. * @param packageName The package performing the operation. * @param active Whether the operation became active or inactive. */ void onOpActiveChanged(int code, int uid, String packageName, boolean active); } /** * Callback for notification of changes to operation state. * This allows you to see the raw op codes instead of strings. Loading Loading @@ -1695,6 +1716,8 @@ public class AppOpsManager { /** * Monitor for changes to the operating mode for the given op in the given app package. * You can watch op changes only for your UID. * * @param op The operation to monitor, one of OPSTR_*. * @param packageName The name of the application to monitor. * @param callback Where to report changes. Loading @@ -1706,11 +1729,17 @@ 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. * * @param op The operation to monitor, one of OP_*. * @param packageName The name of the application to monitor. * @param callback Where to report changes. * @hide */ // TODO: Uncomment below annotation once b/73559440 is fixed // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) { synchronized (mModeWatchers) { IAppOpsCallback cb = mModeWatchers.get(callback); Loading Loading @@ -1752,6 +1781,74 @@ public class AppOpsManager { } } /** * Start watching for changes to the active state of app ops. An app op may be * long running and it has a clear start and stop delimiters. If an op is being * started or stopped by any package you will get a callback. To change the * watched ops for a registered callback you need to unregister and register it * again. * * @param ops The ops to watch. * @param callback Where to report changes. * * @see #isOperationActive(int, int, String) * @see #stopWatchingActive(OnOpActiveChangedListener) * @see #startOp(int, int, String) * @see #finishOp(int, int, String) * * @hide */ @RequiresPermission(Manifest.permission.WATCH_APPOPS) public void startWatchingActive(@NonNull int[] ops, @NonNull OnOpActiveChangedListener callback) { Preconditions.checkNotNull(ops, "ops cannot be null"); Preconditions.checkNotNull(callback, "callback cannot be null"); IAppOpsActiveCallback cb; synchronized (mActiveWatchers) { cb = mActiveWatchers.get(callback); if (cb != null) { return; } cb = new IAppOpsActiveCallback.Stub() { @Override public void opActiveChanged(int op, int uid, String packageName, boolean active) { callback.onOpActiveChanged(op, uid, packageName, active); } }; mActiveWatchers.put(callback, cb); } try { mService.startWatchingActive(ops, cb); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Stop watching for changes to the active state of an app op. An app op may be * long running and it has a clear start and stop delimiters. Unregistering a * non-registered callback has no effect. * * @see #isOperationActive#(int, int, String) * @see #startWatchingActive(int[], OnOpActiveChangedListener) * @see #startOp(int, int, String) * @see #finishOp(int, int, String) * * @hide */ public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) { synchronized (mActiveWatchers) { final IAppOpsActiveCallback cb = mActiveWatchers.get(callback); if (cb != null) { try { mService.stopWatchingActive(cb); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } } private String buildSecurityExceptionMsg(int op, int uid, String packageName) { return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op]; } Loading Loading @@ -2145,6 +2242,7 @@ public class AppOpsManager { } /** @hide */ @RequiresPermission(Manifest.permission.WATCH_APPOPS) public boolean isOperationActive(int code, int uid, String packageName) { try { return mService.isOperationActive(code, uid, packageName); Loading core/java/com/android/internal/app/IAppOpsActiveCallback.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.app; // Iterface to observe op active changes oneway interface IAppOpsActiveCallback { void opActiveChanged(int op, int uid, String packageName, boolean active); } core/java/com/android/internal/app/IAppOpsService.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.app; import android.app.AppOpsManager; import android.os.Bundle; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsActiveCallback; interface IAppOpsService { // These first methods are also called by native code, so must Loading Loading @@ -49,5 +50,7 @@ interface IAppOpsService { void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages); void removeUser(int userHandle); void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback); void stopWatchingActive(IAppOpsActiveCallback callback); boolean isOperationActive(int code, int uid, String packageName); } core/java/com/android/internal/util/function/HexConsumer.java 0 → 100644 +28 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util.function; import java.util.function.Consumer; /** * A 6-argument {@link Consumer} * * @hide */ public interface HexConsumer<A, B, C, D, E, F> { void accept(A a, B b, C c, D d, E e, F f); } Loading
Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -356,6 +356,7 @@ java_library { "core/java/android/speech/IRecognitionService.aidl", "core/java/android/speech/tts/ITextToSpeechCallback.aidl", "core/java/android/speech/tts/ITextToSpeechService.aidl", "core/java/com/android/internal/app/IAppOpsActiveCallback.aidl", "core/java/com/android/internal/app/IAppOpsCallback.aidl", "core/java/com/android/internal/app/IAppOpsService.aidl", "core/java/com/android/internal/app/IBatteryStats.aidl", Loading
core/java/android/app/AppOpsManager.java +100 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; Loading @@ -34,8 +35,10 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import com.android.internal.app.IAppOpsActiveCallback; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Arrays; Loading Loading @@ -74,8 +77,9 @@ public class AppOpsManager { final Context mContext; final IAppOpsService mService; final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = new ArrayMap<OnOpChangedListener, IAppOpsCallback>(); final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = new ArrayMap<>(); final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers = new ArrayMap<>(); static IBinder sToken; Loading Loading @@ -1531,6 +1535,23 @@ public class AppOpsManager { public void onOpChanged(String op, String packageName); } /** * Callback for notification of changes to operation active state. * * @hide */ public interface OnOpActiveChangedListener { /** * Called when the active state of an app op changes. * * @param code The op code. * @param uid The UID performing the operation. * @param packageName The package performing the operation. * @param active Whether the operation became active or inactive. */ void onOpActiveChanged(int code, int uid, String packageName, boolean active); } /** * Callback for notification of changes to operation state. * This allows you to see the raw op codes instead of strings. Loading Loading @@ -1695,6 +1716,8 @@ public class AppOpsManager { /** * Monitor for changes to the operating mode for the given op in the given app package. * You can watch op changes only for your UID. * * @param op The operation to monitor, one of OPSTR_*. * @param packageName The name of the application to monitor. * @param callback Where to report changes. Loading @@ -1706,11 +1729,17 @@ 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. * * @param op The operation to monitor, one of OP_*. * @param packageName The name of the application to monitor. * @param callback Where to report changes. * @hide */ // TODO: Uncomment below annotation once b/73559440 is fixed // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) { synchronized (mModeWatchers) { IAppOpsCallback cb = mModeWatchers.get(callback); Loading Loading @@ -1752,6 +1781,74 @@ public class AppOpsManager { } } /** * Start watching for changes to the active state of app ops. An app op may be * long running and it has a clear start and stop delimiters. If an op is being * started or stopped by any package you will get a callback. To change the * watched ops for a registered callback you need to unregister and register it * again. * * @param ops The ops to watch. * @param callback Where to report changes. * * @see #isOperationActive(int, int, String) * @see #stopWatchingActive(OnOpActiveChangedListener) * @see #startOp(int, int, String) * @see #finishOp(int, int, String) * * @hide */ @RequiresPermission(Manifest.permission.WATCH_APPOPS) public void startWatchingActive(@NonNull int[] ops, @NonNull OnOpActiveChangedListener callback) { Preconditions.checkNotNull(ops, "ops cannot be null"); Preconditions.checkNotNull(callback, "callback cannot be null"); IAppOpsActiveCallback cb; synchronized (mActiveWatchers) { cb = mActiveWatchers.get(callback); if (cb != null) { return; } cb = new IAppOpsActiveCallback.Stub() { @Override public void opActiveChanged(int op, int uid, String packageName, boolean active) { callback.onOpActiveChanged(op, uid, packageName, active); } }; mActiveWatchers.put(callback, cb); } try { mService.startWatchingActive(ops, cb); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Stop watching for changes to the active state of an app op. An app op may be * long running and it has a clear start and stop delimiters. Unregistering a * non-registered callback has no effect. * * @see #isOperationActive#(int, int, String) * @see #startWatchingActive(int[], OnOpActiveChangedListener) * @see #startOp(int, int, String) * @see #finishOp(int, int, String) * * @hide */ public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) { synchronized (mActiveWatchers) { final IAppOpsActiveCallback cb = mActiveWatchers.get(callback); if (cb != null) { try { mService.stopWatchingActive(cb); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } } private String buildSecurityExceptionMsg(int op, int uid, String packageName) { return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op]; } Loading Loading @@ -2145,6 +2242,7 @@ public class AppOpsManager { } /** @hide */ @RequiresPermission(Manifest.permission.WATCH_APPOPS) public boolean isOperationActive(int code, int uid, String packageName) { try { return mService.isOperationActive(code, uid, packageName); Loading
core/java/com/android/internal/app/IAppOpsActiveCallback.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.app; // Iterface to observe op active changes oneway interface IAppOpsActiveCallback { void opActiveChanged(int op, int uid, String packageName, boolean active); }
core/java/com/android/internal/app/IAppOpsService.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.app; import android.app.AppOpsManager; import android.os.Bundle; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsActiveCallback; interface IAppOpsService { // These first methods are also called by native code, so must Loading Loading @@ -49,5 +50,7 @@ interface IAppOpsService { void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages); void removeUser(int userHandle); void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback); void stopWatchingActive(IAppOpsActiveCallback callback); boolean isOperationActive(int code, int uid, String packageName); }
core/java/com/android/internal/util/function/HexConsumer.java 0 → 100644 +28 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util.function; import java.util.function.Consumer; /** * A 6-argument {@link Consumer} * * @hide */ public interface HexConsumer<A, B, C, D, E, F> { void accept(A a, B b, C c, D d, E e, F f); }