diff options
-rw-r--r-- | AndroidManifest.xml | 14 | ||||
-rw-r--r-- | res/layout/preference_progress_category.xml | 8 | ||||
-rw-r--r-- | res/layout/wifi_display_options.xml | 34 | ||||
-rw-r--r-- | res/layout/wifi_display_preference.xml | 43 | ||||
-rw-r--r-- | res/values/strings.xml | 46 | ||||
-rw-r--r-- | res/xml/display_settings.xml | 5 | ||||
-rw-r--r-- | res/xml/wifi_display_settings.xml | 21 | ||||
-rw-r--r-- | src/com/android/settings/DisplaySettings.java | 64 | ||||
-rw-r--r-- | src/com/android/settings/ProgressCategory.java | 8 | ||||
-rw-r--r-- | src/com/android/settings/Settings.java | 3 | ||||
-rwxr-xr-x | src/com/android/settings/bluetooth/BluetoothSettings.java | 3 | ||||
-rwxr-xr-x | src/com/android/settings/wfd/WifiDisplaySettings.java | 405 |
12 files changed, 641 insertions, 13 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b1dd657..e95eec0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -60,6 +60,7 @@ <uses-permission android:name="android.permission.COPY_PROTECTED_DATA" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.READ_PROFILE" /> + <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" /> <application android:label="@string/settings_label" android:icon="@mipmap/ic_launcher_settings" @@ -1226,7 +1227,18 @@ android:value="com.android.settings.nfc.AndroidBeam" /> </activity> - + <activity android:name="Settings$WifiDisplaySettingsActivity" + android:label="@string/wifi_display_settings_title" + android:taskAffinity="com.android.settings" + android:parentActivityName="Settings$DisplaySettingsActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <action android:name="android.settings.WIFI_DISPLAY_SETTINGS" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data android:name="com.android.settings.FRAGMENT_CLASS" + android:value="com.android.settings.wfd.WifiDisplaySettings" /> + </activity> <!-- Development settings --> diff --git a/res/layout/preference_progress_category.xml b/res/layout/preference_progress_category.xml index 6e8188c..17d87d7 100644 --- a/res/layout/preference_progress_category.xml +++ b/res/layout/preference_progress_category.xml @@ -18,19 +18,18 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="?android:attr/listSeparatorTextViewStyle" android:gravity="center_vertical" - android:orientation="horizontal" - > + android:orientation="horizontal"> <!-- This text view has the style of the list separator text view without the background and padding. --> <TextView style="?android:attr/listSeparatorTextViewStyle" android:background="@null" - android:paddingStart="16dip" android:id="@+android:id/title" + android:paddingStart="0dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:layout_gravity="start|bottom" + android:layout_gravity="start|center" /> <ProgressBar @@ -40,7 +39,6 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="16dip" - android:layout_marginEnd="16dip" style="?android:attr/progressBarStyleSmallTitle" /> diff --git a/res/layout/wifi_display_options.xml b/res/layout/wifi_display_options.xml new file mode 100644 index 0000000..c56a512 --- /dev/null +++ b/res/layout/wifi_display_options.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/wifi_display_options_name" /> + + <EditText + android:id="@+id/name" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + +</LinearLayout> diff --git a/res/layout/wifi_display_preference.xml b/res/layout/wifi_display_preference.xml new file mode 100644 index 0000000..d8c4729 --- /dev/null +++ b/res/layout/wifi_display_preference.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical"> + + <!-- Divider --> + <ImageView + android:id="@+id/divider" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:src="@drawable/nav_divider" + android:contentDescription="@null" + /> + + <!-- Details button --> + <ImageView + android:id="@+id/deviceDetails" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:padding="8dip" + android:background="?android:attr/selectableItemBackground" + android:src="@drawable/ic_bt_config" + android:contentDescription="@string/wifi_display_details" /> + +</LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index 5b38b35..97c0726 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1153,6 +1153,52 @@ <!-- Bluetooth settings. Dock Setting Dialog - Remember setting and don't ask user again --> <string name="bluetooth_dock_settings_remember">Remember settings</string> + <!-- Wifi Display settings. The title of the screen. [CHAR LIMIT=40] --> + <string name="wifi_display_settings_title">Wireless display</string> + <!-- Wifi Display settings. Text displayed when Wifi display is off and device list is empty [CHAR LIMIT=80]--> + <string name="wifi_display_settings_empty_list_wifi_display_off">To see devices, turn wireless display on.</string> + <!-- Wifi Display settings. Text displayed when Wifi Display is off and device list is empty [CHAR LIMIT=80]--> + <string name="wifi_display_settings_empty_list_wifi_display_disabled">Wireless display is disabled because Wi-Fi is off.</string> + <!-- Wifi Display settings. The title of the action button that initiates a search for nearby devices [CHAR LIMIT=20] --> + <string name="wifi_display_search_for_devices">Search for displays</string> + <!-- Wifi Display settings. The title of the action button while a search for nearby devices is in progress [CHAR LIMIT=20] --> + <string name="wifi_display_searching_for_devices">Searching\u2026</string> + <!-- Wifi Display settings. Text that appears when scanning for devices is finished and no nearby device was found [CHAR LIMIT=40]--> + <string name="wifi_display_no_devices_found">No nearby wireless displays were found.</string> + <!-- Wifi Display settings. The sub heading for devices which have already been paired with this device. [CHAR LIMIT=40] --> + <string name="wifi_display_paired_devices">Paired displays</string> + <!-- Wifi Display settings. The sub heading for available devices during and after scanning. [CHAR LIMIT=40] --> + <string name="wifi_display_available_devices">Available devices</string> + <!-- Wifi Display settings. The status summary for connecting devices. [CHAR LIMIT=40] --> + <string name="wifi_display_status_connecting">Connecting</string> + <!-- Wifi Display settings. The status summary for connected devices. [CHAR LIMIT=40] --> + <string name="wifi_display_status_connected">Connected</string> + <!-- Wifi Display settings. The status summary for available devices. [CHAR LIMIT=40] --> + <string name="wifi_display_status_available">Available</string> + <!-- Wifi Display settings. Image description for device details button. This opens the screen to rename, unpair, etc. a single device. --> + <string name="wifi_display_details">Display settings</string> + + <!-- Wifi Display settings. Disconnect dialog. The title of the dialog. [CHAR LIMIT=40] --> + <string name="wifi_display_disconnect_title">Disconnect?</string> + <!-- Wifi Display settings. Disconnect dialog. Message for disconnecting from the display. [CHAR LIMIT=NONE] --> + <string name="wifi_display_disconnect_text">This will end your connection with:<br><b><xliff:g id="device_name">%1$s</xliff:g></b></string> + + <!-- Wifi Display settings. Options dialog. The title of the dialog. [CHAR LIMIT=40] --> + <string name="wifi_display_options_title">Wireless display options</string> + <!-- Wifi Display settings. Options dialog. The forget button text. [CHAR LIMIT=20] --> + <string name="wifi_display_options_forget">Forget</string> + <!-- Wifi Display settings. Options dialog. The done button text. [CHAR LIMIT=20] --> + <string name="wifi_display_options_done">Done</string> + <!-- Wifi Display settings. Options dialog. The name label used when prompting the user to rename the display. [CHAR LIMIT=20] --> + <string name="wifi_display_options_name">Name</string> + + <!-- Wifi Display settings. Summary shown in Display settings. Text used for 'On' state. [CHAR LIMIT=40] --> + <string name="wifi_display_summary_on">On</string> + <!-- Wifi Display settings. Summary shown in Display settings. Text used for 'Off' state. [CHAR LIMIT=40] --> + <string name="wifi_display_summary_off">Off</string> + <!-- Wifi Display settings. Summary shown in Display settings. Text used for 'Disabled' state. [CHAR LIMIT=40] --> + <string name="wifi_display_summary_disabled">Disabled</string> + <!-- NFC settings --> <!-- Used in the 1st-level settings screen to turn on NFC --> <string name="nfc_quick_toggle_title">NFC</string> diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index b5f072f..cc526f9 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -58,4 +58,9 @@ android:title="@string/notification_pulse_title" android:persistent="false" /> + <PreferenceScreen + android:key="wifi_display" + android:title="@string/wifi_display_settings_title" + android:fragment="com.android.settings.wfd.WifiDisplaySettings" /> + </PreferenceScreen> diff --git a/res/xml/wifi_display_settings.xml b/res/xml/wifi_display_settings.xml new file mode 100644 index 0000000..2b32106 --- /dev/null +++ b/res/xml/wifi_display_settings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android" + android:title="@string/wifi_display_settings_title" > + +</PreferenceScreen> diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java index 622d77e..e7e1ea6 100644 --- a/src/com/android/settings/DisplaySettings.java +++ b/src/com/android/settings/DisplaySettings.java @@ -20,10 +20,16 @@ import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; import android.app.ActivityManagerNative; import android.app.admin.DevicePolicyManager; +import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.res.Configuration; import android.content.res.Resources; +import android.hardware.display.DisplayManager; +import android.hardware.display.WifiDisplay; +import android.hardware.display.WifiDisplayStatus; import android.os.Bundle; import android.os.RemoteException; import android.preference.CheckBoxPreference; @@ -51,6 +57,9 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private static final String KEY_FONT_SIZE = "font_size"; private static final String KEY_NOTIFICATION_PULSE = "notification_pulse"; private static final String KEY_SCREEN_SAVER = "screensaver"; + private static final String KEY_WIFI_DISPLAY = "wifi_display"; + + private DisplayManager mDisplayManager; private CheckBoxPreference mAccelerometer; private ListPreference mFontSizePref; @@ -61,6 +70,9 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private ListPreference mScreenTimeoutPreference; private Preference mScreenSaverPreference; + private WifiDisplayStatus mWifiDisplayStatus; + private Preference mWifiDisplayPreference; + private final RotationPolicy.RotationPolicyListener mRotationPolicyListener = new RotationPolicy.RotationPolicyListener() { @Override @@ -116,6 +128,15 @@ public class DisplaySettings extends SettingsPreferenceFragment implements } } + mDisplayManager = (DisplayManager)getActivity().getSystemService( + Context.DISPLAY_SERVICE); + mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); + mWifiDisplayPreference = (Preference)findPreference(KEY_WIFI_DISPLAY); + if (mWifiDisplayStatus.getFeatureState() + == WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE) { + getPreferenceScreen().removePreference(mWifiDisplayPreference); + mWifiDisplayPreference = null; + } } private void updateTimeoutPreferenceDescription(long currentTimeout) { @@ -211,10 +232,16 @@ public class DisplaySettings extends SettingsPreferenceFragment implements public void onResume() { super.onResume(); - updateState(); - RotationPolicy.registerRotationPolicyListener(getActivity(), mRotationPolicyListener); + + if (mWifiDisplayPreference != null) { + getActivity().registerReceiver(mReceiver, new IntentFilter( + DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)); + mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); + } + + updateState(); } @Override @@ -223,12 +250,17 @@ public class DisplaySettings extends SettingsPreferenceFragment implements RotationPolicy.unregisterRotationPolicyListener(getActivity(), mRotationPolicyListener); + + if (mWifiDisplayPreference != null) { + getActivity().unregisterReceiver(mReceiver); + } } private void updateState() { updateAccelerometerRotationCheckbox(); readFontSizePreference(mFontSizePref); updateScreenSaverSummary(); + updateWifiDisplaySummary(); } private void updateScreenSaverSummary() { @@ -239,6 +271,23 @@ public class DisplaySettings extends SettingsPreferenceFragment implements mScreenSaverPreference.setSummary(""); } + private void updateWifiDisplaySummary() { + if (mWifiDisplayPreference != null) { + switch (mWifiDisplayStatus.getFeatureState()) { + case WifiDisplayStatus.FEATURE_STATE_OFF: + mWifiDisplayPreference.setSummary(R.string.wifi_display_summary_off); + break; + case WifiDisplayStatus.FEATURE_STATE_ON: + mWifiDisplayPreference.setSummary(R.string.wifi_display_summary_on); + break; + case WifiDisplayStatus.FEATURE_STATE_DISABLED: + default: + mWifiDisplayPreference.setSummary(R.string.wifi_display_summary_disabled); + break; + } + } + } + private void updateAccelerometerRotationCheckbox() { if (getActivity() == null) return; @@ -285,4 +334,15 @@ public class DisplaySettings extends SettingsPreferenceFragment implements return true; } + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) { + mWifiDisplayStatus = (WifiDisplayStatus)intent.getParcelableExtra( + DisplayManager.EXTRA_WIFI_DISPLAY_STATUS); + updateWifiDisplaySummary(); + } + } + }; } diff --git a/src/com/android/settings/ProgressCategory.java b/src/com/android/settings/ProgressCategory.java index 625aa59..6fe34bf 100644 --- a/src/com/android/settings/ProgressCategory.java +++ b/src/com/android/settings/ProgressCategory.java @@ -20,17 +20,19 @@ import android.content.Context; import android.preference.Preference; import android.util.AttributeSet; import android.view.View; -import android.widget.TextView; public class ProgressCategory extends ProgressCategoryBase { + private final int mEmptyTextRes; private boolean mProgress = false; private Preference mNoDeviceFoundPreference; private boolean mNoDeviceFoundAdded; - public ProgressCategory(Context context, AttributeSet attrs) { + public ProgressCategory(Context context, AttributeSet attrs, + int emptyTextRes) { super(context, attrs); setLayoutResource(R.layout.preference_progress_category); + mEmptyTextRes = emptyTextRes; } @Override @@ -52,7 +54,7 @@ public class ProgressCategory extends ProgressCategoryBase { if (mNoDeviceFoundPreference == null) { mNoDeviceFoundPreference = new Preference(getContext()); mNoDeviceFoundPreference.setLayoutResource(R.layout.preference_empty_list); - mNoDeviceFoundPreference.setTitle(R.string.bluetooth_no_devices_found); + mNoDeviceFoundPreference.setTitle(mEmptyTextRes); mNoDeviceFoundPreference.setSelectable(false); } addPreference(mNoDeviceFoundPreference); diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index fa30f09..dade680 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -114,7 +114,7 @@ public class Settings extends PreferenceActivity R.id.account_settings, R.id.account_add, R.id.system_section, - R.id.about_settings + R.id.about_settings, }; // TODO: Update Call Settings based on airplane mode state. @@ -792,4 +792,5 @@ public class Settings extends PreferenceActivity public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ } public static class TextToSpeechSettingsActivity extends Settings { /* empty */ } public static class AndroidBeamSettingsActivity extends Settings { /* empty */ } + public static class WifiDisplaySettingsActivity extends Settings { /* empty */ } } diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java index f44efc4..0765d8f 100755 --- a/src/com/android/settings/bluetooth/BluetoothSettings.java +++ b/src/com/android/settings/bluetooth/BluetoothSettings.java @@ -282,7 +282,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment { // Available devices category if (mAvailableDevicesCategory == null) { - mAvailableDevicesCategory = new ProgressCategory(getActivity(), null); + mAvailableDevicesCategory = new ProgressCategory(getActivity(), null, + R.string.bluetooth_no_devices_found); } else { mAvailableDevicesCategory.removeAll(); } diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java new file mode 100755 index 0000000..f1d0e70 --- /dev/null +++ b/src/com/android/settings/wfd/WifiDisplaySettings.java @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wfd; + +import android.app.ActionBar; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.database.ContentObserver; +import android.hardware.display.DisplayManager; +import android.hardware.display.WifiDisplay; +import android.hardware.display.WifiDisplayStatus; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.preference.PreferenceGroup; +import android.preference.PreferenceScreen; +import android.provider.Settings; +import android.text.Html; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Switch; +import android.widget.TextView; + +import com.android.settings.ProgressCategory; +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +/** + * The Settings screen for WifiDisplay configuration and connection management. + */ +public final class WifiDisplaySettings extends SettingsPreferenceFragment { + private static final String TAG = "WifiDisplaySettings"; + + private static final int MENU_ID_SCAN = Menu.FIRST; + + private DisplayManager mDisplayManager; + + private boolean mWifiDisplayOnSetting; + private WifiDisplayStatus mWifiDisplayStatus; + + private PreferenceGroup mPairedDevicesCategory; + private ProgressCategory mAvailableDevicesCategory; + + private TextView mEmptyView; + + private Switch mActionBarSwitch; + + public WifiDisplaySettings() { + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mDisplayManager = (DisplayManager)getActivity().getSystemService(Context.DISPLAY_SERVICE); + + addPreferencesFromResource(R.xml.wifi_display_settings); + setHasOptionsMenu(true); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + Activity activity = getActivity(); + mActionBarSwitch = new Switch(activity); + if (activity instanceof PreferenceActivity) { + PreferenceActivity preferenceActivity = (PreferenceActivity) activity; + if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) { + final int padding = activity.getResources().getDimensionPixelSize( + R.dimen.action_bar_switch_padding); + mActionBarSwitch.setPadding(0, 0, padding, 0); + activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, + ActionBar.DISPLAY_SHOW_CUSTOM); + activity.getActionBar().setCustomView(mActionBarSwitch, + new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, + ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.END)); + } + } + + mActionBarSwitch.setOnCheckedChangeListener(mSwitchOnCheckedChangedListener); + + mEmptyView = (TextView) getView().findViewById(android.R.id.empty); + getListView().setEmptyView(mEmptyView); + + update(); + + if (mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE) { + activity.finish(); + } + } + + @Override + public void onResume() { + super.onResume(); + + Context context = getActivity(); + IntentFilter filter = new IntentFilter(); + filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); + context.registerReceiver(mReceiver, filter); + + getContentResolver().registerContentObserver(Settings.Secure.getUriFor( + Settings.Global.WIFI_DISPLAY_ON), false, mSettingsObserver); + + mDisplayManager.scanWifiDisplays(); + + update(); + } + + @Override + public void onPause() { + super.onPause(); + + Context context = getActivity(); + context.unregisterReceiver(mReceiver); + + getContentResolver().unregisterContentObserver(mSettingsObserver); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + MenuItem item = menu.add(Menu.NONE, MENU_ID_SCAN, 0, + mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING ? + R.string.wifi_display_searching_for_devices : + R.string.wifi_display_search_for_devices); + item.setEnabled(mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON + && mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_NOT_SCANNING); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_ID_SCAN: + if (mWifiDisplayStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) { + mDisplayManager.scanWifiDisplays(); + } + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, + Preference preference) { + if (preference instanceof WifiDisplayPreference) { + WifiDisplayPreference p = (WifiDisplayPreference)preference; + WifiDisplay display = p.getDisplay(); + + if (display.equals(mWifiDisplayStatus.getActiveDisplay())) { + showDisconnectDialog(display); + } else { + mDisplayManager.connectWifiDisplay(display.getDeviceAddress()); + } + } + + return super.onPreferenceTreeClick(preferenceScreen, preference); + } + + private void update() { + mWifiDisplayOnSetting = Settings.Global.getInt(getContentResolver(), + Settings.Global.WIFI_DISPLAY_ON, 0) != 0; + mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); + + applyState(); + } + + private void applyState() { + final int featureState = mWifiDisplayStatus.getFeatureState(); + mActionBarSwitch.setEnabled(featureState != WifiDisplayStatus.FEATURE_STATE_DISABLED); + mActionBarSwitch.setChecked(mWifiDisplayOnSetting); + + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + preferenceScreen.removeAll(); + + if (featureState == WifiDisplayStatus.FEATURE_STATE_ON) { + final WifiDisplay[] pairedDisplays = mWifiDisplayStatus.getRememberedDisplays(); + final WifiDisplay[] availableDisplays = mWifiDisplayStatus.getAvailableDisplays(); + + if (mPairedDevicesCategory == null) { + mPairedDevicesCategory = new PreferenceCategory(getActivity()); + mPairedDevicesCategory.setTitle(R.string.wifi_display_paired_devices); + } else { + mPairedDevicesCategory.removeAll(); + } + preferenceScreen.addPreference(mPairedDevicesCategory); + + for (WifiDisplay d : pairedDisplays) { + mPairedDevicesCategory.addPreference(createWifiDisplayPreference(d, true)); + } + if (mPairedDevicesCategory.getPreferenceCount() == 0) { + preferenceScreen.removePreference(mPairedDevicesCategory); + } + + if (mAvailableDevicesCategory == null) { + mAvailableDevicesCategory = new ProgressCategory(getActivity(), null, + R.string.wifi_display_no_devices_found); + mAvailableDevicesCategory.setTitle(R.string.wifi_display_available_devices); + } else { + mAvailableDevicesCategory.removeAll(); + } + preferenceScreen.addPreference(mAvailableDevicesCategory); + + for (WifiDisplay d : availableDisplays) { + if (!contains(pairedDisplays, d.getDeviceAddress())) { + mAvailableDevicesCategory.addPreference(createWifiDisplayPreference(d, false)); + } + } + if (mWifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING) { + mAvailableDevicesCategory.setProgress(true); + } else { + mAvailableDevicesCategory.setProgress(false); + } + } else { + mEmptyView.setText(featureState == WifiDisplayStatus.FEATURE_STATE_OFF ? + R.string.wifi_display_settings_empty_list_wifi_display_off : + R.string.wifi_display_settings_empty_list_wifi_display_disabled); + } + + getActivity().invalidateOptionsMenu(); + } + + private Preference createWifiDisplayPreference(final WifiDisplay d, boolean paired) { + WifiDisplayPreference p = new WifiDisplayPreference(getActivity(), d); + if (d.equals(mWifiDisplayStatus.getActiveDisplay())) { + switch (mWifiDisplayStatus.getActiveDisplayState()) { + case WifiDisplayStatus.DISPLAY_STATE_CONNECTED: + p.setSummary(R.string.wifi_display_status_connected); + break; + case WifiDisplayStatus.DISPLAY_STATE_CONNECTING: + p.setSummary(R.string.wifi_display_status_connecting); + break; + } + } else if (paired && contains(mWifiDisplayStatus.getAvailableDisplays(), + d.getDeviceAddress())) { + p.setSummary(R.string.wifi_display_status_available); + } + if (paired) { + p.setWidgetLayoutResource(R.layout.wifi_display_preference); + } + return p; + } + + private void showDisconnectDialog(final WifiDisplay display) { + DialogInterface.OnClickListener ok = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (display.equals(mWifiDisplayStatus.getActiveDisplay())) { + mDisplayManager.disconnectWifiDisplay(); + } + } + }; + + AlertDialog dialog = new AlertDialog.Builder(getActivity()) + .setCancelable(true) + .setTitle(R.string.wifi_display_disconnect_title) + .setMessage(Html.fromHtml(getResources().getString( + R.string.wifi_display_disconnect_text, display.getFriendlyDisplayName()))) + .setPositiveButton(android.R.string.ok, ok) + .setNegativeButton(android.R.string.cancel, null) + .create(); + dialog.show(); + } + + private void showOptionsDialog(final WifiDisplay display) { + View view = getActivity().getLayoutInflater().inflate(R.layout.wifi_display_options, null); + final EditText nameEditText = (EditText)view.findViewById(R.id.name); + nameEditText.setText(display.getFriendlyDisplayName()); + + DialogInterface.OnClickListener done = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String name = nameEditText.getText().toString().trim(); + if (name.isEmpty() || name.equals(display.getDeviceName())) { + name = null; + } + mDisplayManager.renameWifiDisplay(display.getDeviceAddress(), name); + } + }; + DialogInterface.OnClickListener forget = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mDisplayManager.forgetWifiDisplay(display.getDeviceAddress()); + } + }; + + AlertDialog dialog = new AlertDialog.Builder(getActivity()) + .setCancelable(true) + .setTitle(R.string.wifi_display_options_title) + .setView(view) + .setPositiveButton(R.string.wifi_display_options_done, done) + .setNegativeButton(R.string.wifi_display_options_forget, forget) + .create(); + dialog.show(); + } + + private static boolean contains(WifiDisplay[] displays, String address) { + for (WifiDisplay d : displays) { + if (d.getDeviceAddress().equals(address)) { + return true; + } + } + return false; + } + + private final CompoundButton.OnCheckedChangeListener mSwitchOnCheckedChangedListener = + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mWifiDisplayOnSetting = isChecked; + Settings.Global.putInt(getContentResolver(), + Settings.Global.WIFI_DISPLAY_ON, isChecked ? 1 : 0); + } + }; + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) { + WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra( + DisplayManager.EXTRA_WIFI_DISPLAY_STATUS); + mWifiDisplayStatus = status; + applyState(); + } + } + }; + + private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange, Uri uri) { + update(); + } + }; + + private final class WifiDisplayPreference extends Preference + implements View.OnClickListener { + private final WifiDisplay mDisplay; + + public WifiDisplayPreference(Context context, WifiDisplay display) { + super(context); + + mDisplay = display; + setTitle(display.getFriendlyDisplayName()); + } + + public WifiDisplay getDisplay() { + return mDisplay; + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + + ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails); + if (deviceDetails != null) { + deviceDetails.setOnClickListener(this); + + if (!isEnabled()) { + TypedValue value = new TypedValue(); + getContext().getTheme().resolveAttribute(android.R.attr.disabledAlpha, + value, true); + deviceDetails.setImageAlpha((int)(value.getFloat() * 255)); + } + } + } + + @Override + public void onClick(View v) { + showOptionsDialog(mDisplay); + } + } +} |