OSDN Git Service

Don't crash if there's no bluetooth functionality (such as in an emulator) do not...
[android-x86/packages-apps-Settings.git] / src / com / android / settings / bluetooth / BluetoothSettings.java
old mode 100644 (file)
new mode 100755 (executable)
index 2208223..7c8cb6e
@@ -20,6 +20,10 @@ import android.app.ActionBar;
 import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
@@ -48,28 +52,57 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
     private static final String TAG = "BluetoothSettings";
 
     private static final int MENU_ID_SCAN = Menu.FIRST;
-    private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
+    private static final int MENU_ID_RENAME_DEVICE = Menu.FIRST + 1;
+    private static final int MENU_ID_VISIBILITY_TIMEOUT = Menu.FIRST + 2;
+    private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 3;
+
+    /* Private intent to show the list of received files */
+    private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
+            "android.btopp.intent.action.OPEN_RECEIVED_FILES";
 
     private BluetoothEnabler mBluetoothEnabler;
 
+    private BluetoothDiscoverableEnabler mDiscoverableEnabler;
+
+    private PreferenceGroup mPairedDevicesCategory;
+
     private PreferenceGroup mAvailableDevicesCategory;
     private boolean mAvailableDevicesCategoryIsPresent;
+    private boolean mActivityStarted;
 
-    private View mView;
     private TextView mEmptyView;
 
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        mView = inflater.inflate(R.layout.custom_preference_list_fragment, container, false);
-        return mView;
+    private final IntentFilter mIntentFilter;
+
+    // accessed from inner class (not private to avoid thunks)
+    Preference mMyDevicePreference;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
+                updateDeviceName();
+            }
+        }
+
+        private void updateDeviceName() {
+            if (mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
+                mMyDevicePreference.setTitle(mLocalAdapter.getName());
+            }
+        }
+    };
+
+    public BluetoothSettings() {
+        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
     }
 
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
+        mActivityStarted = (savedInstanceState == null);    // don't auto start scan after rotation
 
-        mEmptyView = (TextView) mView.findViewById(R.id.empty);
+        mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
         getListView().setEmptyView(mEmptyView);
     }
 
@@ -103,33 +136,52 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
 
     @Override
     public void onResume() {
+        // resume BluetoothEnabler before calling super.onResume() so we don't get
+        // any onDeviceAdded() callbacks before setting up view in updateContent()
+        if (mBluetoothEnabler != null) {
+            mBluetoothEnabler.resume();
+        }
         super.onResume();
 
-        mBluetoothEnabler.resume();
-
-        updateContent(mLocalAdapter.getBluetoothState());
+        if (mDiscoverableEnabler != null) {
+            mDiscoverableEnabler.resume();
+        }
+        getActivity().registerReceiver(mReceiver, mIntentFilter);
+        if (mLocalAdapter != null) {
+            updateContent(mLocalAdapter.getBluetoothState(), mActivityStarted);
+        }
     }
 
     @Override
     public void onPause() {
         super.onPause();
-
-        mBluetoothEnabler.pause();
+        if (mBluetoothEnabler != null) {
+            mBluetoothEnabler.pause();
+        }
+        getActivity().unregisterReceiver(mReceiver);
+        if (mDiscoverableEnabler != null) {
+            mDiscoverableEnabler.pause();
+        }
     }
 
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        if (mLocalAdapter == null) return;
         boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON;
         boolean isDiscovering = mLocalAdapter.isDiscovering();
         int textId = isDiscovering ? R.string.bluetooth_searching_for_devices :
             R.string.bluetooth_search_for_devices;
         menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
-                //.setIcon(R.drawable.ic_menu_scan_network)
                 .setEnabled(bluetoothIsEnabled && !isDiscovering)
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-        menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced)
-                //.setIcon(android.R.drawable.ic_menu_manage)
-                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
+                .setEnabled(bluetoothIsEnabled)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+        menu.add(Menu.NONE, MENU_ID_VISIBILITY_TIMEOUT, 0, R.string.bluetooth_visibility_timeout)
+                .setEnabled(bluetoothIsEnabled)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+        menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
     }
 
     @Override
@@ -140,16 +192,20 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
                     startScanning();
                 }
                 return true;
-            case MENU_ID_ADVANCED:
-                if (getActivity() instanceof PreferenceActivity) {
-                    ((PreferenceActivity) getActivity()).startPreferencePanel(
-                            AdvancedBluetoothSettings.class.getCanonicalName(),
-                            null,
-                            R.string.bluetooth_advanced_titlebar, null,
-                            this, 0);
-                } else {
-                    startFragment(this, AdvancedBluetoothSettings.class.getCanonicalName(), -1, null);
-                }
+
+            case MENU_ID_RENAME_DEVICE:
+                new BluetoothNameDialogFragment().show(
+                        getFragmentManager(), "rename device");
+                return true;
+
+            case MENU_ID_VISIBILITY_TIMEOUT:
+                new BluetoothVisibilityTimeoutFragment().show(
+                        getFragmentManager(), "visibility timeout");
+                return true;
+
+            case MENU_ID_SHOW_RECEIVED:
+                Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
+                getActivity().sendBroadcast(intent);
                 return true;
         }
         return super.onOptionsItemSelected(item);
