Merge "Add an API hint for metered multipath traffic."
This commit is contained in:
@@ -23767,6 +23767,7 @@ package android.net {
|
||||
method public android.net.Network getBoundNetworkForProcess();
|
||||
method public android.net.ProxyInfo getDefaultProxy();
|
||||
method public android.net.LinkProperties getLinkProperties(android.net.Network);
|
||||
method public int getMultipathPreference(android.net.Network);
|
||||
method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
|
||||
method public deprecated android.net.NetworkInfo getNetworkInfo(int);
|
||||
method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
|
||||
@@ -23814,6 +23815,9 @@ package android.net {
|
||||
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
|
||||
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
|
||||
field public static final java.lang.String EXTRA_REASON = "reason";
|
||||
field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
|
||||
field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
|
||||
field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
|
||||
|
||||
@@ -25554,6 +25554,7 @@ package android.net {
|
||||
method public java.lang.String getCaptivePortalServerUrl();
|
||||
method public android.net.ProxyInfo getDefaultProxy();
|
||||
method public android.net.LinkProperties getLinkProperties(android.net.Network);
|
||||
method public int getMultipathPreference(android.net.Network);
|
||||
method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
|
||||
method public deprecated android.net.NetworkInfo getNetworkInfo(int);
|
||||
method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
|
||||
@@ -25605,6 +25606,9 @@ package android.net {
|
||||
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
|
||||
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
|
||||
field public static final java.lang.String EXTRA_REASON = "reason";
|
||||
field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
|
||||
field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
|
||||
field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
|
||||
|
||||
@@ -23841,6 +23841,7 @@ package android.net {
|
||||
method public android.net.Network getBoundNetworkForProcess();
|
||||
method public android.net.ProxyInfo getDefaultProxy();
|
||||
method public android.net.LinkProperties getLinkProperties(android.net.Network);
|
||||
method public int getMultipathPreference(android.net.Network);
|
||||
method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
|
||||
method public deprecated android.net.NetworkInfo getNetworkInfo(int);
|
||||
method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
|
||||
@@ -23888,6 +23889,9 @@ package android.net {
|
||||
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
|
||||
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
|
||||
field public static final java.lang.String EXTRA_REASON = "reason";
|
||||
field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
|
||||
field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
|
||||
field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
|
||||
field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
|
||||
|
||||
@@ -3406,6 +3406,75 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It is acceptable to briefly use multipath data to provide seamless connectivity for
|
||||
* time-sensitive user-facing operations when the system default network is temporarily
|
||||
* unresponsive. The amount of data should be limited (less than one megabyte), and the
|
||||
* operation should be infrequent to ensure that data usage is limited.
|
||||
*
|
||||
* An example of such an operation might be a time-sensitive foreground activity, such as a
|
||||
* voice command, that the user is performing while walking out of range of a Wi-Fi network.
|
||||
*/
|
||||
public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0;
|
||||
|
||||
/**
|
||||
* It is acceptable to use small amounts of multipath data on an ongoing basis to provide
|
||||
* a backup channel for traffic that is primarily going over another network.
|
||||
*
|
||||
* An example might be maintaining backup connections to peers or servers for the purpose of
|
||||
* fast fallback if the default network is temporarily unresponsive or disconnects. The traffic
|
||||
* on backup paths should be negligible compared to the traffic on the main path.
|
||||
*/
|
||||
public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1;
|
||||
|
||||
/**
|
||||
* It is acceptable to use metered data to improve network latency and performance.
|
||||
*/
|
||||
public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2;
|
||||
|
||||
/**
|
||||
* Return value to use for unmetered networks. On such networks we currently set all the flags
|
||||
* to true.
|
||||
* @hide
|
||||
*/
|
||||
public static final int MULTIPATH_PREFERENCE_UNMETERED =
|
||||
MULTIPATH_PREFERENCE_HANDOVER |
|
||||
MULTIPATH_PREFERENCE_RELIABILITY |
|
||||
MULTIPATH_PREFERENCE_PERFORMANCE;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, value = {
|
||||
MULTIPATH_PREFERENCE_HANDOVER,
|
||||
MULTIPATH_PREFERENCE_RELIABILITY,
|
||||
MULTIPATH_PREFERENCE_PERFORMANCE,
|
||||
})
|
||||
public @interface MultipathPreference {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a hint to the calling application on whether it is desirable to use the
|
||||
* multinetwork APIs (e.g., {@link Network#openConnection}, {@link Network#bindSocket}, etc.)
|
||||
* for multipath data transfer on this network when it is not the system default network.
|
||||
* Applications desiring to use multipath network protocols should call this method before
|
||||
* each such operation.
|
||||
* <p>
|
||||
* This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
|
||||
*
|
||||
* @param network The network on which the application desires to use multipath data.
|
||||
* If {@code null}, this method will return the a preference that will generally
|
||||
* apply to metered networks.
|
||||
* @return a bitwise OR of zero or more of the {@code MULTIPATH_PREFERENCE_*} constants.
|
||||
*/
|
||||
public @MultipathPreference int getMultipathPreference(Network network) {
|
||||
try {
|
||||
return mService.getMultipathPreference(network);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all connectivity manager settings back to factory defaults.
|
||||
* @hide
|
||||
|
||||
@@ -161,6 +161,8 @@ interface IConnectivityManager
|
||||
void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
|
||||
void setAvoidUnvalidated(in Network network);
|
||||
|
||||
int getMultipathPreference(in Network Network);
|
||||
|
||||
int getRestoreDefaultNetworkDelay(int networkType);
|
||||
|
||||
boolean addVpnAddress(String address, int prefixLength);
|
||||
|
||||
@@ -7581,6 +7581,16 @@ public final class Settings {
|
||||
*/
|
||||
public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
|
||||
|
||||
/**
|
||||
* User setting for ConnectivityManager.getMeteredMultipathPreference(). This value may be
|
||||
* overridden by the system based on device or application state. If null, the value
|
||||
* specified by config_networkMeteredMultipathPreference is used.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
|
||||
"network_metered_multipath_preference";
|
||||
|
||||
/**
|
||||
* Whether Wifi display is enabled/disabled
|
||||
* 0=disabled. 1=enabled.
|
||||
|
||||
@@ -281,6 +281,11 @@
|
||||
Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
|
||||
<integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
|
||||
|
||||
<!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual
|
||||
device behaviour is controlled by Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE.
|
||||
This is the default value of that setting. -->
|
||||
<integer translatable="false" name="config_networkMeteredMultipathPreference">3</integer>
|
||||
|
||||
<!-- List of regexpressions describing the interface (if any) that represent tetherable
|
||||
USB interfaces. If the device doesn't want to support tethering over USB this should
|
||||
be empty. An example would be "usb.*" -->
|
||||
|
||||
@@ -1784,6 +1784,7 @@
|
||||
<java-symbol type="integer" name="config_networkNotifySwitchType" />
|
||||
<java-symbol type="array" name="config_networkNotifySwitches" />
|
||||
<java-symbol type="integer" name="config_networkAvoidBadWifi" />
|
||||
<java-symbol type="integer" name="config_networkMeteredMultipathPreference" />
|
||||
<java-symbol type="integer" name="config_notificationsBatteryFullARGB" />
|
||||
<java-symbol type="integer" name="config_notificationsBatteryLedOff" />
|
||||
<java-symbol type="integer" name="config_notificationsBatteryLedOn" />
|
||||
|
||||
@@ -2838,6 +2838,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,6 +632,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
|
||||
private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker {
|
||||
public volatile boolean configRestrictsAvoidBadWifi;
|
||||
public volatile int configMeteredMultipathPreference;
|
||||
|
||||
public WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
|
||||
super(c, h, r);
|
||||
@@ -641,6 +642,11 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
public boolean configRestrictsAvoidBadWifi() {
|
||||
return configRestrictsAvoidBadWifi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int configMeteredMultipathPreference() {
|
||||
return configMeteredMultipathPreference;
|
||||
}
|
||||
}
|
||||
|
||||
private class WrappedConnectivityService extends ConnectivityService {
|
||||
@@ -2454,6 +2460,26 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
mCm.unregisterNetworkCallback(defaultCallback);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testMeteredMultipathPreferenceSetting() throws Exception {
|
||||
final ContentResolver cr = mServiceContext.getContentResolver();
|
||||
final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
|
||||
final String settingName = Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
|
||||
|
||||
for (int config : Arrays.asList(0, 3, 2)) {
|
||||
for (String setting: Arrays.asList(null, "0", "2", "1")) {
|
||||
tracker.configMeteredMultipathPreference = config;
|
||||
Settings.Global.putString(cr, settingName, setting);
|
||||
tracker.reevaluate();
|
||||
mService.waitForIdle();
|
||||
|
||||
final int expected = (setting != null) ? Integer.parseInt(setting) : config;
|
||||
String msg = String.format("config=%d, setting=%s", config, setting);
|
||||
assertEquals(msg, expected, mCm.getMultipathPreference(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a satisfied network request does not trigger onUnavailable() once the
|
||||
* time-out period expires.
|
||||
|
||||
Reference in New Issue
Block a user