am eeb291b7: am 95e3cba1: Merge "Reconnect/teardown proxy network connectivity." into klp-modular-dev

* commit 'eeb291b7f36d63c3db467cc7f4be61af09aa3171':
  Reconnect/teardown proxy network connectivity.
This commit is contained in:
Hui Lu
2014-02-25 18:00:05 +00:00
committed by Android Git Automerger

View File

@ -16,13 +16,24 @@
package android.net; package android.net;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@ -31,27 +42,70 @@ import java.util.concurrent.atomic.AtomicInteger;
* {@hide} * {@hide}
*/ */
public class ProxyDataTracker extends BaseNetworkStateTracker { public class ProxyDataTracker extends BaseNetworkStateTracker {
private static final String NETWORK_TYPE = "PROXY";
private static final String TAG = "ProxyDataTracker"; private static final String TAG = "ProxyDataTracker";
private static final String NETWORK_TYPE = "PROXY";
// TODO: investigate how to get these DNS addresses from the system. // TODO: investigate how to get these DNS addresses from the system.
private static final String DNS1 = "8.8.8.8"; private static final String DNS1 = "8.8.8.8";
private static final String DNS2 = "8.8.4.4"; private static final String DNS2 = "8.8.4.4";
private static final String REASON_ENABLED = "enabled"; private static final String REASON_ENABLED = "enabled";
private static final String REASON_DISABLED = "disabled";
private static final String REASON_PROXY_DOWN = "proxy_down";
private static final int MSG_TEAR_DOWN_REQUEST = 1;
private static final int MSG_SETUP_REQUEST = 2;
private static final String PERMISSION_PROXY_STATUS_SENDER =
"android.permission.ACCESS_NETWORK_CONDITIONS";
private static final String ACTION_PROXY_STATUS_CHANGE =
"com.android.net.PROXY_STATUS_CHANGE";
private static final String KEY_IS_PROXY_AVAILABLE = "is_proxy_available";
private static final String KEY_REPLY_TO_MESSENGER_BINDER = "reply_to_messenger_binder";
private static final String KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE =
"reply_to_messenger_binder_bundle";
private Handler mTarget;
private Messenger mProxyStatusService;
private AtomicBoolean mReconnectRequested = new AtomicBoolean(false);
private AtomicBoolean mIsProxyAvailable = new AtomicBoolean(false);
private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0); private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
private final AtomicInteger mReconnectGeneration = new AtomicInteger(0);
private final BroadcastReceiver mProxyStatusServiceListener = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_PROXY_STATUS_CHANGE)) {
mIsProxyAvailable.set(intent.getBooleanExtra(KEY_IS_PROXY_AVAILABLE, false));
if (mIsProxyAvailable.get()) {
Bundle bundle = intent.getBundleExtra(KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE);
if (bundle == null || bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER) == null) {
Log.e(TAG, "no messenger binder in the intent to send future requests");
mIsProxyAvailable.set(false);
return;
}
mProxyStatusService =
new Messenger(bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER));
// If there is a pending reconnect request, do it now.
if (mReconnectRequested.get()) {
reconnect();
}
} else {
setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
REASON_PROXY_DOWN, null);
}
} else {
Log.d(TAG, "Unrecognized broadcast intent");
}
}
};
/** /**
* Create a new ProxyDataTracker * Create a new ProxyDataTracker
*/ */
public ProxyDataTracker() { public ProxyDataTracker() {
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, ""); mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, "");
// TODO: update available state according to proxy state.
mNetworkInfo.setIsAvailable(true);
mLinkProperties = new LinkProperties(); mLinkProperties = new LinkProperties();
mLinkCapabilities = new LinkCapabilities(); mLinkCapabilities = new LinkCapabilities();
mNetworkInfo.setIsAvailable(true);
try { try {
mLinkProperties.addDns(InetAddress.getByName(DNS1)); mLinkProperties.addDns(InetAddress.getByName(DNS1));
mLinkProperties.addDns(InetAddress.getByName(DNS2)); mLinkProperties.addDns(InetAddress.getByName(DNS2));
@ -64,11 +118,31 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
throw new CloneNotSupportedException(); throw new CloneNotSupportedException();
} }
@Override
public void startMonitoring(Context context, Handler target) {
mContext = context;
mTarget = target;
mContext.registerReceiver(mProxyStatusServiceListener,
new IntentFilter(ACTION_PROXY_STATUS_CHANGE),
PERMISSION_PROXY_STATUS_SENDER,
null);
}
/** /**
* Disable connectivity to the network. * Disable connectivity to the network.
*/ */
public boolean teardown() { public boolean teardown() {
// TODO: tell relevant service to tear down proxy. setTeardownRequested(true);
mReconnectRequested.set(false);
try {
if (mIsProxyAvailable.get() && mProxyStatusService != null) {
mProxyStatusService.send(Message.obtain(null, MSG_TEAR_DOWN_REQUEST));
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to connect to proxy status service", e);
return false;
}
setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_DISABLED, null);
return true; return true;
} }
@ -76,16 +150,24 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
* Re-enable proxy data connectivity after a {@link #teardown()}. * Re-enable proxy data connectivity after a {@link #teardown()}.
*/ */
public boolean reconnect() { public boolean reconnect() {
if (!isAvailable()) { mReconnectRequested.set(true);
Log.w(TAG, "Reconnect requested even though network is disabled. Bailing."); setTeardownRequested(false);
if (!mIsProxyAvailable.get()) {
Log.w(TAG, "Reconnect requested even though proxy service is not up. Bailing.");
return false; return false;
} }
setTeardownRequested(false); setDetailedState(NetworkInfo.DetailedState.CONNECTING, REASON_ENABLED, null);
mReconnectGeneration.incrementAndGet();
// TODO: tell relevant service to setup proxy. Set state to connected only if setup
// succeeds.
setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
try {
mProxyStatusService.send(Message.obtain(null, MSG_SETUP_REQUEST));
} catch (RemoteException e) {
Log.e(TAG, "Unable to connect to proxy status service", e);
setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_PROXY_DOWN, null);
return false;
}
// We'll assume proxy is set up successfully. If not, a status change broadcast will be
// received afterwards to indicate any failure.
setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
return true; return true;
} }
@ -116,7 +198,7 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
private void setDetailedState(NetworkInfo.DetailedState state, String reason, private void setDetailedState(NetworkInfo.DetailedState state, String reason,
String extraInfo) { String extraInfo) {
mNetworkInfo.setDetailedState(state, reason, extraInfo); mNetworkInfo.setDetailedState(state, reason, extraInfo);
Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget(); msg.sendToTarget();
} }
} }