2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.android.settings.wifi;
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.graphics.Color;
29 import android.net.ConnectivityManager;
30 import android.net.NetworkInfo;
31 import android.net.wifi.WifiManager;
32 import android.os.Bundle;
33 import android.preference.PreferenceFragment;
34 import android.util.Log;
36 import com.android.settings.ButtonBarHandler;
37 import com.android.settings.R;
38 import com.android.setupwizard.navigationbar.SetupWizardNavBar;
39 import com.android.setupwizard.navigationbar.SetupWizardNavBar.NavigationBarListener;
41 public class WifiSetupActivity extends WifiPickerActivity
42 implements ButtonBarHandler, NavigationBarListener {
43 private static final String TAG = "WifiSetupActivity";
45 private static final String EXTRA_ALLOW_SKIP = "allowSkip";
46 private static final String EXTRA_USE_IMMERSIVE_MODE = "useImmersiveMode";
48 // this boolean extra specifies whether to auto finish when connection is established
49 private static final String EXTRA_AUTO_FINISH_ON_CONNECT = "wifi_auto_finish_on_connect";
51 // Whether auto finish is suspended until user connects to an access point
52 private static final String EXTRA_REQUIRE_USER_NETWORK_SELECTION =
53 "wifi_require_user_network_selection";
55 // Extra containing the resource name of the theme to be used
56 private static final String EXTRA_THEME = "theme";
57 private static final String THEME_HOLO = "holo";
58 private static final String THEME_HOLO_LIGHT = "holo_light";
59 private static final String THEME_MATERIAL = "material";
60 private static final String THEME_MATERIAL_LIGHT = "material_light";
62 // Key for whether the user selected network in saved instance state bundle
63 private static final String PARAM_USER_SELECTED_NETWORK = "userSelectedNetwork";
65 // Activity result when pressing the Skip button
66 private static final int RESULT_SKIP = Activity.RESULT_FIRST_USER;
68 // From WizardManager (must match constants maintained there)
69 private static final String ACTION_NEXT = "com.android.wizard.NEXT";
70 private static final String EXTRA_SCRIPT_URI = "scriptUri";
71 private static final String EXTRA_ACTION_ID = "actionId";
72 private static final String EXTRA_RESULT_CODE = "com.android.setupwizard.ResultCode";
73 private static final int NEXT_REQUEST = 10000;
75 // Whether we allow skipping without a valid network connection
76 private boolean mAllowSkip = true;
77 // Whether to auto finish when the user selected a network and successfully connected
78 private boolean mAutoFinishOnConnection;
79 // Whether the user connected to a network. This excludes the auto-connecting by the system.
80 private boolean mUserSelectedNetwork;
81 // Whether the device is connected to WiFi
82 private boolean mWifiConnected;
84 private SetupWizardNavBar mNavigationBar;
86 private final IntentFilter mFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
87 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
89 public void onReceive(Context context, Intent intent) {
90 // Refresh the connection state with the latest connection info. Use the connection info
91 // from ConnectivityManager instead of the one attached in the intent to make sure
92 // we have the most up-to-date connection state. b/17511772
93 refreshConnectionState();
98 protected void onCreate(Bundle savedInstanceState) {
99 super.onCreate(savedInstanceState);
101 final Intent intent = getIntent();
103 mAutoFinishOnConnection = intent.getBooleanExtra(EXTRA_AUTO_FINISH_ON_CONNECT, false);
104 mAllowSkip = intent.getBooleanExtra(EXTRA_ALLOW_SKIP, true);
105 // Behave like the user already selected a network if we do not require selection
106 mUserSelectedNetwork = !intent.getBooleanExtra(EXTRA_REQUIRE_USER_NETWORK_SELECTION, false);
110 protected void onSaveInstanceState(Bundle outState) {
111 super.onSaveInstanceState(outState);
112 outState.putBoolean(PARAM_USER_SELECTED_NETWORK, mUserSelectedNetwork);
116 protected void onRestoreInstanceState(Bundle savedInstanceState) {
117 super.onRestoreInstanceState(savedInstanceState);
118 mUserSelectedNetwork = savedInstanceState.getBoolean(PARAM_USER_SELECTED_NETWORK, true);
121 private void refreshConnectionState() {
122 final ConnectivityManager connectivity = (ConnectivityManager)
123 getSystemService(Context.CONNECTIVITY_SERVICE);
124 boolean connected = connectivity != null &&
125 connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected();
126 refreshConnectionState(connected);
129 private void refreshConnectionState(boolean connected) {
130 mWifiConnected = connected;
132 if (mAutoFinishOnConnection && mUserSelectedNetwork) {
133 Log.d(TAG, "Auto-finishing with connection");
134 finishOrNext(Activity.RESULT_OK);
135 // Require a user selection before auto-finishing next time we are here. The user
136 // can either connect to a different network or press "next" to proceed.
137 mUserSelectedNetwork = false;
139 if (mNavigationBar != null) {
140 mNavigationBar.getNextButton().setText(R.string.setup_wizard_next_button_label);
141 mNavigationBar.getNextButton().setEnabled(true);
144 if (mNavigationBar != null) {
145 mNavigationBar.getNextButton().setText(R.string.skip_label);
146 mNavigationBar.getNextButton().setEnabled(mAllowSkip);
151 /* package */ void networkSelected() {
152 Log.d(TAG, "Network selected by user");
153 mUserSelectedNetwork = true;
157 public void onResume() {
159 registerReceiver(mReceiver, mFilter);
160 refreshConnectionState();
164 public void onPause() {
165 unregisterReceiver(mReceiver);
170 protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
171 String themeName = getIntent().getStringExtra(EXTRA_THEME);
172 if (THEME_HOLO_LIGHT.equalsIgnoreCase(themeName) ||
173 THEME_MATERIAL_LIGHT.equalsIgnoreCase(themeName)) {
174 resid = R.style.SetupWizardWifiTheme_Light;
175 } else if (THEME_HOLO.equalsIgnoreCase(themeName) ||
176 THEME_MATERIAL.equalsIgnoreCase(themeName)) {
177 resid = R.style.SetupWizardWifiTheme;
179 super.onApplyThemeResource(theme, resid, first);
183 protected boolean isValidFragment(String fragmentName) {
184 return WifiSettingsForSetupWizard.class.getName().equals(fragmentName);
188 /* package */ Class<? extends PreferenceFragment> getWifiSettingsClass() {
189 return WifiSettingsForSetupWizard.class;
193 * Complete this activity and return the results to the caller. If using WizardManager, this
194 * will invoke the next scripted action; otherwise, we simply finish.
196 public void finishOrNext(int resultCode) {
197 Log.d(TAG, "finishOrNext resultCode=" + resultCode
198 + " isUsingWizardManager=" + isUsingWizardManager());
199 if (isUsingWizardManager()) {
200 sendResultsToSetupWizard(resultCode);
202 setResult(resultCode);
207 private boolean isUsingWizardManager() {
208 return getIntent().hasExtra(EXTRA_SCRIPT_URI);
212 * Send the results of this activity to WizardManager, which will then send out the next
213 * scripted activity. WizardManager does not actually return an activity result, but if we
214 * invoke WizardManager without requesting a result, the framework will choose not to issue a
215 * call to onActivityResult with RESULT_CANCELED when navigating backward.
217 private void sendResultsToSetupWizard(int resultCode) {
218 final Intent intent = getIntent();
219 final Intent nextIntent = new Intent(ACTION_NEXT);
220 nextIntent.putExtra(EXTRA_SCRIPT_URI, intent.getStringExtra(EXTRA_SCRIPT_URI));
221 nextIntent.putExtra(EXTRA_ACTION_ID, intent.getStringExtra(EXTRA_ACTION_ID));
222 nextIntent.putExtra(EXTRA_THEME, intent.getStringExtra(EXTRA_THEME));
223 nextIntent.putExtra(EXTRA_RESULT_CODE, resultCode);
224 startActivityForResult(nextIntent, NEXT_REQUEST);
228 public void onNavigationBarCreated(final SetupWizardNavBar bar) {
229 mNavigationBar = bar;
230 final boolean useImmersiveMode =
231 getIntent().getBooleanExtra(EXTRA_USE_IMMERSIVE_MODE, false);
232 bar.setUseImmersiveMode(useImmersiveMode);
233 if (useImmersiveMode) {
234 getWindow().setNavigationBarColor(Color.TRANSPARENT);
235 getWindow().setStatusBarColor(Color.TRANSPARENT);
240 public void onNavigateBack() {
245 public void onNavigateNext() {
246 if (mWifiConnected) {
247 finishOrNext(RESULT_OK);
249 // Warn of possible data charges if there is a network connection, or lack of updates
251 final int message = isNetworkConnected() ? R.string.wifi_skipped_message :
252 R.string.wifi_and_mobile_skipped_message;
253 WifiSkipDialog.newInstance(message).show(getFragmentManager(), "dialog");
258 * @return True if there is a valid network connection, whether it is via WiFi, mobile data or
261 private boolean isNetworkConnected() {
262 final ConnectivityManager connectivity = (ConnectivityManager)
263 getSystemService(Context.CONNECTIVITY_SERVICE);
264 if (connectivity == null) {
267 final NetworkInfo info = connectivity.getActiveNetworkInfo();
268 return info != null && info.isConnected();
271 public static class WifiSkipDialog extends DialogFragment {
272 public static WifiSkipDialog newInstance(int messageRes) {
273 final Bundle args = new Bundle();
274 args.putInt("messageRes", messageRes);
275 final WifiSkipDialog dialog = new WifiSkipDialog();
276 dialog.setArguments(args);
280 public WifiSkipDialog() {
281 // no-arg constructor for fragment
285 public Dialog onCreateDialog(Bundle savedInstanceState) {
286 int messageRes = getArguments().getInt("messageRes");
287 return new AlertDialog.Builder(getActivity())
288 .setMessage(messageRes)
289 .setCancelable(false)
290 .setNegativeButton(R.string.wifi_skip_anyway,
291 new DialogInterface.OnClickListener() {
293 public void onClick(DialogInterface dialog, int id) {
294 WifiSetupActivity activity = (WifiSetupActivity) getActivity();
295 activity.finishOrNext(RESULT_SKIP);
298 .setPositiveButton(R.string.wifi_dont_skip,
299 new DialogInterface.OnClickListener() {
301 public void onClick(DialogInterface dialog, int id) {