Loading core/java/android/net/CaptivePortalTracker.java +27 −89 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -188,24 +186,25 @@ 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.getType() == ConnectivityManager.TYPE_WIFI) { if (info.isConnected() && isActiveNetwork(info)) { mNetworkInfo = info; transitionTo(mDelayedCaptiveCheckState); } } else { log(getName() + " not a wifi connectivity change, ignore"); } break; default: return NOT_HANDLED; Loading @@ -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 Loading Loading @@ -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); Loading @@ -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) { Loading @@ -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( Loading Loading @@ -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 */ Loading @@ -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; Loading @@ -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; } } core/java/android/net/ConnectivityManager.java +42 −47 Original line number Diff line number Diff line Loading @@ -582,6 +582,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. * Loading Loading @@ -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; Loading Loading @@ -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) { } } } core/java/android/net/IConnectivityManager.aidl +5 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ interface IConnectivityManager NetworkInfo getNetworkInfo(int networkType); NetworkInfo[] getAllNetworkInfo(); NetworkInfo getProvisioningOrActiveNetworkInfo(); boolean isNetworkSupported(int networkType); LinkProperties getActiveLinkProperties(); Loading Loading @@ -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); } core/java/android/net/MobileDataStateTracker.java +74 −26 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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)); } Loading Loading @@ -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; } Loading @@ -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 { Loading Loading @@ -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); Loading core/java/android/net/NetworkInfo.java +7 −0 Original line number Diff line number Diff line Loading @@ -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 } /** Loading @@ -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; Loading Loading
core/java/android/net/CaptivePortalTracker.java +27 −89 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -188,24 +186,25 @@ 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.getType() == ConnectivityManager.TYPE_WIFI) { if (info.isConnected() && isActiveNetwork(info)) { mNetworkInfo = info; transitionTo(mDelayedCaptiveCheckState); } } else { log(getName() + " not a wifi connectivity change, ignore"); } break; default: return NOT_HANDLED; Loading @@ -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 Loading Loading @@ -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); Loading @@ -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) { Loading @@ -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( Loading Loading @@ -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 */ Loading @@ -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; Loading @@ -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; } }
core/java/android/net/ConnectivityManager.java +42 −47 Original line number Diff line number Diff line Loading @@ -582,6 +582,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. * Loading Loading @@ -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; Loading Loading @@ -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) { } } }
core/java/android/net/IConnectivityManager.aidl +5 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ interface IConnectivityManager NetworkInfo getNetworkInfo(int networkType); NetworkInfo[] getAllNetworkInfo(); NetworkInfo getProvisioningOrActiveNetworkInfo(); boolean isNetworkSupported(int networkType); LinkProperties getActiveLinkProperties(); Loading Loading @@ -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); }
core/java/android/net/MobileDataStateTracker.java +74 −26 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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)); } Loading Loading @@ -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; } Loading @@ -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 { Loading Loading @@ -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); Loading
core/java/android/net/NetworkInfo.java +7 −0 Original line number Diff line number Diff line Loading @@ -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 } /** Loading @@ -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; Loading