@@ -178,26 +234,38 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
         preferenceGroup.setEnabled(true);
     }
 
-    private void updateContent(int bluetoothState) {
+    private void updateContent(int bluetoothState, boolean scanState) {
         final PreferenceScreen preferenceScreen = getPreferenceScreen();
-        getActivity().invalidateOptionsMenu();
         int messageId = 0;
 
         switch (bluetoothState) {
             case BluetoothAdapter.STATE_ON:
                 preferenceScreen.removeAll();
                 preferenceScreen.setOrderingAsAdded(true);
+                mDevicePreferenceMap.clear();
 
                 // This device
                 if (mMyDevicePreference == null) {
                     mMyDevicePreference = new Preference(getActivity());
                 }
-                if (mLocalAdapter != null) {
-                    mMyDevicePreference.setTitle(mLocalAdapter.getName());
+                mMyDevicePreference.setTitle(mLocalAdapter.getName());
+                if (getResources().getBoolean(com.android.internal.R.bool.config_voice_capable)) {
+                    mMyDevicePreference.setIcon(R.drawable.ic_bt_cellphone);    // for phones
+                } else {
+                    mMyDevicePreference.setIcon(R.drawable.ic_bt_laptop);   // for tablets, etc.
                 }
+                mMyDevicePreference.setPersistent(false);
                 mMyDevicePreference.setEnabled(true);
                 preferenceScreen.addPreference(mMyDevicePreference);
 
+                if (mDiscoverableEnabler == null) {
+                    mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
+                            mLocalAdapter, mMyDevicePreference);
+                    mDiscoverableEnabler.resume();
+                    LocalBluetoothManager.getInstance(getActivity()).setDiscoverableEnabler(
+                            mDiscoverableEnabler);
+                }
+
                 // Paired devices category
                 if (mPairedDevicesCategory == null) {
                     mPairedDevicesCategory = new PreferenceCategory(getActivity());
@@ -209,6 +277,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
                         BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
                 int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
 
+                mDiscoverableEnabler.setNumberOfPairedDevices(numberOfPairedDevices);
+
                 // Available devices category
                 if (mAvailableDevicesCategory == null) {
                     mAvailableDevicesCategory = new ProgressCategory(getActivity(), null);
@@ -228,16 +298,21 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
 
                 if (numberOfPairedDevices == 0) {
                     preferenceScreen.removePreference(mPairedDevicesCategory);
-                    startScanning();
+                    if (scanState == true) {
+                        mActivityStarted = false;
+                        startScanning();
+                    } else {
+                        if (!mAvailableDevicesCategoryIsPresent) {
+                            getPreferenceScreen().addPreference(mAvailableDevicesCategory);
+                        }
+                    }
                 }
+                getActivity().invalidateOptionsMenu();
                 return; // not break
 
             case BluetoothAdapter.STATE_TURNING_OFF:
-                int preferenceCount = preferenceScreen.getPreferenceCount();
-                for (int i = 0; i < preferenceCount; i++) {
-                    preferenceScreen.getPreference(i).setEnabled(false);
-                }
-                return; // not break
+                messageId = R.string.bluetooth_turning_off;
+                break;
 
             case BluetoothAdapter.STATE_OFF:
                 messageId = R.string.bluetooth_empty_list_bluetooth_off;
@@ -251,12 +326,13 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
         setDeviceListGroup(preferenceScreen);
         removeAllDevices();
         mEmptyView.setText(messageId);
+        getActivity().invalidateOptionsMenu();
     }
 
     @Override
     public void onBluetoothStateChanged(int bluetoothState) {
         super.onBluetoothStateChanged(bluetoothState);
-        updateContent(bluetoothState);
+        updateContent(bluetoothState, true);
     }
 
     @Override
@@ -269,7 +345,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
         setDeviceListGroup(getPreferenceScreen());
         removeAllDevices();
-        updateContent(mLocalAdapter.getBluetoothState());
+        updateContent(mLocalAdapter.getBluetoothState(), false);
     }
 
     private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
@@ -278,23 +354,18 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
             if (v.getTag() instanceof CachedBluetoothDevice) {
                 CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
 
-                Preference pref = new Preference(getActivity());
-                pref.setTitle(device.getName());
-                pref.setFragment(DeviceProfilesSettings.class.getName());
-                pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
-                        device.getDevice());
-                ((PreferenceActivity) getActivity()).onPreferenceStartFragment(
-                        BluetoothSettings.this, pref);
+                Bundle args = new Bundle(1);
+                args.putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, device.getDevice());
+
+                ((PreferenceActivity) getActivity()).startPreferencePanel(
+                        DeviceProfilesSettings.class.getName(), args,
+                        R.string.bluetooth_device_advanced_title, null, null, 0);
             } else {
                 Log.w(TAG, "onClick() called for other View: " + v); // TODO remove
             }
         }
     };
 
-    private Preference mMyDevicePreference;
-
-    private PreferenceGroup mPairedDevicesCategory;
-
     /**
      * Add a listener, which enables the advanced settings icon.
      * @param preference the newly added preference