[Tether13] Move TetheringManager into framework
Move tethering out of ConnectivityService. All client would
use TetheringManager to talk with TetheringService directly.
Bug: 144320246
Test: -build, flash, boot
-atest TetheringTests
Change-Id: Ib051bea724a256f9c4572b566e46ae7b9c4abe6e
This commit is contained in:
@@ -116,6 +116,7 @@ import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkScoreManager;
|
||||
import android.net.NetworkWatchlistManager;
|
||||
import android.net.TestNetworkManager;
|
||||
import android.net.TetheringManager;
|
||||
import android.net.lowpan.ILowpanManager;
|
||||
import android.net.lowpan.LowpanManager;
|
||||
import android.net.nsd.INsdManager;
|
||||
@@ -339,6 +340,17 @@ public final class SystemServiceRegistry {
|
||||
}
|
||||
});
|
||||
|
||||
registerService(Context.TETHERING_SERVICE, TetheringManager.class,
|
||||
new CachedServiceFetcher<TetheringManager>() {
|
||||
@Override
|
||||
public TetheringManager createService(ContextImpl ctx) throws ServiceNotFoundException {
|
||||
IBinder b = ServiceManager.getService(Context.TETHERING_SERVICE);
|
||||
if (b == null) return null;
|
||||
|
||||
return new TetheringManager(ctx, b);
|
||||
}});
|
||||
|
||||
|
||||
registerService(Context.IPSEC_SERVICE, IpSecManager.class,
|
||||
new CachedServiceFetcher<IpSecManager>() {
|
||||
@Override
|
||||
|
||||
@@ -3931,6 +3931,15 @@ public abstract class Context {
|
||||
*/
|
||||
public static final String NETWORK_STACK_SERVICE = "network_stack";
|
||||
|
||||
/**
|
||||
* Use with {@link android.os.ServiceManager.getService()} to retrieve a
|
||||
* {@link ITetheringConnector} IBinder for communicating with the tethering service
|
||||
* @hide
|
||||
* @see TetheringClient
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String TETHERING_SERVICE = "tethering";
|
||||
|
||||
/**
|
||||
* Use with {@link #getSystemService(String)} to retrieve a
|
||||
* {@link android.net.IpSecManager} for encrypting Sockets or Networks with
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -57,7 +58,6 @@ import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
@@ -802,6 +802,7 @@ public class ConnectivityManager {
|
||||
|
||||
private INetworkManagementService mNMService;
|
||||
private INetworkPolicyManager mNPManager;
|
||||
private TetheringManager mTetheringManager;
|
||||
|
||||
/**
|
||||
* Tests if a given integer represents a valid network type.
|
||||
@@ -2339,6 +2340,28 @@ public class ConnectivityManager {
|
||||
return getInstanceOrNull();
|
||||
}
|
||||
|
||||
private static final int TETHERING_TIMEOUT_MS = 60_000;
|
||||
private final Object mTetheringLock = new Object();
|
||||
|
||||
private TetheringManager getTetheringManager() {
|
||||
synchronized (mTetheringLock) {
|
||||
if (mTetheringManager != null) {
|
||||
return mTetheringManager;
|
||||
}
|
||||
final long before = System.currentTimeMillis();
|
||||
while ((mTetheringManager = (TetheringManager) mContext.getSystemService(
|
||||
Context.TETHERING_SERVICE)) == null) {
|
||||
if (System.currentTimeMillis() - before > TETHERING_TIMEOUT_MS) {
|
||||
Log.e(TAG, "Timeout waiting tethering service not ready yet");
|
||||
throw new IllegalStateException("No tethering service yet");
|
||||
}
|
||||
SystemClock.sleep(100);
|
||||
}
|
||||
|
||||
return mTetheringManager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of tetherable, available interfaces. This list is limited by
|
||||
* device configuration and current interface existence.
|
||||
@@ -2350,11 +2373,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public String[] getTetherableIfaces() {
|
||||
try {
|
||||
return mService.getTetherableIfaces();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetherableIfaces();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2367,11 +2386,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public String[] getTetheredIfaces() {
|
||||
try {
|
||||
return mService.getTetheredIfaces();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetheredIfaces();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2390,11 +2405,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public String[] getTetheringErroredIfaces() {
|
||||
try {
|
||||
return mService.getTetheringErroredIfaces();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetheringErroredIfaces();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2405,11 +2416,7 @@ public class ConnectivityManager {
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
|
||||
public String[] getTetheredDhcpRanges() {
|
||||
try {
|
||||
return mService.getTetheredDhcpRanges();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetheredDhcpRanges();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2438,13 +2445,7 @@ public class ConnectivityManager {
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public int tether(String iface) {
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "tether caller:" + pkgName);
|
||||
return mService.tether(iface, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().tether(iface);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2467,13 +2468,7 @@ public class ConnectivityManager {
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public int untether(String iface) {
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "untether caller:" + pkgName);
|
||||
return mService.untether(iface, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().untether(iface);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2498,16 +2493,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
|
||||
android.Manifest.permission.WRITE_SETTINGS})
|
||||
public boolean isTetheringSupported() {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
try {
|
||||
return mService.isTetheringSupported(pkgName);
|
||||
} catch (SecurityException e) {
|
||||
// This API is not available to this caller, but for backward-compatibility
|
||||
// this will just return false instead of throwing.
|
||||
return false;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().isTetheringSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2576,14 +2562,7 @@ public class ConnectivityManager {
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "startTethering caller:" + pkgName);
|
||||
mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception trying to start tethering.", e);
|
||||
wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
|
||||
}
|
||||
getTetheringManager().startTethering(type, wrappedCallback, showProvisioningUi);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2599,13 +2578,7 @@ public class ConnectivityManager {
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void stopTethering(int type) {
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "stopTethering caller:" + pkgName);
|
||||
mService.stopTethering(type, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
getTetheringManager().stopTethering(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2627,10 +2600,6 @@ public class ConnectivityManager {
|
||||
public void onUpstreamChanged(@Nullable Network network) {}
|
||||
}
|
||||
|
||||
@GuardedBy("mTetheringEventCallbacks")
|
||||
private final ArrayMap<OnTetheringEventCallback, ITetheringEventCallback>
|
||||
mTetheringEventCallbacks = new ArrayMap<>();
|
||||
|
||||
/**
|
||||
* Start listening to tethering change events. Any new added callback will receive the last
|
||||
* tethering status right away. If callback is registered when tethering has no upstream or
|
||||
@@ -2648,27 +2617,7 @@ public class ConnectivityManager {
|
||||
@NonNull final OnTetheringEventCallback callback) {
|
||||
Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null.");
|
||||
|
||||
synchronized (mTetheringEventCallbacks) {
|
||||
Preconditions.checkArgument(!mTetheringEventCallbacks.containsKey(callback),
|
||||
"callback was already registered.");
|
||||
ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() {
|
||||
@Override
|
||||
public void onUpstreamChanged(Network network) throws RemoteException {
|
||||
Binder.withCleanCallingIdentity(() ->
|
||||
executor.execute(() -> {
|
||||
callback.onUpstreamChanged(network);
|
||||
}));
|
||||
}
|
||||
};
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "registerTetheringUpstreamCallback:" + pkgName);
|
||||
mService.registerTetheringEventCallback(remoteCallback, pkgName);
|
||||
mTetheringEventCallbacks.put(callback, remoteCallback);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
getTetheringManager().registerTetheringEventCallback(executor, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2682,17 +2631,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||
public void unregisterTetheringEventCallback(
|
||||
@NonNull final OnTetheringEventCallback callback) {
|
||||
synchronized (mTetheringEventCallbacks) {
|
||||
ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback);
|
||||
Preconditions.checkNotNull(remoteCallback, "callback was not registered.");
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "unregisterTetheringEventCallback:" + pkgName);
|
||||
mService.unregisterTetheringEventCallback(remoteCallback, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
getTetheringManager().unregisterTetheringEventCallback(callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -2709,11 +2648,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public String[] getTetherableUsbRegexs() {
|
||||
try {
|
||||
return mService.getTetherableUsbRegexs();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetherableUsbRegexs();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2729,11 +2664,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public String[] getTetherableWifiRegexs() {
|
||||
try {
|
||||
return mService.getTetherableWifiRegexs();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetherableWifiRegexs();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2749,11 +2680,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public String[] getTetherableBluetoothRegexs() {
|
||||
try {
|
||||
return mService.getTetherableBluetoothRegexs();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getTetherableBluetoothRegexs();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2775,13 +2702,7 @@ public class ConnectivityManager {
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public int setUsbTethering(boolean enable) {
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "setUsbTethering caller:" + pkgName);
|
||||
return mService.setUsbTethering(enable, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().setUsbTethering(enable);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@@ -2829,11 +2750,7 @@ public class ConnectivityManager {
|
||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
@UnsupportedAppUsage
|
||||
public int getLastTetherError(String iface) {
|
||||
try {
|
||||
return mService.getLastTetherError(iface);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return getTetheringManager().getLastTetherError(iface);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -2899,14 +2816,8 @@ public class ConnectivityManager {
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
String pkgName = mContext.getOpPackageName();
|
||||
Log.i(TAG, "getLatestTetheringEntitlementResult:" + pkgName);
|
||||
mService.getLatestTetheringEntitlementResult(type, wrappedListener,
|
||||
showEntitlementUi, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
getTetheringManager().requestLatestTetheringEntitlementResult(type, wrappedListener,
|
||||
showEntitlementUi);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4331,6 +4242,7 @@ public class ConnectivityManager {
|
||||
public void factoryReset() {
|
||||
try {
|
||||
mService.factoryReset();
|
||||
getTetheringManager().stopAllTethering();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package android.net;
|
||||
import android.app.PendingIntent;
|
||||
import android.net.ConnectionInfo;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.ITetheringEventCallback;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
@@ -78,41 +77,31 @@ interface IConnectivityManager
|
||||
|
||||
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
|
||||
|
||||
int tether(String iface, String callerPkg);
|
||||
|
||||
int untether(String iface, String callerPkg);
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = 29,
|
||||
publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative")
|
||||
int getLastTetherError(String iface);
|
||||
|
||||
boolean isTetheringSupported(String callerPkg);
|
||||
|
||||
void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
|
||||
String callerPkg);
|
||||
|
||||
void stopTethering(int type, String callerPkg);
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = 29,
|
||||
publicAlternatives = "Use {@code TetheringManager#getTetherableIfaces} as alternative")
|
||||
String[] getTetherableIfaces();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = 29,
|
||||
publicAlternatives = "Use {@code TetheringManager#getTetheredIfaces} as alternative")
|
||||
String[] getTetheredIfaces();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = 29,
|
||||
publicAlternatives = "Use {@code TetheringManager#getTetheringErroredIfaces} "
|
||||
+ "as Alternative")
|
||||
String[] getTetheringErroredIfaces();
|
||||
|
||||
String[] getTetheredDhcpRanges();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = 29,
|
||||
publicAlternatives = "Use {@code TetheringManager#getTetherableUsbRegexs} as alternative")
|
||||
String[] getTetherableUsbRegexs();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = 29,
|
||||
publicAlternatives = "Use {@code TetheringManager#getTetherableWifiRegexs} as alternative")
|
||||
String[] getTetherableWifiRegexs();
|
||||
|
||||
String[] getTetherableBluetoothRegexs();
|
||||
|
||||
int setUsbTethering(boolean enable, String callerPkg);
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = 28)
|
||||
void reportInetCondition(int networkType, int percentage);
|
||||
|
||||
@@ -217,11 +206,5 @@ interface IConnectivityManager
|
||||
boolean isCallerCurrentAlwaysOnVpnApp();
|
||||
boolean isCallerCurrentAlwaysOnVpnLockdownApp();
|
||||
|
||||
void getLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
|
||||
boolean showEntitlementUi, String callerPkg);
|
||||
|
||||
void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
|
||||
void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
|
||||
|
||||
IBinder startOrGetTestNetworkService();
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.net.Network;
|
||||
|
||||
/**
|
||||
* Callback class for receiving tethering changed events
|
||||
* @hide
|
||||
*/
|
||||
oneway interface ITetheringEventCallback
|
||||
{
|
||||
void onUpstreamChanged(in Network network);
|
||||
}
|
||||
@@ -9563,35 +9563,37 @@ public final class Settings {
|
||||
*/
|
||||
public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
|
||||
|
||||
/**
|
||||
* Used to select TCP's default initial receiver window size in segments - defaults to a build config value
|
||||
* @hide
|
||||
*/
|
||||
public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
|
||||
/**
|
||||
* Used to select TCP's default initial receiver window size in segments - defaults to a
|
||||
* build config value.
|
||||
* @hide
|
||||
*/
|
||||
public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
|
||||
|
||||
/**
|
||||
* Used to disable Tethering on a device - defaults to true
|
||||
* @hide
|
||||
*/
|
||||
public static final String TETHER_SUPPORTED = "tether_supported";
|
||||
/**
|
||||
* Used to disable Tethering on a device - defaults to true.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String TETHER_SUPPORTED = "tether_supported";
|
||||
|
||||
/**
|
||||
* Used to require DUN APN on the device or not - defaults to a build config value
|
||||
* which defaults to false
|
||||
* @hide
|
||||
*/
|
||||
public static final String TETHER_DUN_REQUIRED = "tether_dun_required";
|
||||
/**
|
||||
* Used to require DUN APN on the device or not - defaults to a build config value
|
||||
* which defaults to false.
|
||||
* @hide
|
||||
*/
|
||||
public static final String TETHER_DUN_REQUIRED = "tether_dun_required";
|
||||
|
||||
/**
|
||||
* Used to hold a gservices-provisioned apn value for DUN. If set, or the
|
||||
* corresponding build config values are set it will override the APN DB
|
||||
* values.
|
||||
* Consists of a comma seperated list of strings:
|
||||
* "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
|
||||
* note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
|
||||
* @hide
|
||||
*/
|
||||
public static final String TETHER_DUN_APN = "tether_dun_apn";
|
||||
/**
|
||||
* Used to hold a gservices-provisioned apn value for DUN. If set, or the
|
||||
* corresponding build config values are set it will override the APN DB
|
||||
* values.
|
||||
* Consists of a comma separated list of strings:
|
||||
* "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
|
||||
* note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
|
||||
* @hide
|
||||
*/
|
||||
public static final String TETHER_DUN_APN = "tether_dun_apn";
|
||||
|
||||
/**
|
||||
* Used to disable trying to talk to any available tethering offload HAL.
|
||||
|
||||
Reference in New Issue
Block a user