130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh/*
230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * Copyright (C) 2011 The Android Open Source Project
330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh *
430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * Licensed under the Apache License, Version 2.0 (the "License");
530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * you may not use this file except in compliance with the License.
630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * You may obtain a copy of the License at
730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh *
830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh *      http://www.apache.org/licenses/LICENSE-2.0
930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh *
1030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * Unless required by applicable law or agreed to in writing, software
1130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * distributed under the License is distributed on an "AS IS" BASIS,
1230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * See the License for the specific language governing permissions and
1430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * limitations under the License.
1530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh */
1630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshpackage android.server;
1830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
2030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.bluetooth.BluetoothDevice;
2130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.bluetooth.BluetoothDeviceProfileState;
2230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.bluetooth.BluetoothInputDevice;
23cb1d354c1e9b458a0426cd08520d938012e32b34Jaikumar Ganeshimport android.bluetooth.BluetoothProfile;
2430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.bluetooth.BluetoothProfileState;
2530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.content.Context;
2630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.content.Intent;
2730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.os.Message;
2830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.provider.Settings;
2930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport android.util.Log;
3030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
3130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport java.util.ArrayList;
3230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport java.util.HashMap;
3330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganeshimport java.util.List;
3430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
3530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh/**
3630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * This handles all the operations on the HID profile.
3730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * All functions are called by BluetoothService, as Bluetooth Service
3830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh * is the Service handler for the HID profile.
3930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh */
4047898dd398ce7758983c7eca8a204cf9a170342aJaikumar Ganeshfinal class BluetoothInputProfileHandler {
4130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private static final String TAG = "BluetoothInputProfileHandler";
4230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private static final boolean DBG = true;
4330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
4430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    public static BluetoothInputProfileHandler sInstance;
4530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private Context mContext;
4630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private BluetoothService mBluetoothService;
4730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private final HashMap<BluetoothDevice, Integer> mInputDevices;
4830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private final BluetoothProfileState mHidProfileState;
4930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
5030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private BluetoothInputProfileHandler(Context context, BluetoothService service) {
5130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mContext = context;
5230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mBluetoothService = service;
5330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mInputDevices = new HashMap<BluetoothDevice, Integer>();
5430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mHidProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.HID);
5530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mHidProfileState.start();
5630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
5730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
5830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    static synchronized BluetoothInputProfileHandler getInstance(Context context,
5930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            BluetoothService service) {
6030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (sInstance == null) sInstance = new BluetoothInputProfileHandler(context, service);
6130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return sInstance;
6230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
6330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
646003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    boolean connectInputDevice(BluetoothDevice device,
6530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                                            BluetoothDeviceProfileState state) {
6630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
6730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (objectPath == null ||
684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            getInputDeviceConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
6930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_OFF) {
7030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return false;
7130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
7230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (state != null) {
7330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            Message msg = new Message();
7430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            msg.arg1 = BluetoothDeviceProfileState.CONNECT_HID_OUTGOING;
7530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            msg.obj = state;
7630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            mHidProfileState.sendMessage(msg);
7730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return true;
7830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
7930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return false;
8030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
8130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
826003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    boolean connectInputDeviceInternal(BluetoothDevice device) {
8330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
8430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_CONNECTING);
8530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (!mBluetoothService.connectInputDeviceNative(objectPath)) {
8630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_DISCONNECTED);
8730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return false;
8830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
8930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return true;
9030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
9130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
926003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    boolean disconnectInputDevice(BluetoothDevice device,
9330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                                               BluetoothDeviceProfileState state) {
9430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
9530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (objectPath == null ||
964ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                getInputDeviceConnectionState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
9730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return false;
9830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
9930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (state != null) {
10030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            Message msg = new Message();
10130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            msg.arg1 = BluetoothDeviceProfileState.DISCONNECT_HID_OUTGOING;
10230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            msg.obj = state;
10330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            mHidProfileState.sendMessage(msg);
10430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return true;
10530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
10630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return false;
10730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
10830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1096003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    boolean disconnectInputDeviceInternal(BluetoothDevice device) {
11030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
11130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_DISCONNECTING);
11230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (!mBluetoothService.disconnectInputDeviceNative(objectPath)) {
11330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_CONNECTED);
11430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return false;
11530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
11630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return true;
11730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
11830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1196003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    int getInputDeviceConnectionState(BluetoothDevice device) {
12030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (mInputDevices.get(device) == null) {
12130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return BluetoothInputDevice.STATE_DISCONNECTED;
12230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
12330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return mInputDevices.get(device);
12430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
12530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1266003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    List<BluetoothDevice> getConnectedInputDevices() {
12730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(
12830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            new int[] {BluetoothInputDevice.STATE_CONNECTED});
12930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return devices;
13030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
13130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1326003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    List<BluetoothDevice> getInputDevicesMatchingConnectionStates(int[] states) {
1334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(states);
1344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return devices;
1354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    }
1364ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh
1376003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    int getInputDevicePriority(BluetoothDevice device) {
13830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return Settings.Secure.getInt(mContext.getContentResolver(),
13930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
14030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                BluetoothInputDevice.PRIORITY_UNDEFINED);
14130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
14230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1436003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    boolean setInputDevicePriority(BluetoothDevice device, int priority) {
14430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
14530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            return false;
14630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
14730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return Settings.Secure.putInt(mContext.getContentResolver(),
14830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
14930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                priority);
15030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
15130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1526003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    List<BluetoothDevice> lookupInputDevicesMatchingStates(int[] states) {
15330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>();
15430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
15530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        for (BluetoothDevice device: mInputDevices.keySet()) {
1564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            int inputDeviceState = getInputDeviceConnectionState(device);
15730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            for (int state : states) {
15830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                if (state == inputDeviceState) {
15930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                    inputDevices.add(device);
16030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                    break;
16130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                }
16230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            }
16330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
16430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        return inputDevices;
16530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
16630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1676003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    private void handleInputDeviceStateChange(BluetoothDevice device, int state) {
16830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        int prevState;
16930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (mInputDevices.get(device) == null) {
17030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            prevState = BluetoothInputDevice.STATE_DISCONNECTED;
17130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        } else {
17230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            prevState = mInputDevices.get(device);
17330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
17430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (prevState == state) return;
17530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
17630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mInputDevices.put(device, state);
17730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
17830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (getInputDevicePriority(device) >
17930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh              BluetoothInputDevice.PRIORITY_OFF &&
18030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            state == BluetoothInputDevice.STATE_CONNECTING ||
18130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            state == BluetoothInputDevice.STATE_CONNECTED) {
18230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            // We have connected or attempting to connect.
18330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            // Bump priority
18430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_AUTO_CONNECT);
18530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
18630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1874ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
18830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
1894ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_STATE, prevState);
1904ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        intent.putExtra(BluetoothInputDevice.EXTRA_STATE, state);
191e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
19230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
19330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
19430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
195cb1d354c1e9b458a0426cd08520d938012e32b34Jaikumar Ganesh        mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.INPUT_DEVICE, state,
196cb1d354c1e9b458a0426cd08520d938012e32b34Jaikumar Ganesh                                                    prevState);
19730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
19830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
1996003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    void handleInputDevicePropertyChange(String address, boolean connected) {
20030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        int state = connected ? BluetoothInputDevice.STATE_CONNECTED :
20130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            BluetoothInputDevice.STATE_DISCONNECTED;
20230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
20330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        BluetoothDevice device = adapter.getRemoteDevice(address);
20430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        handleInputDeviceStateChange(device, state);
20530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
20630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
2076003fe9af08b134485ebac61ee312528325f6c3cJaikumar Ganesh    void setInitialInputDevicePriority(BluetoothDevice device, int state) {
20830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        switch (state) {
20930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            case BluetoothDevice.BOND_BONDED:
21030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                if (getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_UNDEFINED) {
21130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                    setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_ON);
21230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                }
21330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                break;
21430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh            case BluetoothDevice.BOND_NONE:
21530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_UNDEFINED);
21630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh                break;
21730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        }
21830b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
21930b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
22030b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private static void debugLog(String msg) {
22130b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        if (DBG) Log.d(TAG, msg);
22230b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
22330b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh
22430b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    private static void errorLog(String msg) {
22530b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh        Log.e(TAG, msg);
22630b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh    }
22730b8cbe059b9addff643242e8a1fc86ca72ba54eJaikumar Ganesh}
228