Home | History | Annotate | Download | only in connectivity
      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;
     18 
     19 import android.content.Context;
     20 import android.net.IpConfiguration;
     21 import android.net.IpConfiguration.IpAssignment;
     22 import android.net.IpConfiguration.ProxySettings;
     23 import android.net.LinkAddress;
     24 import android.net.NetworkUtils;
     25 import android.net.ProxyInfo;
     26 import android.net.StaticIpConfiguration;
     27 import android.net.wifi.WifiConfiguration;
     28 import android.os.Bundle;
     29 import android.text.TextUtils;
     30 
     31 import com.android.tv.settings.R;
     32 import com.android.tv.settings.form.FormPage;
     33 
     34 import java.net.Inet4Address;
     35 import java.net.InetAddress;
     36 
     37 /**
     38  * Handles the form page flow of setting advanced options.
     39  */
     40 public class AdvancedWifiOptionsFlow {
     41 
     42     public interface PageHandler {
     43         void addPage(WifiFormPageType formPageType);
     44 
     45         void removePage(FormPage formPage);
     46 
     47         boolean choiceChosen(FormPage formPage, int choiceResourceId);
     48     }
     49 
     50     public static final int RESULT_UNKNOWN_PAGE = 0;
     51     public static final int RESULT_PAGE_HANDLED = 1;
     52     public static final int RESULT_ALL_PAGES_COMPLETE = 2;
     53 
     54     private final Context mContext;
     55     private final PageHandler mPageHandler;
     56     private final boolean mAskFirst;
     57     private final NetworkConfiguration mInitialConfiguration;
     58     private FormPage mAdvancedOptionsPage;
     59     private FormPage mProxySettingsPage;
     60     private FormPage mIpSettingsPage;
     61     private FormPage mProxyHostnamePage;
     62     private FormPage mProxyPortPage;
     63     private FormPage mProxyBypassPage;
     64     private FormPage mIpAddressPage;
     65     private FormPage mGatewayPage;
     66     private FormPage mNetworkPrefixLengthPage;
     67     private FormPage mDns1Page;
     68     private FormPage mDns2Page;
     69     private final IpConfiguration mIpConfiguration;
     70     private final boolean mSettingsFlow;
     71 
     72     public AdvancedWifiOptionsFlow(Context context, PageHandler pageHandler,
     73             NetworkConfiguration initialConfiguration) {
     74         mContext = context;
     75         mPageHandler = pageHandler;
     76         mAskFirst = false;
     77         mSettingsFlow = true;
     78         mInitialConfiguration = initialConfiguration;
     79         mIpConfiguration = (initialConfiguration != null) ?
     80                 mInitialConfiguration.getIpConfiguration() :
     81                 new IpConfiguration();
     82     }
     83 
     84     public AdvancedWifiOptionsFlow(Context context, PageHandler pageHandler, boolean askFirst,
     85             NetworkConfiguration initialConfiguration) {
     86         mContext = context;
     87         mPageHandler = pageHandler;
     88         mAskFirst = askFirst;
     89         mSettingsFlow = false;
     90         mInitialConfiguration = initialConfiguration;
     91         mIpConfiguration = (initialConfiguration != null) ?
     92                 mInitialConfiguration.getIpConfiguration() :
     93                 new IpConfiguration();
     94     }
     95 
     96     public WifiFormPageType getInitialPage() {
     97         return (mAskFirst) ? WifiFormPageType.ADVANCED_OPTIONS : WifiFormPageType.PROXY_SETTINGS;
     98     }
     99 
    100     public WifiFormPageType getInitialProxySettingsPage() {
    101         return WifiFormPageType.PROXY_SETTINGS;
    102     }
    103 
    104    public WifiFormPageType getInitialIpSettingsPage() {
    105         return WifiFormPageType.IP_SETTINGS;
    106     }
    107 
    108     /**
    109      * @param formPageType the type of page that completed.
    110      * @param formPage the page that complete.
    111      * @return RESULT_PAGE_HANDLED if the page has been handled.
    112      *         RESULT_UNKNOWN_PAGE if the page is unrecognized and was ignored.
    113      *         RESULT_ALL_PAGES_COMPLETE if all pages have been completed.
    114      */
    115     public int handlePageComplete(WifiFormPageType formPageType, FormPage formPage) {
    116 
    117         switch (formPageType) {
    118             case ADVANCED_OPTIONS:
    119                 mAdvancedOptionsPage = formPage;
    120                 if (mPageHandler.choiceChosen(formPage, R.string.wifi_action_advanced_no)) {
    121                     processProxySettings();
    122                     processIpSettings();
    123                     return RESULT_ALL_PAGES_COMPLETE;
    124                 } else {
    125                     mPageHandler.addPage(WifiFormPageType.PROXY_SETTINGS);
    126                 }
    127                 break;
    128             case PROXY_SETTINGS:
    129                 mProxySettingsPage = formPage;
    130                 if (mPageHandler.choiceChosen(formPage, R.string.wifi_action_proxy_none)) {
    131                     processProxySettings();
    132                     if (mSettingsFlow) {
    133                         return RESULT_ALL_PAGES_COMPLETE;
    134                     } else {
    135                         mPageHandler.addPage(WifiFormPageType.IP_SETTINGS);
    136                     }
    137                 } else {
    138                     mPageHandler.addPage(WifiFormPageType.PROXY_HOSTNAME);
    139                 }
    140                 break;
    141             case PROXY_HOSTNAME:
    142                 mProxyHostnamePage = formPage;
    143                 mPageHandler.addPage(WifiFormPageType.PROXY_PORT);
    144                 break;
    145             case PROXY_PORT:
    146                 mProxyPortPage = formPage;
    147                 mPageHandler.addPage(WifiFormPageType.PROXY_BYPASS);
    148                 break;
    149             case PROXY_BYPASS:
    150                 mProxyBypassPage = formPage;
    151                 int proxySettingsResult = processProxySettings();
    152                 if (proxySettingsResult == 0) {
    153                     if (mSettingsFlow) {
    154                         return RESULT_ALL_PAGES_COMPLETE;
    155                     } else {
    156                         mPageHandler.addPage(WifiFormPageType.IP_SETTINGS);
    157                     }
    158                 } else {
    159                     mPageHandler.addPage(WifiFormPageType.PROXY_SETTINGS_INVALID);
    160                 }
    161                 break;
    162             case PROXY_SETTINGS_INVALID:
    163                 mPageHandler.removePage(mProxySettingsPage);
    164                 mPageHandler.removePage(mProxyHostnamePage);
    165                 mPageHandler.removePage(mProxyPortPage);
    166                 mPageHandler.removePage(mProxyBypassPage);
    167                 mPageHandler.addPage(WifiFormPageType.PROXY_SETTINGS);
    168                 break;
    169             case IP_SETTINGS:
    170                 mIpSettingsPage = formPage;
    171                 if (mPageHandler.choiceChosen(formPage, R.string.wifi_action_dhcp)) {
    172                     processIpSettings();
    173                     return RESULT_ALL_PAGES_COMPLETE;
    174                 } else {
    175                     mPageHandler.addPage(WifiFormPageType.IP_ADDRESS);
    176                 }
    177                 break;
    178             case IP_ADDRESS:
    179                 mIpAddressPage = formPage;
    180                 mPageHandler.addPage(WifiFormPageType.GATEWAY);
    181                 break;
    182             case GATEWAY:
    183                 mGatewayPage = formPage;
    184                 mPageHandler.addPage(WifiFormPageType.NETWORK_PREFIX_LENGTH);
    185                 break;
    186             case NETWORK_PREFIX_LENGTH:
    187                 mNetworkPrefixLengthPage = formPage;
    188                 mPageHandler.addPage(WifiFormPageType.DNS1);
    189                 break;
    190             case DNS1:
    191                 mDns1Page = formPage;
    192                 mPageHandler.addPage(WifiFormPageType.DNS2);
    193                 break;
    194             case DNS2:
    195                 mDns2Page = formPage;
    196                 int ipSettingsResult = processIpSettings();
    197                 if (ipSettingsResult == 0) {
    198                     return RESULT_ALL_PAGES_COMPLETE;
    199                 } else {
    200                     mPageHandler.addPage(WifiFormPageType.IP_SETTINGS_INVALID);
    201                 }
    202                 break;
    203             case IP_SETTINGS_INVALID:
    204                 mPageHandler.removePage(mIpSettingsPage);
    205                 mPageHandler.removePage(mIpAddressPage);
    206                 mPageHandler.removePage(mGatewayPage);
    207                 mPageHandler.removePage(mDns1Page);
    208                 mPageHandler.removePage(mDns2Page);
    209                 mPageHandler.addPage(WifiFormPageType.IP_SETTINGS);
    210                 break;
    211             default:
    212                 return RESULT_UNKNOWN_PAGE;
    213         }
    214         return RESULT_PAGE_HANDLED;
    215     }
    216 
    217     public FormPage getPreviousPage(WifiFormPageType formPageType) {
    218         switch (formPageType) {
    219             case ADVANCED_OPTIONS:
    220                 return mAdvancedOptionsPage;
    221             case PROXY_SETTINGS:
    222                 if (mProxySettingsPage == null && getInitialProxyInfo() != null) {
    223                     return createFormPage(R.string.wifi_action_proxy_manual);
    224                 }
    225                 return mProxySettingsPage;
    226             case PROXY_HOSTNAME:
    227                 if (mProxyHostnamePage == null && getInitialProxyInfo() != null) {
    228                     return createFormPage(getInitialProxyInfo().getHost());
    229                 }
    230                 return mProxyHostnamePage;
    231             case PROXY_PORT:
    232                 if (mProxyPortPage == null && getInitialProxyInfo() != null) {
    233                     return createFormPage(Integer.toString(getInitialProxyInfo().getPort()));
    234                 }
    235                 return mProxyPortPage;
    236             case PROXY_BYPASS:
    237                 if (mProxyBypassPage == null && getInitialProxyInfo() != null) {
    238                     return createFormPage(getInitialProxyInfo().getExclusionListAsString());
    239                 }
    240                 return mProxyBypassPage;
    241             case IP_SETTINGS:
    242                 if (mIpSettingsPage == null && getInitialLinkAddress() != null) {
    243                     return createFormPage(R.string.wifi_action_static);
    244                 }
    245                 return mIpSettingsPage;
    246             case IP_ADDRESS:
    247                 if (mIpAddressPage == null && getInitialLinkAddress() != null) {
    248                     return createFormPage(getInitialLinkAddress().getAddress().getHostAddress());
    249                 }
    250                 return mIpAddressPage;
    251             case GATEWAY:
    252                 if (mGatewayPage == null && getInitialGateway() != null) {
    253                     return createFormPage(getInitialGateway().getHostAddress());
    254                 }
    255                 return mGatewayPage;
    256             case NETWORK_PREFIX_LENGTH:
    257                 if (mNetworkPrefixLengthPage == null && getInitialLinkAddress() != null) {
    258                     return createFormPage(
    259                             Integer.toString(getInitialLinkAddress().getNetworkPrefixLength()));
    260                 }
    261                 return mNetworkPrefixLengthPage;
    262             case DNS1:
    263                 if (mDns1Page == null && getInitialDns(0) != null) {
    264                     return createFormPage(getInitialDns(0).getHostAddress());
    265                 }
    266                 return mDns1Page;
    267             case DNS2:
    268                 if (mDns2Page == null && getInitialDns(1) != null) {
    269                     return createFormPage(getInitialDns(1).getHostAddress());
    270                 }
    271                 return mDns2Page;
    272             case IP_SETTINGS_INVALID:
    273             case PROXY_SETTINGS_INVALID:
    274             default:
    275                 return null;
    276         }
    277     }
    278 
    279     public boolean isEmptyTextAllowed(WifiFormPageType formPageType) {
    280         switch (formPageType) {
    281             case PROXY_BYPASS:
    282             case DNS1:
    283             case DNS2:
    284             case GATEWAY:
    285                 return true;
    286             default:
    287                 return false;
    288         }
    289     }
    290 
    291     private IpConfiguration getCurrentIpConfiguration() {
    292         return mIpConfiguration;
    293     }
    294 
    295     public void updateConfiguration(WifiConfiguration configuration) {
    296         configuration.setIpConfiguration(mIpConfiguration);
    297     }
    298 
    299     public void updateConfiguration(NetworkConfiguration configuration) {
    300         configuration.setIpConfiguration(mIpConfiguration);
    301     }
    302 
    303     private InetAddress getInitialDns(int index) {
    304         try {
    305             return mInitialConfiguration.getIpConfiguration().getStaticIpConfiguration()
    306                     .dnsServers.get(index);
    307         } catch (IndexOutOfBoundsException|NullPointerException e) {
    308             return null;
    309         }
    310     }
    311 
    312     private InetAddress getInitialGateway() {
    313         try {
    314             return mInitialConfiguration.getIpConfiguration().getStaticIpConfiguration().gateway;
    315         } catch (NullPointerException e) {
    316             return null;
    317         }
    318     }
    319 
    320     private LinkAddress getInitialLinkAddress() {
    321         try {
    322             return mInitialConfiguration.getIpConfiguration().getStaticIpConfiguration().ipAddress;
    323         } catch (NullPointerException e) {
    324             return null;
    325         }
    326     }
    327 
    328     private ProxyInfo getInitialProxyInfo() {
    329         try {
    330             return mInitialConfiguration.getIpConfiguration().getHttpProxy();
    331         } catch (NullPointerException e) {
    332             return null;
    333         }
    334     }
    335 
    336     private FormPage createFormPage(int resultStringResourceId) {
    337         return createFormPage(mContext.getString(resultStringResourceId));
    338     }
    339 
    340     private FormPage createFormPage(String resultString) {
    341         Bundle result = new Bundle();
    342         result.putString(FormPage.DATA_KEY_SUMMARY_STRING, resultString);
    343         FormPage formPage = FormPage.createTextInputForm(resultString);
    344         formPage.complete(result);
    345         return formPage;
    346     }
    347 
    348     private int processProxySettings() {
    349         boolean hasProxySettings = (mAdvancedOptionsPage == null || !mPageHandler.choiceChosen(
    350                 mAdvancedOptionsPage, R.string.wifi_action_advanced_no))
    351                 && !mPageHandler.choiceChosen(mProxySettingsPage, R.string.wifi_action_proxy_none);
    352         mIpConfiguration.setProxySettings(hasProxySettings ?
    353                                           ProxySettings.STATIC : ProxySettings.NONE);
    354         if (hasProxySettings) {
    355             String host = mProxyHostnamePage.getDataSummary();
    356             String portStr = mProxyPortPage.getDataSummary();
    357             String exclusionList = mProxyBypassPage.getDataSummary();
    358             int port = 0;
    359             int result = 0;
    360             try {
    361                 port = Integer.parseInt(portStr);
    362                 result = WifiConfigHelper.validate(host, portStr, exclusionList);
    363             } catch (NumberFormatException e) {
    364                 result = R.string.proxy_error_invalid_port;
    365             }
    366             if (result == 0) {
    367                 mIpConfiguration.setHttpProxy(new ProxyInfo(host, port, exclusionList));
    368             } else {
    369                 return result;
    370             }
    371         } else {
    372             mIpConfiguration.setHttpProxy(null);
    373         }
    374 
    375         return 0;
    376     }
    377 
    378     private int processIpSettings() {
    379         boolean hasIpSettings = (mAdvancedOptionsPage == null || !mPageHandler.choiceChosen(
    380                 mAdvancedOptionsPage, R.string.wifi_action_advanced_no))
    381                 && !mPageHandler.choiceChosen(mIpSettingsPage, R.string.wifi_action_dhcp);
    382         mIpConfiguration.setIpAssignment(hasIpSettings ? IpAssignment.STATIC : IpAssignment.DHCP);
    383 
    384         if (hasIpSettings) {
    385             StaticIpConfiguration staticConfig = new StaticIpConfiguration();
    386             mIpConfiguration.setStaticIpConfiguration(staticConfig);
    387 
    388             String ipAddr = mIpAddressPage.getDataSummary();
    389             if (TextUtils.isEmpty(ipAddr))
    390                 return R.string.wifi_ip_settings_invalid_ip_address;
    391 
    392             Inet4Address inetAddr = null;
    393             try {
    394                 inetAddr = (Inet4Address) NetworkUtils.numericToInetAddress(ipAddr);
    395             } catch (IllegalArgumentException|ClassCastException e) {
    396                 return R.string.wifi_ip_settings_invalid_ip_address;
    397             }
    398 
    399             int networkPrefixLength = -1;
    400             try {
    401                 networkPrefixLength = Integer.parseInt(mNetworkPrefixLengthPage.getDataSummary());
    402                 if (networkPrefixLength < 0 || networkPrefixLength > 32) {
    403                     return R.string.wifi_ip_settings_invalid_network_prefix_length;
    404                 }
    405                 staticConfig.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
    406             } catch (NumberFormatException e) {
    407                 return R.string.wifi_ip_settings_invalid_ip_address;
    408             }
    409 
    410             String gateway = mGatewayPage.getDataSummary();
    411             if (!TextUtils.isEmpty(gateway)) {
    412                 try {
    413                     staticConfig.gateway =
    414                             (Inet4Address) NetworkUtils.numericToInetAddress(gateway);
    415                 } catch (IllegalArgumentException|ClassCastException e) {
    416                     return R.string.wifi_ip_settings_invalid_gateway;
    417                 }
    418             }
    419 
    420             String dns1 = mDns1Page.getDataSummary();
    421             if (!TextUtils.isEmpty(dns1)) {
    422                 try {
    423                     staticConfig.dnsServers.add(
    424                             (Inet4Address) NetworkUtils.numericToInetAddress(dns1));
    425                 } catch (IllegalArgumentException|ClassCastException e) {
    426                     return R.string.wifi_ip_settings_invalid_dns;
    427                 }
    428             }
    429 
    430             String dns2 = mDns2Page.getDataSummary();
    431             if (!TextUtils.isEmpty(dns2)) {
    432                 try {
    433                     staticConfig.dnsServers.add(
    434                             (Inet4Address) NetworkUtils.numericToInetAddress(dns2));
    435                 } catch (IllegalArgumentException|ClassCastException e) {
    436                     return R.string.wifi_ip_settings_invalid_dns;
    437                 }
    438             }
    439         } else {
    440             mIpConfiguration.setStaticIpConfiguration(null);
    441         }
    442         return 0;
    443     }
    444 }
    445