summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/ConnectivityService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/ConnectivityService.java')
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java115
1 files changed, 115 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 26362a4..484908d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -163,6 +163,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
"android.telephony.apn-restore";
+ // How long to wait before putting up a "This network doesn't have an Internet connection,
+ // connect anyway?" dialog after the user selects a network that doesn't validate.
+ private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
+
// How long to delay to removal of a pending intent based request.
// See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
private final int mReleasePendingIntentDelayMs;
@@ -326,6 +330,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
+ /**
+ * used to specify whether a network should be used even if unvalidated.
+ * arg1 = whether to accept the network if it's unvalidated (1 or 0)
+ * arg2 = whether to remember this choice in the future (1 or 0)
+ * obj = network
+ */
+ private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
+
+ /**
+ * used to ask the user to confirm a connection to an unvalidated network.
+ * obj = network
+ */
+ private static final int EVENT_PROMPT_UNVALIDATED = 29;
/** Handler used for internal events. */
final private InternalHandler mHandler;
@@ -1870,6 +1887,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
loge("ERROR: created network explicitly selected.");
}
nai.networkMisc.explicitlySelected = true;
+ nai.networkMisc.acceptUnvalidated = (boolean) msg.obj;
break;
}
case NetworkMonitor.EVENT_NETWORK_TESTED: {
@@ -1893,6 +1911,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS,
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
0, null);
+
+ // TODO: trigger a NetworkCapabilities update so that the dialog can know
+ // that the network is now validated and close itself.
}
break;
}
@@ -2256,6 +2277,91 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
+ enforceConnectivityInternalPermission();
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
+ accept ? 1 : 0, always ? 1: 0, network));
+ }
+
+ private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
+ if (DBG) log("handleSetAcceptUnvalidated network=" + network +
+ " accept=" + accept + " always=" + always);
+
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai == null) {
+ // Nothing to do.
+ return;
+ }
+
+ if (nai.everValidated) {
+ // The network validated while the dialog box was up. Don't make any changes. There's a
+ // TODO in the dialog code to make it go away if the network validates; once that's
+ // implemented, taking action here will be confusing.
+ return;
+ }
+
+ if (!nai.networkMisc.explicitlySelected) {
+ Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
+ }
+
+ if (accept != nai.networkMisc.acceptUnvalidated) {
+ int oldScore = nai.getCurrentScore();
+ nai.networkMisc.acceptUnvalidated = accept;
+ rematchAllNetworksAndRequests(nai, oldScore);
+ sendUpdatedScoreToFactories(nai);
+ }
+
+ if (always) {
+ nai.asyncChannel.sendMessage(
+ NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, accept ? 1 : 0);
+ }
+
+ // TODO: should we also disconnect from the network if accept is false?
+ }
+
+ private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
+ PROMPT_UNVALIDATED_DELAY_MS);
+ }
+
+ private void handlePromptUnvalidated(Network network) {
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+
+ // Only prompt if the network is unvalidated and was explicitly selected by the user, and if
+ // we haven't already been told to switch to it regardless of whether it validated or not.
+ if (nai == null || nai.everValidated ||
+ !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) {
+ return;
+ }
+
+ // TODO: What should we do if we've already switched to this network because we had no
+ // better option? There are two obvious alternatives.
+ //
+ // 1. Decide that there's no point prompting because this is our only usable network.
+ // However, because we didn't prompt, if later on a validated network comes along, we'll
+ // either a) silently switch to it - bad if the user wanted to connect to stay on this
+ // unvalidated network - or b) prompt the user at that later time - bad because the user
+ // might not understand why they are now being prompted.
+ //
+ // 2. Always prompt the user, even if we have no other network to use. The user could then
+ // try to find an alternative network to join (remember, if we got here, then the user
+ // selected this network manually). This is bad because the prompt isn't really very
+ // useful.
+ //
+ // For now we do #1, but we can revisit that later.
+ if (isDefaultNetwork(nai)) {
+ return;
+ }
+
+ Intent intent = new Intent(ConnectivityManager.ACTION_PROMPT_UNVALIDATED);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK, network);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setClassName("com.android.settings",
+ "com.android.settings.wifi.WifiNoInternetDialog");
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ }
+
private class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
@@ -2326,6 +2432,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1);
break;
}
+ case EVENT_SET_ACCEPT_UNVALIDATED: {
+ handleSetAcceptUnvalidated((Network) msg.obj, msg.arg1 != 0, msg.arg2 != 0);
+ break;
+ }
+ case EVENT_PROMPT_UNVALIDATED: {
+ handlePromptUnvalidated((Network) msg.obj);
+ break;
+ }
case EVENT_SYSTEM_READY: {
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.networkMonitor.systemReady = true;
@@ -4125,6 +4239,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
notifyIfacesChanged();
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
+ scheduleUnvalidatedPrompt(networkAgent);
if (networkAgent.isVPN()) {
// Temporarily disable the default proxy (not global).
synchronized (mProxyLock) {