diff options
author | Michael Wright <michaelwr@google.com> | 2015-10-20 15:31:01 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-10-20 15:31:01 +0000 |
commit | 57a5cba606e5d58cc4ad1c5c1cf4918dc16fe819 (patch) | |
tree | 9b0a8e5225992b4272d3a572a1e1f3a8d74d808d /packages | |
parent | ad968cf4e55afdd897ea84a44b7450442aea1e1d (diff) | |
parent | 9209c9cd9a6f779d0d9d86f9b2e368df564fa6bb (diff) | |
download | frameworks_base-57a5cba606e5d58cc4ad1c5c1cf4918dc16fe819.zip frameworks_base-57a5cba606e5d58cc4ad1c5c1cf4918dc16fe819.tar.gz frameworks_base-57a5cba606e5d58cc4ad1c5c1cf4918dc16fe819.tar.bz2 |
Merge "Add SystemUI component to watch for keyboard attachment." into mnc-dr-dev
Diffstat (limited to 'packages')
6 files changed, 602 insertions, 0 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java index 0380e21..f935f31 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java @@ -19,6 +19,7 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; +import android.bluetooth.le.BluetoothLeScanner; import android.content.Context; import android.os.ParcelUuid; import android.util.Log; @@ -106,6 +107,10 @@ public final class LocalBluetoothAdapter { return mAdapter.getScanMode(); } + public BluetoothLeScanner getBluetoothLeScanner() { + return mAdapter.getBluetoothLeScanner(); + } + public int getState() { return mAdapter.getState(); } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 372fa03..80f4d4c 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -127,6 +127,9 @@ <!-- Assist --> <uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" /> + <!-- Listen for keyboard attachment / detachment --> + <uses-permission android:name="android.permission.TABLET_MODE" /> + <!-- Self permission for internal broadcasts. --> <permission android:name="com.android.systemui.permission.SELF" android:protectionLevel="signature" /> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index dfa85ce..dc9c9fd 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1126,4 +1126,14 @@ <!-- Dialog asking if the tuner should really be removed from settings [CHAR LIMIT=NONE]--> <string name="remove_from_settings_prompt">Remove System UI Tuner from Settings and stop using all of its features?"</string> + <!-- Dialog title asking if Bluetooth should be enabled [CHAR LIMIT=NONE] --> + <string name="enable_bluetooth_title">Turn on Bluetooth?</string> + + <!-- Dialog message explaining why Bluetooth should be enabled when a packaged keyboard is + conncted to the device [CHAR LIMIT=NONE] --> + <string name="enable_bluetooth_message">To connect your keyboard with your tablet, you first have to turn on Bluetooth.</string> + + <!-- Bluetooth enablement ok text [CHAR LIMIT=40] --> + <string name="enable_bluetooth_confirmation_ok">Turn on</string> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 33bd726..0b066af 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -48,6 +48,7 @@ public class SystemUIApplication extends Application { com.android.systemui.usb.StorageNotification.class, com.android.systemui.power.PowerUI.class, com.android.systemui.media.RingtonePlayer.class, + com.android.systemui.keyboard.KeyboardUI.class, }; /** diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/BluetoothDialog.java b/packages/SystemUI/src/com/android/systemui/keyboard/BluetoothDialog.java new file mode 100644 index 0000000..64f3e13 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/BluetoothDialog.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2015 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.systemui.keyboard; + +import android.app.AlertDialog; +import android.content.Context; +import android.view.WindowManager; + +import com.android.systemui.R; +import com.android.systemui.statusbar.phone.SystemUIDialog; + +public class BluetoothDialog extends SystemUIDialog { + + public BluetoothDialog(Context context) { + super(context); + + getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); + setShowForAllUsers(true); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java new file mode 100644 index 0000000..a43d520 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java @@ -0,0 +1,549 @@ +/* + * Copyright (C) 2015 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.systemui.keyboard; + +import android.app.AlertDialog; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanFilter; +import android.bluetooth.le.ScanResult; +import android.bluetooth.le.ScanSettings; +import android.content.ContentResolver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.Configuration; +import android.hardware.input.InputManager; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.os.Process; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Settings.Secure; +import android.text.TextUtils; +import android.util.Slog; +import android.view.WindowManager; + +import com.android.settingslib.bluetooth.BluetoothCallback; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LocalBluetoothAdapter; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; +import com.android.systemui.R; +import com.android.systemui.SystemUI; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeChangedListener { + private static final String TAG = "KeyboardUI"; + private static final boolean DEBUG = false; + + // Give BT some time to start after SyUI comes up. This avoids flashing a dialog in the user's + // face because BT starts a little bit later in the boot process than SysUI and it takes some + // time for us to receive the signal that it's starting. + private static final long BLUETOOTH_START_DELAY_MILLIS = 10 * 1000; + + private static final int STATE_NOT_ENABLED = -1; + private static final int STATE_UNKNOWN = 0; + private static final int STATE_WAITING_FOR_BOOT_COMPLETED = 1; + private static final int STATE_WAITING_FOR_TABLET_MODE_EXIT = 2; + private static final int STATE_WAITING_FOR_DEVICE_DISCOVERY = 3; + private static final int STATE_WAITING_FOR_BLUETOOTH = 4; + private static final int STATE_WAITING_FOR_STATE_PAIRED = 5; + private static final int STATE_PAIRING = 6; + private static final int STATE_PAIRED = 7; + private static final int STATE_USER_CANCELLED = 8; + private static final int STATE_DEVICE_NOT_FOUND = 9; + + private static final int MSG_INIT = 0; + private static final int MSG_ON_BOOT_COMPLETED = 1; + private static final int MSG_PROCESS_KEYBOARD_STATE = 2; + private static final int MSG_ENABLE_BLUETOOTH = 3; + private static final int MSG_ON_BLUETOOTH_STATE_CHANGED = 4; + private static final int MSG_ON_DEVICE_BOND_STATE_CHANGED = 5; + private static final int MSG_ON_BLUETOOTH_DEVICE_ADDED = 6; + private static final int MSG_ON_BLE_SCAN_FAILED = 7; + private static final int MSG_SHOW_BLUETOOTH_DIALOG = 8; + private static final int MSG_DISMISS_BLUETOOTH_DIALOG = 9; + + private volatile KeyboardHandler mHandler; + private volatile KeyboardUIHandler mUIHandler; + + protected volatile Context mContext; + + private boolean mEnabled; + private String mKeyboardName; + private CachedBluetoothDeviceManager mCachedDeviceManager; + private LocalBluetoothAdapter mLocalBluetoothAdapter; + private LocalBluetoothProfileManager mProfileManager; + private boolean mBootCompleted; + private long mBootCompletedTime; + + private int mInTabletMode = InputManager.SWITCH_STATE_UNKNOWN; + private ScanCallback mScanCallback; + private BluetoothDialog mDialog; + + private int mState; + + @Override + public void start() { + mContext = super.mContext; + HandlerThread thread = new HandlerThread("Keyboard", Process.THREAD_PRIORITY_BACKGROUND); + thread.start(); + mHandler = new KeyboardHandler(thread.getLooper()); + mHandler.sendEmptyMessage(MSG_INIT); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println("KeyboardUI:"); + pw.println(" mEnabled=" + mEnabled); + pw.println(" mBootCompleted=" + mEnabled); + pw.println(" mBootCompletedTime=" + mBootCompletedTime); + pw.println(" mKeyboardName=" + mKeyboardName); + pw.println(" mInTabletMode=" + mInTabletMode); + pw.println(" mState=" + stateToString(mState)); + } + + @Override + protected void onBootCompleted() { + mHandler.sendEmptyMessage(MSG_ON_BOOT_COMPLETED); + } + + @Override + public void onTabletModeChanged(long whenNanos, boolean inTabletMode) { + if (DEBUG) { + Slog.d(TAG, "onTabletModeChanged(" + whenNanos + ", " + inTabletMode + ")"); + } + + if (inTabletMode && mInTabletMode != InputManager.SWITCH_STATE_ON + || !inTabletMode && mInTabletMode != InputManager.SWITCH_STATE_OFF) { + mInTabletMode = inTabletMode ? + InputManager.SWITCH_STATE_ON : InputManager.SWITCH_STATE_OFF; + processKeyboardState(); + } + } + + // Shoud only be called on the handler thread + private void init() { + Context context = mContext; + mKeyboardName = + context.getString(com.android.internal.R.string.config_packagedKeyboardName); + if (TextUtils.isEmpty(mKeyboardName)) { + if (DEBUG) { + Slog.d(TAG, "No packaged keyboard name given."); + } + return; + } + + LocalBluetoothManager bluetoothManager = LocalBluetoothManager.getInstance(context, null); + if (bluetoothManager == null) { + if (DEBUG) { + Slog.e(TAG, "Failed to retrieve LocalBluetoothManager instance"); + } + return; + } + mEnabled = true; + mCachedDeviceManager = bluetoothManager.getCachedDeviceManager(); + mLocalBluetoothAdapter = bluetoothManager.getBluetoothAdapter(); + mProfileManager = bluetoothManager.getProfileManager(); + bluetoothManager.getEventManager().registerCallback(new BluetoothCallbackHandler()); + + InputManager im = (InputManager) context.getSystemService(Context.INPUT_SERVICE); + im.registerOnTabletModeChangedListener(this, mHandler); + mInTabletMode = im.isInTabletMode(); + + processKeyboardState(); + mUIHandler = new KeyboardUIHandler(); + } + + // Should only be called on the handler thread + private void processKeyboardState() { + mHandler.removeMessages(MSG_PROCESS_KEYBOARD_STATE); + + if (!mEnabled) { + mState = STATE_NOT_ENABLED; + return; + } + + if (!mBootCompleted) { + mState = STATE_WAITING_FOR_BOOT_COMPLETED; + return; + } + + if (mInTabletMode != InputManager.SWITCH_STATE_OFF) { + if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY) { + stopScanning(); + } + mState = STATE_WAITING_FOR_TABLET_MODE_EXIT; + return; + } + + final int btState = mLocalBluetoothAdapter.getState(); + if (btState == BluetoothAdapter.STATE_TURNING_ON || btState == BluetoothAdapter.STATE_ON + && mState == STATE_WAITING_FOR_BLUETOOTH) { + // If we're waiting for bluetooth but it has come on in the meantime, or is coming + // on, just dismiss the dialog. This frequently happens during device startup. + mUIHandler.sendEmptyMessage(MSG_DISMISS_BLUETOOTH_DIALOG); + } + + if (btState == BluetoothAdapter.STATE_TURNING_ON) { + mState = STATE_WAITING_FOR_BLUETOOTH; + // Wait for bluetooth to fully come on. + return; + } + + if (btState != BluetoothAdapter.STATE_ON) { + mState = STATE_WAITING_FOR_BLUETOOTH; + showBluetoothDialog(); + return; + } + + CachedBluetoothDevice device = getPairedKeyboard(); + if ((mState == STATE_WAITING_FOR_TABLET_MODE_EXIT || mState == STATE_WAITING_FOR_BLUETOOTH) + && device != null) { + // If we're just coming out of tablet mode or BT just turned on, + // then we want to go ahead and automatically connect to the + // keyboard. We want to avoid this in other cases because we might + // be spuriously called after the user has manually disconnected + // the keyboard, meaning we shouldn't try to automtically connect + // it again. + mState = STATE_PAIRED; + device.connect(false); + return; + } + + device = getDiscoveredKeyboard(); + if (device != null) { + mState = STATE_PAIRING; + device.startPairing(); + } else { + mState = STATE_WAITING_FOR_DEVICE_DISCOVERY; + startScanning(); + } + } + + // Should only be called on the handler thread + public void onBootCompletedInternal() { + mBootCompleted = true; + mBootCompletedTime = SystemClock.uptimeMillis(); + if (mState == STATE_WAITING_FOR_BOOT_COMPLETED) { + processKeyboardState(); + } + } + + // Should only be called on the handler thread + private void showBluetoothDialog() { + if (isUserSetupComplete()) { + long now = SystemClock.uptimeMillis(); + long earliestDialogTime = mBootCompletedTime + BLUETOOTH_START_DELAY_MILLIS; + if (earliestDialogTime < now) { + mUIHandler.sendEmptyMessage(MSG_SHOW_BLUETOOTH_DIALOG); + } else { + mHandler.sendEmptyMessageAtTime(MSG_PROCESS_KEYBOARD_STATE, earliestDialogTime); + } + } else { + // If we're in setup wizard and the keyboard is docked, just automatically enable BT. + mLocalBluetoothAdapter.enable(); + } + } + + private boolean isUserSetupComplete() { + ContentResolver resolver = mContext.getContentResolver(); + return Secure.getIntForUser( + resolver, Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; + } + + private CachedBluetoothDevice getPairedKeyboard() { + Set<BluetoothDevice> devices = mLocalBluetoothAdapter.getBondedDevices(); + for (BluetoothDevice d : devices) { + if (mKeyboardName.equals(d.getName())) { + return getCachedBluetoothDevice(d); + } + } + return null; + } + + private CachedBluetoothDevice getDiscoveredKeyboard() { + Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy(); + for (CachedBluetoothDevice d : devices) { + if (d.getName().equals(mKeyboardName)) { + return d; + } + } + return null; + } + + + private CachedBluetoothDevice getCachedBluetoothDevice(BluetoothDevice d) { + CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(d); + if (cachedDevice == null) { + cachedDevice = mCachedDeviceManager.addDevice( + mLocalBluetoothAdapter, mProfileManager, d); + } + return cachedDevice; + } + + private void startScanning() { + BluetoothLeScanner scanner = mLocalBluetoothAdapter.getBluetoothLeScanner(); + ScanFilter filter = (new ScanFilter.Builder()).setDeviceName(mKeyboardName).build(); + ScanSettings settings = (new ScanSettings.Builder()) + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT) + .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) + .setReportDelay(0) + .build(); + mScanCallback = new KeyboardScanCallback(); + scanner.startScan(Arrays.asList(filter), settings, mScanCallback); + } + + private void stopScanning() { + if (mScanCallback != null) { + mLocalBluetoothAdapter.getBluetoothLeScanner().stopScan(mScanCallback); + mScanCallback = null; + } + } + + // Should only be called on the handler thread + private void onDeviceAddedInternal(CachedBluetoothDevice d) { + if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY && d.getName().equals(mKeyboardName)) { + stopScanning(); + d.startPairing(); + mState = STATE_PAIRING; + } + } + + // Should only be called on the handler thread + private void onBluetoothStateChangedInternal(int bluetoothState) { + if (bluetoothState == BluetoothAdapter.STATE_ON && mState == STATE_WAITING_FOR_BLUETOOTH) { + processKeyboardState(); + } + } + + // Should only be called on the handler thread + private void onDeviceBondStateChangedInternal(CachedBluetoothDevice d, int bondState) { + if (d.getName().equals(mKeyboardName) && bondState == BluetoothDevice.BOND_BONDED) { + // We don't need to manually connect to the device here because it will automatically + // try to connect after it has been paired. + mState = STATE_PAIRED; + } + } + + // Should only be called on the handler thread + private void onBleScanFailedInternal() { + mScanCallback = null; + if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY) { + mState = STATE_DEVICE_NOT_FOUND; + } + } + + private final class KeyboardUIHandler extends Handler { + public KeyboardUIHandler() { + super(Looper.getMainLooper(), null, true /*async*/); + } + @Override + public void handleMessage(Message msg) { + switch(msg.what) { + case MSG_SHOW_BLUETOOTH_DIALOG: { + DialogInterface.OnClickListener listener = new BluetoothDialogClickListener(); + mDialog = new BluetoothDialog(mContext); + mDialog.setTitle(R.string.enable_bluetooth_title); + mDialog.setMessage(R.string.enable_bluetooth_message); + mDialog.setPositiveButton(R.string.enable_bluetooth_confirmation_ok, listener); + mDialog.setNegativeButton(android.R.string.cancel, listener); + mDialog.show(); + break; + } + case MSG_DISMISS_BLUETOOTH_DIALOG: { + if (mDialog != null) { + mDialog.dismiss(); + mDialog = null; + } + break; + } + } + } + } + + private final class KeyboardHandler extends Handler { + public KeyboardHandler(Looper looper) { + super(looper, null, true /*async*/); + } + + @Override + public void handleMessage(Message msg) { + switch(msg.what) { + case MSG_INIT: { + init(); + break; + } + case MSG_ON_BOOT_COMPLETED: { + onBootCompletedInternal(); + break; + } + case MSG_PROCESS_KEYBOARD_STATE: { + processKeyboardState(); + break; + } + case MSG_ENABLE_BLUETOOTH: { + boolean enable = msg.arg1 == 1; + if (enable) { + mLocalBluetoothAdapter.enable(); + } else { + mState = STATE_USER_CANCELLED; + } + } + case MSG_ON_BLUETOOTH_STATE_CHANGED: { + int bluetoothState = msg.arg1; + onBluetoothStateChangedInternal(bluetoothState); + break; + } + case MSG_ON_DEVICE_BOND_STATE_CHANGED: { + CachedBluetoothDevice d = (CachedBluetoothDevice)msg.obj; + int bondState = msg.arg1; + onDeviceBondStateChangedInternal(d, bondState); + break; + } + case MSG_ON_BLUETOOTH_DEVICE_ADDED: { + BluetoothDevice d = (BluetoothDevice)msg.obj; + CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(d); + onDeviceAddedInternal(cachedDevice); + break; + + } + case MSG_ON_BLE_SCAN_FAILED: { + onBleScanFailedInternal(); + break; + } + } + } + } + + private final class BluetoothDialogClickListener implements DialogInterface.OnClickListener { + @Override + public void onClick(DialogInterface dialog, int which) { + int enable = DialogInterface.BUTTON_POSITIVE == which ? 1 : 0; + mHandler.obtainMessage(MSG_ENABLE_BLUETOOTH, enable, 0).sendToTarget(); + mDialog = null; + } + } + + private final class KeyboardScanCallback extends ScanCallback { + @Override + public void onBatchScanResults(List<ScanResult> results) { + if (DEBUG) { + Slog.d(TAG, "onBatchScanResults(" + results.size() + ")"); + } + if (!results.isEmpty()) { + BluetoothDevice bestDevice = results.get(0).getDevice(); + int bestRssi = results.get(0).getRssi(); + final int N = results.size(); + for (int i = 0; i < N; i++) { + ScanResult r = results.get(i); + if (r.getRssi() > bestRssi) { + bestDevice = r.getDevice(); + } + } + mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED, bestDevice).sendToTarget(); + } + } + + @Override + public void onScanFailed(int errorCode) { + if (DEBUG) { + Slog.d(TAG, "onScanFailed(" + errorCode + ")"); + } + mHandler.obtainMessage(MSG_ON_BLE_SCAN_FAILED).sendToTarget(); + } + + @Override + public void onScanResult(int callbackType, ScanResult result) { + if (DEBUG) { + Slog.d(TAG, "onScanResult(" + callbackType + ", " + result + ")"); + } + mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED, + result.getDevice()).sendToTarget(); + } + } + + private final class BluetoothCallbackHandler implements BluetoothCallback { + @Override + public void onBluetoothStateChanged(int bluetoothState) { + mHandler.obtainMessage(MSG_ON_BLUETOOTH_STATE_CHANGED, + bluetoothState, 0).sendToTarget(); + } + + @Override + public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { + mHandler.obtainMessage(MSG_ON_DEVICE_BOND_STATE_CHANGED, + bondState, 0, cachedDevice).sendToTarget(); + } + + @Override + public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { } + @Override + public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { } + @Override + public void onScanningStateChanged(boolean started) { } + @Override + public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { } + } + + private static String stateToString(int state) { + switch (state) { + case STATE_NOT_ENABLED: + return "STATE_NOT_ENABLED"; + case STATE_WAITING_FOR_BOOT_COMPLETED: + return "STATE_WAITING_FOR_BOOT_COMPLETED"; + case STATE_WAITING_FOR_TABLET_MODE_EXIT: + return "STATE_WAITING_FOR_TABLET_MODE_EXIT"; + case STATE_WAITING_FOR_DEVICE_DISCOVERY: + return "STATE_WAITING_FOR_DEVICE_DISCOVERY"; + case STATE_WAITING_FOR_BLUETOOTH: + return "STATE_WAITING_FOR_BLUETOOTH"; + case STATE_WAITING_FOR_STATE_PAIRED: + return "STATE_WAITING_FOR_STATE_PAIRED"; + case STATE_PAIRING: + return "STATE_PAIRING"; + case STATE_PAIRED: + return "STATE_PAIRED"; + case STATE_USER_CANCELLED: + return "STATE_USER_CANCELLED"; + case STATE_DEVICE_NOT_FOUND: + return "STATE_DEVICE_NOT_FOUND"; + case STATE_UNKNOWN: + default: + return "STATE_UNKNOWN"; + } + } +} |