diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index 354a8c4a84a60..21995c021ca50 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -25,14 +25,15 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
+import android.os.Handler;
import android.os.UserHandle;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Settings;
import android.telephony.TelephonyManager;
-import android.util.Log;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -81,15 +82,21 @@ public class CaptivePortalTracker extends StateMachine {
private State mActiveNetworkState = new ActiveNetworkState();
private State mDelayedCaptiveCheckState = new DelayedCaptiveCheckState();
+ private static final String SETUP_WIZARD_PACKAGE = "com.google.android.setupwizard";
+ private boolean mDeviceProvisioned = false;
+ private ProvisioningObserver mProvisioningObserver;
+
private CaptivePortalTracker(Context context, IConnectivityManager cs) {
super(TAG);
mContext = context;
mConnService = cs;
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ mProvisioningObserver = new ProvisioningObserver();
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
mContext.registerReceiver(mReceiver, filter);
mServer = Settings.Global.getString(mContext.getContentResolver(),
@@ -106,11 +113,31 @@ public class CaptivePortalTracker extends StateMachine {
setInitialState(mNoActiveNetworkState);
}
+ private class ProvisioningObserver extends ContentObserver {
+ ProvisioningObserver() {
+ super(new Handler());
+ mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.DEVICE_PROVISIONED), false, this);
+ onChange(false); // load initial value
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ mDeviceProvisioned = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+ }
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ // Normally, we respond to CONNECTIVITY_ACTION, allowing time for the change in
+ // connectivity to stabilize, but if the device is not yet provisioned, respond
+ // immediately to speed up transit through the setup wizard.
+ if ((mDeviceProvisioned && action.equals(ConnectivityManager.CONNECTIVITY_ACTION))
+ || (!mDeviceProvisioned
+ && action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE))) {
NetworkInfo info = intent.getParcelableExtra(
ConnectivityManager.EXTRA_NETWORK_INFO);
sendMessage(obtainMessage(CMD_CONNECTIVITY_CHANGE, info));
@@ -222,8 +249,12 @@ public class CaptivePortalTracker extends StateMachine {
@Override
public void enter() {
if (DBG) log(getName() + "\n");
- sendMessageDelayed(obtainMessage(CMD_DELAYED_CAPTIVE_CHECK,
- ++mDelayedCheckToken, 0), DELAYED_CHECK_INTERVAL_MS);
+ Message message = obtainMessage(CMD_DELAYED_CAPTIVE_CHECK, ++mDelayedCheckToken, 0);
+ if (mDeviceProvisioned) {
+ sendMessageDelayed(message, DELAYED_CHECK_INTERVAL_MS);
+ } else {
+ sendMessage(message);
+ }
}
@Override
@@ -233,13 +264,26 @@ public class CaptivePortalTracker extends StateMachine {
case CMD_DELAYED_CAPTIVE_CHECK:
if (message.arg1 == mDelayedCheckToken) {
InetAddress server = lookupHost(mServer);
- if (server != null) {
- if (isCaptivePortal(server)) {
- if (DBG) log("Captive network " + mNetworkInfo);
+ boolean captive = server != null && isCaptivePortal(server);
+ if (captive) {
+ if (DBG) log("Captive network " + mNetworkInfo);
+ } else {
+ if (DBG) log("Not captive network " + mNetworkInfo);
+ }
+ if (mDeviceProvisioned) {
+ if (captive) {
+ // Setup Wizard will assist the user in connecting to a captive
+ // portal, so make the notification visible unless during setup
setNotificationVisible(true);
}
+ } else {
+ Intent intent = new Intent(
+ ConnectivityManager.ACTION_CAPTIVE_PORTAL_TEST_COMPLETED);
+ intent.putExtra(ConnectivityManager.EXTRA_IS_CAPTIVE_PORTAL, captive);
+ intent.setPackage(SETUP_WIZARD_PACKAGE);
+ mContext.sendBroadcast(intent);
}
- if (DBG) log("Not captive network " + mNetworkInfo);
+
transitionTo(mActiveNetworkState);
}
break;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a8a68d0e32aa6..000c56c3a4434 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -227,6 +227,21 @@ public class ConnectivityManager {
*/
public static final String EXTRA_ERRORED_TETHER = "erroredArray";
+ /**
+ * Broadcast Action: The captive portal tracker has finished its test.
+ * Sent only while running Setup Wizard, in lieu of showing a user
+ * notification.
+ * @hide
+ */
+ public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
+ "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
+ /**
+ * The lookup key for a boolean that indicates whether a captive portal was detected.
+ * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
+ * @hide
+ */
+ public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
+
/**
* The absence of APN..
* @hide
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5d0614ce40000..d77b504766545 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -129,6 +129,7 @@
+
@@ -641,7 +642,7 @@
android:protectionLevel="normal"
android:description="@string/permdesc_accessWifiState"
android:label="@string/permlab_accessWifiState" />
-
+
-
+
-
+
@@ -719,7 +720,7 @@
-
+
@@ -1129,7 +1130,7 @@
android:protectionLevel="signature|system"
android:label="@string/permlab_manageUsers"
android:description="@string/permdesc_manageUsers" />
-
+
@@ -1671,7 +1672,7 @@
android:label="@string/permlab_freezeScreen"
android:description="@string/permdesc_freezeScreen"
android:protectionLevel="signature" />
-
+