Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2012 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 package com.android.settings.wifi;
     17 
     18 import android.app.Activity;
     19 import android.app.AlertDialog;
     20 import android.app.Dialog;
     21 import android.app.DialogFragment;
     22 import android.content.BroadcastReceiver;
     23 import android.content.Context;
     24 import android.content.DialogInterface;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.content.res.Resources;
     28 import android.net.ConnectivityManager;
     29 import android.net.NetworkInfo;
     30 import android.net.wifi.WifiManager;
     31 import android.os.Bundle;
     32 import android.support.v14.preference.PreferenceFragment;
     33 import android.util.Log;
     34 
     35 import com.android.settings.ButtonBarHandler;
     36 import com.android.settings.R;
     37 import com.android.settings.SetupWizardUtils;
     38 import com.android.setupwizardlib.view.NavigationBar;
     39 
     40 public class WifiSetupActivity extends WifiPickerActivity
     41         implements ButtonBarHandler, NavigationBar.NavigationBarListener {
     42     private static final String TAG = "WifiSetupActivity";
     43 
     44     // this boolean extra specifies whether to auto finish when connection is established
     45     private static final String EXTRA_AUTO_FINISH_ON_CONNECT = "wifi_auto_finish_on_connect";
     46 
     47     // This boolean extra specifies whether network is required
     48     private static final String EXTRA_IS_NETWORK_REQUIRED = "is_network_required";
     49 
     50     // This boolean extra specifies whether wifi is required
     51     private static final String EXTRA_IS_WIFI_REQUIRED = "is_wifi_required";
     52 
     53     // Whether auto finish is suspended until user connects to an access point
     54     private static final String EXTRA_REQUIRE_USER_NETWORK_SELECTION =
     55             "wifi_require_user_network_selection";
     56 
     57     // Key for whether the user selected network in saved instance state bundle
     58     private static final String PARAM_USER_SELECTED_NETWORK = "userSelectedNetwork";
     59 
     60     // Activity result when pressing the Skip button
     61     private static final int RESULT_SKIP = Activity.RESULT_FIRST_USER;
     62 
     63     // Whether to auto finish when the user selected a network and successfully connected
     64     private boolean mAutoFinishOnConnection;
     65     // Whether network is required to proceed. This is decided in SUW and passed in as an extra.
     66     private boolean mIsNetworkRequired;
     67     // Whether wifi is required to proceed. This is decided in SUW and passed in as an extra.
     68     private boolean mIsWifiRequired;
     69     // Whether the user connected to a network. This excludes the auto-connecting by the system.
     70     private boolean mUserSelectedNetwork;
     71     // Whether the device is connected to WiFi
     72     private boolean mWifiConnected;
     73 
     74     private NavigationBar mNavigationBar;
     75 
     76     private IntentFilter mFilter = new IntentFilter();
     77     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
     78         @Override
     79         public void onReceive(Context context, Intent intent) {
     80             // Refresh the connection state with the latest connection info. Use the connection info
     81             // from ConnectivityManager instead of the one attached in the intent to make sure
     82             // we have the most up-to-date connection state. b/17511772
     83             refreshConnectionState();
     84         }
     85     };
     86 
     87     @Override
     88     protected void onCreate(Bundle savedInstanceState) {
     89         super.onCreate(savedInstanceState);
     90 
     91         final Intent intent = getIntent();
     92         mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
     93         mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
     94 
     95         mAutoFinishOnConnection = intent.getBooleanExtra(EXTRA_AUTO_FINISH_ON_CONNECT, false);
     96         mIsNetworkRequired = intent.getBooleanExtra(EXTRA_IS_NETWORK_REQUIRED, false);
     97         mIsWifiRequired = intent.getBooleanExtra(EXTRA_IS_WIFI_REQUIRED, false);
     98         // Behave like the user already selected a network if we do not require selection
     99         mUserSelectedNetwork = !intent.getBooleanExtra(EXTRA_REQUIRE_USER_NETWORK_SELECTION, false);
    100     }
    101 
    102     @Override
    103     protected void onSaveInstanceState(Bundle outState) {
    104         super.onSaveInstanceState(outState);
    105         outState.putBoolean(PARAM_USER_SELECTED_NETWORK, mUserSelectedNetwork);
    106     }
    107 
    108     @Override
    109     protected void onRestoreInstanceState(Bundle savedInstanceState) {
    110         super.onRestoreInstanceState(savedInstanceState);
    111         mUserSelectedNetwork = savedInstanceState.getBoolean(PARAM_USER_SELECTED_NETWORK, true);
    112     }
    113 
    114     private boolean isWifiConnected() {
    115         final ConnectivityManager connectivity = (ConnectivityManager)
    116                 getSystemService(Context.CONNECTIVITY_SERVICE);
    117         boolean wifiConnected = connectivity != null &&
    118                 connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected();
    119         mWifiConnected = wifiConnected;
    120         return wifiConnected;
    121     }
    122 
    123     private void refreshConnectionState() {
    124         if (isWifiConnected()) {
    125             if (mAutoFinishOnConnection && mUserSelectedNetwork) {
    126                 Log.d(TAG, "Auto-finishing with connection");
    127                 finish(Activity.RESULT_OK);
    128                 // Require a user selection before auto-finishing next time we are here. The user
    129                 // can either connect to a different network or press "next" to proceed.
    130                 mUserSelectedNetwork = false;
    131             }
    132             setNextButtonText(R.string.suw_next_button_label);
    133             setNextButtonEnabled(true);
    134         } else if (mIsWifiRequired || (mIsNetworkRequired && !isNetworkConnected())) {
    135             // We do not want the user to skip wifi setting if
    136             // - wifi is required, but wifi connection hasn't been established yet;
    137             // - or network is required, but no valid connection has been established.
    138             setNextButtonText(R.string.skip_label);
    139             setNextButtonEnabled(false);
    140         } else {
    141             // In other cases, user can choose to skip. Specifically these cases are
    142             // - wifi is not required;
    143             // - and network is not required;
    144             // -     or network is required and a valid connection has been established.
    145             setNextButtonText(R.string.skip_label);
    146             setNextButtonEnabled(true);
    147         }
    148     }
    149 
    150     private void setNextButtonEnabled(boolean enabled) {
    151         if (mNavigationBar != null) {
    152             mNavigationBar.getNextButton().setEnabled(enabled);
    153         }
    154     }
    155 
    156     private void setNextButtonText(int resId) {
    157         if (mNavigationBar != null) {
    158             mNavigationBar.getNextButton().setText(resId);
    159         }
    160     }
    161 
    162     /* package */ void networkSelected() {
    163         Log.d(TAG, "Network selected by user");
    164         mUserSelectedNetwork = true;
    165     }
    166 
    167     @Override
    168     public void onResume() {
    169         super.onResume();
    170         registerReceiver(mReceiver, mFilter);
    171         refreshConnectionState();
    172     }
    173 
    174     @Override
    175     public void onPause() {
    176         unregisterReceiver(mReceiver);
    177         super.onPause();
    178     }
    179 
    180     @Override
    181     protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
    182         resid = SetupWizardUtils.getTheme(getIntent());
    183         super.onApplyThemeResource(theme, resid, first);
    184     }
    185 
    186     @Override
    187     protected boolean isValidFragment(String fragmentName) {
    188         return WifiSettingsForSetupWizard.class.getName().equals(fragmentName);
    189     }
    190 
    191     @Override
    192     /* package */ Class<? extends PreferenceFragment> getWifiSettingsClass() {
    193         return WifiSettingsForSetupWizard.class;
    194     }
    195 
    196     /**
    197      * Complete this activity and return the results to the caller.
    198      */
    199     public void finish(int resultCode) {
    200         Log.d(TAG, "finishing, resultCode=" + resultCode);
    201         setResult(resultCode);
    202         finish();
    203     }
    204 
    205     public void onNavigationBarCreated(final NavigationBar bar) {
    206         mNavigationBar = bar;
    207         bar.setNavigationBarListener(this);
    208         SetupWizardUtils.setImmersiveMode(this);
    209     }
    210 
    211     @Override
    212     public void onNavigateBack() {
    213         onBackPressed();
    214     }
    215 
    216     @Override
    217     public void onNavigateNext() {
    218         if (mWifiConnected) {
    219             finish(RESULT_OK);
    220         } else {
    221             // Warn of possible data charges if there is a network connection, or lack of updates
    222             // if there is none.
    223             final int message = isNetworkConnected() ? R.string.wifi_skipped_message :
    224                     R.string.wifi_and_mobile_skipped_message;
    225             WifiSkipDialog.newInstance(message).show(getFragmentManager(), "dialog");
    226         }
    227     }
    228 
    229     /**
    230      * @return True if there is a valid network connection, whether it is via WiFi, mobile data or
    231      *         other means.
    232      */
    233     private boolean isNetworkConnected() {
    234         final ConnectivityManager connectivity = (ConnectivityManager)
    235                 getSystemService(Context.CONNECTIVITY_SERVICE);
    236         if (connectivity == null) {
    237             return false;
    238         }
    239         final NetworkInfo info = connectivity.getActiveNetworkInfo();
    240         return info != null && info.isConnected();
    241     }
    242 
    243     public static class WifiSkipDialog extends DialogFragment {
    244         public static WifiSkipDialog newInstance(int messageRes) {
    245             final Bundle args = new Bundle();
    246             args.putInt("messageRes", messageRes);
    247             final WifiSkipDialog dialog = new WifiSkipDialog();
    248             dialog.setArguments(args);
    249             return dialog;
    250         }
    251 
    252         public WifiSkipDialog() {
    253             // no-arg constructor for fragment
    254         }
    255 
    256         @Override
    257         public Dialog onCreateDialog(Bundle savedInstanceState) {
    258             int messageRes = getArguments().getInt("messageRes");
    259             final AlertDialog dialog = new AlertDialog.Builder(getActivity())
    260                     .setMessage(messageRes)
    261                     .setCancelable(false)
    262                     .setPositiveButton(R.string.wifi_skip_anyway,
    263                             new DialogInterface.OnClickListener() {
    264                                 @Override
    265                                 public void onClick(DialogInterface dialog, int id) {
    266                                     WifiSetupActivity activity = (WifiSetupActivity) getActivity();
    267                                     activity.finish(RESULT_SKIP);
    268                                 }
    269                             })
    270                     .setNegativeButton(R.string.wifi_dont_skip,
    271                             new DialogInterface.OnClickListener() {
    272                                 @Override
    273                                 public void onClick(DialogInterface dialog, int id) {
    274                                 }
    275                             })
    276                     .create();
    277             SetupWizardUtils.applyImmersiveFlags(dialog);
    278             return dialog;
    279         }
    280     }
    281 }
    282