2 * Copyright (C) 2010 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.
17 package com.android.settings.wifi;
19 import com.android.settings.R;
21 import android.app.Activity;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.net.NetworkInfo.DetailedState;
25 import android.net.wifi.WifiConfiguration;
26 import android.net.wifi.WifiManager;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.preference.PreferenceCategory;
30 import android.text.TextUtils;
31 import android.util.Log;
32 import android.view.ContextMenu;
33 import android.view.ContextMenu.ContextMenuInfo;
34 import android.view.View;
35 import android.view.View.OnClickListener;
36 import android.view.ViewGroup;
37 import android.view.Window;
38 import android.view.WindowManager;
39 import android.view.inputmethod.InputMethodManager;
40 import android.widget.Button;
41 import android.widget.ProgressBar;
42 import android.widget.TextView;
44 import java.util.Collection;
45 import java.util.EnumMap;
48 * WifiSetings Activity specific for SetupWizard with X-Large screen size.
50 public class WifiSettingsForSetupWizardXL extends Activity implements OnClickListener {
51 private static final String TAG = "SetupWizard";
52 private static final boolean DEBUG = false;
54 private static final EnumMap<DetailedState, DetailedState> stateMap =
55 new EnumMap<DetailedState, DetailedState>(DetailedState.class);
58 stateMap.put(DetailedState.IDLE, DetailedState.DISCONNECTED);
59 stateMap.put(DetailedState.SCANNING, DetailedState.SCANNING);
60 stateMap.put(DetailedState.CONNECTING, DetailedState.CONNECTING);
61 stateMap.put(DetailedState.AUTHENTICATING, DetailedState.CONNECTING);
62 stateMap.put(DetailedState.OBTAINING_IPADDR, DetailedState.CONNECTING);
63 stateMap.put(DetailedState.CONNECTED, DetailedState.CONNECTED);
64 stateMap.put(DetailedState.SUSPENDED, DetailedState.SUSPENDED); // ?
65 stateMap.put(DetailedState.DISCONNECTING, DetailedState.DISCONNECTED);
66 stateMap.put(DetailedState.DISCONNECTED, DetailedState.DISCONNECTED);
67 stateMap.put(DetailedState.FAILED, DetailedState.FAILED);
70 private WifiManager mWifiManager;
73 * Used for resizing a padding above title. Hiden when software keyboard is shown.
75 private View mTopPadding;
78 * Used for resizing a padding inside Config UI. Hiden when software keyboard is shown.
80 private View mWifiConfigPadding;
82 private TextView mTitleView;
84 * The name of a network currently connecting, or trying to connect.
85 * This may be empty ("") at first, and updated when configuration is changed.
87 private CharSequence mNetworkName = "";
88 private CharSequence mEditingTitle;
90 private ProgressBar mProgressBar;
91 private WifiSettings mWifiSettings;
93 private Button mAddNetworkButton;
94 private Button mRefreshButton;
95 private Button mSkipOrNextButton;
96 private Button mBackButton;
98 private static int CONNECT_BUTTON_TAG_ADD_NETWORK = 1;
100 private Button mConnectButton;
102 private View mConnectingStatusLayout;
103 private TextView mConnectingStatusView;
105 // true when a user already pressed "Connect" button and waiting for connection.
106 // Also true when the device is already connected to a wifi network on launch.
107 private boolean mAfterConnectAction;
109 private WifiConfigUiForSetupWizardXL mWifiConfig;
111 private InputMethodManager mInputMethodManager;
113 private final Handler mHandler = new Handler();
115 private int mPreviousWpsFieldsVisibility = View.GONE;
116 private int mPreviousSecurityFieldsVisibility = View.GONE;
117 private int mPreviousTypeVisibility = View.GONE;
119 private DetailedState mPreviousState = DetailedState.DISCONNECTED;
121 private int mBackgroundId = R.drawable.setups_bg_default;
123 // At first, we set "Skip" button disabled so that users won't press it soon after the screen
124 // migration. The button is enabled after the wifi module returns some result
125 // (a list of available network, etc.) One possible problem is that the notification from the
126 // wifi module may be delayed and users may be stuck here, without any other way to exit this
128 // To let users exit this Activity, we enable the button after waiting for a moment.
129 private final int DELAYED_SKIP_ENABLE_TIME = 10000; // Unit: millis
130 private final Runnable mSkipButtonEnabler = new Runnable() {
133 if (DEBUG) Log.d(TAG, "Delayed skip enabler starts running.");
134 mSkipOrNextButton.setEnabled(true);
139 public void onCreate(Bundle savedInstanceState) {
140 super.onCreate(savedInstanceState);
141 requestWindowFeature(Window.FEATURE_NO_TITLE);
142 setContentView(R.layout.wifi_settings_for_setup_wizard_xl);
144 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
146 mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
147 // There's no button here enabling wifi network, so we need to enable it without
149 mWifiManager.setWifiEnabled(true);
152 (WifiSettings)getFragmentManager().findFragmentById(R.id.wifi_setup_fragment);
153 mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
157 public void setup() {
158 mTitleView = (TextView)findViewById(R.id.wifi_setup_title);
159 mProgressBar = (ProgressBar)findViewById(R.id.scanning_progress_bar);
160 mProgressBar.setMax(2);
162 mProgressBar.setIndeterminate(true);
164 mAddNetworkButton = (Button)findViewById(R.id.wifi_setup_add_network);
165 mAddNetworkButton.setOnClickListener(this);
166 mRefreshButton = (Button)findViewById(R.id.wifi_setup_refresh_list);
167 mRefreshButton.setOnClickListener(this);
168 mSkipOrNextButton = (Button)findViewById(R.id.wifi_setup_skip_or_next);
169 mSkipOrNextButton.setOnClickListener(this);
170 mConnectButton = (Button)findViewById(R.id.wifi_setup_connect);
171 mConnectButton.setOnClickListener(this);
172 mBackButton = (Button)findViewById(R.id.wifi_setup_cancel);
173 mBackButton.setOnClickListener(this);
175 mTopPadding = findViewById(R.id.top_padding);
176 mWifiConfigPadding = findViewById(R.id.wifi_config_padding);
178 mConnectingStatusLayout = findViewById(R.id.connecting_status_layout);
179 mConnectingStatusView = (TextView) findViewById(R.id.connecting_status);
181 // At first, Wifi module doesn't return SCANNING state (it's too early), so we manually
183 showScanningStatus();
184 mHandler.postDelayed(mSkipButtonEnabler, DELAYED_SKIP_ENABLE_TIME);
187 private void restoreFirstButtonVisibilityState() {
189 mAddNetworkButton.setVisibility(View.VISIBLE);
190 mRefreshButton.setVisibility(View.VISIBLE);
191 mSkipOrNextButton.setVisibility(View.VISIBLE);
192 mConnectButton.setVisibility(View.GONE);
193 mBackButton.setVisibility(View.GONE);
194 setPaddingVisibility(View.VISIBLE, View.GONE);
198 public void onClick(View view) {
199 hideSoftwareKeyboard();
200 if (view == mAddNetworkButton) {
201 if (DEBUG) Log.d(TAG, "AddNetwork button pressed");
202 onAddNetworkButtonPressed();
203 } else if (view == mRefreshButton) {
204 if (DEBUG) Log.d(TAG, "Refresh button pressed");
205 refreshAccessPoints(true);
206 } else if (view == mSkipOrNextButton) {
207 if (DEBUG) Log.d(TAG, "Skip/Next button pressed");
208 if (TextUtils.equals(getString(R.string.wifi_setup_skip), ((Button)view).getText())) {
209 // We don't want to let Wifi enabled when a user press skip without choosing
211 mWifiManager.setWifiEnabled(false);
213 setResult(Activity.RESULT_OK);
215 } else if (view == mConnectButton) {
216 if (DEBUG) Log.d(TAG, "Connect button pressed");
217 onConnectButtonPressed();
218 } else if (view == mBackButton) {
219 if (DEBUG) Log.d(TAG, "Back button pressed");
220 onBackButtonPressed();
224 private void hideSoftwareKeyboard() {
225 if (DEBUG) Log.i(TAG, "Hiding software keyboard.");
226 final View focusedView = getCurrentFocus();
227 if (focusedView != null) {
228 mInputMethodManager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0);
232 // Called from WifiSettings
233 /* package */ void updateConnectionState(DetailedState originalState) {
234 final DetailedState state = stateMap.get(originalState);
236 if (originalState == DetailedState.FAILED) {
237 // We clean up the current connectivity status and let users select another network
239 refreshAccessPoints(true);
244 // Let users know the device is working correctly though currently there's
245 // no visible network on the list.
246 if (mWifiSettings.getAccessPointsCount() == 0) {
247 mProgressBar.setIndeterminate(true);
249 // Users already connected to a network, or see available networks.
250 mProgressBar.setIndeterminate(false);
255 showConnectingStatus();
259 hideSoftwareKeyboard();
260 setPaddingVisibility(View.VISIBLE);
262 // If the device is already connected to a wifi without users' "Connect" request,
263 // this can be false here. We want to treat it as "after connect action".
264 mAfterConnectAction = true;
266 trySetBackground(R.drawable.setups_bg_complete);
268 mProgressBar.setIndeterminate(false);
269 mProgressBar.setProgress(2);
271 showConnectedTitle();
272 mConnectingStatusView.setText(R.string.wifi_setup_description_connected);
273 mConnectButton.setVisibility(View.GONE);
274 mAddNetworkButton.setVisibility(View.GONE);
275 mRefreshButton.setVisibility(View.GONE);
276 mBackButton.setVisibility(View.VISIBLE);
277 mBackButton.setText(R.string.wifi_setup_back);
278 mSkipOrNextButton.setVisibility(View.VISIBLE);
279 mSkipOrNextButton.setEnabled(true);
280 mHandler.removeCallbacks(mSkipButtonEnabler);
283 default: // DISCONNECTED, FAILED
284 showDisconnectedStatus(Summary.get(this, state));
287 mPreviousState = state;
290 private void showDisconnectedStatus(String stateString) {
291 mProgressBar.setIndeterminate(false);
292 mProgressBar.setProgress(0);
294 mAddNetworkButton.setEnabled(true);
295 mRefreshButton.setEnabled(true);
298 private void showConnectingStatus() {
299 mBackButton.setVisibility(View.VISIBLE);
300 // We save this title and show it when authentication failed.
301 mEditingTitle = mTitleView.getText();
302 showConnectingTitle();
303 mProgressBar.setIndeterminate(false);
304 mProgressBar.setProgress(1);
306 // We may enter "Connecting" status during editing password again (if the Wifi module
307 // tries to (re)connect a network.)
308 if (mAfterConnectAction) {
309 setPaddingVisibility(View.VISIBLE);
313 private void showDefaultTitle() {
314 mTitleView.setText(getString(R.string.wifi_setup_title));
317 private void showAddNetworkTitle() {
319 mTitleView.setText(R.string.wifi_setup_title_add_network);
322 private void showEditingTitle() {
323 if (TextUtils.isEmpty(mNetworkName) && mWifiConfig != null) {
324 if (mWifiConfig.getController() != null &&
325 mWifiConfig.getController().getConfig() != null) {
326 mNetworkName = mWifiConfig.getController().getConfig().SSID;
328 Log.w(TAG, "Unexpected null found (WifiController or WifiConfig is null). " +
332 mTitleView.setText(getString(R.string.wifi_setup_title_editing_network, mNetworkName));
335 private void showConnectingTitle() {
336 if (TextUtils.isEmpty(mNetworkName) && mWifiConfig != null) {
337 if (mWifiConfig.getController() != null &&
338 mWifiConfig.getController().getConfig() != null) {
339 mNetworkName = mWifiConfig.getController().getConfig().SSID;
341 Log.w(TAG, "Unexpected null found (WifiController or WifiConfig is null). " +
345 mTitleView.setText(getString(R.string.wifi_setup_title_connecting_network, mNetworkName));
348 private void showConnectedTitle() {
349 if (TextUtils.isEmpty(mNetworkName) && mWifiConfig != null) {
350 if (mWifiConfig.getController() != null &&
351 mWifiConfig.getController().getConfig() != null) {
352 mNetworkName = mWifiConfig.getController().getConfig().SSID;
354 Log.w(TAG, "Unexpected null found (WifiController or WifiConfig is null). " +
358 mTitleView.setText(getString(R.string.wifi_setup_title_connected_network, mNetworkName));
361 private void showScanningStatus() {
362 mProgressBar.setIndeterminate(true);
363 mAddNetworkButton.setEnabled(false);
364 mRefreshButton.setEnabled(false);
367 private void onAddNetworkButtonPressed() {
368 mWifiSettings.onAddNetworkPressed();
372 * Called when the screen enters wifi configuration UI. UI widget for configuring network
373 * (a.k.a. ConfigPreference) should be taken care of by caller side.
374 * This method should handle buttons' visibility/enabled.
375 * @param selectedAccessPoint AccessPoint object being selected. null when a user pressed
376 * "Add network" button, meaning there's no selected access point.
378 /* package */ void showConfigUi(AccessPoint selectedAccessPoint, boolean edit) {
379 if (selectedAccessPoint != null &&
380 (selectedAccessPoint.security == AccessPoint.SECURITY_WEP ||
381 selectedAccessPoint.security == AccessPoint.SECURITY_PSK)) {
382 // We forcibly set edit as true so that users can modify every field if they want,
383 // while config UI doesn't allow them to edit some of them when edit is false
384 // (e.g. password field is hiden when edit==false).
388 trySetBackground(R.drawable.setups_bg_default);
390 // We don't want to keep scanning Wi-Fi networks during users' configuring one network.
391 mWifiSettings.pauseWifiScan();
393 findViewById(R.id.wifi_setup).setVisibility(View.GONE);
394 mConnectingStatusLayout.setVisibility(View.GONE);
395 final ViewGroup parent = (ViewGroup)findViewById(R.id.wifi_config_ui);
396 parent.setVisibility(View.VISIBLE);
397 parent.removeAllViews();
398 mWifiConfig = new WifiConfigUiForSetupWizardXL(this, parent, selectedAccessPoint, edit);
400 // For safety, we forget the tag once. Tag will be updated in this method when needed.
401 mConnectButton.setTag(null);
402 if (selectedAccessPoint == null) { // "Add network" flow
403 showAddNetworkTitle();
404 if (mWifiConfig != null) {
405 mWifiConfig.getView().findViewById(R.id.wifi_general_info).setVisibility(View.GONE);
407 mConnectButton.setVisibility(View.VISIBLE);
408 mConnectButton.setTag(CONNECT_BUTTON_TAG_ADD_NETWORK);
410 showEditingButtonState();
411 } else if (selectedAccessPoint.security == AccessPoint.SECURITY_NONE) {
412 mNetworkName = selectedAccessPoint.getTitle().toString();
414 // onConnectButtonPressed() will change visibility status.
415 mConnectButton.performClick();
417 mNetworkName = selectedAccessPoint.getTitle().toString();
419 showEditingButtonState();
420 if (selectedAccessPoint.security == AccessPoint.SECURITY_EAP) {
421 mConnectButton.setVisibility(View.GONE);
422 mBackButton.setText(R.string.wifi_setup_back);
424 mConnectButton.setVisibility(View.VISIBLE);
426 // WifiConfigController shows Connect button as "Save" when edit==true and a user
427 // tried to connect the network.
428 // In SetupWizard, we just show the button as "Connect" instead.
429 mConnectButton.setText(R.string.wifi_connect);
430 mBackButton.setText(R.string.wifi_setup_cancel);
435 private void showEditingButtonState() {
436 mSkipOrNextButton.setVisibility(View.GONE);
437 mAddNetworkButton.setVisibility(View.GONE);
438 mRefreshButton.setVisibility(View.GONE);
439 mBackButton.setVisibility(View.VISIBLE);
442 // May be called when user press "connect" button in WifiDialog
443 /* package */ void onConnectButtonPressed() {
444 mAfterConnectAction = true;
446 trySetBackground(R.drawable.setups_bg_wifi);
448 mWifiSettings.submit(mWifiConfig.getController());
450 // updateConnectionState() isn't called soon after the user's "connect" action,
451 // and the user still sees "not connected" message for a while, which looks strange.
452 // We instead manually show "connecting" message before the system gets actual
453 // "connecting" message from Wi-Fi module.
454 showConnectingStatus();
456 // Might be better to delay showing this button.
457 mBackButton.setVisibility(View.VISIBLE);
458 mBackButton.setText(R.string.wifi_setup_back);
460 // We need to restore visibility status when the device failed to connect the network.
461 final View wpsFieldView = findViewById(R.id.wps_fields);
462 if (wpsFieldView != null) {
463 mPreviousWpsFieldsVisibility = wpsFieldView.getVisibility();
464 wpsFieldView.setVisibility(View.GONE);
466 final View securityFieldsView = findViewById(R.id.security_fields);
467 if (securityFieldsView != null) {
468 mPreviousSecurityFieldsVisibility = securityFieldsView.getVisibility();
469 securityFieldsView.setVisibility(View.GONE);
471 final View typeView = findViewById(R.id.type);
472 if (typeView != null) {
473 mPreviousTypeVisibility = typeView.getVisibility();
474 typeView.setVisibility(View.GONE);
477 // TODO: investigate whether visibility handling above is needed. Now that we hide
478 // them completely when connecting, so we may not need to do so, though we probably
479 // need to show software keyboard conditionaly.
480 final ViewGroup parent = (ViewGroup)findViewById(R.id.wifi_config_ui);
481 parent.setVisibility(View.GONE);
482 mConnectingStatusLayout.setVisibility(View.VISIBLE);
483 mConnectingStatusView.setText(R.string.wifi_setup_description_connecting);
485 mHandler.removeCallbacks(mSkipButtonEnabler);
486 mSkipOrNextButton.setVisibility(View.VISIBLE);
487 mSkipOrNextButton.setEnabled(false);
488 mConnectButton.setVisibility(View.GONE);
489 mAddNetworkButton.setVisibility(View.GONE);
490 mRefreshButton.setVisibility(View.GONE);
493 private void onBackButtonPressed() {
494 trySetBackground(R.drawable.setups_bg_default);
496 if (mAfterConnectAction) {
497 if (DEBUG) Log.d(TAG, "Back button pressed after connect action.");
498 mAfterConnectAction = false;
500 // When a user press "Back" button after pressing "Connect" button, we want to cancel
501 // the "Connect" request and refresh the whole wifi status.
502 restoreFirstButtonVisibilityState();
504 mSkipOrNextButton.setEnabled(true);
505 changeNextButtonState(false); // Skip
507 refreshAccessPoints(true);
508 } else { // During user's Wifi configuration.
509 mWifiSettings.resumeWifiScan();
511 restoreFirstButtonVisibilityState();
513 mAddNetworkButton.setEnabled(true);
514 mRefreshButton.setEnabled(true);
515 mSkipOrNextButton.setEnabled(true);
518 findViewById(R.id.wifi_setup).setVisibility(View.VISIBLE);
519 mConnectingStatusLayout.setVisibility(View.GONE);
520 final ViewGroup parent = (ViewGroup)findViewById(R.id.wifi_config_ui);
521 parent.removeAllViews();
522 parent.setVisibility(View.GONE);
527 * @param connected true when the device is connected to a specific network.
529 /* package */ void changeNextButtonState(boolean connected) {
531 mSkipOrNextButton.setText(R.string.wifi_setup_next);
533 mSkipOrNextButton.setText(R.string.wifi_setup_skip);
538 * Called when the list of AccessPoints are modified and this Activity needs to refresh
541 /* package */ void onAccessPointsUpdated(
542 PreferenceCategory holder, Collection<AccessPoint> accessPoints) {
543 // If we already show some of access points but the bar still shows "scanning" state, it
544 // should be stopped.
545 if (mProgressBar.isIndeterminate() && accessPoints.size() > 0) {
546 mProgressBar.setIndeterminate(false);
547 mAddNetworkButton.setEnabled(true);
548 mRefreshButton.setEnabled(true);
551 for (AccessPoint accessPoint : accessPoints) {
552 accessPoint.setLayoutResource(R.layout.custom_preference);
553 holder.addPreference(accessPoint);
557 private void refreshAccessPoints(boolean disconnectNetwork) {
558 final Object tag = mConnectButton.getTag();
559 if (tag != null && (tag instanceof Integer) &&
560 ((Integer)tag == CONNECT_BUTTON_TAG_ADD_NETWORK)) {
561 // In "Add network" flow, we won't get DetaledState available for changing ProgressBar
562 // state. Instead we manually show previous status here.
563 showDisconnectedStatus(Summary.get(this, mPreviousState));
565 showScanningStatus();
568 if (disconnectNetwork) {
569 mWifiManager.disconnect();
572 mWifiSettings.refreshAccessPoints();
576 * Called when {@link WifiSettings} received
577 * {@link WifiManager#SUPPLICANT_STATE_CHANGED_ACTION}.
579 /* package */ void onSupplicantStateChanged(Intent intent) {
580 final int errorCode = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
581 if (errorCode == WifiManager.ERROR_AUTHENTICATING) {
582 Log.i(TAG, "Received authentication error event.");
583 onAuthenticationFailure();
588 * Called once when Authentication failed.
590 private void onAuthenticationFailure() {
591 mAfterConnectAction = false;
592 mSkipOrNextButton.setVisibility(View.GONE);
593 mConnectButton.setVisibility(View.VISIBLE);
594 mConnectButton.setEnabled(true);
596 trySetBackground(R.drawable.setups_bg_default);
598 if (!TextUtils.isEmpty(mEditingTitle)) {
599 mTitleView.setText(mEditingTitle);
601 Log.w(TAG, "Title during editing/adding a network was empty.");
605 final ViewGroup parent = (ViewGroup)findViewById(R.id.wifi_config_ui);
606 parent.setVisibility(View.VISIBLE);
607 mConnectingStatusLayout.setVisibility(View.GONE);
609 // Restore View status which was tweaked on connection.
610 final View wpsFieldView = findViewById(R.id.wps_fields);
611 if (wpsFieldView != null) {
612 wpsFieldView.setVisibility(mPreviousWpsFieldsVisibility);
614 final View securityFieldsView = findViewById(R.id.security_fields);
615 if (securityFieldsView != null) {
616 securityFieldsView.setVisibility(mPreviousSecurityFieldsVisibility);
617 if (mPreviousSecurityFieldsVisibility == View.VISIBLE && mWifiConfig != null) {
618 final View passwordView = findViewById(R.id.password);
619 if (passwordView != null) {
620 if (passwordView.isFocused()) {
621 setPaddingVisibility(View.GONE);
623 mWifiConfig.requestFocusAndShowKeyboard(R.id.password);
627 final View typeView = findViewById(R.id.type);
628 if (typeView != null) {
629 typeView.setVisibility(mPreviousTypeVisibility);
630 if (mPreviousTypeVisibility == View.VISIBLE && mWifiConfig != null) {
631 final View ssidView = findViewById(R.id.ssid);
632 if (ssidView != null) {
633 if (ssidView.isFocused()) {
634 setPaddingVisibility(View.GONE);
636 mWifiConfig.requestFocusAndShowKeyboard(R.id.ssid);
642 public void setPaddingVisibility(int visibility) {
643 setPaddingVisibility(visibility, visibility);
646 private void setPaddingVisibility(int topPaddingVisibility, int configVisibility) {
647 mTopPadding.setVisibility(topPaddingVisibility);
648 mWifiConfigPadding.setVisibility(configVisibility);
652 * Called when WifiManager is requested to save a network. This method sholud include
653 * WifiManager#saveNetwork() call.
655 * Currently this method calls {@link WifiManager#connectNetwork(int)}.
657 /* package */ void onSaveNetwork(WifiConfiguration config) {
658 mWifiManager.connectNetwork(config);
662 public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
663 super.onCreateContextMenu(menu, view, menuInfo);
667 * Replace the current background with a new background whose id is resId if needed.
669 private void trySetBackground(int resId) {
670 if (mBackgroundId != resId) {
671 getWindow().setBackgroundDrawable(getResources().getDrawable(resId));
672 mBackgroundId = resId;