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.setup;
18
19import android.animation.Animator;
20import android.animation.AnimatorInflater;
21import android.animation.ObjectAnimator;
22import android.app.Fragment;
23import android.app.FragmentManager;
24import android.app.FragmentTransaction;
25import android.content.Context;
26import android.content.Intent;
27import android.net.ConnectivityManager;
28import android.net.NetworkInfo;
29import android.net.wifi.ScanResult;
30import android.net.wifi.WifiConfiguration;
31import android.net.wifi.WifiInfo;
32import android.net.wifi.WifiManager;
33import android.os.Bundle;
34import android.os.HandlerThread;
35import android.os.Process;
36import android.text.TextUtils;
37import android.util.Pair;
38import android.view.accessibility.AccessibilityEvent;
39
40import com.android.settingslib.wifi.WifiTracker;
41import com.android.tv.settings.R;
42import com.android.tv.settings.connectivity.AdvancedWifiOptionsFlow;
43import com.android.tv.settings.connectivity.ConnectToWifiFragment;
44import com.android.tv.settings.connectivity.FormPageDisplayer;
45import com.android.tv.settings.connectivity.TimedMessageWizardFragment;
46import com.android.tv.settings.connectivity.WifiConfigHelper;
47import com.android.tv.settings.connectivity.WifiFormPageType;
48import com.android.tv.settings.connectivity.WifiMultiPagedFormActivity;
49import com.android.tv.settings.connectivity.WifiSecurity;
50import com.android.tv.settings.connectivity.WpsConnectionActivity;
51import com.android.tv.settings.connectivity.setup.SelectFromListWizardFragment.ListItem;
52import com.android.tv.settings.form.FormPage;
53import com.android.tv.settings.form.FormPageResultListener;
54import com.android.tv.settings.util.ThemeHelper;
55import com.android.tv.settings.util.TransitionUtils;
56
57import java.util.ArrayList;
58import java.util.HashMap;
59import java.util.List;
60
61/**
62 * Wi-Fi settings during initial setup for a large no-touch device
63 */
64public class WifiSetupActivity extends WifiMultiPagedFormActivity
65        implements ConnectToWifiFragment.Listener, TimedMessageWizardFragment.Listener {
66
67    private static final String TAG = "WifiSetupActivity";
68    private static final int NETWORK_REFRESH_BUFFER_DURATION = 5000;
69
70    private static final String EXTRA_SHOW_SUMMARY = "extra_show_summary";
71    private static final String EXTRA_SHOW_SKIP_NETWORK = "extra_show_skip_network";
72    private static final String EXTRA_SHOW_WPS_AT_TOP = "extra_show_wps_at_top";
73    private static final String EXTRA_MOVING_FORWARD = "movingForward";
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 mResultOk = false;
78    private boolean mShowFirstFragmentBackwards;
79    private boolean mShowSkipNetwork;
80    private boolean mShowWpsAtTop;
81    private AdvancedWifiOptionsFlow mAdvancedWifiOptionsFlow;
82    private WifiTracker mWifiTracker;
83    private HandlerThread mBgThread;
84
85    private WifiConfiguration mConfiguration;
86    private String mConnectedNetwork;
87    private WifiSecurity mWifiSecurity;
88    private FormPageDisplayer.UserActivityListener mUserActivityListener;
89    private FormPage mChooseNetworkPage;
90    private FormPage mSsidPage;
91    private FormPage mSecurityPage;
92    private FormPage mPasswordPage;
93    private SelectFromListWizardFragment mNetworkListFragment;
94    private FormPage mConnectPage;
95    private FormPage mSuccessPage;
96    private long mNextNetworkRefreshTime;
97
98    @Override
99    protected void onCreate(Bundle savedInstanceState) {
100        mConfiguration = new WifiConfiguration();
101
102        WifiTracker.WifiListener wifiListener = new WifiTracker.WifiListener() {
103            @Override
104            public void onWifiStateChanged(int state) {}
105
106            @Override
107            public void onConnectedChanged() {}
108
109            @Override
110            public void onAccessPointsChanged() {
111                long currentTime = System.currentTimeMillis();
112                if (mNetworkListFragment != null && currentTime >= mNextNetworkRefreshTime) {
113                    mNetworkListFragment.update(WifiFormPageType.CHOOSE_NETWORK.getChoices(
114                            WifiSetupActivity.this, getNetworks()));
115                    mNextNetworkRefreshTime = currentTime + NETWORK_REFRESH_BUFFER_DURATION;
116                }
117            }
118        };
119        mBgThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
120        mBgThread.start();
121        mWifiTracker = new WifiTracker(this, wifiListener, mBgThread.getLooper(), true, true);
122        mNextNetworkRefreshTime = System.currentTimeMillis() + NETWORK_REFRESH_BUFFER_DURATION;
123
124        mUserActivityListener = new FormPageDisplayer.UserActivityListener() {
125            @Override
126            public void onUserActivity() {
127                mNextNetworkRefreshTime =
128                        System.currentTimeMillis() + NETWORK_REFRESH_BUFFER_DURATION;
129            }
130        };
131
132        boolean showSummary = getIntent().getBooleanExtra(EXTRA_SHOW_SUMMARY, false);
133        mShowSkipNetwork = getIntent().getBooleanExtra(EXTRA_SHOW_SKIP_NETWORK, false);
134        mShowWpsAtTop = getIntent().getBooleanExtra(EXTRA_SHOW_WPS_AT_TOP, false);
135        // If we are not moving forwards during the setup flow, we need to show the first fragment
136        // with the reverse animation.
137        mShowFirstFragmentBackwards = !getIntent().getBooleanExtra(EXTRA_MOVING_FORWARD, true);
138
139        if (showSummary) {
140            addSummaryPage();
141        } else {
142            addPage(WifiFormPageType.CHOOSE_NETWORK);
143        }
144
145        super.onCreate(savedInstanceState);
146
147        // fade in
148        ObjectAnimator animator = TransitionUtils.createActivityFadeInAnimator(getResources(),
149                true);
150        animator.setTarget(getContentView());
151        animator.start();
152    }
153
154    @Override
155    public void onResume() {
156        super.onResume();
157        mWifiTracker.startTracking();
158    }
159
160    @Override
161    public void onPause() {
162        super.onPause();
163        mWifiTracker.stopTracking();
164    }
165
166    @Override
167    public void finish() {
168        Animator animator;
169
170        // Choose finish animation based on whether we are in Setup or Settings and really
171        // finish this activity when the animation is complete.
172        if (ThemeHelper.fromSetupWizard(getIntent())) {
173            animator = mResultOk
174                    ? AnimatorInflater.loadAnimator(this, R.anim.setup_fragment_open_out)
175                    : AnimatorInflater.loadAnimator(this, R.anim.setup_fragment_close_out);
176        } else {
177            animator = TransitionUtils.createActivityFadeOutAnimator(getResources(), true);
178        }
179
180        animator.setTarget(getContentView());
181        animator.addListener(new Animator.AnimatorListener() {
182
183            @Override
184            public void onAnimationStart(Animator animation) {
185            }
186
187            @Override
188            public void onAnimationRepeat(Animator animation) {
189            }
190
191            @Override
192            public void onAnimationEnd(Animator animation) {
193                doFinish();
194            }
195
196            @Override
197            public void onAnimationCancel(Animator animation) {
198            }
199        });
200        animator.start();
201    }
202
203    @Override
204    protected void onDestroy() {
205        super.onDestroy();
206        mBgThread.quit();
207    }
208
209    @Override
210    public void onConnectToWifiCompleted(int reason) {
211        Bundle result = new Bundle();
212        result.putString(FormPage.DATA_KEY_SUMMARY_STRING, Integer.toString(reason));
213        onBundlePageResult(mConnectPage, result);
214    }
215
216    @Override
217    public void onTimedMessageCompleted() {
218        Bundle result = new Bundle();
219        result.putString(FormPage.DATA_KEY_SUMMARY_STRING, "");
220        onBundlePageResult(mSuccessPage, result);
221    }
222
223    @Override
224    public void addPage(WifiFormPageType formPageType) {
225        for (int i = mFormPages.size() - 1; i >= 0; i--) {
226            if (getFormPageType(mFormPages.get (i)) == formPageType) {
227                for (int j = mFormPages.size() - 1; j >= i; j--) {
228                    mFormPages.remove(j);
229                }
230                break;
231            }
232        }
233        addPage(formPageType.create());
234    }
235
236    @Override
237    protected boolean onPageComplete(WifiFormPageType formPageType, FormPage formPage) {
238
239        switch (formPageType) {
240            case KNOWN_NETWORK:
241                if (choiceChosen(formPage, R.string.wifi_connect)) {
242                    addStartPage();
243                } else if (choiceChosen(formPage, R.string.wifi_forget_network)) {
244                    ((WifiManager) getSystemService(Context.WIFI_SERVICE)).forget(
245                            mConfiguration.networkId, null);
246                    addPage(WifiFormPageType.CHOOSE_NETWORK);
247                }
248                break;
249            case CHOOSE_NETWORK:
250                if (choiceChosen(formPage, R.string.skip_network)) {
251                    WifiConfigHelper.forgetWifiNetwork(this);
252                    setResult(RESULT_NETWORK_SKIPPED);
253                } else {
254                    mWifiTracker.pauseScanning();
255                    mNetworkListFragment = null;
256                    mChooseNetworkPage = formPage;
257                    addPageBasedOnNetworkChoice(mChooseNetworkPage);
258                }
259                break;
260            case ENTER_SSID:
261                mSsidPage = formPage;
262                String ssid = formPage.getDataSummary();
263                if (mPasswordPage != null
264                        && !TextUtils.equals(mConfiguration.getPrintableSsid(), ssid)) {
265                    mPasswordPage.clearData();
266                }
267                WifiConfigHelper.setConfigSsid(mConfiguration, ssid);
268                addPage(WifiFormPageType.CHOOSE_SECURITY);
269                break;
270            case CHOOSE_SECURITY:
271                mSecurityPage = formPage;
272                if (choiceChosen(formPage, R.string.wifi_security_type_none)) {
273                    mWifiSecurity = WifiSecurity.NONE;
274                } else if (choiceChosen(formPage, R.string.wifi_security_type_wep)) {
275                    mWifiSecurity = WifiSecurity.WEP;
276                } else if (choiceChosen(formPage, R.string.wifi_security_type_wpa)) {
277                    mWifiSecurity = WifiSecurity.PSK;
278                } else if (choiceChosen(formPage, R.string.wifi_security_type_eap)) {
279                    mWifiSecurity = WifiSecurity.EAP;
280                }
281                WifiConfigHelper.setConfigKeyManagementBySecurity(mConfiguration, mWifiSecurity);
282                if (mWifiSecurity == WifiSecurity.NONE) {
283                    optionsOrConnect();
284                } else {
285                    addPage(WifiFormPageType.ENTER_PASSWORD);
286                }
287                break;
288            case ENTER_PASSWORD:
289                mPasswordPage = formPage;
290                String password = formPage.getDataSummary();
291                setWifiConfigurationPassword(mConfiguration, mWifiSecurity, password);
292                optionsOrConnect();
293                break;
294            case CONNECT:
295                switch (Integer.valueOf(formPage.getDataSummary())) {
296                    case ConnectToWifiFragment.RESULT_REJECTED_BY_AP:
297                        addPage(WifiFormPageType.CONNECT_REJECTED_BY_AP);
298                        break;
299                    case ConnectToWifiFragment.RESULT_UNKNOWN_ERROR:
300                        addPage(WifiFormPageType.CONNECT_FAILED);
301                        break;
302                    case ConnectToWifiFragment.RESULT_TIMEOUT:
303                        addPage(WifiFormPageType.CONNECT_TIMEOUT);
304                        break;
305                    case ConnectToWifiFragment.RESULT_BAD_AUTHENTICATION:
306                        WifiConfigHelper.forgetConfiguration(this, mConfiguration);
307                        addPage(WifiFormPageType.CONNECT_AUTHENTICATION_FAILURE);
308                        break;
309                    case ConnectToWifiFragment.RESULT_SUCCESS:
310                        WifiConfigHelper.saveConfiguration(this, mConfiguration);
311                        addPage(WifiFormPageType.SUCCESS);
312                        break;
313                    default:
314                        break;
315                }
316                break;
317            case CONNECT_TIMEOUT:
318                mAdvancedWifiOptionsFlow = new AdvancedWifiOptionsFlow(this, this, true, null);
319                // fall through
320            case CONNECT_REJECTED_BY_AP:
321                if (choiceChosen(formPage, R.string.wifi_action_try_again)) {
322                    optionsOrConnect();
323                } else {
324                    mSsidPage = null;
325                    mSecurityPage = null;
326                    mPasswordPage = null;
327                    addPage(WifiFormPageType.CHOOSE_NETWORK);
328                }
329                break;
330            case CONNECT_FAILED:
331                // fall through
332            case CONNECT_AUTHENTICATION_FAILURE:
333                if (choiceChosen(formPage, R.string.wifi_action_try_again)) {
334                    addPageBasedOnNetworkChoice(mChooseNetworkPage);
335                } else {
336                    mSsidPage = null;
337                    mSecurityPage = null;
338                    mPasswordPage = null;
339                    addPage(WifiFormPageType.CHOOSE_NETWORK);
340                }
341                break;
342            case SUMMARY_CONNECTED_WIFI:
343                if (choiceChosen(formPage, R.string.wifi_action_dont_change_network)) {
344                    setResultOk();
345                    finish();
346                } else if (choiceChosen(formPage, R.string.wifi_action_change_network)) {
347                    addPage(WifiFormPageType.CHOOSE_NETWORK);
348                }
349                break;
350            case SUMMARY_CONNECTED_NON_WIFI:
351                setResultOk();
352                finish();
353                break;
354            case SUMMARY_NOT_CONNECTED:
355                addPage(WifiFormPageType.CHOOSE_NETWORK);
356                break;
357            case SUCCESS:
358                setResultOk();
359                break;
360            case WPS:
361                setResultOk();
362                break;
363            default:
364                if (mAdvancedWifiOptionsFlow != null) {
365                    switch (mAdvancedWifiOptionsFlow.handlePageComplete(formPageType, formPage)) {
366                        case AdvancedWifiOptionsFlow.RESULT_ALL_PAGES_COMPLETE:
367                            connect();
368                            break;
369                        case AdvancedWifiOptionsFlow.RESULT_UNKNOWN_PAGE:
370                        case AdvancedWifiOptionsFlow.RESULT_PAGE_HANDLED:
371                        default:
372                            break;
373                    }
374                }
375                break;
376        }
377        return true;
378    }
379
380    @Override
381    protected void displayPage(FormPage formPage, FormPageResultListener listener,
382            boolean forward) {
383        WifiFormPageType formPageType = getFormPageType(formPage);
384
385        if (mShowFirstFragmentBackwards) {
386            // We entered this activity by moving backwards in setup, so set the forward boolean
387            // to false in order to show the first fragment with backwards animation.
388            forward = false;
389
390            // Reset the flag to false so that following fragments are handled normally.
391            mShowFirstFragmentBackwards = false;
392        }
393
394        if (formPageType == WifiFormPageType.CONNECT) {
395            mConnectPage = formPage;
396            Fragment fragment = ConnectToWifiFragment.newInstance(
397                    getString(formPageType.getTitleResourceId(), mConfiguration.getPrintableSsid()),
398                    true, mConfiguration);
399            displayFragment(fragment, forward);
400        } else if (formPageType == WifiFormPageType.SUCCESS) {
401            mSuccessPage = formPage;
402            Fragment fragment = TimedMessageWizardFragment.newInstance(
403                    getString(formPageType.getTitleResourceId()));
404            displayFragment(fragment, forward);
405        } else if (formPageType == WifiFormPageType.WPS) {
406            displayFragment(MessageWizardFragment.newInstance("", true), forward);
407        } else {
408            Fragment fragment = displayPage(formPageType, mConfiguration.getPrintableSsid(),
409                    formPageType == WifiFormPageType.SUMMARY_CONNECTED_WIFI ? mConnectedNetwork
410                            : null,
411                    formPageType == WifiFormPageType.CHOOSE_NETWORK ? getNetworks() : null,
412                    getLastPage(formPageType),
413                    formPageType == WifiFormPageType.CHOOSE_NETWORK ? mUserActivityListener : null,
414                    formPageType != WifiFormPageType.SUCCESS, formPage, listener, forward,
415                            (mAdvancedWifiOptionsFlow != null) ? mAdvancedWifiOptionsFlow
416                            .isEmptyTextAllowed(formPageType) : false);
417            if (formPageType == WifiFormPageType.CHOOSE_NETWORK) {
418                mNetworkListFragment = (SelectFromListWizardFragment) fragment;
419                mWifiTracker.resumeScanning();
420            }
421        }
422        if (ThemeHelper.fromSetupWizard(getIntent())) {
423            updateTitle(formPageType);
424        }
425    }
426
427    @Override
428    protected void undisplayCurrentPage() {
429        mWifiTracker.pauseScanning();
430
431        FragmentManager fragMan = getFragmentManager();
432        Fragment target = fragMan.findFragmentById(R.id.content);
433        FragmentTransaction transaction = fragMan.beginTransaction();
434        transaction.remove(target);
435        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
436        transaction.commit();
437    }
438
439    private void doFinish() {
440        super.finish();
441    }
442
443    private void connect() {
444        if (!WifiConfigHelper.isNetworkSaved(mConfiguration) &&
445            mAdvancedWifiOptionsFlow != null) {
446            mAdvancedWifiOptionsFlow.updateConfiguration(mConfiguration);
447        }
448        addPage(WifiFormPageType.CONNECT);
449    }
450
451    private void optionsOrConnect() {
452        if (mAdvancedWifiOptionsFlow != null) {
453            addPage(mAdvancedWifiOptionsFlow.getInitialPage());
454        } else {
455            connect();
456        }
457    }
458
459    private FormPage getLastPage(WifiFormPageType formPageType) {
460        switch (formPageType) {
461            case CHOOSE_NETWORK:
462                return mChooseNetworkPage;
463            case CHOOSE_SECURITY:
464                return mSecurityPage;
465            case ENTER_PASSWORD:
466                return mPasswordPage;
467            case ENTER_SSID:
468                return mSsidPage;
469            default:
470                return (mAdvancedWifiOptionsFlow != null) ? mAdvancedWifiOptionsFlow
471                        .getPreviousPage(formPageType)
472                        : null;
473        }
474    }
475
476    private ArrayList<ListItem> getNetworks() {
477        ArrayList<SelectFromListWizardFragment.ListItem> listItems = new ArrayList<>();
478        final List<ScanResult> results = mWifiTracker.getManager().getScanResults();
479        final HashMap<Pair<String, WifiSecurity>, ScanResult> consolidatedScanResults =
480                new HashMap<>();
481        for (ScanResult result : results) {
482            if (TextUtils.isEmpty(result.SSID)) {
483                continue;
484            }
485
486            Pair<String, WifiSecurity> key =
487                    new Pair<>(result.SSID, WifiSecurity.getSecurity(result));
488            ScanResult existing = consolidatedScanResults.get(key);
489            if (existing == null || existing.level < result.level) {
490                consolidatedScanResults.put(key, result);
491            }
492        }
493        for (ScanResult result : consolidatedScanResults.values()) {
494            listItems.add(new SelectFromListWizardFragment.ListItem(result));
495        }
496
497        int wpsPinnedPos = mShowWpsAtTop ? SelectFromListWizardFragment.PinnedListItem.FIRST
498                                         : SelectFromListWizardFragment.PinnedListItem.LAST;
499
500        SelectFromListWizardFragment.PinnedListItem wpsItem =
501                new SelectFromListWizardFragment.PinnedListItem(
502                        getString(R.string.wps_network), R.drawable.setup_wps, wpsPinnedPos, 0);
503
504        listItems.add(wpsItem);
505
506        if (mShowSkipNetwork) {
507            listItems.add(new SelectFromListWizardFragment.PinnedListItem(
508                    getString(R.string.skip_network), R.drawable.ic_arrow_forward,
509                    SelectFromListWizardFragment.PinnedListItem.LAST, 1));
510        }
511
512        return listItems;
513    }
514
515    private void addPageBasedOnNetworkChoice(FormPage chooseNetworkPage) {
516        if (choiceChosen(chooseNetworkPage, R.string.other_network)) {
517            mConfiguration.hiddenSSID = true;
518            addPage(WifiFormPageType.ENTER_SSID);
519        } else if (choiceChosen(chooseNetworkPage, R.string.wps_network)) {
520            addPage(WifiFormPageType.WPS, new Intent(this, WpsConnectionActivity.class)
521                    .putExtras(getIntent().getExtras()));
522        } else {
523            ScanResult scanResult = getListItem(chooseNetworkPage).getScanResult();
524
525            // If we are entering password for an AP that is different from the previously saved AP,
526            // clear out the saved password.
527            if (mPasswordPage != null
528                    && (mConfiguration == null
529                               || !scanResult.SSID.equals(mConfiguration.getPrintableSsid()))) {
530                mPasswordPage.clearData();
531            }
532
533            mConfiguration = WifiConfigHelper.getConfiguration(this, scanResult.SSID,
534                    WifiSecurity.getSecurity(scanResult));
535            mWifiSecurity = WifiSecurity.getSecurity(scanResult);
536
537            if (WifiConfigHelper.isNetworkSaved(mConfiguration)) {
538                addPage(WifiFormPageType.KNOWN_NETWORK);
539            } else {
540                addStartPage();
541            }
542        }
543    }
544
545    private void addStartPage() {
546        if ((mWifiSecurity == WifiSecurity.WEP && TextUtils.isEmpty(mConfiguration.wepKeys[0]))
547                || (!mWifiSecurity.isOpen() && TextUtils.isEmpty(mConfiguration.preSharedKey))) {
548            addPage(WifiFormPageType.ENTER_PASSWORD);
549        } else {
550            connect();
551        }
552    }
553
554    private void addSummaryPage() {
555        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(
556                Context.CONNECTIVITY_SERVICE);
557        NetworkInfo currentConnection = connectivityManager.getActiveNetworkInfo();
558        boolean isConnected = (currentConnection != null) && currentConnection.isConnected();
559        if (isConnected) {
560            if (currentConnection.getType() == ConnectivityManager.TYPE_WIFI) {
561                WifiInfo currentWifiConnection = mWifiTracker.getManager().getConnectionInfo();
562                mConnectedNetwork = WifiInfo.removeDoubleQuotes(
563                        currentWifiConnection.getSSID());
564                if (mConnectedNetwork == null) {
565                    mConnectedNetwork = getString(R.string.wifi_summary_unknown_network);
566                }
567                addPage(WifiFormPageType.SUMMARY_CONNECTED_WIFI);
568            } else {
569                addPage(WifiFormPageType.SUMMARY_CONNECTED_NON_WIFI);
570            }
571        } else {
572            addPage(WifiFormPageType.SUMMARY_NOT_CONNECTED);
573        }
574    }
575
576    private void updateTitle(WifiFormPageType pageType) {
577        switch (pageType) {
578            // Fall through for all pageTypes that require the SSID of the network for
579            // the title.
580            case ADVANCED_OPTIONS:
581            case CONNECT:
582            case CONNECT_FAILED:
583            case CONNECT_TIMEOUT:
584            case KNOWN_NETWORK:
585            case SAVE:
586            case SAVE_FAILED:
587                setTitle(getResources().getString(pageType.getTitleResourceId(),
588                        mConfiguration.getPrintableSsid()));
589                break;
590            case WPS:
591                // Delegate title to the WPSConnectionActivity. Use blank string to prevent
592                // talkback from announcing a misplaced title.
593                setTitle("");
594                return;
595            case ENTER_PASSWORD:
596                // IME screen; Let the IME handle announcements.
597                setTitle("");
598                return;
599            case ENTER_SSID:
600                // IME screen; Let the IME handle announcements.
601                setTitle("");
602                return;
603            default:
604                setTitle(getResources().getString(pageType.getTitleResourceId()));
605                break;
606        }
607        getWindow().getDecorView()
608                .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
609    }
610
611    private void setResultOk() {
612        setResult(RESULT_OK);
613        mResultOk = true;
614    }
615}
616