From 2139fcf34542f7e88de0c07d5e55297c87df5a94 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 6 Jun 2025 18:15:54 +0900 Subject: [PATCH] Fix mobile data preferred on multi-user devices. The mobile data preferred feature stores the list of UIDs in Settings.Secure, which is per-user. But the code only sets, reads and observes the setting for the current user instead of for all users. This does not work on HSUM or automotive. Fix this as follows: - Register the ContentObserver on UserHandle.ALL - Any time the observer fires, read the setting on all current users, and operate on the merged result. - Ensure that the code gets called on ACTION_USER_ADDED and ACTION_USER_REMOVED. Because the code now aggregates the setting for all UIDs, it should just work on single-user devices. It should also work if there are OEM devices that store all UIDs (for all users) in Settings.Secure for user 0. Because the bug is fixed, re-enable the test on automotive. Also fix style nits. Fix: 404186833 Flag: EXEMPT bug fix Test: covered by existing CTS tests Change-Id: I69ad789f1c7c7f3bab04ab8789dfb93ee0de553d --- .../com/android/server/ConnectivityService.java | 15 ++++++++++++--- .../android/net/cts/ConnectivityManagerTest.java | 4 ---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 9acfb7c348..e9dc6b9768 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -2516,7 +2516,7 @@ public class ConnectivityService extends IConnectivityManager.Stub EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); // Watch for mobile data preferred uids changes. - mSettingsObserver.observe( + mSettingsObserver.observeForAllUsers( Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS), EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); @@ -4388,7 +4388,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Note that updating can be skipped here if the list is empty only because no uid // rules are applied before system ready. Normally, the empty uid list means to clear // the uids rules on netd. - if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) { + if (!getMobileDataPreferredUids().isEmpty()) { mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED); } @@ -14971,8 +14971,17 @@ public class ConnectivityService extends IConnectivityManager.Stub return requests; } + private Set getMobileDataPreferredUids() { + Set uids = new ArraySet<>(); + for (UserHandle userHandle : mUserManager.getUserHandles(/* excludeDying= */ true)) { + final Context userContext = mContext.createContextAsUser(userHandle, 0 /* flags */); + uids.addAll(ConnectivitySettingsManager.getMobileDataPreferredUids(userContext)); + } + return uids; + } + private void handleMobileDataPreferredUidsChanged() { - mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext); + mMobileDataPreferredUids = getMobileDataPreferredUids(); removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED); addPerAppDefaultNetworkRequests( createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids)); diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index e25eddb63d..6d5cc5f6f2 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -28,7 +28,6 @@ import static android.Manifest.permission.NETWORK_SETUP_WIZARD; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.READ_DEVICE_CONFIG; import static android.Manifest.permission.TETHER_PRIVILEGED; -import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; import static android.content.pm.PackageManager.FEATURE_BLUETOOTH; import static android.content.pm.PackageManager.FEATURE_ETHERNET; import static android.content.pm.PackageManager.FEATURE_TELEPHONY; @@ -3416,9 +3415,6 @@ public class ConnectivityManagerTest { && mPackageManager.hasSystemFeature(FEATURE_TELEPHONY); assumeTrue("testMobileDataPreferredUidsWithCallback cannot execute" + " unless device supports both WiFi and telephony", canRunTest); - // TODO(b/404186833): re-enable - assumeFalse("testMobileDataPreferredUids is broken on automotive", - mPackageManager.hasSystemFeature(FEATURE_AUTOMOTIVE)); final int uid = mPackageManager.getPackageUid(mContext.getPackageName(), 0 /* flag */); final Set mobileDataPreferredUids =