Loading services/api/current.txt +8 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,14 @@ package com.android.server.am { } package com.android.server.appop { public interface AppOpsManagerLocal { method public boolean isUidInForeground(int); } } package com.android.server.pm { public interface PackageManagerLocal { Loading services/core/java/com/android/server/appop/AppOpsManagerLocal.java 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.server.appop; import android.annotation.SystemApi; /** * In-process app ops API for mainline modules. * * @hide */ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public interface AppOpsManagerLocal { /** * Determines if the UID is in foreground in the same way as how foreground runtime * permissions work. * * @return Returns {@code true} if the given UID is in the foreground. */ boolean isUidInForeground(int uid); } services/core/java/com/android/server/appop/AppOpsService.java +10 −0 Original line number Diff line number Diff line Loading @@ -978,6 +978,7 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch public void publish() { ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder()); LocalServices.addService(AppOpsManagerInternal.class, mAppOpsManagerInternal); LocalServices.addService(AppOpsManagerLocal.class, new AppOpsManagerLocalImpl()); } /** Handler for work when packages are removed or updated */ Loading Loading @@ -6138,6 +6139,15 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch } } private final class AppOpsManagerLocalImpl implements AppOpsManagerLocal { @Override public boolean isUidInForeground(int uid) { synchronized (AppOpsService.this) { return mUidStateTracker.isUidInForeground(uid); } } } private final class AppOpsManagerInternalImpl extends AppOpsManagerInternal { @Override public void setDeviceAndProfileOwners(SparseIntArray owners) { synchronized (AppOpsService.this) { Loading services/core/java/com/android/server/appop/AppOpsUidStateTracker.java +5 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ interface AppOpsUidStateTracker { */ int getUidState(int uid); /** * Determines if the uid is in foreground. */ boolean isUidInForeground(int uid); /** * Given a uid, code, and mode, resolve any foregroundness to MODE_IGNORED or MODE_ALLOWED */ Loading services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +38 −42 Original line number Diff line number Diff line Loading @@ -24,8 +24,10 @@ import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.ProcessCapability; import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE; Loading Loading @@ -124,67 +126,61 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { @Override public int evalMode(int uid, int code, int mode) { if (mode != AppOpsManager.MODE_FOREGROUND) { if (mode != MODE_FOREGROUND) { return mode; } int uidStateValue; int capability; boolean visibleAppWidget; boolean pendingTop; boolean tempAllowlist; uidStateValue = getUidState(uid); capability = getUidCapability(uid); visibleAppWidget = getUidVisibleAppWidget(uid); pendingTop = mActivityManagerInternal.isPendingTopUid(uid); tempAllowlist = mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid); int result = evalMode(uidStateValue, code, mode, capability, visibleAppWidget, pendingTop, tempAllowlist); mEventLog.logEvalForegroundMode(uid, uidStateValue, capability, code, result); int uidState = getUidState(uid); int uidCapability = getUidCapability(uid); int result = evalModeInternal(uid, code, uidState, uidCapability); mEventLog.logEvalForegroundMode(uid, uidState, uidCapability, code, result); return result; } private static int evalMode(int uidState, int code, int mode, int capability, boolean appWidgetVisible, boolean pendingTop, boolean tempAllowlist) { if (mode != AppOpsManager.MODE_FOREGROUND) { return mode; } private int evalModeInternal(int uid, int code, int uidState, int uidCapability) { if (appWidgetVisible || pendingTop || tempAllowlist) { if (getUidVisibleAppWidget(uid) || mActivityManagerInternal.isPendingTopUid(uid) || mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid)) { return MODE_ALLOWED; } switch (code) { case AppOpsManager.OP_FINE_LOCATION: case AppOpsManager.OP_COARSE_LOCATION: case AppOpsManager.OP_MONITOR_LOCATION: case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION: if ((capability & PROCESS_CAPABILITY_FOREGROUND_LOCATION) == 0) { int opCapability = getOpCapability(code); if (opCapability != PROCESS_CAPABILITY_NONE) { if ((uidCapability & opCapability) == 0) { return MODE_IGNORED; } else { return MODE_ALLOWED; } case OP_CAMERA: if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) == 0) { } if (uidState > AppOpsManager.resolveFirstUnrestrictedUidState(code)) { return MODE_IGNORED; } else { } return MODE_ALLOWED; } private int getOpCapability(int opCode) { switch (opCode) { case AppOpsManager.OP_FINE_LOCATION: case AppOpsManager.OP_COARSE_LOCATION: case AppOpsManager.OP_MONITOR_LOCATION: case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION: return PROCESS_CAPABILITY_FOREGROUND_LOCATION; case OP_CAMERA: return PROCESS_CAPABILITY_FOREGROUND_CAMERA; case OP_RECORD_AUDIO: case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO: if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) == 0) { return MODE_IGNORED; } else { return MODE_ALLOWED; return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; default: return PROCESS_CAPABILITY_NONE; } } if (uidState > AppOpsManager.resolveFirstUnrestrictedUidState(code)) { return MODE_IGNORED; } return MODE_ALLOWED; @Override public boolean isUidInForeground(int uid) { return evalMode(uid, OP_NONE, MODE_FOREGROUND) == MODE_ALLOWED; } @Override Loading Loading
services/api/current.txt +8 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,14 @@ package com.android.server.am { } package com.android.server.appop { public interface AppOpsManagerLocal { method public boolean isUidInForeground(int); } } package com.android.server.pm { public interface PackageManagerLocal { Loading
services/core/java/com/android/server/appop/AppOpsManagerLocal.java 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.server.appop; import android.annotation.SystemApi; /** * In-process app ops API for mainline modules. * * @hide */ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public interface AppOpsManagerLocal { /** * Determines if the UID is in foreground in the same way as how foreground runtime * permissions work. * * @return Returns {@code true} if the given UID is in the foreground. */ boolean isUidInForeground(int uid); }
services/core/java/com/android/server/appop/AppOpsService.java +10 −0 Original line number Diff line number Diff line Loading @@ -978,6 +978,7 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch public void publish() { ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder()); LocalServices.addService(AppOpsManagerInternal.class, mAppOpsManagerInternal); LocalServices.addService(AppOpsManagerLocal.class, new AppOpsManagerLocalImpl()); } /** Handler for work when packages are removed or updated */ Loading Loading @@ -6138,6 +6139,15 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch } } private final class AppOpsManagerLocalImpl implements AppOpsManagerLocal { @Override public boolean isUidInForeground(int uid) { synchronized (AppOpsService.this) { return mUidStateTracker.isUidInForeground(uid); } } } private final class AppOpsManagerInternalImpl extends AppOpsManagerInternal { @Override public void setDeviceAndProfileOwners(SparseIntArray owners) { synchronized (AppOpsService.this) { Loading
services/core/java/com/android/server/appop/AppOpsUidStateTracker.java +5 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ interface AppOpsUidStateTracker { */ int getUidState(int uid); /** * Determines if the uid is in foreground. */ boolean isUidInForeground(int uid); /** * Given a uid, code, and mode, resolve any foregroundness to MODE_IGNORED or MODE_ALLOWED */ Loading
services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +38 −42 Original line number Diff line number Diff line Loading @@ -24,8 +24,10 @@ import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.ProcessCapability; import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE; Loading Loading @@ -124,67 +126,61 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { @Override public int evalMode(int uid, int code, int mode) { if (mode != AppOpsManager.MODE_FOREGROUND) { if (mode != MODE_FOREGROUND) { return mode; } int uidStateValue; int capability; boolean visibleAppWidget; boolean pendingTop; boolean tempAllowlist; uidStateValue = getUidState(uid); capability = getUidCapability(uid); visibleAppWidget = getUidVisibleAppWidget(uid); pendingTop = mActivityManagerInternal.isPendingTopUid(uid); tempAllowlist = mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid); int result = evalMode(uidStateValue, code, mode, capability, visibleAppWidget, pendingTop, tempAllowlist); mEventLog.logEvalForegroundMode(uid, uidStateValue, capability, code, result); int uidState = getUidState(uid); int uidCapability = getUidCapability(uid); int result = evalModeInternal(uid, code, uidState, uidCapability); mEventLog.logEvalForegroundMode(uid, uidState, uidCapability, code, result); return result; } private static int evalMode(int uidState, int code, int mode, int capability, boolean appWidgetVisible, boolean pendingTop, boolean tempAllowlist) { if (mode != AppOpsManager.MODE_FOREGROUND) { return mode; } private int evalModeInternal(int uid, int code, int uidState, int uidCapability) { if (appWidgetVisible || pendingTop || tempAllowlist) { if (getUidVisibleAppWidget(uid) || mActivityManagerInternal.isPendingTopUid(uid) || mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid)) { return MODE_ALLOWED; } switch (code) { case AppOpsManager.OP_FINE_LOCATION: case AppOpsManager.OP_COARSE_LOCATION: case AppOpsManager.OP_MONITOR_LOCATION: case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION: if ((capability & PROCESS_CAPABILITY_FOREGROUND_LOCATION) == 0) { int opCapability = getOpCapability(code); if (opCapability != PROCESS_CAPABILITY_NONE) { if ((uidCapability & opCapability) == 0) { return MODE_IGNORED; } else { return MODE_ALLOWED; } case OP_CAMERA: if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) == 0) { } if (uidState > AppOpsManager.resolveFirstUnrestrictedUidState(code)) { return MODE_IGNORED; } else { } return MODE_ALLOWED; } private int getOpCapability(int opCode) { switch (opCode) { case AppOpsManager.OP_FINE_LOCATION: case AppOpsManager.OP_COARSE_LOCATION: case AppOpsManager.OP_MONITOR_LOCATION: case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION: return PROCESS_CAPABILITY_FOREGROUND_LOCATION; case OP_CAMERA: return PROCESS_CAPABILITY_FOREGROUND_CAMERA; case OP_RECORD_AUDIO: case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO: if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) == 0) { return MODE_IGNORED; } else { return MODE_ALLOWED; return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; default: return PROCESS_CAPABILITY_NONE; } } if (uidState > AppOpsManager.resolveFirstUnrestrictedUidState(code)) { return MODE_IGNORED; } return MODE_ALLOWED; @Override public boolean isUidInForeground(int uid) { return evalMode(uid, OP_NONE, MODE_FOREGROUND) == MODE_ALLOWED; } @Override Loading