Final platform settings UX for ephemeral networks.
Show "Connected via Wi-Fi assistant" instead of just "Connected" when a Wi-Fi connection is ephemeral. Otherwise, treat ephemeral connections just like saved ones - show (read-only) connection stats when you click the network, and offer the ability to "forget" the network, which prevents further ephemeral connections. Bug: 18525241 Change-Id: I0d2146ab47b82d32c50b2ef883f176a6b6066713
This commit is contained in:
@@ -595,7 +595,7 @@ class AccessPoint extends Preference {
|
|||||||
* For ephemeral connections (networkId is invalid), this returns false if the network is
|
* For ephemeral connections (networkId is invalid), this returns false if the network is
|
||||||
* disconnected.
|
* disconnected.
|
||||||
*/
|
*/
|
||||||
private boolean isActive() {
|
boolean isActive() {
|
||||||
return mNetworkInfo != null &&
|
return mNetworkInfo != null &&
|
||||||
(networkId != WifiConfiguration.INVALID_NETWORK_ID ||
|
(networkId != WifiConfiguration.INVALID_NETWORK_ID ||
|
||||||
mNetworkInfo.getState() != State.DISCONNECTED);
|
mNetworkInfo.getState() != State.DISCONNECTED);
|
||||||
@@ -617,7 +617,8 @@ class AccessPoint extends Preference {
|
|||||||
StringBuilder summary = new StringBuilder();
|
StringBuilder summary = new StringBuilder();
|
||||||
|
|
||||||
if (isActive()) { // This is the active connection
|
if (isActive()) { // This is the active connection
|
||||||
summary.append(Summary.get(context, getState()));
|
summary.append(Summary.get(context, getState(),
|
||||||
|
networkId == WifiConfiguration.INVALID_NETWORK_ID));
|
||||||
} else if (mConfig != null
|
} else if (mConfig != null
|
||||||
&& mConfig.hasNoInternetAccess()) {
|
&& mConfig.hasNoInternetAccess()) {
|
||||||
summary.append(context.getString(R.string.wifi_no_internet));
|
summary.append(context.getString(R.string.wifi_no_internet));
|
||||||
|
@@ -22,7 +22,12 @@ import android.content.Context;
|
|||||||
import android.net.NetworkInfo.DetailedState;
|
import android.net.NetworkInfo.DetailedState;
|
||||||
|
|
||||||
class Summary {
|
class Summary {
|
||||||
static String get(Context context, String ssid, DetailedState state) {
|
static String get(Context context, String ssid, DetailedState state, boolean isEphemeral) {
|
||||||
|
if (state == DetailedState.CONNECTED && isEphemeral && ssid == null) {
|
||||||
|
// Special case for connected + ephemeral networks.
|
||||||
|
return context.getString(R.string.connected_via_wfa);
|
||||||
|
}
|
||||||
|
|
||||||
String[] formats = context.getResources().getStringArray((ssid == null)
|
String[] formats = context.getResources().getStringArray((ssid == null)
|
||||||
? R.array.wifi_status : R.array.wifi_status_with_ssid);
|
? R.array.wifi_status : R.array.wifi_status_with_ssid);
|
||||||
int index = state.ordinal();
|
int index = state.ordinal();
|
||||||
@@ -33,7 +38,7 @@ class Summary {
|
|||||||
return String.format(formats[index], ssid);
|
return String.format(formats[index], ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String get(Context context, DetailedState state) {
|
static String get(Context context, DetailedState state, boolean isEphemeral) {
|
||||||
return get(context, null, state);
|
return get(context, null, state, isEphemeral);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -242,7 +242,8 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAccessPoint.networkId == INVALID_NETWORK_ID || mEdit) {
|
if ((mAccessPoint.networkId == INVALID_NETWORK_ID && !mAccessPoint.isActive())
|
||||||
|
|| mEdit) {
|
||||||
showSecurityFields();
|
showSecurityFields();
|
||||||
showIpConfigFields();
|
showIpConfigFields();
|
||||||
showProxyFields();
|
showProxyFields();
|
||||||
@@ -266,7 +267,8 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
} else {
|
} else {
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
addRow(group, R.string.wifi_status, Summary.get(mConfigUi.getContext(),
|
addRow(group, R.string.wifi_status, Summary.get(mConfigUi.getContext(),
|
||||||
state));
|
state, mAccessPoint.networkId ==
|
||||||
|
WifiConfiguration.INVALID_NETWORK_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signalLevel != null) {
|
if (signalLevel != null) {
|
||||||
@@ -300,7 +302,7 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
addRow(group, R.string.wifi_security, mAccessPoint.getSecurityString(false));
|
addRow(group, R.string.wifi_security, mAccessPoint.getSecurityString(false));
|
||||||
mView.findViewById(R.id.ip_fields).setVisibility(View.GONE);
|
mView.findViewById(R.id.ip_fields).setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (mAccessPoint.networkId != INVALID_NETWORK_ID
|
if ((mAccessPoint.networkId != INVALID_NETWORK_ID || mAccessPoint.isActive())
|
||||||
&& ActivityManager.getCurrentUser() == UserHandle.USER_OWNER) {
|
&& ActivityManager.getCurrentUser() == UserHandle.USER_OWNER) {
|
||||||
mConfigUi.setForgetButton(res.getString(R.string.wifi_forget));
|
mConfigUi.setForgetButton(res.getString(R.string.wifi_forget));
|
||||||
}
|
}
|
||||||
|
@@ -502,26 +502,21 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
mSelectedAccessPoint = (AccessPoint) preference;
|
mSelectedAccessPoint = (AccessPoint) preference;
|
||||||
menu.setHeaderTitle(mSelectedAccessPoint.ssid);
|
menu.setHeaderTitle(mSelectedAccessPoint.ssid);
|
||||||
if (mSelectedAccessPoint.getLevel() != -1) {
|
if (mSelectedAccessPoint.getLevel() != -1) {
|
||||||
int connectStringRes = 0;
|
|
||||||
if (mSelectedAccessPoint.getState() == null) {
|
if (mSelectedAccessPoint.getState() == null) {
|
||||||
connectStringRes = R.string.wifi_menu_connect;
|
menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect);
|
||||||
} else if (mSelectedAccessPoint.networkId == INVALID_NETWORK_ID &&
|
|
||||||
mSelectedAccessPoint.getNetworkInfo().getState()
|
|
||||||
!= State.DISCONNECTED) {
|
|
||||||
// State is non-null (and not disconnected) but this network has no
|
|
||||||
// configuration, which means it is ephemeral. Allow the user to save the
|
|
||||||
// configuration permanently (but still issue this as a CONNECT command).
|
|
||||||
connectStringRes = R.string.wifi_menu_remember;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectStringRes != 0) {
|
|
||||||
menu.add(Menu.NONE, MENU_ID_CONNECT, 0, connectStringRes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ActivityManager.getCurrentUser() == UserHandle.USER_OWNER &&
|
||||||
|
(mSelectedAccessPoint.networkId != INVALID_NETWORK_ID ||
|
||||||
|
(mSelectedAccessPoint.getNetworkInfo() != null &&
|
||||||
|
mSelectedAccessPoint.getNetworkInfo().getState() != State.DISCONNECTED))) {
|
||||||
|
// Allow forgetting a network if the current user is the owner and either the
|
||||||
|
// network is saved or ephemerally connected. (In the latter case, "forget"
|
||||||
|
// blacklists the network so it won't be used again, ephemerally).
|
||||||
|
menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
|
||||||
|
}
|
||||||
if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {
|
if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {
|
||||||
if (ActivityManager.getCurrentUser() == UserHandle.USER_OWNER) {
|
|
||||||
menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
|
|
||||||
}
|
|
||||||
menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
|
menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
|
||||||
|
|
||||||
if (mSelectedAccessPoint.security != AccessPoint.SECURITY_NONE) {
|
if (mSelectedAccessPoint.security != AccessPoint.SECURITY_NONE) {
|
||||||
@@ -552,7 +547,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case MENU_ID_FORGET: {
|
case MENU_ID_FORGET: {
|
||||||
mWifiManager.forget(mSelectedAccessPoint.networkId, mForgetListener);
|
forget();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case MENU_ID_MODIFY: {
|
case MENU_ID_MODIFY: {
|
||||||
@@ -571,9 +566,10 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
|
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
|
||||||
if (preference instanceof AccessPoint) {
|
if (preference instanceof AccessPoint) {
|
||||||
mSelectedAccessPoint = (AccessPoint) preference;
|
mSelectedAccessPoint = (AccessPoint) preference;
|
||||||
/** Bypass dialog for unsecured, unsaved networks */
|
/** Bypass dialog for unsecured, unsaved, and inactive networks */
|
||||||
if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&
|
if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&
|
||||||
mSelectedAccessPoint.networkId == INVALID_NETWORK_ID) {
|
mSelectedAccessPoint.networkId == INVALID_NETWORK_ID &&
|
||||||
|
!mSelectedAccessPoint.isActive()) {
|
||||||
mSelectedAccessPoint.generateOpenNetworkConfig();
|
mSelectedAccessPoint.generateOpenNetworkConfig();
|
||||||
if (!savedNetworksExist) {
|
if (!savedNetworksExist) {
|
||||||
savedNetworksExist = true;
|
savedNetworksExist = true;
|
||||||
@@ -903,12 +899,19 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
/* package */ void forget() {
|
/* package */ void forget() {
|
||||||
if (mSelectedAccessPoint.networkId == INVALID_NETWORK_ID) {
|
if (mSelectedAccessPoint.networkId == INVALID_NETWORK_ID) {
|
||||||
// Should not happen, but a monkey seems to trigger it
|
if (mSelectedAccessPoint.getNetworkInfo().getState() != State.DISCONNECTED) {
|
||||||
Log.e(TAG, "Failed to forget invalid network " + mSelectedAccessPoint.getConfig());
|
// Network is active but has no network ID - must be ephemeral.
|
||||||
return;
|
mWifiManager.disableEphemeralNetwork(
|
||||||
|
AccessPoint.convertToQuotedString(mSelectedAccessPoint.ssid));
|
||||||
|
} else {
|
||||||
|
// Should not happen, but a monkey seems to trigger it
|
||||||
|
Log.e(TAG, "Failed to forget invalid network " + mSelectedAccessPoint.getConfig());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mWifiManager.forget(mSelectedAccessPoint.networkId, mForgetListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
mWifiManager.forget(mSelectedAccessPoint.networkId, mForgetListener);
|
|
||||||
|
|
||||||
if (mWifiManager.isWifiEnabled()) {
|
if (mWifiManager.isWifiEnabled()) {
|
||||||
mScanner.resume();
|
mScanner.resume();
|
||||||
|
@@ -285,7 +285,7 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
|
|||||||
default: // DISCONNECTED, FAILED
|
default: // DISCONNECTED, FAILED
|
||||||
if (mScreenState != SCREEN_STATE_CONNECTED &&
|
if (mScreenState != SCREEN_STATE_CONNECTED &&
|
||||||
mWifiSettings.getAccessPointsCount() > 0) {
|
mWifiSettings.getAccessPointsCount() > 0) {
|
||||||
showDisconnectedState(Summary.get(this, state));
|
showDisconnectedState(Summary.get(this, state, false /* isEphemeral */));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -17,12 +17,16 @@
|
|||||||
package com.android.settings.wifi;
|
package com.android.settings.wifi;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
import android.net.wifi.ScanResult;
|
import android.net.wifi.ScanResult;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -30,6 +34,7 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.wifi.SupplicantState;
|
import android.net.wifi.SupplicantState;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -40,6 +45,7 @@ import android.view.View;
|
|||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
@@ -294,8 +300,9 @@ public class WifiStatusTest extends Activity {
|
|||||||
|
|
||||||
private void handleNetworkStateChanged(NetworkInfo networkInfo) {
|
private void handleNetworkStateChanged(NetworkInfo networkInfo) {
|
||||||
if (mWifiManager.isWifiEnabled()) {
|
if (mWifiManager.isWifiEnabled()) {
|
||||||
String summary = Summary.get(this, mWifiManager.getConnectionInfo().getSSID(),
|
WifiInfo info = mWifiManager.getConnectionInfo();
|
||||||
networkInfo.getDetailedState());
|
String summary = Summary.get(this, info.getSSID(), networkInfo.getDetailedState(),
|
||||||
|
info.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID);
|
||||||
mNetworkState.setText(summary);
|
mNetworkState.setText(summary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user