summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2013-08-29 08:55:16 -0700
committerWink Saville <wink@google.com>2013-08-29 08:55:16 -0700
commit948282b0e6cf5310f09db97a4ae939db7c1cef72 (patch)
tree8d24b04f379e58a6fa40751106ff2452a6c54e62 /core/java
parentdce52cdbf1eab8bd979bf4676973699c39f7b32e (diff)
downloadframeworks_base-948282b0e6cf5310f09db97a4ae939db7c1cef72.zip
frameworks_base-948282b0e6cf5310f09db97a4ae939db7c1cef72.tar.gz
frameworks_base-948282b0e6cf5310f09db97a4ae939db7c1cef72.tar.bz2
Add support for handling mobile provisioning networks.
When a sim is new or it has expired it needs to be provisioned with the carrier. Basically provisioning is associating a sim with a user account. When a sim isn't provisioned then operators will restrict access to the network and only allow certain addresses or services to be used. This set of changes allows two types of provisioning networks to be recognized. The first is a network that causes all DNS lookups to be redirected to a different address than was intended. This is exemplified by how T-Mobile works. The second technique uses a special apn for provisioning. An example is AT&T where lwaactivate is the provisioning apn and broadband is the normal apn. We first try broadband and if we are unable to connect we try lwaactivate. When we see the activate we identify it as special and the ApnContext.isProvisioningApn will return true. In the future our plan is to create a new network type that can be added to the apn list, but for now it identified by name. Here is a list of significant changes: - CaptivePortalTracker now only test WiFi networks instead of all networks - checkMobileProvisioning checks for provisioning networks and doesn't try to ping. - IConnectivityManager.aidl changes: * getProvisioningOrActiveNetworkInfo was added to and used by Manage mobile plan in WirelessSettings so even when there is no active network it will still allow provisioning. Otherwise it would report no internet connection. * setSignInErrorNotificationVisible is used by both CaptiviePortalTracker and checkMobileProvisioning so they use the same code for the notifications. * checkMobileProvisioning was simplified to have only a timeout as returning the result is now harder as we abort simultaneous call otherwise we'd could get into loops because we now check every time we connect to mobile. - Enhanced MDST to handle the provisioning network. - Added CONNECTED_TO_PROVISIONING_NETWORK to NetworkInfo to make a new state so we don't announce to the world we're connected. - TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN is sent by the low level data connection code to notify Connectivity Service that a provisioning apn has connected. This allows CS to handle the connection differently than a normal connection. Bug: 10328264 Change-Id: I3925004011bb1243793c4c1b963d923dc2b00cb5
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/net/CaptivePortalTracker.java116
-rw-r--r--core/java/android/net/ConnectivityManager.java89
-rw-r--r--core/java/android/net/IConnectivityManager.aidl6
-rw-r--r--core/java/android/net/MobileDataStateTracker.java100
-rw-r--r--core/java/android/net/NetworkInfo.java7
5 files changed, 155 insertions, 163 deletions
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index 09fe931..19c5f39 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -58,13 +58,11 @@ public class CaptivePortalTracker extends StateMachine {
private static final String TAG = "CaptivePortalTracker";
private static final String DEFAULT_SERVER = "clients3.google.com";
- private static final String NOTIFICATION_ID = "CaptivePortal.Notification";
private static final int SOCKET_TIMEOUT_MS = 10000;
private String mServer;
private String mUrl;
- private boolean mNotificationShown = false;
private boolean mIsCaptivePortalCheckEnabled = false;
private IConnectivityManager mConnService;
private TelephonyManager mTelephonyManager;
@@ -161,12 +159,12 @@ public class CaptivePortalTracker extends StateMachine {
private class DefaultState extends State {
@Override
public void enter() {
- if (DBG) log(getName() + "\n");
+ setNotificationOff();
}
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_DETECT_PORTAL:
NetworkInfo info = (NetworkInfo) message.obj;
@@ -188,23 +186,24 @@ public class CaptivePortalTracker extends StateMachine {
private class NoActiveNetworkState extends State {
@Override
public void enter() {
- if (DBG) log(getName() + "\n");
mNetworkInfo = null;
- /* Clear any previous notification */
- setNotificationVisible(false);
}
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString());
InetAddress server;
NetworkInfo info;
switch (message.what) {
case CMD_CONNECTIVITY_CHANGE:
info = (NetworkInfo) message.obj;
- if (info.isConnected() && isActiveNetwork(info)) {
- mNetworkInfo = info;
- transitionTo(mDelayedCaptiveCheckState);
+ if (info.getType() == ConnectivityManager.TYPE_WIFI) {
+ if (info.isConnected() && isActiveNetwork(info)) {
+ mNetworkInfo = info;
+ transitionTo(mDelayedCaptiveCheckState);
+ }
+ } else {
+ log(getName() + " not a wifi connectivity change, ignore");
}
break;
default:
@@ -217,7 +216,7 @@ public class CaptivePortalTracker extends StateMachine {
private class ActiveNetworkState extends State {
@Override
public void enter() {
- if (DBG) log(getName() + "\n");
+ setNotificationOff();
}
@Override
@@ -250,7 +249,6 @@ public class CaptivePortalTracker extends StateMachine {
private class DelayedCaptiveCheckState extends State {
@Override
public void enter() {
- if (DBG) log(getName() + "\n");
Message message = obtainMessage(CMD_DELAYED_CAPTIVE_CHECK, ++mDelayedCheckToken, 0);
if (mDeviceProvisioned) {
sendMessageDelayed(message, DELAYED_CHECK_INTERVAL_MS);
@@ -261,7 +259,7 @@ public class CaptivePortalTracker extends StateMachine {
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_DELAYED_CAPTIVE_CHECK:
if (message.arg1 == mDelayedCheckToken) {
@@ -277,7 +275,12 @@ public class CaptivePortalTracker extends StateMachine {
if (captive) {
// Setup Wizard will assist the user in connecting to a captive
// portal, so make the notification visible unless during setup
- setNotificationVisible(true);
+ try {
+ mConnService.setProvisioningNotificationVisible(true,
+ mNetworkInfo.getType(), mNetworkInfo.getExtraInfo(), mUrl);
+ } catch(RemoteException e) {
+ e.printStackTrace();
+ }
}
} else {
Intent intent = new Intent(
@@ -335,6 +338,15 @@ public class CaptivePortalTracker extends StateMachine {
return false;
}
+ private void setNotificationOff() {
+ try {
+ mConnService.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_NONE,
+ null, null);
+ } catch (RemoteException e) {
+ log("setNotificationOff: " + e);
+ }
+ }
+
/**
* Do a URL fetch on a known server to see if we get the data we expect
*/
@@ -354,9 +366,6 @@ public class CaptivePortalTracker extends StateMachine {
urlConnection.getInputStream();
// we got a valid response, but not from the real google
return urlConnection.getResponseCode() != 204;
- } catch (SocketTimeoutException e) {
- if (DBG) log("Probably a portal: exception " + e);
- return true;
} catch (IOException e) {
if (DBG) log("Probably not a portal: exception " + e);
return false;
@@ -380,75 +389,4 @@ public class CaptivePortalTracker extends StateMachine {
}
return null;
}
-
- private void setNotificationVisible(boolean visible) {
- // if it should be hidden and it is already hidden, then noop
- if (!visible && !mNotificationShown) {
- if (DBG) log("setNotivicationVisible: false and not shown, so noop");
- return;
- }
-
- Resources r = Resources.getSystem();
- NotificationManager notificationManager = (NotificationManager) mContext
- .getSystemService(Context.NOTIFICATION_SERVICE);
-
- if (visible) {
- CharSequence title;
- CharSequence details;
- int icon;
- String url = null;
- switch (mNetworkInfo.getType()) {
- case ConnectivityManager.TYPE_WIFI:
- title = r.getString(R.string.wifi_available_sign_in, 0);
- details = r.getString(R.string.network_available_sign_in_detailed,
- mNetworkInfo.getExtraInfo());
- icon = R.drawable.stat_notify_wifi_in_range;
- url = mUrl;
- break;
- case ConnectivityManager.TYPE_MOBILE:
- title = r.getString(R.string.network_available_sign_in, 0);
- // TODO: Change this to pull from NetworkInfo once a printable
- // name has been added to it
- details = mTelephonyManager.getNetworkOperatorName();
- icon = R.drawable.stat_notify_rssi_in_range;
- try {
- url = mConnService.getMobileProvisioningUrl();
- if (TextUtils.isEmpty(url)) {
- url = mConnService.getMobileRedirectedProvisioningUrl();
- }
- } catch(RemoteException e) {
- e.printStackTrace();
- }
- if (TextUtils.isEmpty(url)) {
- url = mUrl;
- }
- break;
- default:
- title = r.getString(R.string.network_available_sign_in, 0);
- details = r.getString(R.string.network_available_sign_in_detailed,
- mNetworkInfo.getExtraInfo());
- icon = R.drawable.stat_notify_rssi_in_range;
- url = mUrl;
- break;
- }
-
- Notification notification = new Notification();
- notification.when = 0;
- notification.icon = icon;
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- notification.contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
- notification.tickerText = title;
- notification.setLatestEventInfo(mContext, title, details, notification.contentIntent);
-
- if (DBG) log("setNotivicationVisible: make visible");
- notificationManager.notify(NOTIFICATION_ID, 1, notification);
- } else {
- if (DBG) log("setNotivicationVisible: cancel notification");
- notificationManager.cancel(NOTIFICATION_ID, 1);
- }
- mNotificationShown = visible;
- }
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index aa2d4ce..02a6494 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -583,6 +583,29 @@ public class ConnectivityManager {
}
/**
+ * Returns details about the Provisioning or currently active default data network. When
+ * connected, this network is the default route for outgoing connections.
+ * You should always check {@link NetworkInfo#isConnected()} before initiating
+ * network traffic. This may return {@code null} when there is no default
+ * network.
+ *
+ * @return a {@link NetworkInfo} object for the current default network
+ * or {@code null} if no network default network is currently active
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ *
+ * {@hide}
+ */
+ public NetworkInfo getProvisioningOrActiveNetworkInfo() {
+ try {
+ return mService.getProvisioningOrActiveNetworkInfo();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Returns the IP information for the current default network.
*
* @return a {@link LinkProperties} object describing the IP info
@@ -1316,63 +1339,19 @@ public class ConnectivityManager {
}
/**
- * The ResultReceiver resultCode for checkMobileProvisioning (CMP_RESULT_CODE)
- */
-
- /**
- * No connection was possible to the network.
- * {@hide}
- */
- public static final int CMP_RESULT_CODE_NO_CONNECTION = 0;
-
- /**
- * A connection was made to the internet, all is well.
- * {@hide}
- */
- public static final int CMP_RESULT_CODE_CONNECTABLE = 1;
-
- /**
- * A connection was made but there was a redirection, we appear to be in walled garden.
- * This is an indication of a warm sim on a mobile network.
- * {@hide}
- */
- public static final int CMP_RESULT_CODE_REDIRECTED = 2;
-
- /**
- * A connection was made but no dns server was available to resolve a name to address.
- * This is an indication of a warm sim on a mobile network.
+ * Check mobile provisioning.
*
- * {@hide}
- */
- public static final int CMP_RESULT_CODE_NO_DNS = 3;
-
- /**
- * A connection was made but could not open a TCP connection.
- * This is an indication of a warm sim on a mobile network.
- * {@hide}
- */
- public static final int CMP_RESULT_CODE_NO_TCP_CONNECTION = 4;
-
- /**
- * Check mobile provisioning. The resultCode passed to
- * onReceiveResult will be one of the CMP_RESULT_CODE_xxxx values above.
- * This may take a minute or more to complete.
- *
- * @param sendNotificaiton, when true a notification will be sent to user.
* @param suggestedTimeOutMs, timeout in milliseconds
- * @param resultReceiver needs to be supplied to receive the result
*
* @return time out that will be used, maybe less that suggestedTimeOutMs
* -1 if an error.
*
* {@hide}
*/
- public int checkMobileProvisioning(boolean sendNotification, int suggestedTimeOutMs,
- ResultReceiver resultReceiver) {
+ public int checkMobileProvisioning(int suggestedTimeOutMs) {
int timeOutMs = -1;
try {
- timeOutMs = mService.checkMobileProvisioning(sendNotification, suggestedTimeOutMs,
- resultReceiver);
+ timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
} catch (RemoteException e) {
}
return timeOutMs;
@@ -1401,4 +1380,20 @@ public class ConnectivityManager {
}
return null;
}
+
+ /**
+ * Set sign in error notification to visible or in visible
+ *
+ * @param visible
+ * @param networkType
+ *
+ * {@hide}
+ */
+ public void setProvisioningNotificationVisible(boolean visible, int networkType,
+ String extraInfo, String url) {
+ try {
+ mService.setProvisioningNotificationVisible(visible, networkType, extraInfo, url);
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 3ac5f13..a17b4f5 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -46,6 +46,8 @@ interface IConnectivityManager
NetworkInfo getNetworkInfo(int networkType);
NetworkInfo[] getAllNetworkInfo();
+ NetworkInfo getProvisioningOrActiveNetworkInfo();
+
boolean isNetworkSupported(int networkType);
LinkProperties getActiveLinkProperties();
@@ -135,9 +137,11 @@ interface IConnectivityManager
int findConnectionTypeForIface(in String iface);
- int checkMobileProvisioning(boolean sendNotification, int suggestedTimeOutMs, in ResultReceiver resultReceiver);
+ int checkMobileProvisioning(int suggestedTimeOutMs);
String getMobileProvisioningUrl();
String getMobileRedirectedProvisioningUrl();
+
+ void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo, in String url);
}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 98cccb8..77b7314 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class MobileDataStateTracker implements NetworkStateTracker {
private static final String TAG = "MobileDataStateTracker";
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
private static final boolean VDBG = false;
private PhoneConstants.DataState mMobileDataState;
@@ -104,6 +104,7 @@ public class MobileDataStateTracker implements NetworkStateTracker {
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
+ filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
mContext.registerReceiver(new MobileDataStateReceiver(), filter);
@@ -171,20 +172,49 @@ public class MobileDataStateTracker implements NetworkStateTracker {
public void releaseWakeLock() {
}
+ private void updateLinkProperitesAndCapatilities(Intent intent) {
+ mLinkProperties = intent.getParcelableExtra(
+ PhoneConstants.DATA_LINK_PROPERTIES_KEY);
+ if (mLinkProperties == null) {
+ loge("CONNECTED event did not supply link properties.");
+ mLinkProperties = new LinkProperties();
+ }
+ mLinkCapabilities = intent.getParcelableExtra(
+ PhoneConstants.DATA_LINK_CAPABILITIES_KEY);
+ if (mLinkCapabilities == null) {
+ loge("CONNECTED event did not supply link capabilities.");
+ mLinkCapabilities = new LinkCapabilities();
+ }
+ }
+
private class MobileDataStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(TelephonyIntents.
- ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
+ ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN)) {
+ String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
- if (VDBG) {
- log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED"
- + "mApnType=%s %s received apnType=%s", mApnType,
- TextUtils.equals(apnType, mApnType) ? "==" : "!=", apnType));
+ if (!TextUtils.equals(mApnType, apnType)) {
+ return;
+ }
+ if (DBG) {
+ log("Broadcast received: " + intent.getAction() + " apnType=" + apnType
+ + " apnName=" + apnName);
}
+
+ // Make us in the connecting state until we make a new TYPE_MOBILE_PROVISIONING
+ mMobileDataState = PhoneConstants.DataState.CONNECTING;
+ updateLinkProperitesAndCapatilities(intent);
+ setDetailedState(DetailedState.CONNECTED_TO_PROVISIONING_NETWORK, "", apnName);
+ } else if (intent.getAction().equals(TelephonyIntents.
+ ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
+ String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
if (!TextUtils.equals(apnType, mApnType)) {
return;
}
+ if (DBG) {
+ log("Broadcast received: " + intent.getAction() + " apnType=" + apnType);
+ }
int oldSubtype = mNetworkInfo.getSubtype();
int newSubType = TelephonyManager.getDefault().getNetworkType();
@@ -202,7 +232,7 @@ public class MobileDataStateTracker implements NetworkStateTracker {
String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
mNetworkInfo.setRoaming(intent.getBooleanExtra(
PhoneConstants.DATA_NETWORK_ROAMING_KEY, false));
- if (VDBG) {
+ if (DBG) {
log(mApnType + " setting isAvailable to " +
intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false));
}
@@ -236,18 +266,7 @@ public class MobileDataStateTracker implements NetworkStateTracker {
setDetailedState(DetailedState.SUSPENDED, reason, apnName);
break;
case CONNECTED:
- mLinkProperties = intent.getParcelableExtra(
- PhoneConstants.DATA_LINK_PROPERTIES_KEY);
- if (mLinkProperties == null) {
- loge("CONNECTED event did not supply link properties.");
- mLinkProperties = new LinkProperties();
- }
- mLinkCapabilities = intent.getParcelableExtra(
- PhoneConstants.DATA_LINK_CAPABILITIES_KEY);
- if (mLinkCapabilities == null) {
- loge("CONNECTED event did not supply link capabilities.");
- mLinkCapabilities = new LinkCapabilities();
- }
+ updateLinkProperitesAndCapatilities(intent);
setDetailedState(DetailedState.CONNECTED, reason, apnName);
break;
}
@@ -272,18 +291,13 @@ public class MobileDataStateTracker implements NetworkStateTracker {
equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
if (!TextUtils.equals(apnType, mApnType)) {
- if (DBG) {
- log(String.format(
- "Broadcast received: ACTION_ANY_DATA_CONNECTION_FAILED ignore, " +
- "mApnType=%s != received apnType=%s", mApnType, apnType));
- }
return;
}
String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY);
String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
if (DBG) {
- log("Received " + intent.getAction() +
- " broadcast" + reason == null ? "" : "(" + reason + ")");
+ log("Broadcast received: " + intent.getAction() +
+ " reason=" + reason == null ? "null" : reason);
}
setDetailedState(DetailedState.FAILED, reason, apnName);
} else {
@@ -544,6 +558,40 @@ public class MobileDataStateTracker implements NetworkStateTracker {
}
}
+ /**
+ * Inform DCT mobile provisioning has started, it ends when provisioning completes.
+ */
+ public void enableMobileProvisioning(String url) {
+ if (DBG) log("enableMobileProvisioning(url=" + url + ")");
+ final AsyncChannel channel = mDataConnectionTrackerAc;
+ if (channel != null) {
+ Message msg = Message.obtain();
+ msg.what = DctConstants.CMD_ENABLE_MOBILE_PROVISIONING;
+ msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, url));
+ channel.sendMessage(msg);
+ }
+ }
+
+ /**
+ * Return if this network is the provisioning network. Valid only if connected.
+ * @param met
+ */
+ public boolean isProvisioningNetwork() {
+ boolean retVal;
+ try {
+ Message msg = Message.obtain();
+ msg.what = DctConstants.CMD_IS_PROVISIONING_APN;
+ msg.setData(Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType));
+ Message result = mDataConnectionTrackerAc.sendMessageSynchronously(msg);
+ retVal = result.arg1 == DctConstants.ENABLED;
+ } catch (NullPointerException e) {
+ loge("isProvisioningNetwork: X " + e);
+ retVal = false;
+ }
+ if (DBG) log("isProvisioningNetwork: retVal=" + retVal);
+ return retVal;
+ }
+
@Override
public void addStackedLink(LinkProperties link) {
mLinkProperties.addStackedLink(link);
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 689dae5..dabc73a 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -84,6 +84,12 @@ public class NetworkInfo implements Parcelable {
VERIFYING_POOR_LINK,
/** Checking if network is a captive portal */
CAPTIVE_PORTAL_CHECK,
+ /**
+ * Network is connected to provisioning network
+ * TODO: Probably not needed when we add TYPE_PROVISIONING_NETWORK
+ * @hide
+ */
+ CONNECTED_TO_PROVISIONING_NETWORK
}
/**
@@ -108,6 +114,7 @@ public class NetworkInfo implements Parcelable {
stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
+ stateMap.put(DetailedState.CONNECTED_TO_PROVISIONING_NETWORK, State.CONNECTED);
}
private int mNetworkType;