WifiDisplaySettings.java revision 94417b41c0090d6da5ae982259f69deb6c99d3d1
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 mActionBarSwitch.setOnCheckedChangeListener(mSwitchOnCheckedChangedListener); 97 98 final int padding = activity.getResources().getDimensionPixelSize( 99 R.dimen.action_bar_switch_padding); 100 mActionBarSwitch.setPaddingRelative(0, 0, padding, 0); 101 activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, 102 ActionBar.DISPLAY_SHOW_CUSTOM); 103 activity.getActionBar().setCustomView(mActionBarSwitch, 104 new ActionBar.LayoutParams( 105 ActionBar.LayoutParams.WRAP_CONTENT, 106 ActionBar.LayoutParams.WRAP_CONTENT, 107 Gravity.CENTER_VERTICAL | Gravity.END)); 108 109 mEmptyView = (TextView) getView().findViewById(android.R.id.empty); 110 getListView().setEmptyView(mEmptyView); 111 112 update(); 113 114 if (mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE) { 115 activity.finish(); 116 } 117 } 118 119 @Override 120 public void onDestroyView() { 121 getActivity().getActionBar().setCustomView(null); 122 super.onDestroyView(); 123 } 124 125 @Override 126 public void onResume() { 127 super.onResume(); 128 129 Context context = getActivity(); 130 IntentFilter filter = new IntentFilter(); 131 filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); 132 context.registerReceiver(mReceiver, filter); 133 134 getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 135 Settings.Global.WIFI_DISPLAY_ON), false, mSettingsObserver); 136 137 mDisplayManager.scanWifiDisplays(); 138 139 update(); 140 } 141 142 @Override 143 public void onPause() { 144 super.onPause(); 145 146 Context context = getActivity(); 147 context.unregisterReceiver(mReceiver); 148 149 getContentResolver().unregisterContentObserver(mSettingsObserver); 150 } 151 152 @Override 153 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 154 MenuItem item = menu.add(Menu.NONE, MENU_ID_SCAN, 0, 155 mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING ? 156 R.string.wifi_display_searching_for_devices : 157 R.string.wifi_display_search_for_devices); 158 item.setEnabled(mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON 159 && mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_NOT_SCANNING); 160 item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 161 super.onCreateOptionsMenu(menu, inflater); 162 } 163 164 @Override 165 public boolean onOptionsItemSelected(MenuItem item) { 166 switch (item.getItemId()) { 167 case MENU_ID_SCAN: 168 if (mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) { 169 mDisplayManager.scanWifiDisplays(); 170 } 171 return true; 172 } 173 return super.onOptionsItemSelected(item); 174 } 175 176 @Override 177 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 178 Preference preference) { 179 if (preference instanceof WifiDisplayPreference) { 180 WifiDisplayPreference p = (WifiDisplayPreference)preference; 181 WifiDisplay display = p.getDisplay(); 182 183 if (display.equals(mWifiDisplayStatus.getActiveDisplay())) { 184 showDisconnectDialog(display); 185 } else if (display.canConnect()){ 186 mDisplayManager.connectWifiDisplay(display.getDeviceAddress()); 187 } 188 } 189 190 return super.onPreferenceTreeClick(preferenceScreen, preference); 191 } 192 193 private void update() { 194 mWifiDisplayOnSetting = Settings.Global.getInt(getContentResolver(), 195 Settings.Global.WIFI_DISPLAY_ON, 0) != 0; 196 mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); 197 198 applyState(); 199 } 200 201 private void applyState() { 202 final int featureState = mWifiDisplayStatus.getFeatureState(); 203 mActionBarSwitch.setEnabled(featureState != WifiDisplayStatus.FEATURE_STATE_DISABLED); 204 mActionBarSwitch.setChecked(mWifiDisplayOnSetting); 205 206 final PreferenceScreen preferenceScreen = getPreferenceScreen(); 207 preferenceScreen.removeAll(); 208 209 if (featureState == WifiDisplayStatus.FEATURE_STATE_ON) { 210 final WifiDisplay[] displays = mWifiDisplayStatus.getDisplays(); 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 if (mAvailableDevicesCategory == null) { 221 mAvailableDevicesCategory = new ProgressCategory(getActivity(), null, 222 R.string.wifi_display_no_devices_found); 223 mAvailableDevicesCategory.setTitle(R.string.wifi_display_available_devices); 224 } else { 225 mAvailableDevicesCategory.removeAll(); 226 } 227 preferenceScreen.addPreference(mAvailableDevicesCategory); 228 229 for (WifiDisplay d : displays) { 230 if (d.isRemembered()) { 231 mPairedDevicesCategory.addPreference(createWifiDisplayPreference(d)); 232 } else if (d.isAvailable()){ 233 mAvailableDevicesCategory.addPreference(createWifiDisplayPreference(d)); 234 } 235 } 236 if (mPairedDevicesCategory.getPreferenceCount() == 0) { 237 preferenceScreen.removePreference(mPairedDevicesCategory); 238 } 239 if (mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING) { 240 mAvailableDevicesCategory.setProgress(true); 241 } else { 242 mAvailableDevicesCategory.setProgress(false); 243 } 244 } else { 245 mEmptyView.setText(featureState == WifiDisplayStatus.FEATURE_STATE_OFF ? 246 R.string.wifi_display_settings_empty_list_wifi_display_off : 247 R.string.wifi_display_settings_empty_list_wifi_display_disabled); 248 } 249 250 getActivity().invalidateOptionsMenu(); 251 } 252 253 private Preference createWifiDisplayPreference(final WifiDisplay d) { 254 WifiDisplayPreference p = new WifiDisplayPreference(getActivity(), d); 255 if (d.equals(mWifiDisplayStatus.getActiveDisplay())) { 256 switch (mWifiDisplayStatus.getActiveDisplayState()) { 257 case WifiDisplayStatus.DISPLAY_STATE_CONNECTED: 258 p.setSummary(R.string.wifi_display_status_connected); 259 break; 260 case WifiDisplayStatus.DISPLAY_STATE_CONNECTING: 261 p.setSummary(R.string.wifi_display_status_connecting); 262 break; 263 } 264 } else if (d.isAvailable()) { 265 if (!d.canConnect()) { 266 p.setSummary(R.string.wifi_display_status_in_use); 267 p.setEnabled(false); 268 } else if (d.isRemembered()) { 269 p.setSummary(R.string.wifi_display_status_available); 270 } 271 } 272 if (d.isRemembered()) { 273 p.setWidgetLayoutResource(R.layout.wifi_display_preference); 274 } 275 return p; 276 } 277 278 private void showDisconnectDialog(final WifiDisplay display) { 279 DialogInterface.OnClickListener ok = new DialogInterface.OnClickListener() { 280 @Override 281 public void onClick(DialogInterface dialog, int which) { 282 if (display.equals(mWifiDisplayStatus.getActiveDisplay())) { 283 mDisplayManager.disconnectWifiDisplay(); 284 } 285 } 286 }; 287 288 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 289 .setCancelable(true) 290 .setTitle(R.string.wifi_display_disconnect_title) 291 .setMessage(Html.fromHtml(getResources().getString( 292 R.string.wifi_display_disconnect_text, display.getFriendlyDisplayName()))) 293 .setPositiveButton(android.R.string.ok, ok) 294 .setNegativeButton(android.R.string.cancel, null) 295 .create(); 296 dialog.show(); 297 } 298 299 private void showOptionsDialog(final WifiDisplay display) { 300 View view = getActivity().getLayoutInflater().inflate(R.layout.wifi_display_options, null); 301 final EditText nameEditText = (EditText)view.findViewById(R.id.name); 302 nameEditText.setText(display.getFriendlyDisplayName()); 303 304 DialogInterface.OnClickListener done = new DialogInterface.OnClickListener() { 305 @Override 306 public void onClick(DialogInterface dialog, int which) { 307 String name = nameEditText.getText().toString().trim(); 308 if (name.isEmpty() || name.equals(display.getDeviceName())) { 309 name = null; 310 } 311 mDisplayManager.renameWifiDisplay(display.getDeviceAddress(), name); 312 } 313 }; 314 DialogInterface.OnClickListener forget = new DialogInterface.OnClickListener() { 315 @Override 316 public void onClick(DialogInterface dialog, int which) { 317 mDisplayManager.forgetWifiDisplay(display.getDeviceAddress()); 318 } 319 }; 320 321 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 322 .setCancelable(true) 323 .setTitle(R.string.wifi_display_options_title) 324 .setView(view) 325 .setPositiveButton(R.string.wifi_display_options_done, done) 326 .setNegativeButton(R.string.wifi_display_options_forget, forget) 327 .create(); 328 dialog.show(); 329 } 330 331 private static boolean contains(WifiDisplay[] displays, String address) { 332 for (WifiDisplay d : displays) { 333 if (d.getDeviceAddress().equals(address)) { 334 return true; 335 } 336 } 337 return false; 338 } 339 340 private final CompoundButton.OnCheckedChangeListener mSwitchOnCheckedChangedListener = 341 new CompoundButton.OnCheckedChangeListener() { 342 @Override 343 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 344 mWifiDisplayOnSetting = isChecked; 345 Settings.Global.putInt(getContentResolver(), 346 Settings.Global.WIFI_DISPLAY_ON, isChecked ? 1 : 0); 347 } 348 }; 349 350 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 351 @Override 352 public void onReceive(Context context, Intent intent) { 353 String action = intent.getAction(); 354 if (action.equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) { 355 WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra( 356 DisplayManager.EXTRA_WIFI_DISPLAY_STATUS); 357 mWifiDisplayStatus = status; 358 applyState(); 359 } 360 } 361 }; 362 363 private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 364 @Override 365 public void onChange(boolean selfChange, Uri uri) { 366 update(); 367 } 368 }; 369 370 private final class WifiDisplayPreference extends Preference 371 implements View.OnClickListener { 372 private final WifiDisplay mDisplay; 373 374 public WifiDisplayPreference(Context context, WifiDisplay display) { 375 super(context); 376 377 mDisplay = display; 378 setTitle(display.getFriendlyDisplayName()); 379 } 380 381 public WifiDisplay getDisplay() { 382 return mDisplay; 383 } 384 385 @Override 386 protected void onBindView(View view) { 387 super.onBindView(view); 388 389 ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails); 390 if (deviceDetails != null) { 391 deviceDetails.setOnClickListener(this); 392 393 if (!isEnabled()) { 394 TypedValue value = new TypedValue(); 395 getContext().getTheme().resolveAttribute(android.R.attr.disabledAlpha, 396 value, true); 397 deviceDetails.setImageAlpha((int)(value.getFloat() * 255)); 398 } 399 } 400 } 401 402 @Override 403 public void onClick(View v) { 404 showOptionsDialog(mDisplay); 405 } 406 } 407} 408