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
17package com.android.tv.settings.connectivity;
18
19import android.app.Fragment;
20import android.content.Context;
21import android.content.Intent;
22import android.net.wifi.WifiConfiguration;
23import android.os.Bundle;
24import android.text.TextUtils;
25
26import com.android.settingslib.wifi.AccessPoint;
27import com.android.tv.settings.R;
28import com.android.tv.settings.form.FormPage;
29import com.android.tv.settings.form.FormPageResultListener;
30
31/**
32 * Add a wifi network where we already know the ssid/security; normal post-install settings.
33 */
34public class WifiConnectionActivity extends WifiMultiPagedFormActivity
35        implements ConnectToWifiFragment.Listener, TimedMessageWizardFragment.Listener {
36
37    private static final String EXTRA_WIFI_SSID = "wifi_ssid";
38    private static final String EXTRA_WIFI_SECURITY_NAME = "wifi_security_name";
39
40    public static Intent createIntent(Context context, AccessPoint result, WifiSecurity security) {
41        return new Intent(context, WifiConnectionActivity.class)
42                .putExtra(EXTRA_WIFI_SSID, result.getSsidStr())
43                .putExtra(EXTRA_WIFI_SECURITY_NAME, security.name());
44    }
45
46    public static Intent createIntent(Context context, AccessPoint result) {
47        final WifiSecurity security = WifiSecurity.getSecurity(result);
48        return createIntent(context, result, security);
49    }
50
51    public static Intent createIntent(Context context, WifiConfiguration configuration) {
52        final WifiSecurity security = WifiSecurity.getSecurity(configuration);
53        final String ssid = configuration.getPrintableSsid();
54        return new Intent(context, WifiConnectionActivity.class)
55                .putExtra(EXTRA_WIFI_SSID, ssid)
56                .putExtra(EXTRA_WIFI_SECURITY_NAME, security.name());
57    }
58
59    private AdvancedWifiOptionsFlow mAdvancedWifiOptionsFlow;
60    private WifiConfiguration mConfiguration;
61    private WifiSecurity mWifiSecurity;
62    private FormPage mPasswordPage;
63    private FormPage mConnectPage;
64    private FormPage mSuccessPage;
65
66    @Override
67    protected void onCreate(Bundle savedInstanceState) {
68        mWifiSecurity = WifiSecurity.valueOf(getIntent().getStringExtra(EXTRA_WIFI_SECURITY_NAME));
69
70        mConfiguration = WifiConfigHelper.getConfiguration(
71                this, getIntent().getStringExtra(EXTRA_WIFI_SSID), mWifiSecurity);
72
73        if (WifiConfigHelper.isNetworkSaved(mConfiguration)) {
74            addPage(WifiFormPageType.KNOWN_NETWORK);
75        } else {
76            addStartPage();
77        }
78        super.onCreate(savedInstanceState);
79    }
80
81    @Override
82    public void onConnectToWifiCompleted(int reason) {
83        Bundle result = new Bundle();
84        result.putString(FormPage.DATA_KEY_SUMMARY_STRING, Integer.toString(reason));
85        onBundlePageResult(mConnectPage, result);
86    }
87
88    @Override
89    public void onTimedMessageCompleted() {
90        Bundle result = new Bundle();
91        result.putString(FormPage.DATA_KEY_SUMMARY_STRING, "");
92        onBundlePageResult(mSuccessPage, result);
93    }
94
95    @Override
96    protected boolean onPageComplete(WifiFormPageType formPageType, FormPage formPage) {
97
98        switch (formPageType) {
99            case KNOWN_NETWORK:
100                if (choiceChosen(formPage, R.string.wifi_connect)) {
101                    addStartPage();
102                } else if (choiceChosen(formPage, R.string.wifi_forget_network)) {
103                    WifiConfigHelper.forgetConfiguration(this, mConfiguration);
104                    setResult(RESULT_OK);
105                    finish();
106                }
107                break;
108            case ENTER_PASSWORD:
109                mPasswordPage = formPage;
110                String password = formPage.getDataSummary();
111                setWifiConfigurationPassword(mConfiguration, mWifiSecurity, password);
112                optionsOrConnect();
113                break;
114            case CONNECT:
115                switch (Integer.valueOf(formPage.getDataSummary())) {
116                    case ConnectToWifiFragment.RESULT_REJECTED_BY_AP:
117                        addPage(WifiFormPageType.CONNECT_REJECTED_BY_AP);
118                        break;
119                    case ConnectToWifiFragment.RESULT_UNKNOWN_ERROR:
120                        addPage(WifiFormPageType.CONNECT_FAILED);
121                        break;
122                    case ConnectToWifiFragment.RESULT_TIMEOUT:
123                        addPage(WifiFormPageType.CONNECT_TIMEOUT);
124                        break;
125                    case ConnectToWifiFragment.RESULT_BAD_AUTHENTICATION:
126                        WifiConfigHelper.forgetConfiguration(this, mConfiguration);
127                        addPage(WifiFormPageType.CONNECT_AUTHENTICATION_FAILURE);
128                        break;
129                    case ConnectToWifiFragment.RESULT_SUCCESS:
130                        WifiConfigHelper.saveConfiguration(this, mConfiguration);
131                        addPage(WifiFormPageType.SUCCESS);
132                        break;
133                    default:
134                        break;
135                }
136                break;
137            case CONNECT_FAILED:
138                // Fall through
139            case CONNECT_TIMEOUT:
140                mAdvancedWifiOptionsFlow = new AdvancedWifiOptionsFlow(this, this, true, null);
141                // Fall through
142            case CONNECT_REJECTED_BY_AP:
143                if (choiceChosen(formPage, R.string.wifi_action_try_again)) {
144                    clear();
145                    optionsOrConnect();
146                }
147                break;
148            case CONNECT_AUTHENTICATION_FAILURE:
149                if (choiceChosen(formPage, R.string.wifi_action_try_again)) {
150                    clear();
151                    if (mWifiSecurity.isOpen()) {
152                        optionsOrConnect();
153                    } else {
154                        addPage(WifiFormPageType.ENTER_PASSWORD);
155                    }
156                }
157                break;
158            case SUCCESS:
159                break;
160            default:
161                if (mAdvancedWifiOptionsFlow != null) {
162                    switch (mAdvancedWifiOptionsFlow.handlePageComplete(formPageType, formPage)) {
163                        case AdvancedWifiOptionsFlow.RESULT_ALL_PAGES_COMPLETE:
164                            connect();
165                            break;
166                        case AdvancedWifiOptionsFlow.RESULT_UNKNOWN_PAGE:
167                        case AdvancedWifiOptionsFlow.RESULT_PAGE_HANDLED:
168                        default:
169                            break;
170                    }
171                }
172                break;
173        }
174        return true;
175    }
176
177    @Override
178    protected void displayPage(FormPage formPage, FormPageResultListener listener,
179            boolean forward) {
180        WifiFormPageType formPageType = getFormPageType(formPage);
181        if (formPageType == WifiFormPageType.CONNECT) {
182            mConnectPage = formPage;
183            Fragment fragment = ConnectToWifiFragment.newInstance(
184                    getString(formPageType.getTitleResourceId(), mConfiguration.getPrintableSsid()),
185                    true, mConfiguration);
186            displayFragment(fragment, forward);
187        } else if (formPageType == WifiFormPageType.SUCCESS) {
188            mSuccessPage = formPage;
189            Fragment fragment = TimedMessageWizardFragment.newInstance(
190                    getString(formPageType.getTitleResourceId()));
191            displayFragment(fragment, forward);
192        } else {
193            displayPage(formPageType, mConfiguration.getPrintableSsid(), null, null,
194                    getPreviousPage(formPageType), null, formPageType != WifiFormPageType.SUCCESS,
195                    formPage, listener, forward, (mAdvancedWifiOptionsFlow != null) &&
196                            mAdvancedWifiOptionsFlow.isEmptyTextAllowed(formPageType));
197        }
198    }
199
200    private FormPage getPreviousPage(WifiFormPageType formPageType) {
201        switch (formPageType) {
202            case ENTER_PASSWORD:
203                return mPasswordPage;
204            default:
205                return (mAdvancedWifiOptionsFlow != null) ? mAdvancedWifiOptionsFlow
206                        .getPreviousPage(formPageType)
207                        : null;
208        }
209    }
210
211    private void addStartPage() {
212        /**
213         * WEP connections use the wepKeys for authentication.  Other networks use preSharedKey.
214         * If the network isn't open or doesn't have its authentication info present, ask for it.
215         * Otherwise, go straight to connecting.
216         */
217        if ((mWifiSecurity == WifiSecurity.WEP && TextUtils.isEmpty(mConfiguration.wepKeys[0]))
218                || (!mWifiSecurity.isOpen() && TextUtils.isEmpty(mConfiguration.preSharedKey))) {
219            addPage(WifiFormPageType.ENTER_PASSWORD);
220        } else {
221            connect();
222        }
223    }
224
225    private void connect() {
226        if (!WifiConfigHelper.isNetworkSaved(mConfiguration) &&
227            mAdvancedWifiOptionsFlow != null) {
228            mAdvancedWifiOptionsFlow.updateConfiguration(mConfiguration);
229        }
230        addPage(WifiFormPageType.CONNECT);
231    }
232
233    private void optionsOrConnect() {
234        if (mAdvancedWifiOptionsFlow != null) {
235            addPage(mAdvancedWifiOptionsFlow.getInitialPage());
236        } else {
237            connect();
238        }
239    }
240}
241