1545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/*
24ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Copyright (C) 2011 The Android Open Source Project
3545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh *
4545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Licensed under the Apache License, Version 2.0 (the "License");
5545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * you may not use this file except in compliance with the License.
6545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * You may obtain a copy of the License at
7545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh *
8545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh *      http://www.apache.org/licenses/LICENSE-2.0
9545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh *
10545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Unless required by applicable law or agreed to in writing, software
11545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * distributed under the License is distributed on an "AS IS" BASIS,
12545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * See the License for the specific language governing permissions and
14545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * limitations under the License.
15545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */
16545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
17545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshpackage android.bluetooth;
18545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
19545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.annotation.SdkConstant;
20545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.annotation.SdkConstant.SdkConstantType;
21bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.ComponentName;
22545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.content.Context;
23bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.Intent;
24bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.ServiceConnection;
250a17db1cc5942ea000ca87bb72853de57a15ec64Jeff Sharkeyimport android.os.Binder;
26545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.os.IBinder;
27545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.os.RemoteException;
28545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.util.Log;
29545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
305a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.ArrayList;
315a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.List;
32545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh
34545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/**
354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth Input
364ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device Profile.
37545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh *
384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
404ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * the BluetoothInputDevice proxy object.
41545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh *
424ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>Each method is protected with its appropriate permission.
434ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *@hide
44545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */
454ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganeshpublic final class BluetoothInputDevice implements BluetoothProfile {
46545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    private static final String TAG = "BluetoothInputDevice";
470f42037eb7b5118015c2caca635538324ccf0ccffredc    private static final boolean DBG = true;
48563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie    private static final boolean VDBG = false;
49545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
50545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    /**
514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * Intent used to broadcast the change in connection state of the Input
524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * Device profile.
534ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *
544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * <p>This intent will have 3 extras:
554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * <ul>
564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
574ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
584ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * </ul>
604ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *
614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
644ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *
654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
664ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * receive.
67545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
694ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public static final String ACTION_CONNECTION_STATE_CHANGED =
704ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
71545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
72fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    /**
73349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
74349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
75349e62f329bbb8edab89356973773a5648f26751Priti Aghera    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
76349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String ACTION_PROTOCOL_MODE_CHANGED =
77349e62f329bbb8edab89356973773a5648f26751Priti Aghera        "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
78349e62f329bbb8edab89356973773a5648f26751Priti Aghera
79d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen    /**
80d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen     * @hide
81d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen     */
82d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
838faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen    public static final String ACTION_HANDSHAKE =
848faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen        "android.bluetooth.input.profile.action.HANDSHAKE";
858faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen
868faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen    /**
878faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen     * @hide
888faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen     */
898faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
90d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen    public static final String ACTION_REPORT =
91d96d5cfffcfb4975c462c0b9feff753fba4f8709Mike J. Chen        "android.bluetooth.input.profile.action.REPORT";
92349e62f329bbb8edab89356973773a5648f26751Priti Aghera
93349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
94349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
95349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
96349e62f329bbb8edab89356973773a5648f26751Priti Aghera    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
97349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
98349e62f329bbb8edab89356973773a5648f26751Priti Aghera        "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
99349e62f329bbb8edab89356973773a5648f26751Priti Aghera
10056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    /**
10156048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @hide
10256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     */
10356048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
10456048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    public static final String ACTION_IDLE_TIME_CHANGED =
10556048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        "android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
106349e62f329bbb8edab89356973773a5648f26751Priti Aghera
107349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
108fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh     * Return codes for the connect and disconnect Bluez / Dbus calls.
1094ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
110fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh     */
111fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
112fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
1134ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
1144ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
1154ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     */
116fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
117fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
1184ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
1194ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
1204ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     */
121fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
122fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
1234ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
1244ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
1254ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     */
126fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
127fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
1284ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
1294ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
1304ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     */
131fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    public static final int INPUT_OPERATION_SUCCESS = 5004;
132fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
133349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
134349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
135349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
136349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final int PROTOCOL_REPORT_MODE = 0;
137349e62f329bbb8edab89356973773a5648f26751Priti Aghera
138349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
139349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
140349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
141349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final int PROTOCOL_BOOT_MODE = 1;
142349e62f329bbb8edab89356973773a5648f26751Priti Aghera
143349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
144349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
145349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
146349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final int PROTOCOL_UNSUPPORTED_MODE = 255;
147349e62f329bbb8edab89356973773a5648f26751Priti Aghera
148349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /*  int reportType, int reportType, int bufferSize */
149349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
150349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
151349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
1521b47f7cc1af63b3ae8ec79808dbf6147b73db605Mike J. Chen    public static final byte REPORT_TYPE_INPUT = 1;
153349e62f329bbb8edab89356973773a5648f26751Priti Aghera
154349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
155349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
156349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
1571b47f7cc1af63b3ae8ec79808dbf6147b73db605Mike J. Chen    public static final byte REPORT_TYPE_OUTPUT = 2;
158349e62f329bbb8edab89356973773a5648f26751Priti Aghera
159349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
160349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
161349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
1621b47f7cc1af63b3ae8ec79808dbf6147b73db605Mike J. Chen    public static final byte REPORT_TYPE_FEATURE = 3;
163349e62f329bbb8edab89356973773a5648f26751Priti Aghera
164349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
165349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
166349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
167349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0;
168349e62f329bbb8edab89356973773a5648f26751Priti Aghera
169349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
170349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
171349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
172349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1;
173349e62f329bbb8edab89356973773a5648f26751Priti Aghera
174349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
175349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
176349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
177349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE";
178349e62f329bbb8edab89356973773a5648f26751Priti Aghera
179349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
180349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
181349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
182349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE";
183349e62f329bbb8edab89356973773a5648f26751Priti Aghera
184349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
185349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
186349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
187349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID";
188349e62f329bbb8edab89356973773a5648f26751Priti Aghera
189349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
190349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
191349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
192349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE";
193349e62f329bbb8edab89356973773a5648f26751Priti Aghera
194349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
195349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
196349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
197349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String EXTRA_REPORT = "android.bluetooth.BluetoothInputDevice.extra.REPORT";
198349e62f329bbb8edab89356973773a5648f26751Priti Aghera
199349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
200349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
201349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
2028faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen    public static final String EXTRA_STATUS = "android.bluetooth.BluetoothInputDevice.extra.STATUS";
2038faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen
2048faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen    /**
2058faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen     * @hide
2068faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen     */
207349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
208349e62f329bbb8edab89356973773a5648f26751Priti Aghera
20956048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    /**
21056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @hide
21156048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     */
21256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    public static final String EXTRA_IDLE_TIME = "android.bluetooth.BluetoothInputDevice.extra.IDLE_TIME";
21356048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta
214bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie    private Context mContext;
2154ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    private ServiceListener mServiceListener;
2164ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    private BluetoothAdapter mAdapter;
2170146463d70355592da85c3605aaaef4cf0b7335eJack He    private volatile IBluetoothInputDevice mService;
218545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
2190f42037eb7b5118015c2caca635538324ccf0ccffredc    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
2200f42037eb7b5118015c2caca635538324ccf0ccffredc            new IBluetoothStateChangeCallback.Stub() {
2210f42037eb7b5118015c2caca635538324ccf0ccffredc                public void onBluetoothStateChange(boolean up) {
2220f42037eb7b5118015c2caca635538324ccf0ccffredc                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
2230f42037eb7b5118015c2caca635538324ccf0ccffredc                    if (!up) {
224563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie                        if (VDBG) Log.d(TAG,"Unbinding service...");
2250f42037eb7b5118015c2caca635538324ccf0ccffredc                        synchronized (mConnection) {
2260f42037eb7b5118015c2caca635538324ccf0ccffredc                            try {
2270f42037eb7b5118015c2caca635538324ccf0ccffredc                                mService = null;
2280f42037eb7b5118015c2caca635538324ccf0ccffredc                                mContext.unbindService(mConnection);
2290f42037eb7b5118015c2caca635538324ccf0ccffredc                            } catch (Exception re) {
2300f42037eb7b5118015c2caca635538324ccf0ccffredc                                Log.e(TAG,"",re);
2310f42037eb7b5118015c2caca635538324ccf0ccffredc                            }
2320f42037eb7b5118015c2caca635538324ccf0ccffredc                        }
2330f42037eb7b5118015c2caca635538324ccf0ccffredc                    } else {
2340f42037eb7b5118015c2caca635538324ccf0ccffredc                        synchronized (mConnection) {
2350f42037eb7b5118015c2caca635538324ccf0ccffredc                            try {
2360f42037eb7b5118015c2caca635538324ccf0ccffredc                                if (mService == null) {
237563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie                                    if (VDBG) Log.d(TAG,"Binding service...");
238221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn                                    doBind();
2390f42037eb7b5118015c2caca635538324ccf0ccffredc                                }
2400f42037eb7b5118015c2caca635538324ccf0ccffredc                            } catch (Exception re) {
2410f42037eb7b5118015c2caca635538324ccf0ccffredc                                Log.e(TAG,"",re);
2420f42037eb7b5118015c2caca635538324ccf0ccffredc                            }
2430f42037eb7b5118015c2caca635538324ccf0ccffredc                        }
2440f42037eb7b5118015c2caca635538324ccf0ccffredc                    }
2450f42037eb7b5118015c2caca635538324ccf0ccffredc                }
2460f42037eb7b5118015c2caca635538324ccf0ccffredc        };
2470f42037eb7b5118015c2caca635538324ccf0ccffredc
248545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    /**
249545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     * Create a BluetoothInputDevice proxy object for interacting with the local
2504ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * Bluetooth Service which handles the InputDevice profile
2514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     *
252545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
253bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie    /*package*/ BluetoothInputDevice(Context context, ServiceListener l) {
254bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie        mContext = context;
2554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        mServiceListener = l;
2564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        mAdapter = BluetoothAdapter.getDefaultAdapter();
2570f42037eb7b5118015c2caca635538324ccf0ccffredc
2580f42037eb7b5118015c2caca635538324ccf0ccffredc        IBluetoothManager mgr = mAdapter.getBluetoothManager();
2590f42037eb7b5118015c2caca635538324ccf0ccffredc        if (mgr != null) {
2600f42037eb7b5118015c2caca635538324ccf0ccffredc            try {
2610f42037eb7b5118015c2caca635538324ccf0ccffredc                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
2620f42037eb7b5118015c2caca635538324ccf0ccffredc            } catch (RemoteException e) {
2630f42037eb7b5118015c2caca635538324ccf0ccffredc                Log.e(TAG,"",e);
2640f42037eb7b5118015c2caca635538324ccf0ccffredc            }
2650f42037eb7b5118015c2caca635538324ccf0ccffredc        }
2660f42037eb7b5118015c2caca635538324ccf0ccffredc
267221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn        doBind();
268221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn    }
269221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn
270221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn    boolean doBind() {
271221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn        Intent intent = new Intent(IBluetoothInputDevice.class.getName());
272221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
273221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn        intent.setComponent(comp);
274466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
275466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn                android.os.Process.myUserHandle())) {
276221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn            Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
277221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn            return false;
278545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
279221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn        return true;
280545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
281545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
2829bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    /*package*/ void close() {
283563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie        if (VDBG) log("close()");
2840f42037eb7b5118015c2caca635538324ccf0ccffredc        IBluetoothManager mgr = mAdapter.getBluetoothManager();
2850f42037eb7b5118015c2caca635538324ccf0ccffredc        if (mgr != null) {
2860f42037eb7b5118015c2caca635538324ccf0ccffredc            try {
2870f42037eb7b5118015c2caca635538324ccf0ccffredc                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
2880f42037eb7b5118015c2caca635538324ccf0ccffredc            } catch (Exception e) {
2890f42037eb7b5118015c2caca635538324ccf0ccffredc                Log.e(TAG,"",e);
2900f42037eb7b5118015c2caca635538324ccf0ccffredc            }
2910f42037eb7b5118015c2caca635538324ccf0ccffredc        }
2920f42037eb7b5118015c2caca635538324ccf0ccffredc
2930f42037eb7b5118015c2caca635538324ccf0ccffredc        synchronized (mConnection) {
2940f42037eb7b5118015c2caca635538324ccf0ccffredc            if (mService != null) {
2950f42037eb7b5118015c2caca635538324ccf0ccffredc                try {
2960f42037eb7b5118015c2caca635538324ccf0ccffredc                    mService = null;
2970f42037eb7b5118015c2caca635538324ccf0ccffredc                    mContext.unbindService(mConnection);
2980f42037eb7b5118015c2caca635538324ccf0ccffredc                } catch (Exception re) {
2990f42037eb7b5118015c2caca635538324ccf0ccffredc                    Log.e(TAG,"",re);
3000f42037eb7b5118015c2caca635538324ccf0ccffredc                }
3010f42037eb7b5118015c2caca635538324ccf0ccffredc           }
302bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie        }
3039bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh        mServiceListener = null;
3049bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh    }
3059bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh
3064ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
307f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate connection to a profile of the remote bluetooth device.
308f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
309f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The system supports connection to multiple input devices.
310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
311f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API returns false in scenarios like the profile on the
312f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * device is already connected or Bluetooth is not turned on.
313f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * When this API returns true, it is guaranteed that
314f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * connection state intent for the profile will be broadcasted with
315f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * the state. Users can get the connection state of the profile
316f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * from this intent.
317f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
318f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
319f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
320f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
321f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
322f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
323f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
3244ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
325545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
3264ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public boolean connect(BluetoothDevice device) {
3274ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        if (DBG) log("connect(" + device + ")");
3280146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
3290146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
3304ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
3310146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.connect(device);
3324ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
3334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
3344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return false;
335bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
336545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
3370146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
3384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return false;
339545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
340545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
3414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
342f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate disconnection from a profile
343f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
344f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API will return false in scenarios like the profile on the
345f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Bluetooth device is not in connected state etc. When this API returns,
346f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * true, it is guaranteed that the connection state change
347f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * intent will be broadcasted with the state. Users can get the
348f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * disconnection state of the profile from this intent.
349f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
350f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> If the disconnection is initiated by a remote device, the state
351f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * will transition from {@link #STATE_CONNECTED} to
352f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
353f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * host (local) device the state will transition from
354f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
355f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * state {@link #STATE_DISCONNECTED}. The transition to
356f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
357f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * two scenarios.
358f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
359f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
360f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
361f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
362f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
363f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
364f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
3654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
366545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
3674ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public boolean disconnect(BluetoothDevice device) {
3684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        if (DBG) log("disconnect(" + device + ")");
3690146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
3700146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
3714ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
3720146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.disconnect(device);
3734ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
3744ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
3754ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return false;
376bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
377545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
3780146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
3794ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return false;
380545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
381545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
3824ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
3834ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * {@inheritDoc}
384545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
3854ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public List<BluetoothDevice> getConnectedDevices() {
386563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie        if (VDBG) log("getConnectedDevices()");
3870146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
3880146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled()) {
3894ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
3900146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getConnectedDevices();
3914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
3924ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
3934ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
394bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
3954ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        }
3960146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
3974ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
398545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
399545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
4004ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
4014ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * {@inheritDoc}
402545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
4034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
404563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie        if (VDBG) log("getDevicesMatchingStates()");
4050146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
4060146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled()) {
4074ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
4080146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getDevicesMatchingConnectionStates(states);
4094ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
4104ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
4114ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
412bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
413545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
4140146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
4154ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
416545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
417545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
4184ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    /**
4194ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * {@inheritDoc}
420545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
4214ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public int getConnectionState(BluetoothDevice device) {
422563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie        if (VDBG) log("getState(" + device + ")");
4230146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
4240146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
4254ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
4260146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getConnectionState(device);
4274ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
4284ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
4294ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return BluetoothProfile.STATE_DISCONNECTED;
430bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
431545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
4320146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
4334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return BluetoothProfile.STATE_DISCONNECTED;
434545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
435545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
436545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    /**
437f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Set priority of the profile
438f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
439f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The device should already be paired.
440f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *  Priority can be one of {@link #PRIORITY_ON} or
441f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_OFF},
442f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
443f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
444f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
445f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
446f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Paired bluetooth device
447f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param priority
448f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return true if priority is set, false on error
4494ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
450545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
4514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public boolean setPriority(BluetoothDevice device, int priority) {
4524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        if (DBG) log("setPriority(" + device + ", " + priority + ")");
4530146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
4540146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
4550146463d70355592da85c3605aaaef4cf0b7335eJack He            if (priority != BluetoothProfile.PRIORITY_OFF
4560146463d70355592da85c3605aaaef4cf0b7335eJack He                    && priority != BluetoothProfile.PRIORITY_ON) {
4570146463d70355592da85c3605aaaef4cf0b7335eJack He                return false;
4584ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            }
4594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
4600146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.setPriority(device, priority);
4614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
4624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
4634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return false;
464bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
465545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
4660146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
4674ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return false;
468545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
469545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
470545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    /**
471f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Get the priority of the profile.
472f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
473f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The priority can be any of:
474f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
475f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
476f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
477f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
478f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
479f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Bluetooth device
480f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return priority of the device
4814ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh     * @hide
482545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh     */
4834ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    public int getPriority(BluetoothDevice device) {
484563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie        if (VDBG) log("getPriority(" + device + ")");
4850146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
4860146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
4874ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            try {
4880146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getPriority(device);
4894ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh            } catch (RemoteException e) {
4904ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
4914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh                return BluetoothProfile.PRIORITY_OFF;
492bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
493545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
4940146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
4954ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh        return BluetoothProfile.PRIORITY_OFF;
4964ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    }
4974ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh
4989b6939939901cb82bc6fca93aad3810a4936dfc6Matthew Xie    private final ServiceConnection mConnection = new ServiceConnection() {
499bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie        public void onServiceConnected(ComponentName className, IBinder service) {
500bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            if (DBG) Log.d(TAG, "Proxy object connected");
5010a17db1cc5942ea000ca87bb72853de57a15ec64Jeff Sharkey            mService = IBluetoothInputDevice.Stub.asInterface(Binder.allowBlocking(service));
502bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie
503bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            if (mServiceListener != null) {
504bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
505bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
506bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie        }
507bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie        public void onServiceDisconnected(ComponentName className) {
508bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            if (DBG) Log.d(TAG, "Proxy object disconnected");
509bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            mService = null;
510bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            if (mServiceListener != null) {
511bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie                mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE);
512bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie            }
513bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie        }
514bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie    };
515bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie
5164ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    private boolean isEnabled() {
5170146463d70355592da85c3605aaaef4cf0b7335eJack He        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
5184ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh    }
5194ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh
5200146463d70355592da85c3605aaaef4cf0b7335eJack He    private static boolean isValidDevice(BluetoothDevice device) {
5210146463d70355592da85c3605aaaef4cf0b7335eJack He        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
522545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
523545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
524349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
525349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * Initiate virtual unplug for a HID input device.
526349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
527349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
528349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
529349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param device Remote Bluetooth Device
530349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @return false on immediate error,
531349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *               true otherwise
532349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
533349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
534349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public boolean virtualUnplug(BluetoothDevice device) {
535349e62f329bbb8edab89356973773a5648f26751Priti Aghera        if (DBG) log("virtualUnplug(" + device + ")");
5360146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
5370146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
538349e62f329bbb8edab89356973773a5648f26751Priti Aghera            try {
5390146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.virtualUnplug(device);
540349e62f329bbb8edab89356973773a5648f26751Priti Aghera            } catch (RemoteException e) {
541349e62f329bbb8edab89356973773a5648f26751Priti Aghera                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
542349e62f329bbb8edab89356973773a5648f26751Priti Aghera                return false;
543349e62f329bbb8edab89356973773a5648f26751Priti Aghera            }
544349e62f329bbb8edab89356973773a5648f26751Priti Aghera        }
545349e62f329bbb8edab89356973773a5648f26751Priti Aghera
5460146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
547349e62f329bbb8edab89356973773a5648f26751Priti Aghera        return false;
548349e62f329bbb8edab89356973773a5648f26751Priti Aghera
549349e62f329bbb8edab89356973773a5648f26751Priti Aghera    }
550349e62f329bbb8edab89356973773a5648f26751Priti Aghera
551349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
552349e62f329bbb8edab89356973773a5648f26751Priti Aghera    * Send Get_Protocol_Mode command to the connected HID input device.
553349e62f329bbb8edab89356973773a5648f26751Priti Aghera    *
554349e62f329bbb8edab89356973773a5648f26751Priti Aghera    * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
555349e62f329bbb8edab89356973773a5648f26751Priti Aghera    *
556349e62f329bbb8edab89356973773a5648f26751Priti Aghera    * @param device Remote Bluetooth Device
557349e62f329bbb8edab89356973773a5648f26751Priti Aghera    * @return false on immediate error,
558349e62f329bbb8edab89356973773a5648f26751Priti Aghera    *true otherwise
559349e62f329bbb8edab89356973773a5648f26751Priti Aghera    * @hide
560349e62f329bbb8edab89356973773a5648f26751Priti Aghera    */
561349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public boolean getProtocolMode(BluetoothDevice device) {
562563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie        if (VDBG) log("getProtocolMode(" + device + ")");
5630146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
5640146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
565349e62f329bbb8edab89356973773a5648f26751Priti Aghera            try {
5660146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getProtocolMode(device);
567349e62f329bbb8edab89356973773a5648f26751Priti Aghera            } catch (RemoteException e) {
568349e62f329bbb8edab89356973773a5648f26751Priti Aghera                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
569349e62f329bbb8edab89356973773a5648f26751Priti Aghera                return false;
570349e62f329bbb8edab89356973773a5648f26751Priti Aghera            }
571349e62f329bbb8edab89356973773a5648f26751Priti Aghera        }
5720146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
5730146463d70355592da85c3605aaaef4cf0b7335eJack He        return false;
574349e62f329bbb8edab89356973773a5648f26751Priti Aghera    }
575349e62f329bbb8edab89356973773a5648f26751Priti Aghera
576349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
577349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * Send Set_Protocol_Mode command to the connected HID input device.
578349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
579349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
580349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
581349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param device Remote Bluetooth Device
582349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @return false on immediate error,
583349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *               true otherwise
584349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
585349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
586349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
587349e62f329bbb8edab89356973773a5648f26751Priti Aghera        if (DBG) log("setProtocolMode(" + device + ")");
5880146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
5890146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
590349e62f329bbb8edab89356973773a5648f26751Priti Aghera            try {
5910146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.setProtocolMode(device, protocolMode);
592349e62f329bbb8edab89356973773a5648f26751Priti Aghera            } catch (RemoteException e) {
593349e62f329bbb8edab89356973773a5648f26751Priti Aghera                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
594349e62f329bbb8edab89356973773a5648f26751Priti Aghera                return false;
595349e62f329bbb8edab89356973773a5648f26751Priti Aghera            }
596349e62f329bbb8edab89356973773a5648f26751Priti Aghera        }
5970146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
598349e62f329bbb8edab89356973773a5648f26751Priti Aghera        return false;
599349e62f329bbb8edab89356973773a5648f26751Priti Aghera    }
600349e62f329bbb8edab89356973773a5648f26751Priti Aghera
601349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
602349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * Send Get_Report command to the connected HID input device.
603349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
604349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
605349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
606349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param device Remote Bluetooth Device
607349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param reportType Report type
608349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param reportId Report ID
609349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param bufferSize Report receiving buffer size
610349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @return false on immediate error,
611349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *               true otherwise
612349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
613349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
6140146463d70355592da85c3605aaaef4cf0b7335eJack He    public boolean getReport(BluetoothDevice device, byte reportType, byte reportId,
6150146463d70355592da85c3605aaaef4cf0b7335eJack He            int bufferSize) {
6160146463d70355592da85c3605aaaef4cf0b7335eJack He        if (VDBG) {
6170146463d70355592da85c3605aaaef4cf0b7335eJack He            log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId
6180146463d70355592da85c3605aaaef4cf0b7335eJack He                    + "bufferSize=" + bufferSize);
6190146463d70355592da85c3605aaaef4cf0b7335eJack He        }
6200146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
6210146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
622349e62f329bbb8edab89356973773a5648f26751Priti Aghera            try {
6230146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getReport(device, reportType, reportId, bufferSize);
624349e62f329bbb8edab89356973773a5648f26751Priti Aghera            } catch (RemoteException e) {
625349e62f329bbb8edab89356973773a5648f26751Priti Aghera                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
626349e62f329bbb8edab89356973773a5648f26751Priti Aghera                return false;
627349e62f329bbb8edab89356973773a5648f26751Priti Aghera            }
628349e62f329bbb8edab89356973773a5648f26751Priti Aghera        }
6290146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
630349e62f329bbb8edab89356973773a5648f26751Priti Aghera        return false;
631349e62f329bbb8edab89356973773a5648f26751Priti Aghera    }
632349e62f329bbb8edab89356973773a5648f26751Priti Aghera
633349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
634349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * Send Set_Report command to the connected HID input device.
635349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
636349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
637349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
638349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param device Remote Bluetooth Device
639349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param reportType Report type
640349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param report Report receiving buffer size
641349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @return false on immediate error,
642349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *               true otherwise
643349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
644349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
645349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public boolean setReport(BluetoothDevice device, byte reportType, String report) {
6468faffa400b6dea9134f9d419196bf18994f3363dMike J. Chen        if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
6470146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
6480146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
649349e62f329bbb8edab89356973773a5648f26751Priti Aghera            try {
6500146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.setReport(device, reportType, report);
651349e62f329bbb8edab89356973773a5648f26751Priti Aghera            } catch (RemoteException e) {
652349e62f329bbb8edab89356973773a5648f26751Priti Aghera                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
653349e62f329bbb8edab89356973773a5648f26751Priti Aghera                return false;
654349e62f329bbb8edab89356973773a5648f26751Priti Aghera            }
655349e62f329bbb8edab89356973773a5648f26751Priti Aghera        }
6560146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
657349e62f329bbb8edab89356973773a5648f26751Priti Aghera        return false;
658349e62f329bbb8edab89356973773a5648f26751Priti Aghera    }
659349e62f329bbb8edab89356973773a5648f26751Priti Aghera
660349e62f329bbb8edab89356973773a5648f26751Priti Aghera    /**
661349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * Send Send_Data command to the connected HID input device.
662349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
663349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
664349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *
665349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @param device Remote Bluetooth Device
666707fd39f8bac49e216de3bd6f4248ee61d207aecAng Li     * @param report Report to send
667349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @return false on immediate error,
668349e62f329bbb8edab89356973773a5648f26751Priti Aghera     *               true otherwise
669349e62f329bbb8edab89356973773a5648f26751Priti Aghera     * @hide
670349e62f329bbb8edab89356973773a5648f26751Priti Aghera     */
671349e62f329bbb8edab89356973773a5648f26751Priti Aghera    public boolean sendData(BluetoothDevice device, String report) {
672349e62f329bbb8edab89356973773a5648f26751Priti Aghera        if (DBG) log("sendData(" + device + "), report=" + report);
6730146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
6740146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
675349e62f329bbb8edab89356973773a5648f26751Priti Aghera            try {
6760146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.sendData(device, report);
677349e62f329bbb8edab89356973773a5648f26751Priti Aghera            } catch (RemoteException e) {
678349e62f329bbb8edab89356973773a5648f26751Priti Aghera                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
679349e62f329bbb8edab89356973773a5648f26751Priti Aghera                return false;
680349e62f329bbb8edab89356973773a5648f26751Priti Aghera            }
681349e62f329bbb8edab89356973773a5648f26751Priti Aghera        }
6820146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
683349e62f329bbb8edab89356973773a5648f26751Priti Aghera        return false;
684349e62f329bbb8edab89356973773a5648f26751Priti Aghera    }
68556048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta
68656048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    /**
68756048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * Send Get_Idle_Time command to the connected HID input device.
68856048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     *
68956048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
69056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     *
69156048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @param device Remote Bluetooth Device
69256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @return false on immediate error,
69356048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     *               true otherwise
69456048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @hide
69556048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     */
69656048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    public boolean getIdleTime(BluetoothDevice device) {
69756048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        if (DBG) log("getIdletime(" + device + ")");
6980146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
6990146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
70056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta            try {
7010146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.getIdleTime(device);
70256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta            } catch (RemoteException e) {
70356048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
70456048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta                return false;
70556048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta            }
70656048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        }
7070146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
70856048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        return false;
70956048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    }
71056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta
71156048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    /**
71256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * Send Set_Idle_Time command to the connected HID input device.
71356048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     *
71456048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
71556048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     *
71656048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @param device Remote Bluetooth Device
71756048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @param idleTime Idle time to be set on HID Device
71856048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @return false on immediate error,
71956048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     *               true otherwise
72056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     * @hide
72156048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta     */
72256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
72356048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
7240146463d70355592da85c3605aaaef4cf0b7335eJack He        final IBluetoothInputDevice service = mService;
7250146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service != null && isEnabled() && isValidDevice(device)) {
72656048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta            try {
7270146463d70355592da85c3605aaaef4cf0b7335eJack He                return service.setIdleTime(device, idleTime);
72856048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta            } catch (RemoteException e) {
72956048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
73056048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta                return false;
73156048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta            }
73256048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        }
7330146463d70355592da85c3605aaaef4cf0b7335eJack He        if (service == null) Log.w(TAG, "Proxy not attached to service");
73456048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta        return false;
73556048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta    }
73656048c446a54612074e5d89d52cebfa376bd4686Hemant Gupta
737545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    private static void log(String msg) {
7384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh      Log.d(TAG, msg);
739545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    }
740545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh}
741