diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index cfbd948db9..2a985e703a 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -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. + *
+ * 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
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b123c28f64..425e494078 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -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);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a81e6b755f..8223cdf158 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2835,6 +2835,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);
diff --git a/services/net/java/android/net/util/MultinetworkPolicyTracker.java b/services/net/java/android/net/util/MultinetworkPolicyTracker.java
index ebd131bebb..424e40d209 100644
--- a/services/net/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/services/net/java/android/net/util/MultinetworkPolicyTracker.java
@@ -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