diff options
Diffstat (limited to 'src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java')
| -rw-r--r-- | src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java new file mode 100644 index 000000000..a51f9b5ea --- /dev/null +++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2008 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 com.android.settings.R; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothError; +import android.bluetooth.BluetoothIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.os.Handler; +import android.os.SystemProperties; +import android.preference.Preference; +import android.preference.CheckBoxPreference; +import android.util.Log; + +/** + * BluetoothDiscoverableEnabler is a helper to manage the "Discoverable" + * checkbox. It sets/unsets discoverability and keeps track of how much time + * until the the discoverability is automatically turned off. + */ +public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener { + private static final String TAG = "BluetoothDiscoverableEnabler"; + private static final boolean V = LocalBluetoothManager.V; + + private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT = + "debug.bt.discoverable_time"; + private static final int DISCOVERABLE_TIMEOUT = 120; + + private static final String SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP = + "discoverable_end_timestamp"; + + private final Context mContext; + private final Handler mUiHandler; + private final CheckBoxPreference mCheckBoxPreference; + + private final LocalBluetoothManager mLocalManager; + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (BluetoothIntent.SCAN_MODE_CHANGED_ACTION.equals(intent.getAction())) { + int mode = intent.getIntExtra(BluetoothIntent.SCAN_MODE, BluetoothError.ERROR); + if (mode != BluetoothError.ERROR) { + handleModeChanged(mode); + } + } + } + }; + + private final Runnable mUpdateCountdownSummaryRunnable = new Runnable() { + public void run() { + updateCountdownSummary(); + } + }; + + public BluetoothDiscoverableEnabler(Context context, CheckBoxPreference checkBoxPreference) { + mContext = context; + mUiHandler = new Handler(); + mCheckBoxPreference = checkBoxPreference; + + checkBoxPreference.setPersistent(false); + + mLocalManager = LocalBluetoothManager.getInstance(context); + if (mLocalManager == null) { + // Bluetooth not supported + checkBoxPreference.setEnabled(false); + } + } + + public void resume() { + if (mLocalManager == null) { + return; + } + + IntentFilter filter = new IntentFilter(BluetoothIntent.SCAN_MODE_CHANGED_ACTION); + filter.addAction(BluetoothIntent.DISABLED_ACTION); + mContext.registerReceiver(mReceiver, filter); + mCheckBoxPreference.setOnPreferenceChangeListener(this); + + handleModeChanged(mLocalManager.getBluetoothManager().getScanMode()); + } + + public void pause() { + if (mLocalManager == null) { + return; + } + + mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable); + mCheckBoxPreference.setOnPreferenceChangeListener(null); + mContext.unregisterReceiver(mReceiver); + } + + public boolean onPreferenceChange(Preference preference, Object value) { + if (V) { + Log.v(TAG, "Preference changed to " + value); + } + + // Turn on/off BT discoverability + setEnabled((Boolean) value); + + return true; + } + + private void setEnabled(final boolean enable) { + BluetoothDevice manager = mLocalManager.getBluetoothManager(); + + if (enable) { + + int timeout = getDiscoverableTimeout(); + manager.setDiscoverableTimeout(timeout); + + long endTimestamp = System.currentTimeMillis() + timeout * 1000; + persistDiscoverableEndTimestamp(endTimestamp); + + manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + } else { + manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE); + } + } + + private int getDiscoverableTimeout() { + int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1); + if (timeout <= 0) { + timeout = DISCOVERABLE_TIMEOUT; + } + + return timeout; + } + + private void persistDiscoverableEndTimestamp(long endTimestamp) { + SharedPreferences.Editor editor = mLocalManager.getSharedPreferences().edit(); + editor.putLong(SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp); + editor.commit(); + } + + private void handleModeChanged(int mode) { + if (V) { + Log.v(TAG, "Got mode changed: " + mode); + } + + if (mode == BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + mCheckBoxPreference.setChecked(true); + updateCountdownSummary(); + + } else { + mCheckBoxPreference.setChecked(false); + } + } + + private void updateCountdownSummary() { + int mode = mLocalManager.getBluetoothManager().getScanMode(); + if (mode != BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + return; + } + + long currentTimestamp = System.currentTimeMillis(); + long endTimestamp = mLocalManager.getSharedPreferences().getLong( + SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0); + + if (currentTimestamp > endTimestamp) { + // We're still in discoverable mode, but maybe there isn't a timeout. + mCheckBoxPreference.setSummaryOn(null); + return; + } + + String formattedTimeLeft = String.valueOf((endTimestamp - currentTimestamp) / 1000); + + mCheckBoxPreference.setSummaryOn( + mContext.getResources().getString(R.string.bluetooth_is_discoverable, + formattedTimeLeft)); + + synchronized (this) { + mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable); + mUiHandler.postDelayed(mUpdateCountdownSummaryRunnable, 1000); + } + } + + +} |
