From 172b29e8b35ab441a4481ba8348cb30d596957ff Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 7 Aug 2013 15:36:08 -0700 Subject: [PATCH 1/7] Fix issue #10226007: Reset apps restores most of the changed settings... ...to original but not all modified ones Very stupid mistakes in messing up the iteration when pruning op entries. Change-Id: Ie536b9095f797fcd2b86c9a386a72746796430d1 --- .../java/com/android/server/AppOpsService.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java index 20ad63683acd8..a55fddcd7ed8c 100644 --- a/services/java/com/android/server/AppOpsService.java +++ b/services/java/com/android/server/AppOpsService.java @@ -380,12 +380,14 @@ public class AppOpsService extends IAppOpsService.Stub { HashMap>> callbacks = null; synchronized (this) { boolean changed = false; - for (int i=0; i=0; i--) { HashMap packages = mUidOps.valueAt(i); - for (Map.Entry ent : packages.entrySet()) { + Iterator> it = packages.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry ent = it.next(); String packageName = ent.getKey(); Ops pkgOps = ent.getValue(); - for (int j=0; j=0; j--) { Op curOp = pkgOps.valueAt(j); if (curOp.mode != AppOpsManager.MODE_ALLOWED) { curOp.mode = AppOpsManager.MODE_ALLOWED; @@ -394,9 +396,17 @@ public class AppOpsService extends IAppOpsService.Stub { mOpModeWatchers.get(curOp.op)); callbacks = addCallbacks(callbacks, packageName, curOp.op, mPackageModeWatchers.get(packageName)); - pruneOp(curOp, mUidOps.keyAt(i), packageName); + if (curOp.time == 0 && curOp.rejectTime == 0) { + pkgOps.removeAt(j); + } } } + if (pkgOps.size() == 0) { + it.remove(); + } + } + if (packages.size() == 0) { + mUidOps.removeAt(i); } } if (changed) { From 0f69536859299bd35b6305c63f33497a32f6a172 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 7 Aug 2013 15:36:08 -0700 Subject: [PATCH 2/7] Fix issue #10226007: Reset apps restores most of the changed settings... ...to original but not all modified ones Very stupid mistakes in messing up the iteration when pruning op entries. Change-Id: Ie536b9095f797fcd2b86c9a386a72746796430d1 --- .../java/com/android/server/AppOpsService.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java index 20ad63683acd8..a55fddcd7ed8c 100644 --- a/services/java/com/android/server/AppOpsService.java +++ b/services/java/com/android/server/AppOpsService.java @@ -380,12 +380,14 @@ public class AppOpsService extends IAppOpsService.Stub { HashMap>> callbacks = null; synchronized (this) { boolean changed = false; - for (int i=0; i=0; i--) { HashMap packages = mUidOps.valueAt(i); - for (Map.Entry ent : packages.entrySet()) { + Iterator> it = packages.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry ent = it.next(); String packageName = ent.getKey(); Ops pkgOps = ent.getValue(); - for (int j=0; j=0; j--) { Op curOp = pkgOps.valueAt(j); if (curOp.mode != AppOpsManager.MODE_ALLOWED) { curOp.mode = AppOpsManager.MODE_ALLOWED; @@ -394,9 +396,17 @@ public class AppOpsService extends IAppOpsService.Stub { mOpModeWatchers.get(curOp.op)); callbacks = addCallbacks(callbacks, packageName, curOp.op, mPackageModeWatchers.get(packageName)); - pruneOp(curOp, mUidOps.keyAt(i), packageName); + if (curOp.time == 0 && curOp.rejectTime == 0) { + pkgOps.removeAt(j); + } } } + if (pkgOps.size() == 0) { + it.remove(); + } + } + if (packages.size() == 0) { + mUidOps.removeAt(i); } } if (changed) { From 19b73883ed9bb3678b7f6bff46dd864592244782 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Wed, 7 Aug 2013 11:02:57 -0700 Subject: [PATCH 3/7] Check that hipri has started. I needed to test the result of startUsingNetworkFeature, otherwise on mobile networks that are slow to come up, we won't detect warm SIMs after booting. Bug: 9962943 Change-Id: Ib638a4e43867ecaa85d6abff65643b77a63526b6 --- .../android/server/ConnectivityService.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index cb4e89cc0f38c..caab49ece74c2 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -3732,11 +3732,26 @@ public class ConnectivityService extends IConnectivityManager.Stub { // hipri connection so the default connection stays active. log("isMobileOk: start hipri url=" + params.mUrl); mCs.setEnableFailFastMobileData(DctConstants.ENABLED); - mCs.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - Phone.FEATURE_ENABLE_HIPRI, new Binder()); // Continue trying to connect until time has run out long endTime = SystemClock.elapsedRealtime() + params.mTimeOutMs; + + // First wait until we can start using hipri + Binder binder = new Binder(); + while(SystemClock.elapsedRealtime() < endTime) { + int ret = mCs.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + Phone.FEATURE_ENABLE_HIPRI, binder); + if ((ret == PhoneConstants.APN_ALREADY_ACTIVE) + || (ret == PhoneConstants.APN_REQUEST_STARTED)) { + log("isMobileOk: hipri started"); + break; + } + if (VDBG) log("isMobileOk: hipri not started yet"); + result = ConnectivityManager.CMP_RESULT_CODE_NO_CONNECTION; + sleep(1); + } + + // Continue trying to connect until time has run out while(SystemClock.elapsedRealtime() < endTime) { try { // Wait for hipri to connect. @@ -3745,8 +3760,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkInfo.State state = mCs .getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); if (state != NetworkInfo.State.CONNECTED) { - log("isMobileOk: not connected ni=" + + if (VDBG) { + log("isMobileOk: not connected ni=" + mCs.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI)); + } sleep(1); result = ConnectivityManager.CMP_RESULT_CODE_NO_CONNECTION; continue; From 02a727fde936f346f26e8e902844c9ab6c3d0a4e Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Fri, 2 Aug 2013 11:25:23 -0700 Subject: [PATCH 4/7] In CaptiviePortalTracker a socket timeout is probably a captive portal. On a AT&T warm SIM a socket is not possible so a timeout occurs. In CheckMp a timing out on a socket is declared as a "warm" sim, make CaptivePortalTracker the same. Bug: 10038362 Change-Id: Icb9fb0a1b67704dc9adf6a6348a3781fb9582a89 --- core/java/android/net/CaptivePortalTracker.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index 21995c021ca50..2f1eb8d9ffe2e 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -42,6 +42,7 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.Inet4Address; +import java.net.SocketTimeoutException; import java.net.URL; import java.net.UnknownHostException; @@ -52,7 +53,7 @@ import com.android.internal.R; * @hide */ public class CaptivePortalTracker extends StateMachine { - private static final boolean DBG = false; + private static final boolean DBG = true; private static final String TAG = "CaptivePortalTracker"; private static final String DEFAULT_SERVER = "clients3.google.com"; @@ -337,6 +338,9 @@ 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; From dae8f3d1f4552ff5fca26ecd630fa2fddca8816c Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Sat, 20 Jul 2013 20:31:59 -0700 Subject: [PATCH 5/7] Have CaptivePortalTracker use gservices updateable provisioning urls. After detecting there is a captive portal the url used in the notification for mobile networks should be updateable via gservices. These urls will be the same as used by CheckMp and is needed for carriers that have specific provisioning urls such as AT&T and Verizon. Bug: 9622647 Change-Id: Idcf4dabc72ece1dbbe1d5e5a21e550dd06fe16c7 --- .../android/net/CaptivePortalTracker.java | 20 ++++++++++++++++++- .../java/android/net/ConnectivityManager.java | 14 ++++++++++++- .../android/net/IConnectivityManager.aidl | 2 ++ .../android/server/ConnectivityService.java | 9 ++++++--- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index 2f1eb8d9ffe2e..e5efc83a31e6e 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -34,6 +34,7 @@ import android.os.Message; import android.os.RemoteException; import android.provider.Settings; import android.telephony.TelephonyManager; +import android.text.TextUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -368,6 +369,7 @@ public class CaptivePortalTracker extends StateMachine { 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; } @@ -379,12 +381,14 @@ public class CaptivePortalTracker extends StateMachine { 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); @@ -392,12 +396,24 @@ public class CaptivePortalTracker extends StateMachine { // 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; } @@ -405,15 +421,17 @@ public class CaptivePortalTracker extends StateMachine { notification.when = 0; notification.icon = icon; notification.flags = Notification.FLAG_AUTO_CANCEL; - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mUrl)); + 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 697bde99a2d1f..b6df2fa660a8f 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1360,7 +1360,7 @@ public class ConnectivityManager { } /** - * Get the carrier provisioning url. + * Get the mobile provisioning url. * {@hide} */ public String getMobileProvisioningUrl() { @@ -1370,4 +1370,16 @@ public class ConnectivityManager { } return null; } + + /** + * Get the mobile redirected provisioning url. + * {@hide} + */ + public String getMobileRedirectedProvisioningUrl() { + try { + return mService.getMobileRedirectedProvisioningUrl(); + } catch (RemoteException e) { + } + return null; + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 4600c1a4dc27e..5daf39c60db8b 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -136,4 +136,6 @@ interface IConnectivityManager int checkMobileProvisioning(boolean sendNotification, int suggestedTimeOutMs, in ResultReceiver resultReceiver); String getMobileProvisioningUrl(); + + String getMobileRedirectedProvisioningUrl(); } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index caab49ece74c2..68037e08d2b3c 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -4103,7 +4103,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { return null; } - private String getMobileRedirectedProvisioningUrl() { + @Override + public String getMobileRedirectedProvisioningUrl() { + enforceConnectivityInternalPermission(); String url = getProvisioningUrlBaseFromFile(REDIRECTED_PROVISIONING); if (TextUtils.isEmpty(url)) { url = mContext.getResources().getString(R.string.mobile_redirected_provisioning_url); @@ -4111,14 +4113,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { return url; } + @Override public String getMobileProvisioningUrl() { enforceConnectivityInternalPermission(); String url = getProvisioningUrlBaseFromFile(PROVISIONING); if (TextUtils.isEmpty(url)) { url = mContext.getResources().getString(R.string.mobile_provisioning_url); - log("getProvisioningUrl: mobile_provisioining_url from resource =" + url); + log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url); } else { - log("getProvisioningUrl: mobile_provisioning_url from File =" + url); + log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url); } // populate the iccid, imei and phone number in the provisioning url. if (!TextUtils.isEmpty(url)) { From 96706a21532fdfb84780f3986f2623ad78976b8c Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Wed, 7 Aug 2013 16:22:47 -0700 Subject: [PATCH 6/7] If in a mobile captive portal is detected enable fail fast. When captive portal checking completes pass back the result. This is used to enable/disable failing fast for mobile. When failing fast is enabled we don't check for data stalls and thus won't be continually trying to do recovery operations, such as restarting the radio. Bug: 9462512 Change-Id: I0dea0eee519f8ee7f94e79d40e82c18f30d7fe2e --- .../BluetoothTetheringDataTracker.java | 5 +++++ .../android/net/BaseNetworkStateTracker.java | 5 +++++ .../android/net/CaptivePortalTracker.java | 15 +++++++++++++++ .../java/android/net/ConnectivityManager.java | 19 +++++++++++++++++++ .../android/net/DummyDataStateTracker.java | 6 ++++++ .../java/android/net/EthernetDataTracker.java | 5 +++++ .../android/net/IConnectivityManager.aidl | 2 ++ .../android/net/MobileDataStateTracker.java | 12 ++++++++++++ .../java/android/net/NetworkStateTracker.java | 5 +++++ .../android/server/ConnectivityService.java | 11 +++++++++++ .../android/net/wifi/WifiStateMachine.java | 6 ++++++ .../android/net/wifi/WifiStateTracker.java | 5 +++++ 12 files changed, 96 insertions(+) diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java index 81c0a6a87eaf2..0aedecb82dd2b 100644 --- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java +++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java @@ -152,6 +152,11 @@ public class BluetoothTetheringDataTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Re-enable connectivity to a network after a {@link #teardown()}. */ diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java index 1165281e39bb7..e87f84c56a21c 100644 --- a/core/java/android/net/BaseNetworkStateTracker.java +++ b/core/java/android/net/BaseNetworkStateTracker.java @@ -101,6 +101,11 @@ public abstract class BaseNetworkStateTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + @Override public boolean setRadio(boolean turnOn) { // Base tracker doesn't handle radios diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index e5efc83a31e6e..09fe9312c8306 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -272,6 +272,7 @@ public class CaptivePortalTracker extends StateMachine { } else { if (DBG) log("Not captive network " + mNetworkInfo); } + notifyPortalCheckCompleted(mNetworkInfo, captive); if (mDeviceProvisioned) { if (captive) { // Setup Wizard will assist the user in connecting to a captive @@ -302,12 +303,26 @@ public class CaptivePortalTracker extends StateMachine { return; } try { + if (DBG) log("notifyPortalCheckComplete: ni=" + info); mConnService.captivePortalCheckComplete(info); } catch(RemoteException e) { e.printStackTrace(); } } + private void notifyPortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) { + if (info == null) { + loge("notifyPortalCheckComplete on null"); + return; + } + try { + if (DBG) log("notifyPortalCheckCompleted: captive=" + isCaptivePortal + " ni=" + info); + mConnService.captivePortalCheckCompleted(info, isCaptivePortal); + } catch(RemoteException e) { + e.printStackTrace(); + } + } + private boolean isActiveNetwork(NetworkInfo info) { try { NetworkInfo active = mConnService.getActiveNetworkInfo(); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index b6df2fa660a8f..aa2d4ce92e6b2 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1282,6 +1282,25 @@ public class ConnectivityManager { } } + /** + * Signal that the captive portal check on the indicated network + * is complete and whether its a captive portal or not. + * + * @param info the {@link NetworkInfo} object for the networkType + * in question. + * @param isCaptivePortal true/false. + * + *

