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