diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 7d1644ed3b..1837b8426c 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -969,6 +969,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // Flag to optimize closing frozen app sockets by waiting for the cellular modem to wake up. private final boolean mDelayDestroyFrozenSockets; + // Flag to allow SysUI to receive connectivity reports for wifi picker UI. + private final boolean mAllowSysUiConnectivityReports; + // Uids that ConnectivityService is pending to close sockets of. private final Set mPendingFrozenUids = new ArraySet<>(); @@ -1468,6 +1471,13 @@ public class ConnectivityService extends IConnectivityManager.Stub return DeviceConfigUtils.isTetheringFeatureEnabled(context, name); } + /** + * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut + */ + public boolean isFeatureNotChickenedOut(Context context, String name) { + return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, name); + } + /** * Get the BpfNetMaps implementation to use in ConnectivityService. * @param netd a netd binder @@ -1835,6 +1845,8 @@ public class ConnectivityService extends IConnectivityManager.Stub && mDeps.isFeatureEnabled(context, KEY_DESTROY_FROZEN_SOCKETS_VERSION); mDelayDestroyFrozenSockets = mDeps.isAtLeastU() && mDeps.isFeatureEnabled(context, DELAY_DESTROY_FROZEN_SOCKETS_VERSION); + mAllowSysUiConnectivityReports = mDeps.isFeatureNotChickenedOut( + mContext, ALLOW_SYSUI_CONNECTIVITY_REPORTS); if (mDestroyFrozenSockets) { final UidFrozenStateChangedCallback frozenStateChangedCallback = new UidFrozenStateChangedCallback() { @@ -3297,6 +3309,10 @@ public class ConnectivityService extends IConnectivityManager.Stub static final String DELAY_DESTROY_FROZEN_SOCKETS_VERSION = "delay_destroy_frozen_sockets_version"; + @VisibleForTesting + public static final String ALLOW_SYSUI_CONNECTIVITY_REPORTS = + "allow_sysui_connectivity_reports"; + private void enforceInternetPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERNET, @@ -3460,6 +3476,11 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); } + private boolean checkSystemBarServicePermission(int pid, int uid) { + return checkAnyPermissionOf(mContext, pid, uid, + android.Manifest.permission.STATUS_BAR_SERVICE); + } + private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) { return checkAnyPermissionOf(mContext, pid, uid, android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, @@ -11581,6 +11602,10 @@ public class ConnectivityService extends IConnectivityManager.Stub if (checkNetworkStackPermission(callbackPid, callbackUid)) { return true; } + if (mAllowSysUiConnectivityReports + && checkSystemBarServicePermission(callbackPid, callbackUid)) { + return true; + } // Administrator UIDs also contains the Owner UID final int[] administratorUids = nai.networkCapabilities.getAdministratorUids(); diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index bafd450ff3..97e134adab 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -31,6 +31,7 @@ import static android.Manifest.permission.NETWORK_SETUP_WIZARD; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; import static android.Manifest.permission.READ_DEVICE_CONFIG; +import static android.Manifest.permission.STATUS_BAR_SERVICE; import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN; import static android.app.PendingIntent.FLAG_IMMUTABLE; @@ -157,6 +158,7 @@ import static android.system.OsConstants.IPPROTO_TCP; import static com.android.server.ConnectivityService.DELAY_DESTROY_FROZEN_SOCKETS_VERSION; import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME; +import static com.android.server.ConnectivityService.ALLOW_SYSUI_CONNECTIVITY_REPORTS; import static com.android.server.ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION; import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID; import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED; @@ -2150,6 +2152,16 @@ public class ConnectivityServiceTest { } } + @Override + public boolean isFeatureNotChickenedOut(Context context, String name) { + switch (name) { + case ALLOW_SYSUI_CONNECTIVITY_REPORTS: + return true; + default: + return super.isFeatureNotChickenedOut(context, name); + } + } + public void setChangeIdEnabled(final boolean enabled, final long changeId, final int uid) { final Pair data = new Pair<>(changeId, uid); // mEnabledChangeIds is read on the handler thread and maybe the test thread, so @@ -12809,6 +12821,18 @@ public class ConnectivityServiceTest { mContext.getOpPackageName())); } + @Test + public void testCheckConnectivityDiagnosticsPermissionsSysUi() throws Exception { + final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); + + mServiceContext.setPermission(STATUS_BAR_SERVICE, PERMISSION_GRANTED); + assertTrue( + "SysUi permission (STATUS_BAR_SERVICE) not applied", + mService.checkConnectivityDiagnosticsPermissions( + Process.myPid(), Process.myUid(), naiWithoutUid, + mContext.getOpPackageName())); + } + @Test public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { final int wrongUid = Process.myUid() + 1; diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt index 0ccbfc3e80..1786edcec0 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt @@ -127,6 +127,7 @@ open class CSTest { it[ConnectivityFlags.NO_REMATCH_ALL_REQUESTS_ON_REGISTER] = true it[ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION] = true it[ConnectivityService.DELAY_DESTROY_FROZEN_SOCKETS_VERSION] = true + it[ConnectivityService.ALLOW_SYSUI_CONNECTIVITY_REPORTS] = true } fun enableFeature(f: String) = enabledFeatures.set(f, true) fun disableFeature(f: String) = enabledFeatures.set(f, false) @@ -195,6 +196,8 @@ open class CSTest { // checking permissions. override fun isFeatureEnabled(context: Context?, name: String?) = enabledFeatures[name] ?: fail("Unmocked feature $name, see CSTest.enabledFeatures") + override fun isFeatureNotChickenedOut(context: Context?, name: String?) = + enabledFeatures[name] ?: fail("Unmocked feature $name, see CSTest.enabledFeatures") // Mocked change IDs private val enabledChangeIds = ArraySet()