Merge changes I69ad789f,I5954b196 into main

* changes:
  Fix mobile data preferred on multi-user devices.
  Support multi-user SettingsObservers in ConnectivityService
This commit is contained in:
Treehugger Robot 2025-08-14 00:33:06 -07:00 • committed by Android (Google) Code Review
commit 4c516ffd67

View file

@ -1600,6 +1600,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
cr.registerContentObserver(uri, notifyForDescendants, observer);
}
public void registerContentObserverAsUser(ContentResolver cr, Uri uri,
boolean notifyForDescendants, ContentObserver observer, UserHandle userHandle) {
cr.registerContentObserverAsUser(uri, notifyForDescendants, observer, userHandle);
}
/**
* Get a reference to the ModuleNetworkStackClient.
*/
@ -2518,7 +2523,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);
@ -4390,7 +4395,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);
}
@ -7674,11 +7679,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private static class SettingsObserver extends ContentObserver {
private final HashMap<Uri, Integer> mUriEventMap;
private final HashMap<Uri, SettingInfo> mUriEventMap;
private final Context mContext;
private final Handler mHandler;
private final Dependencies mDeps;
private static class SettingInfo {
final int what;
final boolean forAllUsers;
SettingInfo(int what, boolean forAllUsers) {
this.what = what;
this.forAllUsers = forAllUsers;
}
}
SettingsObserver(Context context, Handler handler, Dependencies deps) {
super(null);
mUriEventMap = new HashMap<>();
@ -7687,9 +7701,50 @@ public class ConnectivityService extends IConnectivityManager.Stub
mDeps = deps;
}
/**
* Observe settings changes for the specified URI on the current user.
*
* Sends an empty message with the specified {@code what} whenever the setting changes on
* the current user.
*
* @param uri The URI to observe.
* @param what The empty message to send whenever the setting changes.
*/
void observe(Uri uri, int what) {
mUriEventMap.put(uri, what);
mDeps.registerContentObserver(mContext.getContentResolver(), uri, false, this);
mUriEventMap.put(uri, new SettingInfo(what, false /* forAllUsers */));
final ContentResolver resolver = mContext.getContentResolver();
mDeps.registerContentObserver(resolver, uri, false, this);
}
/**
* Observe settings changes for the specified URI on all users.
*
* Sends an empty message with the specified {@code what} whenever the setting changes on
* any user, or whenever a user is added or removed.
*
* @param uri The URI to observe.
* @param what The empty message to send whenever the setting changes.
*/
void observeForAllUsers(Uri uri, int what) {
if (!SdkLevel.isAtLeastT()) {
observe(uri, what);
return;
}
mUriEventMap.put(uri, new SettingInfo(what, true /* forAllUsers */));
final ContentResolver resolver = mContext.getContentResolver();
mDeps.registerContentObserverAsUser(resolver, uri, false, this, UserHandle.ALL);
}
void onUsersChanged() {
for (SettingInfo si : mUriEventMap.values()) {
if (si.forAllUsers) {
sendMessage(si.what);
}
}
}
private void sendMessage(int what) {
mHandler.obtainMessage(what).sendToTarget();
}
@Override
@ -7699,13 +7754,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void onChange(boolean selfChange, Uri uri) {
final Integer what = mUriEventMap.get(uri);
if (what != null) {
mHandler.obtainMessage(what).sendToTarget();
final SettingInfo si = mUriEventMap.get(uri);
if (si != null) {
sendMessage(si.what);
} else {
loge("No matching event to send for URI=" + uri);
}
}
@Override
public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
int flags, UserHandle unused) {
for (Uri uri : uris) {
onChange(selfChange, uri);
}
}
}
private static void log(String s) {
@ -8005,6 +8068,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (mSatelliteAccessController != null) {
mSatelliteAccessController.onUserAddedWithInstalledPackageList(user, apps);
}
mSettingsObserver.onUsersChanged();
}
@Override
@ -8023,6 +8087,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (mSatelliteAccessController != null) {
mSatelliteAccessController.onUserRemoved(user);
}
mSettingsObserver.onUsersChanged();
}
@Override
@ -14919,8 +14984,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
return requests;
}
private Set<Integer> getMobileDataPreferredUids() {
Set<Integer> 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));