Add an API hint for metered multipath traffic.
This allows an application that knows how to provide seamless network connectivity (e.g., using QUIC multipath) to find out if doing so is desired. Test: builds, boots, runtest frameworks-net passes. Bug: 34630278 Change-Id: Ic7fd0b9e1cd879fdfaf84009d7125391895e9087
This commit is contained in:
@@ -2882,6 +2882,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMultipathPreference(Network network) {
|
||||
enforceAccessPermission();
|
||||
|
||||
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||
if (nai != null && !nai.networkInfo.isMetered()) {
|
||||
return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
|
||||
}
|
||||
|
||||
return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
|
||||
}
|
||||
|
||||
private class InternalHandler extends Handler {
|
||||
public InternalHandler(Looper looper) {
|
||||
super(looper);
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -29,10 +30,14 @@ import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.R;
|
||||
|
||||
import static android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI;
|
||||
import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
|
||||
|
||||
/**
|
||||
* A class to encapsulate management of the "Smart Networking" capability of
|
||||
@@ -57,12 +62,13 @@ public class MultinetworkPolicyTracker {
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final Runnable mReevaluateRunnable;
|
||||
private final Uri mAvoidBadWifiUri;
|
||||
private final List<Uri> mSettingsUris;
|
||||
private final ContentResolver mResolver;
|
||||
private final SettingObserver mSettingObserver;
|
||||
private final BroadcastReceiver mBroadcastReceiver;
|
||||
|
||||
private volatile boolean mAvoidBadWifi = true;
|
||||
private volatile int mMeteredMultipathPreference;
|
||||
|
||||
public MultinetworkPolicyTracker(Context ctx, Handler handler) {
|
||||
this(ctx, handler, null);
|
||||
@@ -72,9 +78,14 @@ public class MultinetworkPolicyTracker {
|
||||
mContext = ctx;
|
||||
mHandler = handler;
|
||||
mReevaluateRunnable = () -> {
|
||||
if (updateAvoidBadWifi() && avoidBadWifiCallback != null) avoidBadWifiCallback.run();
|
||||
if (updateAvoidBadWifi() && avoidBadWifiCallback != null) {
|
||||
avoidBadWifiCallback.run();
|
||||
}
|
||||
updateMeteredMultipathPreference();
|
||||
};
|
||||
mAvoidBadWifiUri = Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI);
|
||||
mSettingsUris = Arrays.asList(
|
||||
Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI),
|
||||
Settings.Global.getUriFor(NETWORK_METERED_MULTIPATH_PREFERENCE));
|
||||
mResolver = mContext.getContentResolver();
|
||||
mSettingObserver = new SettingObserver();
|
||||
mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@@ -85,10 +96,13 @@ public class MultinetworkPolicyTracker {
|
||||
};
|
||||
|
||||
updateAvoidBadWifi();
|
||||
updateMeteredMultipathPreference();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mResolver.registerContentObserver(mAvoidBadWifiUri, false, mSettingObserver);
|
||||
for (Uri uri : mSettingsUris) {
|
||||
mResolver.registerContentObserver(uri, false, mSettingObserver);
|
||||
}
|
||||
|
||||
final IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
|
||||
@@ -108,6 +122,10 @@ public class MultinetworkPolicyTracker {
|
||||
return mAvoidBadWifi;
|
||||
}
|
||||
|
||||
public int getMeteredMultipathPreference() {
|
||||
return mMeteredMultipathPreference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the device or carrier configuration disables avoiding bad wifi by default.
|
||||
*/
|
||||
@@ -138,6 +156,23 @@ public class MultinetworkPolicyTracker {
|
||||
return mAvoidBadWifi != prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default (device and carrier-dependent) value for metered multipath preference.
|
||||
*/
|
||||
public int configMeteredMultipathPreference() {
|
||||
return mContext.getResources().getInteger(
|
||||
R.integer.config_networkMeteredMultipathPreference);
|
||||
}
|
||||
|
||||
public void updateMeteredMultipathPreference() {
|
||||
String setting = Settings.Global.getString(mResolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
|
||||
try {
|
||||
mMeteredMultipathPreference = Integer.parseInt(setting);
|
||||
} catch (NumberFormatException e) {
|
||||
mMeteredMultipathPreference = configMeteredMultipathPreference();
|
||||
}
|
||||
}
|
||||
|
||||
private class SettingObserver extends ContentObserver {
|
||||
public SettingObserver() {
|
||||
super(null);
|
||||
@@ -150,7 +185,9 @@ public class MultinetworkPolicyTracker {
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
if (!mAvoidBadWifiUri.equals(uri)) return;
|
||||
if (!mSettingsUris.contains(uri)) {
|
||||
Slog.wtf(TAG, "Unexpected settings observation: " + uri);
|
||||
}
|
||||
reevaluate();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user