WifiServiceImpl: Allow system apps to use legacy API surface

Provide a bypass for system apps to use the legacy API surface.

Bug: 119547807
Test: ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: I9af9d4763d0aba97bce6340baf23b4aabba81547
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 477b24b..aba10b9 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -48,6 +48,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.database.ContentObserver;
@@ -713,6 +714,19 @@
                 || checkNetworkStackPermission(pid, uid);
     }
 
+    // Helper method to check if the entity initiating the binder call is a system app.
+    private boolean isSystem(String packageName) {
+        try {
+            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName, 0);
+            return info.isSystemApp() || info.isUpdatedSystemApp();
+        } catch (PackageManager.NameNotFoundException e) {
+            // In case of exception, assume unknown app (more strict checking)
+            // Note: This case will never happen since checkPackage is
+            // called to verify validity before checking App's version.
+        }
+        return false;
+    }
+
     private void enforceNetworkSettingsPermission() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS,
                 "WifiService");
@@ -788,9 +802,9 @@
                 return true;
             }
         } catch (PackageManager.NameNotFoundException e) {
-            // In case of exception, assume known app (more strict checking)
+            // In case of exception, assume unknown app (more strict checking)
             // Note: This case will never happen since checkPackage is
-            // called to verify valididity before checking App's version.
+            // called to verify validity before checking App's version.
         }
         return false;
 
@@ -802,7 +816,10 @@
      * Note: Invoke mAppOps.checkPackage(uid, packageName) before to ensure correct package name.
      */
     private boolean isTargetSdkLessThanQOrPrivileged(String packageName, int pid, int uid) {
-        return isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q) ||  isPrivileged(pid, uid);
+        return isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q)
+                || isPrivileged(pid, uid)
+                // TODO: Remove this system app bypass once Q is released.
+                || isSystem(packageName);
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 27c2421..5b90686 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -2893,6 +2893,24 @@
     }
 
     /**
+     * Verify that add or update networks is allowed for system apps.
+     */
+    @Test
+    public void testAddOrUpdateNetworkIsAllowedForSystemApp() throws Exception {
+        mLooper.dispatchAll();
+        doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+                .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+        mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+        when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+
+        WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+        assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+
+        verifyCheckChangePermission(TEST_PACKAGE_NAME);
+        verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+    }
+
+    /**
      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
      * suggestions.
      */