Give the location mode exemption for emergency location service

Due to the AppOpsManager disallow the privileged apps to bypass location
restriction, for ELS use case give the bypass from Wifi stack

Bug: 231657841
Test: atest com.android.server.wifi
Test: gts WifiHostTest
Change-Id: Ice55cbe9524e6d3526210861ad9c431df7255d99
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 57dd17f..2e601e6 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -423,7 +423,7 @@
      */
     public void enforceFineLocationPermission(String pkgName, @Nullable String featureId,
             int uid) {
-        if (!checkCallersFineLocationPermission(pkgName, featureId, uid, false)) {
+        if (!checkCallersFineLocationPermission(pkgName, featureId, uid, false, false)) {
             throw new SecurityException("UID " + uid + " does not have Fine Location permission");
         }
     }
@@ -438,22 +438,28 @@
      * @param hideFromAppOps True to invoke {@link AppOpsManager#checkOp(int, int, String)}, false
      *                       to invoke {@link AppOpsManager#noteOp(String, int, String, String,
      *                       String)}.
+     * @param ignoreLocationSettings Whether this request can bypass location settings.
      */
     private boolean checkCallersFineLocationPermission(String pkgName, @Nullable String featureId,
-            int uid, boolean hideFromAppOps) {
+            int uid, boolean hideFromAppOps, boolean ignoreLocationSettings) {
         // Having FINE permission implies having COARSE permission (but not the reverse)
         if (mWifiPermissionsWrapper.getUidPermission(
                 ACCESS_FINE_LOCATION, uid)
                 == PackageManager.PERMISSION_DENIED) {
             return false;
         }
+
+        boolean isAllowed;
         if (hideFromAppOps) {
             // Don't note the operation, just check if the app is allowed to perform the operation.
-            return checkAppOpAllowed(AppOpsManager.OPSTR_FINE_LOCATION, pkgName, uid);
+            isAllowed = checkAppOpAllowed(AppOpsManager.OPSTR_FINE_LOCATION, pkgName, uid);
         } else {
-            return noteAppOpAllowed(AppOpsManager.OPSTR_FINE_LOCATION, pkgName, featureId, uid,
+            isAllowed = noteAppOpAllowed(AppOpsManager.OPSTR_FINE_LOCATION, pkgName, featureId, uid,
                     null);
         }
+        // If the ignoreLocationSettings is true, we always return true. This is for the emergency
+        // location service use case. But still notify the operation manager.
+        return isAllowed || ignoreLocationSettings;
     }
 
     /**
@@ -613,8 +619,8 @@
         }
         // LocationAccess by App: caller must have fine & hardware Location permission to have
         // access to location information.
-        if (!checkCallersFineLocationPermission(pkgName, featureId, uid, hideFromAppOps)
-                || !checkCallersHardwareLocationPermission(uid)) {
+        if (!checkCallersFineLocationPermission(pkgName, featureId, uid, hideFromAppOps,
+                ignoreLocationSettings) || !checkCallersHardwareLocationPermission(uid)) {
             throw new SecurityException("UID " + uid + " has no location permission");
         }
         // Check if Wifi Scan request is an operation allowed for this App.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
index 786289d..0e1d9b1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
@@ -1117,7 +1117,7 @@
      * Validate no Exceptions are thrown - has all permissions & don't note in app-ops.
      */
     @Test
-    public void testCannotAccessScanResultsForWifiScanner_HideFromAppOps()
+    public void testCanAccessScanResultsForWifiScanner_HideFromAppOps()
             throws Exception {
         mThrowSecurityException = false;
         mIsLocationEnabled = true;
@@ -1290,13 +1290,13 @@
      * Validate no Exceptions are thrown - has all permissions & ignores location settings.
      */
     @Test
-    public void testCannotAccessScanResultsForWifiScanner_IgnoreLocationSettings()
+    public void testCanAccessScanResultsForWifiScanner_IgnoreLocationSettings()
             throws Exception {
         mThrowSecurityException = false;
         mIsLocationEnabled = false;
         mFineLocationPermission = PackageManager.PERMISSION_GRANTED;
         mHardwareLocationPermission = PackageManager.PERMISSION_GRANTED;
-        mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED;
+        mAllowFineLocationApps = AppOpsManager.MODE_IGNORED;
         mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
         mUid = MANAGED_PROFILE_UID;
         setupTestCase();
@@ -1304,6 +1304,8 @@
                 mMockContext, mMockUserManager, mWifiInjector);
         codeUnderTest.enforceCanAccessScanResultsForWifiScanner(TEST_PACKAGE_NAME, TEST_FEATURE_ID,
                 mUid, IGNORE_LOCATION_SETTINGS, DONT_HIDE_FROM_APP_OPS);
+        verify(mMockAppOps).noteOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME,
+                TEST_FEATURE_ID, null);
     }
 
     /**