DO NOT MERGE: Fix a few issues with foreground service location accesses.
Location access should be allowed only when the UID state is higher than
UID_STATE_FOREGROUND_SERVICE_LOCATION. UID_STATE_FOREGROUND_SERVICE
should not have location access.
Also fixed an issue where MONITOR_LOCATION is allowed for location access
from foreground services.
Since UID_STATE_FOREGROUND_SERVICE is considered as background for
location, and foreground for other ops, we cannot simply use UID state
to check the foreground status of an app. Instead, the uid_state <-> op
pair needs to be evaluated together.
Bug: 128520624
Test: Manually run GNSS logger app to verify
Change-Id: I9413e9c6009e38e3d9db57a02e8f0a275119b063
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index c9e7cfa..c7bb8f1 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -341,7 +341,7 @@
int evalMode(int op, int mode) {
if (mode == AppOpsManager.MODE_FOREGROUND) {
- return state <= AppOpsManager.resolveLastRestrictedUidState(op)
+ return state <= AppOpsManager.resolveFirstUnrestrictedUidState(op)
? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
}
return mode;
@@ -915,9 +915,12 @@
if (uidState != null && uidState.pendingState != newState) {
final int oldPendingState = uidState.pendingState;
uidState.pendingState = newState;
- if (newState < uidState.state || newState <= UID_STATE_MAX_LAST_NON_RESTRICTED) {
- // We are moving to a more important state, or the new state is in the
- // foreground, then always do it immediately.
+ if (newState < uidState.state
+ || (newState <= UID_STATE_MAX_LAST_NON_RESTRICTED
+ && uidState.state > UID_STATE_MAX_LAST_NON_RESTRICTED)) {
+ // We are moving to a more important state, or the new state may be in the
+ // foreground and the old state is in the background, then always do it
+ // immediately.
commitUidPendingStateLocked(uidState);
} else if (uidState.pendingStateCommitTime == 0) {
// We are moving to a less important state for the first time,
@@ -2414,9 +2417,7 @@
}
private void commitUidPendingStateLocked(UidState uidState) {
- final boolean lastForeground = uidState.state <= UID_STATE_MAX_LAST_NON_RESTRICTED;
- final boolean nowForeground = uidState.pendingState <= UID_STATE_MAX_LAST_NON_RESTRICTED;
- if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
+ if (uidState.hasForegroundWatchers) {
for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
if (!uidState.foregroundOps.valueAt(fgi)) {
continue;