Home | History | Annotate | Download | only in setup
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tv.settings.connectivity.setup;
     18 
     19 import com.android.tv.settings.R;
     20 import com.android.tv.settings.connectivity.AdvancedWifiOptionsFlow;
     21 import com.android.tv.settings.connectivity.ConnectToWifiFragment;
     22 import com.android.tv.settings.connectivity.FormPageDisplayer;
     23 import com.android.tv.settings.connectivity.TimedMessageWizardFragment;
     24 import com.android.tv.settings.connectivity.WifiConfigHelper;
     25 import com.android.tv.settings.connectivity.WifiFormPageType;
     26 import com.android.tv.settings.connectivity.WifiMultiPagedFormActivity;
     27 import com.android.tv.settings.connectivity.WifiSecurity;
     28 import com.android.tv.settings.connectivity.WpsConnectionActivity;
     29 import com.android.tv.settings.connectivity.setup.SelectFromListWizardFragment;
     30 import com.android.tv.settings.connectivity.setup.SelectFromListWizardFragment.ListItem;
     31 import com.android.tv.settings.util.ThemeHelper;
     32 import com.android.tv.settings.util.TransitionUtils;
     33 
     34 import com.android.tv.settings.form.FormPage;
     35 import com.android.tv.settings.form.FormPageResultListener;
     36 
     37 import android.animation.Animator;
     38 import android.animation.ObjectAnimator;
     39 import android.app.Fragment;
     40 import android.app.FragmentManager;
     41 import android.app.FragmentTransaction;
     42 import android.content.Context;
     43 import android.content.Intent;
     44 import android.net.ConnectivityManager;
     45 import android.net.NetworkInfo;
     46 import android.net.wifi.ScanResult;
     47 import android.net.wifi.WifiConfiguration;
     48 import android.net.wifi.WifiInfo;
     49 import android.net.wifi.WifiManager;
     50 import android.os.Bundle;
     51 import android.os.Handler;
     52 import android.os.Message;
     53 import android.text.TextUtils;
     54 import android.util.Pair;
     55 import android.view.View;
     56 
     57 import java.util.ArrayList;
     58 import java.util.Collections;
     59 import java.util.HashMap;
     60 import java.util.List;
     61 
     62 /**
     63  * Wi-Fi settings during initial setup for a large no-touch device
     64  */
     65 public class WifiSetupActivity extends WifiMultiPagedFormActivity
     66         implements ConnectToWifiFragment.Listener, TimedMessageWizardFragment.Listener {
     67 
     68     private static final String TAG = "WifiSetupActivity";
     69     private static final int MSG_NETWORK_REFRESH = 1;
     70     private static final int NETWORK_REFRESH_TIMEOUT = 5000;
     71     private static final String EXTRA_SHOW_SUMMARY = "extra_show_summary";
     72     private static final String EXTRA_SHOW_SKIP_NETWORK = "extra_show_skip_network";
     73     private static final String EXTRA_SHOW_WPS_AT_TOP = "extra_show_wps_at_top";
     74     // If you change this constant, make sure to change the constant in setup wizard
     75     private static final int RESULT_NETWORK_SKIPPED = 3;
     76 
     77     private boolean mShowSkipNetwork;
     78     private boolean mShowWpsAtTop;
     79     private AdvancedWifiOptionsFlow mAdvancedWifiOptionsFlow;
     80     private WifiManager mWifiManager;
     81     private WifiConfiguration mConfiguration;
     82     private String mConnectedNetwork;
     83     private WifiSecurity mWifiSecurity;
     84     private Handler mHandler;
     85     private FormPageDisplayer.UserActivityListener mUserActivityListener;
     86     private FormPage mChooseNetworkPage;
     87     private FormPage mSsidPage;
     88     private FormPage mSecurityPage;
     89     private FormPage mPasswordPage;
     90     private SelectFromListWizardFragment mNetworkListFragment;
     91     private FormPage mConnectPage;
     92     private FormPage mSuccessPage;
     93 
     94     @Override
     95     protected void onCreate(Bundle savedInstanceState) {
     96         setTheme(ThemeHelper.getThemeResource(getIntent()));
     97 
     98         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
     99         mConfiguration = new WifiConfiguration();
    100 
    101         mHandler = new Handler() {
    102             @Override
    103             public void handleMessage(Message msg) {
    104                 if (mNetworkListFragment != null) {
    105                     mNetworkListFragment.update(WifiFormPageType.CHOOSE_NETWORK.getChoices(
    106                             WifiSetupActivity.this, getNetworks()));
    107                     mHandler.sendEmptyMessageDelayed(MSG_NETWORK_REFRESH, NETWORK_REFRESH_TIMEOUT);
    108                 }
    109             }
    110         };
    111         mUserActivityListener = new FormPageDisplayer.UserActivityListener() {
    112             @Override
    113             public void onUserActivity() {
    114                 mHandler.removeMessages(MSG_NETWORK_REFRESH);
    115                 mHandler.sendEmptyMessageDelayed(MSG_NETWORK_REFRESH, NETWORK_REFRESH_TIMEOUT);
    116             }
    117         };
    118 
    119         boolean showSummary = getIntent().getBooleanExtra(EXTRA_SHOW_SUMMARY, false);
    120         mShowSkipNetwork = getIntent().getBooleanExtra(EXTRA_SHOW_SKIP_NETWORK, false);
    121         mShowWpsAtTop = getIntent().getBooleanExtra(EXTRA_SHOW_WPS_AT_TOP, false);
    122 
    123         if (showSummary) {
    124             addSummaryPage();
    125         } else {
    126             addPage(WifiFormPageType.CHOOSE_NETWORK);
    127         }
    128 
    129         super.onCreate(savedInstanceState);
    130 
    131         // fade in
    132         ObjectAnimator animator = TransitionUtils.createActivityFadeInAnimator(getResources(),
    133                 true);
    134         animator.setTarget(getContentView());
    135         animator.start();
    136     }
    137 
    138     @Override
    139     public void finish() {
    140         // fade out and really finish when we're done
    141         ObjectAnimator animator = TransitionUtils.createActivityFadeOutAnimator(getResources(),
    142                 true);
    143         animator.setTarget(getContentView());
    144         animator.addListener(new Animator.AnimatorListener() {
    145 
    146             @Override
    147             public void onAnimationStart(Animator animation) {
    148             }
    149 
    150             @Override
    151             public void onAnimationRepeat(Animator animation) {
    152             }
    153 
    154             @Override
    155             public void onAnimationEnd(Animator animation) {
    156                 doFinish();
    157             }
    158 
    159             @Override
    160             public void onAnimationCancel(Animator animation) {
    161             }
    162         });
    163         animator.start();
    164     }
    165 
    166     @Override
    167     public void onConnectToWifiCompleted(int reason) {
    168         Bundle result = new Bundle();
    169         result.putString(FormPage.DATA_KEY_SUMMARY_STRING, Integer.toString(reason));
    170         onBundlePageResult(mConnectPage, result);
    171     }
    172 
    173     @Override
    174     public void onTimedMessageCompleted() {
    175         Bundle result = new Bundle();
    176         result.putString(FormPage.DATA_KEY_SUMMARY_STRING, "");
    177         onBundlePageResult(mSuccessPage, result);
    178     }
    179 
    180     @Override
    181     public void addPage(WifiFormPageType formPageType) {
    182         for (int i = mFormPages.size() - 1; i >= 0; i--) {
    183             if (getFormPageType(mFormPages.get (i)) == formPageType) {
    184                 for (int j = mFormPages.size() - 1; j >= i; j--) {
    185                     mFormPages.remove(j);
    186                 }
    187                 break;
    188             }
    189         }
    190         addPage(formPageType.create());
    191     }
    192 
    193     @Override
    194     protected boolean onPageComplete(WifiFormPageType formPageType, FormPage formPage) {
    195 
    196         switch (formPageType) {
    197             case KNOWN_NETWORK:
    198                 if (choiceChosen(formPage, R.string.wifi_connect)) {
    199                     addStartPage();
    200                 } else if (choiceChosen(formPage, R.string.wifi_forget_network)) {
    201                     ((WifiManager) getSystemService(Context.WIFI_SERVICE)).forget(
    202                             mConfiguration.networkId, null);
    203                     addPage(WifiFormPageType.CHOOSE_NETWORK);
    204                 }
    205                 break;
    206             case CHOOSE_NETWORK:
    207                 if (choiceChosen(formPage, R.string.skip_network)) {
    208                     WifiConfigHelper.forgetWifiNetwork(this);
    209                     setResult(RESULT_NETWORK_SKIPPED);
    210                 } else {
    211                     mHandler.removeMessages(MSG_NETWORK_REFRESH);
    212                     mNetworkListFragment = null;
    213                     mChooseNetworkPage = formPage;
    214                     addPageBasedOnNetworkChoice(mChooseNetworkPage);
    215                 }
    216                 break;
    217             case ENTER_SSID:
    218                 mSsidPage = formPage;
    219                 String ssid = formPage.getDataSummary();
    220                 WifiConfigHelper.setConfigSsid(mConfiguration, ssid);
    221                 addPage(WifiFormPageType.CHOOSE_SECURITY);
    222                 break;
    223             case CHOOSE_SECURITY:
    224                 mSecurityPage = formPage;
    225                 if (choiceChosen(formPage, R.string.wifi_security_type_none)) {
    226                     mWifiSecurity = WifiSecurity.NONE;
    227                 } else if (choiceChosen(formPage, R.string.wifi_security_type_wep)) {
    228                     mWifiSecurity = WifiSecurity.WEP;
    229                 } else if (choiceChosen(formPage, R.string.wifi_security_type_wpa)) {
    230                     mWifiSecurity = WifiSecurity.PSK;
    231                 } else if (choiceChosen(formPage, R.string.wifi_security_type_eap)) {
    232                     mWifiSecurity = WifiSecurity.EAP;
    233                 }
    234                 WifiConfigHelper.setConfigKeyManagementBySecurity(mConfiguration, mWifiSecurity);
    235                 if (mWifiSecurity == WifiSecurity.NONE) {
    236                     optionsOrConnect();
    237                 } else {
    238                     addPage(WifiFormPageType.ENTER_PASSWORD);
    239                 }
    240                 break;
    241             case ENTER_PASSWORD:
    242                 mPasswordPage = formPage;
    243                 String password = formPage.getDataSummary();
    244                 setWifiConfigurationPassword(mConfiguration, mWifiSecurity, password);
    245                 optionsOrConnect();
    246                 break;
    247             case CONNECT:
    248                 switch (Integer.valueOf(formPage.getDataSummary())) {
    249                     case ConnectToWifiFragment.RESULT_REJECTED_BY_AP:
    250                         addPage(WifiFormPageType.CONNECT_REJECTED_BY_AP);
    251                         break;
    252                     case ConnectToWifiFragment.RESULT_UNKNOWN_ERROR:
    253                         addPage(WifiFormPageType.CONNECT_FAILED);
    254                         break;
    255                     case ConnectToWifiFragment.RESULT_TIMEOUT:
    256                         addPage(WifiFormPageType.CONNECT_TIMEOUT);
    257                         break;
    258                     case ConnectToWifiFragment.RESULT_BAD_AUTHENTICATION:
    259                         WifiConfigHelper.forgetConfiguration(this, mConfiguration);
    260                         addPage(WifiFormPageType.CONNECT_AUTHENTICATION_FAILURE);
    261                         break;
    262                     case ConnectToWifiFragment.RESULT_SUCCESS:
    263                         WifiConfigHelper.saveConfiguration(this, mConfiguration);
    264                         addPage(WifiFormPageType.SUCCESS);
    265                         break;
    266                     default:
    267                         break;
    268                 }
    269                 break;
    270             case CONNECT_TIMEOUT:
    271                 mAdvancedWifiOptionsFlow = new AdvancedWifiOptionsFlow(this, this, true, null);
    272                 // fall through
    273             case CONNECT_REJECTED_BY_AP:
    274                 if (choiceChosen(formPage, R.string.wifi_action_try_again)) {
    275                     optionsOrConnect();
    276                 } else {
    277                     mSsidPage = null;
    278                     mSecurityPage = null;
    279                     mPasswordPage = null;
    280                     addPage(WifiFormPageType.CHOOSE_NETWORK);
    281                 }
    282                 break;
    283             case CONNECT_FAILED:
    284                 // fall through
    285             case CONNECT_AUTHENTICATION_FAILURE:
    286                 if (choiceChosen(formPage, R.string.wifi_action_try_again)) {
    287                     addPageBasedOnNetworkChoice(mChooseNetworkPage);
    288                 } else {
    289                     mSsidPage = null;
    290                     mSecurityPage = null;
    291                     mPasswordPage = null;
    292                     addPage(WifiFormPageType.CHOOSE_NETWORK);
    293                 }
    294                 break;
    295             case SUMMARY_CONNECTED_WIFI:
    296                 if (choiceChosen(formPage, R.string.wifi_action_dont_change_network)) {
    297                     setResult(RESULT_OK);
    298                     finish();
    299                 } else if (choiceChosen(formPage, R.string.wifi_action_change_network)) {
    300                     addPage(WifiFormPageType.CHOOSE_NETWORK);
    301                 }
    302                 break;
    303             case SUMMARY_CONNECTED_NON_WIFI:
    304                 setResult(RESULT_OK);
    305                 finish();
    306                 break;
    307             case SUMMARY_NOT_CONNECTED:
    308                 addPage(WifiFormPageType.CHOOSE_NETWORK);
    309                 break;
    310             case SUCCESS:
    311                 setResult(RESULT_OK);
    312                 break;
    313             case WPS:
    314                 setResult(RESULT_OK);
    315                 break;
    316             default:
    317                 if (mAdvancedWifiOptionsFlow != null) {
    318                     switch (mAdvancedWifiOptionsFlow.handlePageComplete(formPageType, formPage)) {
    319                         case AdvancedWifiOptionsFlow.RESULT_ALL_PAGES_COMPLETE:
    320                             connect();
    321                             break;
    322                         case AdvancedWifiOptionsFlow.RESULT_UNKNOWN_PAGE:
    323                         case AdvancedWifiOptionsFlow.RESULT_PAGE_HANDLED:
    324                         default:
    325                             break;
    326                     }
    327                 }
    328                 break;
    329         }
    330         return true;
    331     }
    332 
    333     @Override
    334     protected void displayPage(FormPage formPage, FormPageResultListener listener,
    335             boolean forward) {
    336         WifiFormPageType formPageType = getFormPageType(formPage);
    337 
    338         if (formPageType == WifiFormPageType.CONNECT) {
    339             mConnectPage = formPage;
    340             Fragment fragment = ConnectToWifiFragment.newInstance(
    341                     getString(formPageType.getTitleResourceId(), mConfiguration.getPrintableSsid()),
    342                     true, mConfiguration);
    343             displayFragment(fragment, forward);
    344         } else if (formPageType == WifiFormPageType.SUCCESS) {
    345             mSuccessPage = formPage;
    346             Fragment fragment = TimedMessageWizardFragment.newInstance(
    347                     getString(formPageType.getTitleResourceId()));
    348             displayFragment(fragment, forward);
    349         } else if (formPageType == WifiFormPageType.WPS) {
    350             displayFragment(MessageWizardFragment.newInstance("", true), forward);
    351         } else {
    352             Fragment fragment = displayPage(formPageType, mConfiguration.getPrintableSsid(),
    353                     formPageType == WifiFormPageType.SUMMARY_CONNECTED_WIFI ? mConnectedNetwork
    354                             : null,
    355                     formPageType == WifiFormPageType.CHOOSE_NETWORK ? getNetworks() : null,
    356                     getLastPage(formPageType),
    357                     formPageType == WifiFormPageType.CHOOSE_NETWORK ? mUserActivityListener : null,
    358                     formPageType != WifiFormPageType.SUCCESS, formPage, listener, forward,
    359                             (mAdvancedWifiOptionsFlow != null) ? mAdvancedWifiOptionsFlow
    360                             .isEmptyTextAllowed(formPageType) : false);
    361             if (formPageType == WifiFormPageType.CHOOSE_NETWORK) {
    362                 mNetworkListFragment = (SelectFromListWizardFragment) fragment;
    363                 mHandler.sendEmptyMessageDelayed(MSG_NETWORK_REFRESH, NETWORK_REFRESH_TIMEOUT);
    364             }
    365         }
    366     }
    367 
    368     @Override
    369     protected void undisplayCurrentPage() {
    370         FragmentManager fragMan = getFragmentManager();
    371         Fragment target = fragMan.findFragmentById(R.id.content);
    372         FragmentTransaction transaction = fragMan.beginTransaction();
    373         transaction.remove(target);
    374         transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
    375         transaction.commit();
    376     }
    377 
    378     private void doFinish() {
    379         super.finish();
    380     }
    381 
    382     private void connect() {
    383         if (!WifiConfigHelper.isNetworkSaved(mConfiguration) &&
    384             mAdvancedWifiOptionsFlow != null) {
    385             mAdvancedWifiOptionsFlow.updateConfiguration(mConfiguration);
    386         }
    387         addPage(WifiFormPageType.CONNECT);
    388     }
    389 
    390     private void optionsOrConnect() {
    391         if (mAdvancedWifiOptionsFlow != null) {
    392             addPage(mAdvancedWifiOptionsFlow.getInitialPage());
    393         } else {
    394             connect();
    395         }
    396     }
    397 
    398     private FormPage getLastPage(WifiFormPageType formPageType) {
    399         switch (formPageType) {
    400             case CHOOSE_NETWORK:
    401                 return mChooseNetworkPage;
    402             case CHOOSE_SECURITY:
    403                 return mSecurityPage;
    404             case ENTER_PASSWORD:
    405                 return mPasswordPage;
    406             case ENTER_SSID:
    407                 return mSsidPage;
    408             default:
    409                 return (mAdvancedWifiOptionsFlow != null) ? mAdvancedWifiOptionsFlow
    410                         .getPreviousPage(formPageType)
    411                         : null;
    412         }
    413     }
    414 
    415     private ArrayList<ListItem> getNetworks() {
    416         ArrayList<SelectFromListWizardFragment.ListItem> listItems = new ArrayList<
    417                 SelectFromListWizardFragment.ListItem>();
    418         final List<ScanResult> results = mWifiManager.getScanResults();
    419         final HashMap<Pair<String, WifiSecurity>, ScanResult> consolidatedScanResults = new HashMap<
    420                 Pair<String, WifiSecurity>, ScanResult>();
    421         for (ScanResult result : results) {
    422             if (TextUtils.isEmpty(result.SSID)) {
    423                 continue;
    424             }
    425 
    426             Pair<String, WifiSecurity> key = new Pair<String, WifiSecurity>(
    427                     result.SSID, WifiSecurity.getSecurity(result));
    428             ScanResult existing = consolidatedScanResults.get(key);
    429             if (existing == null || existing.level < result.level) {
    430                 consolidatedScanResults.put(key, result);
    431             }
    432         }
    433         for (ScanResult result : consolidatedScanResults.values()) {
    434             listItems.add(new SelectFromListWizardFragment.ListItem(result));
    435         }
    436         Collections.sort(listItems, new SelectFromListWizardFragment.ListItemComparator());
    437 
    438         SelectFromListWizardFragment.ListItem wpsItem = new SelectFromListWizardFragment.ListItem(
    439                 getString(R.string.wps_network).toUpperCase(), R.drawable.ic_setup_wps);
    440         if (mShowWpsAtTop) {
    441             listItems.add(0, wpsItem);
    442         } else {
    443             listItems.add(wpsItem);
    444         }
    445 
    446         if (mShowSkipNetwork) {
    447             listItems.add(new SelectFromListWizardFragment.ListItem(
    448                    getString(R.string.skip_network).toUpperCase(), 0));
    449         }
    450 
    451         return listItems;
    452     }
    453 
    454     private void addPageBasedOnNetworkChoice(FormPage chooseNetworkPage) {
    455         if (choiceChosen(chooseNetworkPage, R.string.other_network)) {
    456             mConfiguration.hiddenSSID = true;
    457             addPage(WifiFormPageType.ENTER_SSID);
    458         } else if (choiceChosen(chooseNetworkPage, R.string.wps_network)) {
    459             addPage(WifiFormPageType.WPS, new Intent(this, WpsConnectionActivity.class)
    460                     .putExtras(getIntent().getExtras()));
    461         } else {
    462             ScanResult scanResult = getListItem(chooseNetworkPage).getScanResult();
    463             mConfiguration = WifiConfigHelper.getConfigurationForNetwork(this, scanResult);
    464             mWifiSecurity = WifiSecurity.getSecurity(scanResult);
    465 
    466             if (WifiConfigHelper.isNetworkSaved(mConfiguration)) {
    467                 addPage(WifiFormPageType.KNOWN_NETWORK);
    468             } else {
    469                 addStartPage();
    470             }
    471         }
    472     }
    473 
    474     private void addStartPage() {
    475         if ((mWifiSecurity == WifiSecurity.WEP && TextUtils.isEmpty(mConfiguration.wepKeys[0]))
    476                 || (!mWifiSecurity.isOpen() && TextUtils.isEmpty(mConfiguration.preSharedKey))) {
    477             addPage(WifiFormPageType.ENTER_PASSWORD);
    478         } else {
    479             connect();
    480         }
    481     }
    482 
    483     private void addSummaryPage() {
    484         ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(
    485                 Context.CONNECTIVITY_SERVICE);
    486         NetworkInfo currentConnection = connectivityManager.getActiveNetworkInfo();
    487         boolean isConnected = (currentConnection != null) && currentConnection.isConnected();
    488         if (isConnected) {
    489             if (currentConnection.getType() == ConnectivityManager.TYPE_WIFI) {
    490                 WifiInfo currentWifiConnection = mWifiManager.getConnectionInfo();
    491                 mConnectedNetwork = WifiInfo.removeDoubleQuotes(
    492                         currentWifiConnection.getSSID());
    493                 if (mConnectedNetwork == null) {
    494                     mConnectedNetwork = getString(R.string.wifi_summary_unknown_network);
    495                 }
    496                 addPage(WifiFormPageType.SUMMARY_CONNECTED_WIFI);
    497             } else {
    498                 addPage(WifiFormPageType.SUMMARY_CONNECTED_NON_WIFI);
    499             }
    500         } else {
    501             addPage(WifiFormPageType.SUMMARY_NOT_CONNECTED);
    502         }
    503     }
    504 }
    505