WifiDisplaySettings.java revision 9e143f5e9d836d2d3dd0b2f59f7d14327ade0193
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 17package com.android.settings.wfd; 18 19import android.app.ActionBar; 20import android.app.Activity; 21import android.app.AlertDialog; 22import android.content.BroadcastReceiver; 23import android.content.Context; 24import android.content.DialogInterface; 25import android.content.Intent; 26import android.content.IntentFilter; 27import android.database.ContentObserver; 28import android.hardware.display.DisplayManager; 29import android.hardware.display.WifiDisplay; 30import android.hardware.display.WifiDisplayStatus; 31import android.net.Uri; 32import android.os.Bundle; 33import android.os.Handler; 34import android.preference.Preference; 35import android.preference.PreferenceActivity; 36import android.preference.PreferenceCategory; 37import android.preference.PreferenceGroup; 38import android.preference.PreferenceScreen; 39import android.provider.Settings; 40import android.text.Html; 41import android.util.TypedValue; 42import android.view.Gravity; 43import android.view.Menu; 44import android.view.MenuInflater; 45import android.view.MenuItem; 46import android.view.View; 47import android.widget.CompoundButton; 48import android.widget.EditText; 49import android.widget.ImageView; 50import android.widget.Switch; 51import android.widget.TextView; 52 53import com.android.settings.ProgressCategory; 54import com.android.settings.R; 55import com.android.settings.SettingsPreferenceFragment; 56 57/** 58 * The Settings screen for WifiDisplay configuration and connection management. 59 */ 60public final class WifiDisplaySettings extends SettingsPreferenceFragment { 61 private static final String TAG = "WifiDisplaySettings"; 62 63 private static final int MENU_ID_SCAN = Menu.FIRST; 64 65 private DisplayManager mDisplayManager; 66 67 private boolean mWifiDisplayOnSetting; 68 private WifiDisplayStatus mWifiDisplayStatus; 69 70 private PreferenceGroup mPairedDevicesCategory; 71 private ProgressCategory mAvailableDevicesCategory; 72 73 private TextView mEmptyView; 74 75 private Switch mActionBarSwitch; 76 77 public WifiDisplaySettings() { 78 } 79 80 @Override 81 public void onCreate(Bundle icicle) { 82 super.onCreate(icicle); 83 84 mDisplayManager = (DisplayManager)getActivity().getSystemService(Context.DISPLAY_SERVICE); 85 86 addPreferencesFromResource(R.xml.wifi_display_settings); 87 setHasOptionsMenu(true); 88 } 89 90 @Override 91 public void onActivityCreated(Bundle savedInstanceState) { 92 super.onActivityCreated(savedInstanceState); 93 94 Activity activity = getActivity(); 95 mActionBarSwitch = new Switch(activity); 96 if (activity instanceof PreferenceActivity) { 97 PreferenceActivity preferenceActivity = (PreferenceActivity) activity; 98 if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) { 99 final int padding = activity.getResources().getDimensionPixelSize( 100 R.dimen.action_bar_switch_padding); 101 mActionBarSwitch.setPadding(0, 0, padding, 0); 102 activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, 103 ActionBar.DISPLAY_SHOW_CUSTOM); 104 activity.getActionBar().setCustomView(mActionBarSwitch, 105 new ActionBar.LayoutParams( 106 ActionBar.LayoutParams.WRAP_CONTENT, 107 ActionBar.LayoutParams.WRAP_CONTENT, 108 Gravity.CENTER_VERTICAL | Gravity.END)); 109 } 110 } 111 112 mActionBarSwitch.setOnCheckedChangeListener(mSwitchOnCheckedChangedListener); 113 114 mEmptyView = (TextView) getView().findViewById(android.R.id.empty); 115 getListView().setEmptyView(mEmptyView); 116 117 update(); 118 119 if (mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE) { 120 activity.finish(); 121 } 122 } 123 124 @Override 125 public void onResume() { 126 super.onResume(); 127 128 Context context = getActivity(); 129 IntentFilter filter = new IntentFilter(); 130 filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); 131 context.registerReceiver(mReceiver, filter); 132 133 getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 134 Settings.Global.WIFI_DISPLAY_ON), false, mSettingsObserver); 135 136 mDisplayManager.scanWifiDisplays(); 137 138 update(); 139 } 140 141 @Override 142 public void onPause() { 143 super.onPause(); 144 145 Context context = getActivity(); 146 context.unregisterReceiver(mReceiver); 147 148 getContentResolver().unregisterContentObserver(mSettingsObserver); 149 } 150 151 @Override 152 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 153 MenuItem item = menu.add(Menu.NONE, MENU_ID_SCAN, 0, 154 mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING ? 155 R.string.wifi_display_searching_for_devices : 156 R.string.wifi_display_search_for_devices); 157 item.setEnabled(mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON 158 && mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_NOT_SCANNING); 159 item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 160 super.onCreateOptionsMenu(menu, inflater); 161 } 162 163 @Override 164 public boolean onOptionsItemSelected(MenuItem item) { 165 switch (item.getItemId()) { 166 case MENU_ID_SCAN: 167 if (mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) { 168 mDisplayManager.scanWifiDisplays(); 169 } 170 return true; 171 } 172 return super.onOptionsItemSelected(item); 173 } 174 175 @Override 176 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 177 Preference preference) { 178 if (preference instanceof WifiDisplayPreference) { 179 WifiDisplayPreference p = (WifiDisplayPreference)preference; 180 WifiDisplay display = p.getDisplay(); 181 182 if (display.equals(mWifiDisplayStatus.getActiveDisplay())) { 183 showDisconnectDialog(display); 184 } else { 185 mDisplayManager.connectWifiDisplay(display.getDeviceAddress()); 186 } 187 } 188 189 return super.onPreferenceTreeClick(preferenceScreen, preference); 190 } 191 192 private void update() { 193 mWifiDisplayOnSetting = Settings.Global.getInt(getContentResolver(), 194 Settings.Global.WIFI_DISPLAY_ON, 0) != 0; 195 mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); 196 197 applyState(); 198 } 199 200 private void applyState() { 201 final int featureState = mWifiDisplayStatus.getFeatureState(); 202 mActionBarSwitch.setEnabled(featureState != WifiDisplayStatus.FEATURE_STATE_DISABLED); 203 mActionBarSwitch.setChecked(mWifiDisplayOnSetting); 204 205 final PreferenceScreen preferenceScreen = getPreferenceScreen(); 206 preferenceScreen.removeAll(); 207 208 if (featureState == WifiDisplayStatus.FEATURE_STATE_ON) { 209 final WifiDisplay[] pairedDisplays = mWifiDisplayStatus.getRememberedDisplays(); 210 final WifiDisplay[] availableDisplays = mWifiDisplayStatus.getAvailableDisplays(); 211 212 if (mPairedDevicesCategory == null) { 213 mPairedDevicesCategory = new PreferenceCategory(getActivity()); 214 mPairedDevicesCategory.setTitle(R.string.wifi_display_paired_devices); 215 } else { 216 mPairedDevicesCategory.removeAll(); 217 } 218 preferenceScreen.addPreference(mPairedDevicesCategory); 219 220 for (WifiDisplay d : pairedDisplays) { 221 mPairedDevicesCategory.addPreference(createWifiDisplayPreference(d, true)); 222 } 223 if (mPairedDevicesCategory.getPreferenceCount() == 0) { 224 preferenceScreen.removePreference(mPairedDevicesCategory); 225 } 226 227 if (mAvailableDevicesCategory == null) { 228 mAvailableDevicesCategory = new ProgressCategory(getActivity(), null, 229 R.string.wifi_display_no_devices_found); 230 mAvailableDevicesCategory.setTitle(R.string.wifi_display_available_devices); 231 } else { 232 mAvailableDevicesCategory.removeAll(); 233 } 234 preferenceScreen.addPreference(mAvailableDevicesCategory); 235 236 for (WifiDisplay d : availableDisplays) { 237 if (!contains(pairedDisplays, d.getDeviceAddress())) { 238 mAvailableDevicesCategory.addPreference(createWifiDisplayPreference(d, false)); 239 } 240 } 241 if (mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING) { 242 mAvailableDevicesCategory.setProgress(true); 243 } else { 244 mAvailableDevicesCategory.setProgress(false); 245 } 246 } else { 247 mEmptyView.setText(featureState == WifiDisplayStatus.FEATURE_STATE_OFF ? 248 R.string.wifi_display_settings_empty_list_wifi_display_off : 249 R.string.wifi_display_settings_empty_list_wifi_display_disabled); 250 } 251 252 getActivity().invalidateOptionsMenu(); 253 } 254 255 private Preference createWifiDisplayPreference(final WifiDisplay d, boolean paired) { 256 WifiDisplayPreference p = new WifiDisplayPreference(getActivity(), d); 257 if (d.equals(mWifiDisplayStatus.getActiveDisplay())) { 258 switch (mWifiDisplayStatus.getActiveDisplayState()) { 259 case WifiDisplayStatus.DISPLAY_STATE_CONNECTED: 260 p.setSummary(R.string.wifi_display_status_connected); 261 break; 262 case WifiDisplayStatus.DISPLAY_STATE_CONNECTING: 263 p.setSummary(R.string.wifi_display_status_connecting); 264 break; 265 } 266 } else if (paired && contains(mWifiDisplayStatus.getAvailableDisplays(), 267 d.getDeviceAddress())) { 268 p.setSummary(R.string.wifi_display_status_available); 269 } 270 if (paired) { 271 p.setWidgetLayoutResource(R.layout.wifi_display_preference); 272 } 273 return p; 274 } 275 276 private void showDisconnectDialog(final WifiDisplay display) { 277 DialogInterface.OnClickListener ok = new DialogInterface.OnClickListener() { 278 @Override 279 public void onClick(DialogInterface dialog, int which) { 280 if (display.equals(mWifiDisplayStatus.getActiveDisplay())) { 281 mDisplayManager.disconnectWifiDisplay(); 282 } 283 } 284 }; 285 286 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 287 .setCancelable(true) 288 .setTitle(R.string.wifi_display_disconnect_title) 289 .setMessage(Html.fromHtml(getResources().getString( 290 R.string.wifi_display_disconnect_text, display.getFriendlyDisplayName()))) 291 .setPositiveButton(android.R.string.ok, ok) 292 .setNegativeButton(android.R.string.cancel, null) 293 .create(); 294 dialog.show(); 295 } 296 297 private void showOptionsDialog(final WifiDisplay display) { 298 View view = getActivity().getLayoutInflater().inflate(R.layout.wifi_display_options, null); 299 final EditText nameEditText = (EditText)view.findViewById(R.id.name); 300 nameEditText.setText(display.getFriendlyDisplayName()); 301 302 DialogInterface.OnClickListener done = new DialogInterface.OnClickListener() { 303 @Override 304 public void onClick(DialogInterface dialog, int which) { 305 String name = nameEditText.getText().toString().trim(); 306 if (name.isEmpty() || name.equals(display.getDeviceName())) { 307 name = null; 308 } 309 mDisplayManager.renameWifiDisplay(display.getDeviceAddress(), name); 310 } 311 }; 312 DialogInterface.OnClickListener forget = new DialogInterface.OnClickListener() { 313 @Override 314 public void onClick(DialogInterface dialog, int which) { 315 mDisplayManager.forgetWifiDisplay(display.getDeviceAddress()); 316 } 317 }; 318 319 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 320 .setCancelable(true) 321 .setTitle(R.string.wifi_display_options_title) 322 .setView(view) 323 .setPositiveButton(R.string.wifi_display_options_done, done) 324 .setNegativeButton(R.string.wifi_display_options_forget, forget) 325 .create(); 326 dialog.show(); 327 } 328 329 private static boolean contains(WifiDisplay[] displays, String address) { 330 for (WifiDisplay d : displays) { 331 if (d.getDeviceAddress().equals(address)) { 332 return true; 333 } 334 } 335 return false; 336 } 337 338 private final CompoundButton.OnCheckedChangeListener mSwitchOnCheckedChangedListener = 339 new CompoundButton.OnCheckedChangeListener() { 340 @Override 341 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 342 mWifiDisplayOnSetting = isChecked; 343 Settings.Global.putInt(getContentResolver(), 344 Settings.Global.WIFI_DISPLAY_ON, isChecked ? 1 : 0); 345 } 346 }; 347 348 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 349 @Override 350 public void onReceive(Context context, Intent intent) { 351 String action = intent.getAction(); 352 if (action.equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) { 353 WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra( 354 DisplayManager.EXTRA_WIFI_DISPLAY_STATUS); 355 mWifiDisplayStatus = status; 356 applyState(); 357 } 358 } 359 }; 360 361 private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 362 @Override 363 public void onChange(boolean selfChange, Uri uri) { 364 update(); 365 } 366 }; 367 368 private final class WifiDisplayPreference extends Preference 369 implements View.OnClickListener { 370 private final WifiDisplay mDisplay; 371 372 public WifiDisplayPreference(Context context, WifiDisplay display) { 373 super(context); 374 375 mDisplay = display; 376 setTitle(display.getFriendlyDisplayName()); 377 } 378 379 public WifiDisplay getDisplay() { 380 return mDisplay; 381 } 382 383 @Override 384 protected void onBindView(View view) { 385 super.onBindView(view); 386 387 ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails); 388 if (deviceDetails != null) { 389 deviceDetails.setOnClickListener(this); 390 391 if (!isEnabled()) { 392 TypedValue value = new TypedValue(); 393 getContext().getTheme().resolveAttribute(android.R.attr.disabledAlpha, 394 value, true); 395 deviceDetails.setImageAlpha((int)(value.getFloat() * 255)); 396 } 397 } 398 } 399 400 @Override 401 public void onClick(View v) { 402 showOptionsDialog(mDisplay); 403 } 404 } 405} 406