165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.connectivity; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.Resources; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.IpConfiguration; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.IpConfiguration.IpAssignment; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.IpConfiguration.ProxySettings; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.wifi.WifiConfiguration; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.wifi.ScanResult; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.wifi.WifiInfo; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.wifi.WifiManager; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Handler; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.SystemClock; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.text.TextUtils; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Pair; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.SettingsLayoutActivity; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout.Header; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout.Action; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout.Status; 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout.Static; 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout.StringGetter; 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.Layout.LayoutGetter; 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Collections; 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.HashMap; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.List; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Activity to manage network settings. 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class NetworkActivity extends SettingsLayoutActivity implements 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ConnectivityListener.Listener { 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5801a5b81394670c6c5c2011673ed48c4fee1cf77bbulic private static final boolean DEBUG = false; 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String TAG = "NetworkActivity"; 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int REQUEST_CODE_ADVANCED_OPTIONS = 1; 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int WIFI_REFRESH_INTERVAL_CAP_MILLIS = 15 * 1000; 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ConnectivityListener mConnectivityListener; 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Resources mRes; 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Handler mHandler = new Handler(); 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onCreate(Bundle savedInstanceState) { 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRes = getResources(); 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener = new ConnectivityListener(this, this); 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.start(); 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onCreate(savedInstanceState); 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onDestroy(){ 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onDestroy(); 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.stop(); 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onConnectivityChange(Intent intent) { 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mEthernetConnectedDescription.refreshView(); 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiConnectedDescription.refreshView(); 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onResume() { 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mWifiShortListLayout != null) { 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiShortListLayout.onWifiListInvalidated(); 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mWifiAllListLayout != null) { 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiAllListLayout.onWifiListInvalidated(); 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onResume(); 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane StringGetter mEthernetConnectedDescription = new StringGetter() { 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean lastIsEthernetConnected; 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String get() { 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane lastIsEthernetConnected = 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.getConnectivityStatus().isEthernetConnected(); 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resId = lastIsEthernetConnected ? R.string.connected : R.string.not_connected; 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mRes.getString(resId); 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void refreshView() { 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mConnectivityListener.getConnectivityStatus().isEthernetConnected() != 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane lastIsEthernetConnected) { 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.refreshView(); 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane StringGetter mWifiConnectedDescription = new StringGetter() { 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean lastIsWifiConnected; 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String get() { 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane lastIsWifiConnected = mConnectivityListener.getConnectivityStatus().isWifiConnected(); 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resId = lastIsWifiConnected ? R.string.connected : R.string.not_connected; 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mRes.getString(resId); 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void refreshView() { 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mConnectivityListener.getConnectivityStatus().isWifiConnected() != 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane lastIsWifiConnected) { 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.refreshView(); 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane StringGetter mEthernetIPAddress = new StringGetter() { 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String get() { 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ConnectivityListener.ConnectivityStatus status = 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.getConnectivityStatus(); 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (status.isEthernetConnected()) { 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mConnectivityListener.getEthernetIpAddress(); 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ""; 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane StringGetter mEthernetMacAddress = new StringGetter() { 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String get() { 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mConnectivityListener.getEthernetMacAddress(); 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane LayoutGetter mEthernetAdvancedLayout = new LayoutGetter() { 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public Layout get() { 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Layout layout = new Layout(); 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Do not check Ethernet's availability here 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // because it might not be active due to the invalid configuration. 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane IpConfiguration ipConfiguration = mConnectivityListener.getIpConfiguration(); 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ipConfiguration != null) { 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int proxySettingsResourceId = 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (ipConfiguration.getProxySettings() == ProxySettings.STATIC) ? 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_proxy_manual : 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_proxy_none; 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int ipSettingsResourceId = 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (ipConfiguration.getIpAssignment() == IpAssignment.STATIC) ? 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_static : 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_dhcp; 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, ACTION_ETHERNET_PROXY_SETTINGS) 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_wifi_proxy_settings) 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(proxySettingsResourceId).build()) 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, ACTION_ETHERNET_IP_SETTINGS) 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_wifi_ip_settings) 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(ipSettingsResourceId).build()); 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_internet_connection) 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.not_connected).build()); 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return layout; 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane LayoutGetter mEthernetLayout = new LayoutGetter() { 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public Layout get() { 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean ethernetConnected = 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.getConnectivityStatus().isEthernetConnected(); 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ethernetConnected) { 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new Layout() 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes).title(R.string.title_internet_connection) 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.connected).build()) 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_ip_address) 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mEthernetIPAddress) 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_mac_address) 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mEthernetMacAddress) 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_action_advanced_options_title).build() 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mEthernetAdvancedLayout) 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ); 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new Layout() 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_internet_connection) 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.not_connected) 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_action_advanced_options_title).build() 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mEthernetAdvancedLayout) 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ); 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int NUMBER_SIGNAL_LEVELS = 4; 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int ACTION_WIFI_FORGET_NETWORK = 1; 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int ACTION_WIFI_PROXY_SETTINGS = 4; 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int ACTION_WIFI_IP_SETTINGS = 5; 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int ACTION_ETHERNET_PROXY_SETTINGS = 6; 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int ACTION_ETHERNET_IP_SETTINGS = 7; 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext = this; 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int getCurrentNetworkIconResourceId( 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ScanResult scanResult, int signalLevel) { 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resourceId = 0; 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (scanResult != null) { 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WifiSecurity security = WifiSecurity.getSecurity(scanResult); 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (security.isOpen()) { 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (signalLevel) { 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 0: 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_active_1; 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 1: 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_active_2; 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 2: 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_active_3; 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 3: 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_active_4; 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (signalLevel) { 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 0: 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_secure_active_1; 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 1: 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_secure_active_2; 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 2: 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_secure_active_3; 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case 3: 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resourceId = R.drawable.ic_settings_wifi_secure_active_4; 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return resourceId; 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String getSignalStrength() { 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] signalLevels = mRes.getStringArray(R.array.wifi_signal_strength); 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int strength = mConnectivityListener.getWifiSignalStrength(signalLevels.length); 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return signalLevels[strength]; 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane LayoutGetter mWifiInfoLayout = new LayoutGetter() { 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public Layout get() { 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Layout layout = new Layout(); 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ConnectivityListener.ConnectivityStatus status = 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.getConnectivityStatus(); 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isConnected = status.isWifiConnected(); 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isConnected) { 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_internet_connection) 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.connected).build()) 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_ip_address) 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mConnectivityListener.getWifiIpAddress()).build()) 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_mac_address) 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mConnectivityListener.getWifiMacAddress()).build()) 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_signal_strength) 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(getSignalStrength()).build()); 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_internet_connection) 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.not_connected).build()); 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return layout; 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane LayoutGetter mWifiAdvancedLayout = new LayoutGetter() { 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public Layout get() { 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Layout layout = new Layout(); 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WifiConfiguration wifiConfiguration = mConnectivityListener.getWifiConfiguration(); 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (wifiConfiguration != null) { 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int proxySettingsResourceId = 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (wifiConfiguration.getProxySettings() == ProxySettings.NONE) ? 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_proxy_none : 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_proxy_manual; 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int ipSettingsResourceId = 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (wifiConfiguration.getIpAssignment() == IpAssignment.STATIC) ? 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_static : 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.wifi_action_dhcp; 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, ACTION_WIFI_PROXY_SETTINGS) 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_wifi_proxy_settings) 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(proxySettingsResourceId).build()) 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, ACTION_WIFI_IP_SETTINGS) 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_wifi_ip_settings) 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(ipSettingsResourceId).build()); 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Status.Builder(mRes) 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_internet_connection) 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.not_connected).build()); 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return layout; 33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addWifiConnectedHeader(Layout layout, String SSID) { 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(SSID) 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(R.string.connected).build() 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_action_status_info).build() 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mWifiInfoLayout) 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ) 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_action_advanced_options_title).build() 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mWifiAdvancedLayout) 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ) 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_forget_network).build() 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, ACTION_WIFI_FORGET_NETWORK) 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_ok).build()) 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, Action.ACTION_BACK) 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_cancel).build()) 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ) 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ); 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class WifiListLayout extends LayoutGetter implements 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ConnectivityListener.WifiNetworkListener { 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final boolean mTop3EntriesOnly; 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String mSelectedTitle; 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private long mLastWifiRefresh = 0; 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Runnable mRefreshViewRunnable = new Runnable() { 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void run() { 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Layout.Node selected = getSelectedNode(); 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (selected != null) { 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSelectedTitle = selected.getTitle(); 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane refreshView(); 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WifiListLayout(boolean top3EntriesOnly) { 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mTop3EntriesOnly = top3EntriesOnly; 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public Layout get() { 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.startScanningWifi(this); 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mLastWifiRefresh = SystemClock.elapsedRealtime(); 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.removeCallbacks(mRefreshViewRunnable); 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return initAvailableWifiNetworks(mTop3EntriesOnly, mSelectedTitle). 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setSelectedByTitle(mSelectedTitle); 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onMovedOffScreen() { 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.removeCallbacks(mRefreshViewRunnable); 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.stopScanningWifi(this); 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onWifiListChanged() { 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane long now = SystemClock.elapsedRealtime(); 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane long millisToNextRefreshView = 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WIFI_REFRESH_INTERVAL_CAP_MILLIS - now + mLastWifiRefresh; 39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.removeCallbacks(mRefreshViewRunnable); 39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.postDelayed(mRefreshViewRunnable, millisToNextRefreshView); 39965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 40065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 40165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 40265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Wifi network configuration has changed and an immediate refresh of the list of Wifi 40365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * networks is required. 40465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 40565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onWifiListInvalidated() { 40665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mLastWifiRefresh = 0; 40765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onWifiListChanged(); 40865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 40965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 41065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 41165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Create a list of available Wifi networks sorted by connection status (a connected Wifi 41265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * network is shown at the first position on the list) and signal strength, with the 41365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * provisio that the wireless network with SSID "mustHave" should be included in the list 41465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * even if it would be otherwise excluded. 41565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 41665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param top3EntriesOnly Show only 3 entries in the list. 41765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param mustHave Include this wifi network in the list even if it would otherwise 41865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * be excluded by virtue of inadequate signal strength. 41965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 42065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Layout initAvailableWifiNetworks(boolean top3EntriesOnly, String mustHave) { 42165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane List<ScanResult> networks = mConnectivityListener.getAvailableNetworks(); 42265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Layout layout = new Layout(); 42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (networks.size() > 0) { 42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int maxItems = top3EntriesOnly ? 3 : Integer.MAX_VALUE; 42565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // "networks" is already sorted by the signal strength and connection status. 42665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Generate a new list with size less than "maxItems" that ensures "mustHave" is 42765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // included. 42865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean haveMustHave = false; 42965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane List<ScanResult> displayList = new ArrayList<ScanResult>(); 43065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (ScanResult scanResult : networks) { 43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!haveMustHave && TextUtils.equals(scanResult.SSID, mustHave)) { 43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane haveMustHave = true; 43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (displayList.size() == maxItems) { 43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayList.remove(maxItems-1); 43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayList.add(scanResult); 43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (displayList.size() < maxItems) { 43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayList.add(scanResult); 43965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (haveMustHave && displayList.size() == maxItems) { 44165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 44265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 44565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If a network is connected, it will be the first on the list. 44665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isConnected = 44765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.getConnectivityStatus().isWifiConnected(); 44865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (ScanResult network : displayList) { 44965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (network != null) { 45065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WifiSecurity security = WifiSecurity.getSecurity(network); 45165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String networkDescription = 45365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane security.isOpen() ? "" : security.getName(mContext); 45465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = 45565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WifiConnectionActivity.createIntent(mContext, network, security); 45665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int signalLevel = WifiManager.calculateSignalLevel( 45765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane network.level, NUMBER_SIGNAL_LEVELS); 45865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane //TODO implement signal dependent list icon. 45965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /* 46065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int imageResourceId = getNetworkIconResourceId(network, signalLevel); 46165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiConfigHelper.areSameNetwork(mWifiManager, network, 46265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane currentConnection)) { 46365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane networkDescription = getString(R.string.connected); 46465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane signalLevel = WifiManager.calculateSignalLevel( 46565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane currentConnection.getRssi(), NUMBER_SIGNAL_LEVELS); 46665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane imageResourceId = getCurrentNetworkIconResourceId(network, signalLevel); 46765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } */ 46865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isConnected) { 47065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addWifiConnectedHeader(layout, network.SSID); 47165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 47265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout.add(new Action.Builder(mRes, intent) 47365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(network.SSID) 47465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(networkDescription).build()); 47565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isConnected = false; 47865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 48065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane layout.add(new Action.Builder(mRes, 0) 48165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.title_wifi_no_networks_available).build()); 48265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return layout; 48465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 48665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final WifiListLayout mWifiShortListLayout = new WifiListLayout(true); 48865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final WifiListLayout mWifiAllListLayout = new WifiListLayout(false); 49065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 49265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public Layout createLayout() { 49365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return 49465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new Layout() 49565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .breadcrumb(getString(R.string.header_category_device)) 49665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 497a40d3a1dd3127512097a7ae3d4c7bfb00f673815bulic .icon(R.drawable.ic_settings_wifi_4) 49865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.connectivity_network) 49965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mWifiConnectedDescription) 50065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build() 50165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes).title(R.string.connectivity_wifi) 50201a5b81394670c6c5c2011673ed48c4fee1cf77bbulic .contentIconRes(R.drawable.ic_settings_wifi_4) 50365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mWifiConnectedDescription).build() 50465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Static.Builder(mRes) 50565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_setting_available_networks) 50665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 50765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mWifiShortListLayout) 50865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 50965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_setting_see_all) 51065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build() 51165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mWifiAllListLayout) 51265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ) 51365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Static.Builder(mRes) 51465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_setting_header_other_options) 51565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 51665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, 51765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new Intent(this, WpsConnectionActivity.class)) 51865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_setting_other_options_wps) 51965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 52065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Action.Builder(mRes, 52165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new Intent(this, AddWifiNetworkActivity.class)) 52265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.wifi_setting_other_options_add_network) 52365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()) 52465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ) 52565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(new Header.Builder(mRes) 52665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(R.string.connectivity_ethernet) 52701a5b81394670c6c5c2011673ed48c4fee1cf77bbulic .contentIconRes(R.drawable.ic_settings_ethernet) 52865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mEthernetConnectedDescription) 52965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build() 53065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .add(mEthernetLayout) 53165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ) 53265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ); 53365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 53465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 53665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onActivityResult(int requestCode, int resultCode, Intent data) { 53765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (requestCode == REQUEST_CODE_ADVANCED_OPTIONS && resultCode == RESULT_OK) { 53865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane //TODO make sure view reflects model deltas 53965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 54065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onActivityResult(requestCode, resultCode, data); 54165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 54265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 54365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 54465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 54501a5b81394670c6c5c2011673ed48c4fee1cf77bbulic public void onActionFocused(Layout.LayoutRow item) { 54601a5b81394670c6c5c2011673ed48c4fee1cf77bbulic int resId = item.getContentIconRes(); 54701a5b81394670c6c5c2011673ed48c4fee1cf77bbulic if (resId != 0) { 54801a5b81394670c6c5c2011673ed48c4fee1cf77bbulic setIcon(resId); 54901a5b81394670c6c5c2011673ed48c4fee1cf77bbulic } 55001a5b81394670c6c5c2011673ed48c4fee1cf77bbulic } 55101a5b81394670c6c5c2011673ed48c4fee1cf77bbulic 55201a5b81394670c6c5c2011673ed48c4fee1cf77bbulic @Override 55365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Action action) { 55465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (action.getId()) { 55565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case Action.ACTION_INTENT: 55665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivityForResult(action.getIntent(), REQUEST_CODE_ADVANCED_OPTIONS); 55765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 55865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case ACTION_WIFI_FORGET_NETWORK: 55965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectivityListener.forgetWifiNetwork(); 56065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane goBackToTitle(mRes.getString(R.string.connectivity_wifi)); 56165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiShortListLayout.onWifiListInvalidated(); 56265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiAllListLayout.onWifiListInvalidated(); 56365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 56465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case ACTION_WIFI_PROXY_SETTINGS: { 56565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int networkId = mConnectivityListener.getWifiNetworkId(); 56665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (networkId != -1) { 56765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivityForResult(EditProxySettingsActivity.createIntent(this, networkId), 56865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane REQUEST_CODE_ADVANCED_OPTIONS); 56965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 57065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 57165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 57265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case ACTION_WIFI_IP_SETTINGS: { 57365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int networkId = mConnectivityListener.getWifiNetworkId(); 57465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (networkId != -1) { 57565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivityForResult(EditIpSettingsActivity.createIntent(this, networkId), 57665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane REQUEST_CODE_ADVANCED_OPTIONS); 57765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 57865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 57965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 58065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case ACTION_ETHERNET_PROXY_SETTINGS: { 58165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int networkId = WifiConfiguration.INVALID_NETWORK_ID; 58265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivityForResult(EditProxySettingsActivity.createIntent(this, networkId), 58365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane REQUEST_CODE_ADVANCED_OPTIONS); 58465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 58565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 58665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case ACTION_ETHERNET_IP_SETTINGS: { 58765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int networkId = WifiConfiguration.INVALID_NETWORK_ID; 58865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivityForResult(EditIpSettingsActivity.createIntent(this, networkId), 58965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane REQUEST_CODE_ADVANCED_OPTIONS); 59065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 59165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 59265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 59365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 59465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 595