This method requires the call to hold the permission + * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}. + * {@hide} + */ + public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) { + try { + mService.captivePortalCheckCompleted(info, isCaptivePortal); + } catch (RemoteException e) { + } + } + /** * Supply the backend messenger for a network tracker * diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java index 15a81f3e45e8b..ee738fd9c715e 100644 --- a/core/java/android/net/DummyDataStateTracker.java +++ b/core/java/android/net/DummyDataStateTracker.java @@ -120,10 +120,16 @@ public class DummyDataStateTracker implements NetworkStateTracker { return true; } + @Override public void captivePortalCheckComplete() { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Record the detailed state of a network, and if it is a * change from the previous state, send a notification to diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java index 27d5a58e49188..ac2b0d9a8bd4f 100644 --- a/core/java/android/net/EthernetDataTracker.java +++ b/core/java/android/net/EthernetDataTracker.java @@ -279,6 +279,11 @@ public class EthernetDataTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Turn the wireless radio off for a network. * @param turnOn {@code true} to turn the radio on, {@code false} diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 5daf39c60db8b..3ac5f1367fc54 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -129,6 +129,8 @@ interface IConnectivityManager void captivePortalCheckComplete(in NetworkInfo info); + void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal); + void supplyMessenger(int networkType, in Messenger messenger); int findConnectionTypeForIface(in String iface); diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 5a1daed9511a8..adad8decca897 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -40,6 +40,7 @@ import com.android.internal.util.AsyncChannel; import java.io.CharArrayWriter; import java.io.PrintWriter; +import java.util.concurrent.atomic.AtomicBoolean; /** * Track the state of mobile data connectivity. This is done by @@ -75,6 +76,8 @@ public class MobileDataStateTracker implements NetworkStateTracker { private Handler mHandler; private AsyncChannel mDataConnectionTrackerAc; + private AtomicBoolean mIsCaptivePortal = new AtomicBoolean(false); + /** * Create a new MobileDataStateTracker * @param netType the ConnectivityManager network type @@ -377,6 +380,15 @@ public class MobileDataStateTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + if (mIsCaptivePortal.getAndSet(isCaptivePortal) != isCaptivePortal) { + // Captive portal change enable/disable failing fast + setEnableFailFastMobileData( + isCaptivePortal ? DctConstants.ENABLED : DctConstants.DISABLED); + } + } + /** * Record the detailed state of a network, and if it is a * change from the previous state, send a notification to diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java index cf77a1cdbe617..9ed7533719073 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -143,6 +143,11 @@ public interface NetworkStateTracker { */ public void captivePortalCheckComplete(); + /** + * Captive portal check has completed + */ + public void captivePortalCheckCompleted(boolean isCaptive); + /** * Turn the wireless radio off for a network. * @param turnOn {@code true} to turn the radio on, {@code false} diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 68037e08d2b3c..00935f3472023 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2169,15 +2169,26 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + if (DBG) log("handleCaptivePortalTrackerCheck: call captivePortalCheckComplete ni=" + info); thisNet.captivePortalCheckComplete(); } /** @hide */ + @Override public void captivePortalCheckComplete(NetworkInfo info) { enforceConnectivityInternalPermission(); + if (DBG) log("captivePortalCheckComplete: ni=" + info); mNetTrackers[info.getType()].captivePortalCheckComplete(); } + /** @hide */ + @Override + public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) { + enforceConnectivityInternalPermission(); + if (DBG) log("captivePortalCheckCompleted: ni=" + info + " captive=" + isCaptivePortal); + mNetTrackers[info.getType()].captivePortalCheckCompleted(isCaptivePortal); + } + /** * Setup data activity tracking for the given network interface. * diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 007735459aa78..6589ff5a83366 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -3166,6 +3166,7 @@ public class WifiStateMachine extends StateMachine { class VerifyingLinkState extends State { @Override public void enter() { + log(getName() + " enter"); setNetworkDetailedState(DetailedState.VERIFYING_POOR_LINK); mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.VERIFYING_POOR_LINK); sendNetworkStateChangeBroadcast(mLastBssid); @@ -3175,11 +3176,14 @@ public class WifiStateMachine extends StateMachine { switch (message.what) { case WifiWatchdogStateMachine.POOR_LINK_DETECTED: //stay here + log(getName() + " POOR_LINK_DETECTED: no transition"); break; case WifiWatchdogStateMachine.GOOD_LINK_DETECTED: + log(getName() + " GOOD_LINK_DETECTED: transition to captive portal check"); transitionTo(mCaptivePortalCheckState); break; default: + log(getName() + " what=" + message.what + " NOT_HANDLED"); return NOT_HANDLED; } return HANDLED; @@ -3189,6 +3193,7 @@ public class WifiStateMachine extends StateMachine { class CaptivePortalCheckState extends State { @Override public void enter() { + log(getName() + " enter"); setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK); mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CAPTIVE_PORTAL_CHECK); sendNetworkStateChangeBroadcast(mLastBssid); @@ -3197,6 +3202,7 @@ public class WifiStateMachine extends StateMachine { public boolean processMessage(Message message) { switch (message.what) { case CMD_CAPTIVE_CHECK_COMPLETE: + log(getName() + " CMD_CAPTIVE_CHECK_COMPLETE"); try { mNwService.enableIpv6(mInterfaceName); } catch (RemoteException re) { diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index cf75381e6c454..461dedb8a04bd 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -120,6 +120,11 @@ public class WifiStateTracker implements NetworkStateTracker { mWifiManager.captivePortalCheckComplete(); } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Turn the wireless radio off for a network. * @param turnOn {@code true} to turn the radio on, {@code false} From fb381053d5547e4840a85f06b70781c7d35307ed Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Tue, 23 Jul 2013 20:36:03 -0700 Subject: [PATCH 7/7] Use hostname verifier directly instead of instance DO NOT MERGE Instead of local instance of the default HostnameVerifier, use it directly from HttpsURLConnection. This avoids class preloading creating an instance of it before it's necessary. (cherry picked from commit 928ee1e48fa89302d02fdf8a8a2c7315d7195e7c) Bug: 9984058 Change-Id: I79d8a934bfc390e4cd503fd592e21bc4e5446a7d --- core/java/android/net/SSLCertificateSocketFactory.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index 2a2f7cf81f84d..0fe5cc415c6a2 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -81,9 +81,6 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { } }; - private static final HostnameVerifier HOSTNAME_VERIFIER = - HttpsURLConnection.getDefaultHostnameVerifier(); - private SSLSocketFactory mInsecureFactory = null; private SSLSocketFactory mSecureFactory = null; private TrustManager[] mTrustManagers = null; @@ -195,7 +192,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { if (session == null) { throw new SSLException("Cannot verify SSL socket without session"); } - if (!HOSTNAME_VERIFIER.verify(hostname, session)) { + if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) { throw new SSLPeerUnverifiedException("Cannot verify hostname: " + hostname); } }