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;