Merge commit '0b62467b142b61ee1e449ba958ba37dfd961ef56' into HEAD
This commit is contained in:
@@ -395,6 +395,8 @@ public class ConnectivityManager {
|
||||
|
||||
private final IConnectivityManager mService;
|
||||
|
||||
private final String mPackageName;
|
||||
|
||||
/**
|
||||
* Tests if a given integer represents a valid network type.
|
||||
* @param networkType the type to be tested
|
||||
@@ -802,7 +804,7 @@ public class ConnectivityManager {
|
||||
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
|
||||
byte[] address = hostAddress.getAddress();
|
||||
try {
|
||||
return mService.requestRouteToHostAddress(networkType, address);
|
||||
return mService.requestRouteToHostAddress(networkType, address, mPackageName);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
@@ -898,8 +900,9 @@ public class ConnectivityManager {
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public ConnectivityManager(IConnectivityManager service) {
|
||||
public ConnectivityManager(IConnectivityManager service, String packageName) {
|
||||
mService = checkNotNull(service, "missing IConnectivityManager");
|
||||
mPackageName = checkNotNull(packageName, "missing package name");
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
|
||||
@@ -71,9 +71,9 @@ interface IConnectivityManager
|
||||
|
||||
int stopUsingNetworkFeature(int networkType, in String feature);
|
||||
|
||||
boolean requestRouteToHost(int networkType, int hostAddress);
|
||||
boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
|
||||
|
||||
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
|
||||
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
|
||||
|
||||
boolean getMobileDataEnabled();
|
||||
void setMobileDataEnabled(boolean enabled);
|
||||
|
||||
@@ -32,6 +32,7 @@ import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
|
||||
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
@@ -43,7 +44,9 @@ import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
@@ -412,6 +415,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
|
||||
private SettingsObserver mSettingsObserver;
|
||||
|
||||
private AppOpsManager mAppOpsManager;
|
||||
|
||||
NetworkConfig[] mNetConfigs;
|
||||
int mNetworksDefined;
|
||||
|
||||
@@ -695,6 +700,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
|
||||
mContext.registerReceiver(mProvisioningReceiver, filter);
|
||||
|
||||
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1526,6 +1533,40 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the address falls into any of currently running VPN's route's.
|
||||
*/
|
||||
private boolean isAddressUnderVpn(InetAddress address) {
|
||||
synchronized (mVpns) {
|
||||
synchronized (mRoutesLock) {
|
||||
int uid = UserHandle.getCallingUserId();
|
||||
Vpn vpn = mVpns.get(uid);
|
||||
if (vpn == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if an exemption exists for this address.
|
||||
for (LinkAddress destination : mExemptAddresses) {
|
||||
if (!NetworkUtils.addressTypeMatches(address, destination.getAddress())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int prefix = destination.getNetworkPrefixLength();
|
||||
InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
|
||||
InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
|
||||
prefix);
|
||||
|
||||
if (addrMasked.equals(destMasked)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally check if the address is covered by the VPN.
|
||||
return vpn.isAddressCovered(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use requestRouteToHostAddress instead
|
||||
*
|
||||
@@ -1537,14 +1578,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
* desired
|
||||
* @return {@code true} on success, {@code false} on failure
|
||||
*/
|
||||
public boolean requestRouteToHost(int networkType, int hostAddress) {
|
||||
public boolean requestRouteToHost(int networkType, int hostAddress, String packageName) {
|
||||
InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
|
||||
|
||||
if (inetAddress == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return requestRouteToHostAddress(networkType, inetAddress.getAddress());
|
||||
return requestRouteToHostAddress(networkType, inetAddress.getAddress(), packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1556,11 +1597,40 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
* desired
|
||||
* @return {@code true} on success, {@code false} on failure
|
||||
*/
|
||||
public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
|
||||
public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
|
||||
String packageName) {
|
||||
enforceChangePermission();
|
||||
if (mProtectedNetworks.contains(networkType)) {
|
||||
enforceConnectivityInternalPermission();
|
||||
}
|
||||
boolean exempt;
|
||||
InetAddress addr;
|
||||
try {
|
||||
addr = InetAddress.getByAddress(hostAddress);
|
||||
} catch (UnknownHostException e) {
|
||||
if (DBG) log("requestRouteToHostAddress got " + e.toString());
|
||||
return false;
|
||||
}
|
||||
// System apps may request routes bypassing the VPN to keep other networks working.
|
||||
if (Binder.getCallingUid() == Process.SYSTEM_UID) {
|
||||
exempt = true;
|
||||
} else {
|
||||
mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
|
||||
try {
|
||||
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName,
|
||||
0);
|
||||
exempt = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||
} catch (NameNotFoundException e) {
|
||||
throw new IllegalArgumentException("Failed to find calling package details", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Non-exempt routeToHost's can only be added if the host is not covered by the VPN.
|
||||
// This can be either because the VPN's routes do not cover the destination or a
|
||||
// system application added an exemption that covers this destination.
|
||||
if (!exempt && isAddressUnderVpn(addr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
|
||||
if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
|
||||
@@ -1587,18 +1657,13 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByAddress(hostAddress);
|
||||
LinkProperties lp = tracker.getLinkProperties();
|
||||
boolean ok = addRouteToAddress(lp, addr, EXEMPT);
|
||||
boolean ok = addRouteToAddress(lp, addr, exempt);
|
||||
if (DBG) log("requestRouteToHostAddress ok=" + ok);
|
||||
return ok;
|
||||
} catch (UnknownHostException e) {
|
||||
if (DBG) log("requestRouteToHostAddress got " + e.toString());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
if (DBG) log("requestRouteToHostAddress X bottom return false");
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable,
|
||||
@@ -2308,9 +2373,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
mInetConditionChangeInFlight = false;
|
||||
// Don't do this - if we never sign in stay, grey
|
||||
//reportNetworkCondition(mActiveDefaultNetwork, 100);
|
||||
updateNetworkSettings(thisNet);
|
||||
}
|
||||
thisNet.setTeardownRequested(false);
|
||||
updateNetworkSettings(thisNet);
|
||||
updateMtuSizeSettings(thisNet);
|
||||
handleConnectivityChange(newNetType, false);
|
||||
sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
|
||||
@@ -2695,6 +2760,15 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
}
|
||||
setBufferSize(bufferSizes);
|
||||
}
|
||||
|
||||
final String defaultRwndKey = "net.tcp.default_init_rwnd";
|
||||
int defaultRwndValue = SystemProperties.getInt(defaultRwndKey, 0);
|
||||
Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.TCP_DEFAULT_INIT_RWND, defaultRwndValue);
|
||||
final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd";
|
||||
if (rwndValue != 0) {
|
||||
SystemProperties.set(sysctlKey, rwndValue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3037,7 +3111,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED: {
|
||||
info = (NetworkInfo) msg.obj;
|
||||
int type = info.getType();
|
||||
updateNetworkSettings(mNetTrackers[type]);
|
||||
if (mNetConfigs[type].isDefault()) updateNetworkSettings(mNetTrackers[type]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3596,8 +3670,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
int user = UserHandle.getUserId(Binder.getCallingUid());
|
||||
if (ConnectivityManager.isNetworkTypeValid(type) && mNetTrackers[type] != null) {
|
||||
synchronized(mVpns) {
|
||||
mVpns.get(user).protect(socket,
|
||||
mNetTrackers[type].getLinkProperties().getInterfaceName());
|
||||
mVpns.get(user).protect(socket);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3837,7 +3910,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
boolean forwardDns) {
|
||||
try {
|
||||
mNetd.clearUidRangeRoute(interfaze, uidStart, uidEnd);
|
||||
if (forwardDns) mNetd.clearDnsInterfaceForUidRange(uidStart, uidEnd);
|
||||
if (forwardDns) mNetd.clearDnsInterfaceForUidRange(interfaze, uidStart, uidEnd);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
|
||||
@@ -3992,6 +4065,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
*/
|
||||
private static final int CMP_RESULT_CODE_PROVISIONING_NETWORK = 5;
|
||||
|
||||
/**
|
||||
* The mobile network is provisioning
|
||||
*/
|
||||
private static final int CMP_RESULT_CODE_IS_PROVISIONING = 6;
|
||||
|
||||
private AtomicBoolean mIsProvisioningNetwork = new AtomicBoolean(false);
|
||||
private AtomicBoolean mIsStartingProvisioning = new AtomicBoolean(false);
|
||||
|
||||
private AtomicBoolean mIsCheckingMobileProvisioning = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
@@ -4062,11 +4143,25 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
setProvNotificationVisible(true,
|
||||
ConnectivityManager.TYPE_MOBILE_HIPRI, ni.getExtraInfo(),
|
||||
url);
|
||||
// Mark that we've got a provisioning network and
|
||||
// Disable Mobile Data until user actually starts provisioning.
|
||||
mIsProvisioningNetwork.set(true);
|
||||
MobileDataStateTracker mdst = (MobileDataStateTracker)
|
||||
mNetTrackers[ConnectivityManager.TYPE_MOBILE];
|
||||
mdst.setInternalDataEnable(false);
|
||||
} else {
|
||||
if (DBG) log("CheckMp.onComplete: warm (no dns/tcp), no url");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CMP_RESULT_CODE_IS_PROVISIONING: {
|
||||
// FIXME: Need to know when provisioning is done. Probably we can
|
||||
// check the completion status if successful we're done if we
|
||||
// "timedout" or still connected to provisioning APN turn off data?
|
||||
if (DBG) log("CheckMp.onComplete: provisioning started");
|
||||
mIsStartingProvisioning.set(false);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
loge("CheckMp.onComplete: ignore unexpected result=" + result);
|
||||
break;
|
||||
@@ -4216,6 +4311,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mCs.mIsStartingProvisioning.get()) {
|
||||
result = CMP_RESULT_CODE_IS_PROVISIONING;
|
||||
log("isMobileOk: X is provisioning result=" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// See if we've already determined we've got a provisioning connection,
|
||||
// if so we don't need to do anything active.
|
||||
MobileDataStateTracker mdstDefault = (MobileDataStateTracker)
|
||||
@@ -4354,7 +4455,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
|
||||
// Make a route to host so we check the specific interface.
|
||||
if (mCs.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI,
|
||||
hostAddr.getAddress())) {
|
||||
hostAddr.getAddress(), null)) {
|
||||
// Wait a short time to be sure the route is established ??
|
||||
log("isMobileOk:"
|
||||
+ " wait to establish route to hostAddr=" + hostAddr);
|
||||
@@ -4550,19 +4651,20 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
};
|
||||
|
||||
private void handleMobileProvisioningAction(String url) {
|
||||
// Notication mark notification as not visible
|
||||
// Mark notification as not visible
|
||||
setProvNotificationVisible(false, ConnectivityManager.TYPE_MOBILE_HIPRI, null, null);
|
||||
|
||||
// If provisioning network handle as a special case,
|
||||
// otherwise launch browser with the intent directly.
|
||||
NetworkInfo ni = getProvisioningNetworkInfo();
|
||||
if ((ni != null) && ni.isConnectedToProvisioningNetwork()) {
|
||||
if (DBG) log("handleMobileProvisioningAction: on provisioning network");
|
||||
if (mIsProvisioningNetwork.get()) {
|
||||
if (DBG) log("handleMobileProvisioningAction: on prov network enable then launch");
|
||||
mIsStartingProvisioning.set(true);
|
||||
MobileDataStateTracker mdst = (MobileDataStateTracker)
|
||||
mNetTrackers[ConnectivityManager.TYPE_MOBILE];
|
||||
mdst.setEnableFailFastMobileData(DctConstants.ENABLED);
|
||||
mdst.enableMobileProvisioning(url);
|
||||
} else {
|
||||
if (DBG) log("handleMobileProvisioningAction: on default network");
|
||||
if (DBG) log("handleMobileProvisioningAction: not prov network, launch browser directly");
|
||||
Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
|
||||
Intent.CATEGORY_APP_BROWSER);
|
||||
newIntent.setData(Uri.parse(url));
|
||||
|
||||
Reference in New Issue
Block a user