diff options
Diffstat (limited to 'src/com')
6 files changed, 494 insertions, 389 deletions
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 22fc4bf9f..613b082bf 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -124,7 +124,7 @@ public class Settings extends PreferenceActivity { /** * Switch to parent fragment and store the grand parent's info - * @param class name of the activity wrapper for the parent fragment. + * @param className name of the activity wrapper for the parent fragment. */ private void switchToParent(String className) { final ComponentName cn = new ComponentName(this, className); diff --git a/src/com/android/settings/UserLeaveHintListener.java b/src/com/android/settings/UserLeaveHintListener.java deleted file mode 100644 index c5c2a7a47..000000000 --- a/src/com/android/settings/UserLeaveHintListener.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2010 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; - -/** - * Interface enabling fragments to listen to Activity#onUserLeaveHint(). - */ -public interface UserLeaveHintListener { - public void onUserLeaveHint(); -}
\ No newline at end of file diff --git a/src/com/android/settings/bluetooth/BluetoothFindNearby.java b/src/com/android/settings/bluetooth/BluetoothFindNearby.java new file mode 100644 index 000000000..f1b876e76 --- /dev/null +++ b/src/com/android/settings/bluetooth/BluetoothFindNearby.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011 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.bluetooth; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.util.Log; + +import com.android.settings.R; + +/** + * Fragment to scan and show the discoverable devices. + */ +public class BluetoothFindNearby extends DeviceListPreferenceFragment { + + private static final String TAG = "BluetoothFindNearby"; + + void addPreferencesForActivity(Activity activity) { + addPreferencesFromResource(R.xml.device_picker); + } + + @Override + public void onResume() { + super.onResume(); + if (mSelectedDevice != null) { + CachedBluetoothDevice device = + mLocalManager.getCachedDeviceManager().findDevice(mSelectedDevice); + if (device.getBondState() == BluetoothDevice.BOND_BONDED) { + // selected device was paired, so return from this screen + finish(); + return; + } + } + mLocalManager.startScanning(true); + } + + void onDevicePreferenceClick(BluetoothDevicePreference btPreference) { + mLocalManager.stopScanning(); + super.onDevicePreferenceClick(btPreference); + } + + public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, + int bondState) { + if (bondState == BluetoothDevice.BOND_BONDED) { + // return from scan screen after successful auto-pairing + finish(); + } + } + + void onBluetoothStateChanged(int bluetoothState) { + super.onBluetoothStateChanged(bluetoothState); + + if (bluetoothState == BluetoothAdapter.STATE_ON) { + mLocalManager.startScanning(false); + } + } +} diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java index 54f9fb1a6..2893ce3a0 100644 --- a/src/com/android/settings/bluetooth/BluetoothSettings.java +++ b/src/com/android/settings/bluetooth/BluetoothSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2011 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. @@ -16,166 +16,41 @@ package com.android.settings.bluetooth; -import com.android.settings.ProgressCategory; -import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.UserLeaveHintListener; - import android.app.Activity; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothDevicePicker; -import android.bluetooth.BluetoothUuid; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.os.ParcelUuid; import android.preference.CheckBoxPreference; -import android.preference.Preference; -import android.preference.PreferenceCategory; -import android.preference.PreferenceScreen; -import android.text.TextUtils; import android.util.Log; import android.view.View; -import java.util.List; -import java.util.WeakHashMap; +import com.android.settings.R; /** * BluetoothSettings is the Settings screen for Bluetooth configuration and * connection management. */ -public class BluetoothSettings extends SettingsPreferenceFragment - implements LocalBluetoothManager.Callback, UserLeaveHintListener, View.OnClickListener { +public class BluetoothSettings extends DeviceListPreferenceFragment + implements LocalBluetoothManager.Callback, View.OnClickListener { private static final String TAG = "BluetoothSettings"; private static final String KEY_BT_CHECKBOX = "bt_checkbox"; private static final String KEY_BT_DISCOVERABLE = "bt_discoverable"; - private static final String KEY_BT_DEVICE_LIST = "bt_device_list"; private static final String KEY_BT_NAME = "bt_name"; - private static final String KEY_BT_SCAN = "bt_scan"; - - private static final int SCREEN_TYPE_SETTINGS = 0; - private static final int SCREEN_TYPE_DEVICEPICKER = 1; - private static final int SCREEN_TYPE_SCAN = 2; - - public static final String ACTION = "bluetooth_action"; - public static final String ACTION_LAUNCH_SCAN_MODE = - "com.android.settings.bluetooth.action.LAUNCH_SCAN_MODE"; - - /*package*/ int mScreenType; - private int mFilterType; - private boolean mNeedAuth; - private String mLaunchPackage; - private String mLaunchClass; - - /*package*/ BluetoothDevice mSelectedDevice= null; - - /*package*/ LocalBluetoothManager mLocalManager; private BluetoothEnabler mEnabler; private BluetoothDiscoverableEnabler mDiscoverableEnabler; - private BluetoothNamePreference mNamePreference; - private PreferenceCategory mDeviceList; - - private WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap = - new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>(); - - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - onBluetoothStateChanged(mLocalManager.getBluetoothState()); - } else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { - // TODO: If this is a scanning screen, maybe return on successful pairing - - int bondState = intent - .getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR); - if (bondState == BluetoothDevice.BOND_BONDED) { - BluetoothDevice device = intent - .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (device.equals(mSelectedDevice)) { - if (mScreenType == SCREEN_TYPE_DEVICEPICKER) { - sendDevicePickedIntent(device); - finish(); - } else if (mScreenType == SCREEN_TYPE_SCAN) { - finish(); - } - } - } - } - } - }; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - // We delay calling super.onActivityCreated(). See WifiSettings.java for more info. - - final Activity activity = getActivity(); - mLocalManager = LocalBluetoothManager.getInstance(activity); - if (mLocalManager == null) { - finish(); - } - - // Note: - // If an application wishes to show the BT device list, it can send an - // intent to Settings application with the following extra data: - // -DEVICE_PICKER_FILTER_TYPE: the type of BT devices to show. - // -DEVICE_PICKER_LAUNCH_PACKAGE: the package which the application belongs to. - // -DEVICE_PICKER_LAUNCH_CLASS: the class which will receive user's selected - // result from the BT list. - // -DEVICE_PICKER_NEED_AUTH: to show if bonding procedure needed. + void addPreferencesForActivity(Activity activity) { + addPreferencesFromResource(R.xml.bluetooth_settings); - mFilterType = BluetoothDevicePicker.FILTER_TYPE_ALL; - final Intent intent = activity.getIntent(); + mEnabler = new BluetoothEnabler(activity, + (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX)); - // This additional argument comes from PreferenceScreen (See TetherSettings.java). - Bundle args = getArguments(); - String action = args != null ? args.getString(ACTION) : null; - if (TextUtils.isEmpty(action)) { - action = intent.getAction(); - } - - if (getPreferenceScreen() != null) getPreferenceScreen().removeAll(); - - if (action.equals(BluetoothDevicePicker.ACTION_LAUNCH)) { - mScreenType = SCREEN_TYPE_DEVICEPICKER; - mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false); - mFilterType = intent.getIntExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE, - BluetoothDevicePicker.FILTER_TYPE_ALL); - mLaunchPackage = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE); - mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS); - - activity.setTitle(activity.getString(R.string.device_picker)); - addPreferencesFromResource(R.xml.device_picker); - } else if (action.equals(ACTION_LAUNCH_SCAN_MODE)) { - mScreenType = SCREEN_TYPE_SCAN; - - addPreferencesFromResource(R.xml.device_picker); - } else { - addPreferencesFromResource(R.xml.bluetooth_settings); + mDiscoverableEnabler = new BluetoothDiscoverableEnabler(activity, + (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE)); - mEnabler = new BluetoothEnabler( - activity, - (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX)); - - mDiscoverableEnabler = new BluetoothDiscoverableEnabler( - activity, - (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE)); - - mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME); - - } - - mDeviceList = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST); - - super.onActivityCreated(savedInstanceState); + mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME); } @Override @@ -184,251 +59,53 @@ public class BluetoothSettings extends SettingsPreferenceFragment // Repopulate (which isn't too bad since it's cached in the settings // bluetooth manager) - mDevicePreferenceMap.clear(); - mDeviceList.removeAll(); - if (mScreenType != SCREEN_TYPE_SCAN) { - addDevices(); - } - - if (mScreenType == SCREEN_TYPE_SETTINGS) { - mEnabler.resume(); - mDiscoverableEnabler.resume(); - mNamePreference.resume(); - } - - mLocalManager.registerCallback(this); - - updateProgressUi(mLocalManager.getBluetoothAdapter().isDiscovering()); - - if (mScreenType != SCREEN_TYPE_SETTINGS) { - mLocalManager.startScanning(true); - } + addDevices(); - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); - getActivity().registerReceiver(mReceiver, intentFilter); - mLocalManager.setForegroundActivity(getActivity()); + mEnabler.resume(); + mDiscoverableEnabler.resume(); + mNamePreference.resume(); } @Override public void onPause() { super.onPause(); - mLocalManager.setForegroundActivity(null); - mDevicePreferenceMap.clear(); - mDeviceList.removeAll(); - getActivity().unregisterReceiver(mReceiver); - - mLocalManager.unregisterCallback(this); - if (mScreenType == SCREEN_TYPE_SETTINGS) { - mNamePreference.pause(); - mDiscoverableEnabler.pause(); - mEnabler.pause(); - } - } - - public void onUserLeaveHint() { - mLocalManager.stopScanning(); - } - - private void addDevices() { - List<CachedBluetoothDevice> cachedDevices = - mLocalManager.getCachedDeviceManager().getCachedDevicesCopy(); - for (CachedBluetoothDevice cachedDevice : cachedDevices) { - onDeviceAdded(cachedDevice); - } - } - - public void onClick(View v) { - // User clicked on advanced options icon for a device in the list - if (v.getTag() instanceof CachedBluetoothDevice) { - CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag(); - device.onClickedAdvancedOptions(this); - } - } - - @Override - public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, - Preference preference) { - - if (KEY_BT_SCAN.equals(preference.getKey())) { - mLocalManager.startScanning(true); - return true; - } - - if (preference instanceof BluetoothDevicePreference) { - BluetoothDevicePreference btPreference = (BluetoothDevicePreference)preference; - CachedBluetoothDevice device = btPreference.getCachedDevice(); - mSelectedDevice = device.getDevice(); - if (mScreenType == SCREEN_TYPE_SETTINGS || mScreenType == SCREEN_TYPE_SCAN) { - btPreference.getCachedDevice().onClicked(); - } else if (mScreenType == SCREEN_TYPE_DEVICEPICKER) { - mLocalManager.stopScanning(); - mLocalManager.persistSelectedDeviceInPicker(mSelectedDevice.getAddress()); - if ((device.getBondState() == BluetoothDevice.BOND_BONDED) || - (mNeedAuth == false)) { - sendDevicePickedIntent(mSelectedDevice); - finish(); - } else { - btPreference.getCachedDevice().onClicked(); - } - } else { - Log.e(TAG, "onPreferenceTreeClick has invalid mScreenType: " - + mScreenType); - } - return true; - } - - return super.onPreferenceTreeClick(preferenceScreen, preference); + mNamePreference.pause(); + mDiscoverableEnabler.pause(); + mEnabler.pause(); } - public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { - - if (mDevicePreferenceMap.get(cachedDevice) != null) { - Log.e(TAG, "Got onDeviceAdded, but cachedDevice already exists"); - return; - } - - if (mScreenType != SCREEN_TYPE_SETTINGS - || cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { - if (addDevicePreference(cachedDevice)) { - createDevicePreference(cachedDevice); - } - } - } - public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { - // add to "Paired devices" list after remote-initiated pairing - if (mDevicePreferenceMap.get(cachedDevice) == null && - mScreenType == SCREEN_TYPE_SETTINGS && - bondState == BluetoothDevice.BOND_BONDED) { - if (addDevicePreference(cachedDevice)) { - createDevicePreference(cachedDevice); - } - } - } - - private boolean addDevicePreference(CachedBluetoothDevice cachedDevice) { - ParcelUuid[] uuids = cachedDevice.getDevice().getUuids(); - BluetoothClass bluetoothClass = cachedDevice.getDevice().getBluetoothClass(); - - switch(mFilterType) { - case BluetoothDevicePicker.FILTER_TYPE_TRANSFER: - if (uuids != null) { - if (BluetoothUuid.containsAnyUuid(uuids, - LocalBluetoothProfileManager.OPP_PROFILE_UUIDS)) return true; - } - if (bluetoothClass != null - && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_OPP)) { - return true; - } - break; - case BluetoothDevicePicker.FILTER_TYPE_AUDIO: - if (uuids != null) { - if (BluetoothUuid.containsAnyUuid(uuids, - LocalBluetoothProfileManager.A2DP_SINK_PROFILE_UUIDS)) return true; - - if (BluetoothUuid.containsAnyUuid(uuids, - LocalBluetoothProfileManager.HEADSET_PROFILE_UUIDS)) return true; - } else if (bluetoothClass != null) { - if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) return true; - - if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) return true; - } - break; - case BluetoothDevicePicker.FILTER_TYPE_PANU: - if (uuids != null) { - if (BluetoothUuid.containsAnyUuid(uuids, - LocalBluetoothProfileManager.PANU_PROFILE_UUIDS)) return true; - - } - if (bluetoothClass != null - && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_PANU)) { - return true; - } - break; - case BluetoothDevicePicker.FILTER_TYPE_NAP: - if (uuids != null) { - if (BluetoothUuid.containsAnyUuid(uuids, - LocalBluetoothProfileManager.NAP_PROFILE_UUIDS)) return true; - } - if (bluetoothClass != null - && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_NAP)) { - return true; - } - break; - default: - return true; - } - return false; - } - - private void createDevicePreference(CachedBluetoothDevice cachedDevice) { - BluetoothDevicePreference preference = new BluetoothDevicePreference( - getActivity(), cachedDevice); - - if (mScreenType == SCREEN_TYPE_SETTINGS) { - preference.setOnSettingsClickListener(this); - } - mDeviceList.addPreference(preference); - mDevicePreferenceMap.put(cachedDevice, preference); - } - - public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { - BluetoothDevicePreference preference = mDevicePreferenceMap.remove(cachedDevice); - if (preference != null) { - mDeviceList.removePreference(preference); - } - } - - public void onScanningStateChanged(boolean started) { - updateProgressUi(started); - } - - private void updateProgressUi(boolean start) { - if (mDeviceList instanceof ProgressCategory) { - ((ProgressCategory) mDeviceList).setProgress(start); - } - } - - /*package*/ void onBluetoothStateChanged(int bluetoothState) { - // When bluetooth is enabled (and we are in the activity, which we are), - // we should start a scan - if (bluetoothState == BluetoothAdapter.STATE_ON) { - if (mScreenType != SCREEN_TYPE_SETTINGS) { - mLocalManager.startScanning(false); + if (bondState == BluetoothDevice.BOND_BONDED) { + // add to "Paired devices" list after remote-initiated pairing + if (mDevicePreferenceMap.get(cachedDevice) == null) { + if (addDevicePreference(cachedDevice)) { + createDevicePreference(cachedDevice); + } } - } else if (bluetoothState == BluetoothAdapter.STATE_OFF) { - updateProgressUi(false); + } else if (bondState == BluetoothDevice.BOND_NONE) { + // remove unpaired device from paired devices list + onDeviceDeleted(cachedDevice); } } - /*package*/ void sendDevicePickedIntent(BluetoothDevice device) { - Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED); - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - if (mScreenType == SCREEN_TYPE_DEVICEPICKER && - mLaunchPackage != null && mLaunchClass != null) { - intent.setClassName(mLaunchPackage, mLaunchClass); + /** + * Additional check to only add paired devices to list. + */ + boolean addDevicePreference(CachedBluetoothDevice cachedDevice) { + if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { + return super.addDevicePreference(cachedDevice); + } else { + return false; } - getActivity().sendBroadcast(intent); } - public static class FindNearby extends BluetoothSettings { - - public FindNearby() { - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - Bundle args = super.getArguments(); - if (args == null) { - args = new Bundle(); - setArguments(args); - } - args.putString(ACTION, ACTION_LAUNCH_SCAN_MODE); - super.onActivityCreated(savedInstanceState); - } + /** + * Add a listener, which enables the advanced settings icon. + * @param preference the newly added preference + */ + void initDevicePreference(BluetoothDevicePreference preference) { + preference.setOnSettingsClickListener(this); } } diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java new file mode 100644 index 000000000..46fff6e01 --- /dev/null +++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2011 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.bluetooth; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothDevicePicker; +import android.bluetooth.BluetoothUuid; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.ParcelUuid; +import android.preference.Preference; +import android.preference.PreferenceCategory; +import android.preference.PreferenceScreen; +import android.util.Log; +import android.view.View; + +import com.android.settings.ProgressCategory; +import com.android.settings.SettingsPreferenceFragment; + +import java.util.List; +import java.util.WeakHashMap; + +/** + * Parent class for settings fragments that contain a list of Bluetooth + * devices. + * + * @see BluetoothSettings + * @see DevicePickerFragment + * @see BluetoothFindNearby + */ +public abstract class DeviceListPreferenceFragment extends SettingsPreferenceFragment + implements LocalBluetoothManager.Callback, View.OnClickListener { + + private static final String TAG = "DeviceListPreferenceFragment"; + + static final String KEY_BT_DEVICE_LIST = "bt_device_list"; + static final String KEY_BT_SCAN = "bt_scan"; + + int mFilterType; + + BluetoothDevice mSelectedDevice = null; + + LocalBluetoothManager mLocalManager; + + private PreferenceCategory mDeviceList; + + WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap = + new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>(); + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + onBluetoothStateChanged(mLocalManager.getBluetoothState()); + } + } + }; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + // We delay calling super.onActivityCreated(). See WifiSettings.java for more info. + + final Activity activity = getActivity(); + mLocalManager = LocalBluetoothManager.getInstance(activity); + if (mLocalManager == null) { + finish(); + } + + mFilterType = BluetoothDevicePicker.FILTER_TYPE_ALL; + + if (getPreferenceScreen() != null) getPreferenceScreen().removeAll(); + + addPreferencesForActivity(activity); + + mDeviceList = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST); + + super.onActivityCreated(savedInstanceState); + } + + /** Add preferences from the subclass. */ + abstract void addPreferencesForActivity(Activity activity); + + @Override + public void onResume() { + super.onResume(); + + mLocalManager.registerCallback(this); + + updateProgressUi(mLocalManager.getBluetoothAdapter().isDiscovering()); + + IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); + getActivity().registerReceiver(mReceiver, intentFilter); + mLocalManager.setForegroundActivity(getActivity()); + } + + @Override + public void onPause() { + super.onPause(); + mLocalManager.stopScanning(); + mLocalManager.setForegroundActivity(null); + mDevicePreferenceMap.clear(); + mDeviceList.removeAll(); + getActivity().unregisterReceiver(mReceiver); + + mLocalManager.unregisterCallback(this); + } + + void addDevices() { + List<CachedBluetoothDevice> cachedDevices = + mLocalManager.getCachedDeviceManager().getCachedDevicesCopy(); + for (CachedBluetoothDevice cachedDevice : cachedDevices) { + onDeviceAdded(cachedDevice); + } + } + + public void onClick(View v) { + // User clicked on advanced options icon for a device in the list + if (v.getTag() instanceof CachedBluetoothDevice) { + CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag(); + device.onClickedAdvancedOptions(this); + } + } + + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, + Preference preference) { + + if (KEY_BT_SCAN.equals(preference.getKey())) { + mLocalManager.startScanning(true); + return true; + } + + if (preference instanceof BluetoothDevicePreference) { + BluetoothDevicePreference btPreference = (BluetoothDevicePreference)preference; + CachedBluetoothDevice device = btPreference.getCachedDevice(); + mSelectedDevice = device.getDevice(); + onDevicePreferenceClick(btPreference); + return true; + } + + return super.onPreferenceTreeClick(preferenceScreen, preference); + } + + void onDevicePreferenceClick(BluetoothDevicePreference btPreference) { + btPreference.getCachedDevice().onClicked(); + } + + public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { + if (mDevicePreferenceMap.get(cachedDevice) != null) { + Log.e(TAG, "Got onDeviceAdded, but cachedDevice already exists"); + return; + } + + if (addDevicePreference(cachedDevice)) { + createDevicePreference(cachedDevice); + } + } + + /** + * Determine whether to add the new device to the list. + * @param cachedDevice the newly discovered device + * @return true if the device should be added; false otherwise + */ + boolean addDevicePreference(CachedBluetoothDevice cachedDevice) { + ParcelUuid[] uuids = cachedDevice.getDevice().getUuids(); + BluetoothClass bluetoothClass = cachedDevice.getDevice().getBluetoothClass(); + + switch(mFilterType) { + case BluetoothDevicePicker.FILTER_TYPE_TRANSFER: + if (uuids != null) { + if (BluetoothUuid.containsAnyUuid(uuids, + LocalBluetoothProfileManager.OPP_PROFILE_UUIDS)) return true; + } + if (bluetoothClass != null + && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_OPP)) { + return true; + } + break; + case BluetoothDevicePicker.FILTER_TYPE_AUDIO: + if (uuids != null) { + if (BluetoothUuid.containsAnyUuid(uuids, + LocalBluetoothProfileManager.A2DP_SINK_PROFILE_UUIDS)) return true; + + if (BluetoothUuid.containsAnyUuid(uuids, + LocalBluetoothProfileManager.HEADSET_PROFILE_UUIDS)) return true; + } else if (bluetoothClass != null) { + if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) return true; + + if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) return true; + } + break; + case BluetoothDevicePicker.FILTER_TYPE_PANU: + if (uuids != null) { + if (BluetoothUuid.containsAnyUuid(uuids, + LocalBluetoothProfileManager.PANU_PROFILE_UUIDS)) return true; + + } + if (bluetoothClass != null + && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_PANU)) { + return true; + } + break; + case BluetoothDevicePicker.FILTER_TYPE_NAP: + if (uuids != null) { + if (BluetoothUuid.containsAnyUuid(uuids, + LocalBluetoothProfileManager.NAP_PROFILE_UUIDS)) return true; + } + if (bluetoothClass != null + && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_NAP)) { + return true; + } + break; + default: + return true; + } + return false; + } + + void createDevicePreference(CachedBluetoothDevice cachedDevice) { + BluetoothDevicePreference preference = new BluetoothDevicePreference( + getActivity(), cachedDevice); + + initDevicePreference(preference); + mDeviceList.addPreference(preference); + mDevicePreferenceMap.put(cachedDevice, preference); + } + + /** + * Overridden in {@link BluetoothSettings} to add a listener. + * @param preference the newly added preference + */ + void initDevicePreference(BluetoothDevicePreference preference) { } + + public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { + BluetoothDevicePreference preference = mDevicePreferenceMap.remove(cachedDevice); + if (preference != null) { + mDeviceList.removePreference(preference); + } + } + + public void onScanningStateChanged(boolean started) { + updateProgressUi(started); + } + + private void updateProgressUi(boolean start) { + if (mDeviceList instanceof ProgressCategory) { + ((ProgressCategory) mDeviceList).setProgress(start); + } + } + + void onBluetoothStateChanged(int bluetoothState) { + if (bluetoothState == BluetoothAdapter.STATE_OFF) { + updateProgressUi(false); + } + } + + void sendDevicePickedIntent(BluetoothDevice device) { + Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + getActivity().sendBroadcast(intent); + } +} diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java new file mode 100644 index 000000000..d3e3d6925 --- /dev/null +++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 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.bluetooth; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothDevicePicker; +import android.content.Intent; +import android.util.Log; + +import com.android.settings.R; + +/** + * BluetoothSettings is the Settings screen for Bluetooth configuration and + * connection management. + */ +public class DevicePickerFragment extends DeviceListPreferenceFragment { + + private static final String TAG = "BluetoothDevicePicker"; + + private boolean mNeedAuth; + private String mLaunchPackage; + private String mLaunchClass; + + void addPreferencesForActivity(Activity activity) { + Intent intent = activity.getIntent(); + mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false); + mFilterType = intent.getIntExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE, + BluetoothDevicePicker.FILTER_TYPE_ALL); + mLaunchPackage = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE); + mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS); + + activity.setTitle(activity.getString(R.string.device_picker)); + addPreferencesFromResource(R.xml.device_picker); + } + + @Override + public void onResume() { + super.onResume(); + addDevices(); + mLocalManager.startScanning(true); + } + + void onDevicePreferenceClick(BluetoothDevicePreference btPreference) { + mLocalManager.stopScanning(); + mLocalManager.persistSelectedDeviceInPicker(mSelectedDevice.getAddress()); + if ((btPreference.getCachedDevice().getBondState() == + BluetoothDevice.BOND_BONDED) || !mNeedAuth) { + sendDevicePickedIntent(mSelectedDevice); + finish(); + } else { + super.onDevicePreferenceClick(btPreference); + } + } + + public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, + int bondState) { + if (bondState == BluetoothDevice.BOND_BONDED) { + BluetoothDevice device = cachedDevice.getDevice(); + if (device.equals(mSelectedDevice)) { + sendDevicePickedIntent(device); + finish(); + } + } + } + + void onBluetoothStateChanged(int bluetoothState) { + super.onBluetoothStateChanged(bluetoothState); + + if (bluetoothState == BluetoothAdapter.STATE_ON) { + mLocalManager.startScanning(false); + } + } + + void sendDevicePickedIntent(BluetoothDevice device) { + Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + if (mLaunchPackage != null && mLaunchClass != null) { + intent.setClassName(mLaunchPackage, mLaunchClass); + } + getActivity().sendBroadcast(intent); + } +} |