Loading android/app/jni/com_android_bluetooth_hid.cpp +59 −2 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ static jmethodID method_onGetProtocolMode; static jmethodID method_onGetReport; static jmethodID method_onHandshake; static jmethodID method_onVirtualUnplug; static jmethodID method_onGetIdleTime; static const bthh_interface_t* sBluetoothHidInterface = NULL; static jobject mCallbacksObj = NULL; Loading Loading @@ -157,12 +158,26 @@ static void handshake_callback(bt_bdaddr_t* bd_addr, bthh_status_t hh_status) { (jint)hh_status); } static void get_idle_time_callback(bt_bdaddr_t* bd_addr, bthh_status_t hh_status, int idle_time) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { ALOGE("%s: Fail to new jbyteArray bd addr", __func__); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIdleTime, addr.get(), (jint)idle_time); } static bthh_callbacks_t sBluetoothHidCallbacks = { sizeof(sBluetoothHidCallbacks), connection_state_callback, NULL, get_protocol_mode_callback, NULL, get_idle_time_callback, get_report_callback, virtual_unplug_callback, handshake_callback}; Loading @@ -177,6 +192,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_onGetReport = env->GetMethodID(clazz, "onGetReport", "([B[BI)V"); method_onHandshake = env->GetMethodID(clazz, "onHandshake", "([BI)V"); method_onVirtualUnplug = env->GetMethodID(clazz, "onVirtualUnplug", "([BI)V"); method_onGetIdleTime = env->GetMethodID(clazz, "onGetIdleTime", "([BI)V"); ALOGI("%s: succeeds", __func__); } Loading Loading @@ -434,7 +450,7 @@ static jboolean sendDataNative(JNIEnv* env, jobject object, jbyteArray address, bt_status_t status = sBluetoothHidInterface->send_data((bt_bdaddr_t*)addr, (char*)c_report); if (status != BT_STATUS_SUCCESS) { ALOGE("Failed set report, status: %d", status); ALOGE("Failed set data, status: %d", status); ret = JNI_FALSE; } env->ReleaseStringUTFChars(report, c_report); Loading @@ -443,6 +459,45 @@ static jboolean sendDataNative(JNIEnv* env, jobject object, jbyteArray address, return ret; } static jboolean getIdleTimeNative(JNIEnv* env, jobject object, jbyteArray address) { if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { ALOGE("%s: Bluetooth device address null", __func__); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->get_idle_time((bt_bdaddr_t*)addr); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed get idle time, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE; } static jboolean setIdleTimeNative(JNIEnv* env, jobject object, jbyteArray address, jbyte idle_time) { if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { ALOGE("%s: Bluetooth device address null", __func__); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->set_idle_time( (bt_bdaddr_t*)addr, idle_time); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed set idle time, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE; } static JNINativeMethod sMethods[] = { {"classInitNative", "()V", (void*)classInitNative}, {"initializeNative", "()V", (void*)initializeNative}, Loading @@ -455,6 +510,8 @@ static JNINativeMethod sMethods[] = { {"getReportNative", "([BBBI)Z", (void*)getReportNative}, {"setReportNative", "([BBLjava/lang/String;)Z", (void*)setReportNative}, {"sendDataNative", "([BLjava/lang/String;)Z", (void*)sendDataNative}, {"getIdleTimeNative", "([B)Z", (void*)getIdleTimeNative}, {"setIdleTimeNative", "([BB)Z", (void*)setIdleTimeNative}, }; int register_com_android_bluetooth_hid(JNIEnv* env) { Loading android/app/src/com/android/bluetooth/hid/HidService.java 100755 → 100644 +78 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public class HidService extends ProfileService { private static final int MESSAGE_SEND_DATA = 11; private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12; private static final int MESSAGE_ON_HANDSHAKE = 13; private static final int MESSAGE_GET_IDLE_TIME = 14; private static final int MESSAGE_ON_GET_IDLE_TIME = 15; private static final int MESSAGE_SET_IDLE_TIME = 16; static { classInitNative(); Loading Loading @@ -287,6 +290,25 @@ public class HidService extends ProfileService { broadcastVirtualUnplugStatus(device, status); } break; case MESSAGE_GET_IDLE_TIME: { BluetoothDevice device = (BluetoothDevice) msg.obj; if (!getIdleTimeNative(Utils.getByteAddress(device))) { Log.e(TAG, "Error: get idle time native returns false"); } } break; case MESSAGE_ON_GET_IDLE_TIME: { BluetoothDevice device = getDevice((byte[]) msg.obj); int idleTime = msg.arg1; broadcastIdleTime(device, idleTime); } break; case MESSAGE_SET_IDLE_TIME: { BluetoothDevice device = (BluetoothDevice) msg.obj; Bundle data = msg.getData(); byte idleTime = data.getByte(BluetoothInputDevice.EXTRA_IDLE_TIME); if (!setIdleTimeNative(Utils.getByteAddress(device), idleTime)) { Log.e(TAG, "Error: get idle time native returns false"); } } break; } } }; Loading Loading @@ -394,6 +416,18 @@ public class HidService extends ProfileService { if (service == null) return false; return service.sendData(device, report); } public boolean setIdleTime(BluetoothDevice device, byte idleTime) { HidService service = getService(); if (service == null) return false; return service.setIdleTime(device, idleTime); } public boolean getIdleTime(BluetoothDevice device) { HidService service = getService(); if (service == null) return false; return service.getIdleTime(device); } }; //APIs Loading Loading @@ -550,6 +584,32 @@ public class HidService extends ProfileService { return sendDataNative(Utils.getByteAddress(device), report); } boolean getIdleTime(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int state = this.getConnectionState(device); if (state != BluetoothInputDevice.STATE_CONNECTED) { return false; } Message msg = mHandler.obtainMessage(MESSAGE_GET_IDLE_TIME, device); mHandler.sendMessage(msg); return true; } boolean setIdleTime(BluetoothDevice device, byte idleTime) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int state = this.getConnectionState(device); if (state != BluetoothInputDevice.STATE_CONNECTED) { return false; } Message msg = mHandler.obtainMessage(MESSAGE_SET_IDLE_TIME); msg.obj = device; Bundle data = new Bundle(); data.putByte(BluetoothInputDevice.EXTRA_IDLE_TIME, idleTime); msg.setData(data); mHandler.sendMessage(msg); return true; } private void onGetProtocolMode(byte[] address, int mode) { Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE); msg.obj = address; Loading @@ -557,6 +617,13 @@ public class HidService extends ProfileService { mHandler.sendMessage(msg); } private void onGetIdleTime(byte[] address, int idleTime) { Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_IDLE_TIME); msg.obj = address; msg.arg1 = idleTime; mHandler.sendMessage(msg); } private void onGetReport(byte[] address, byte[] report, int rpt_size) { Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_REPORT); msg.obj = address; Loading Loading @@ -645,6 +712,15 @@ public class HidService extends ProfileService { sendBroadcast(intent, BLUETOOTH_PERM); } private void broadcastIdleTime(BluetoothDevice device, int idleTime) { Intent intent = new Intent(BluetoothInputDevice.ACTION_IDLE_TIME_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothInputDevice.EXTRA_IDLE_TIME, idleTime); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); sendBroadcast(intent, BLUETOOTH_PERM); if (DBG) log("Idle time (" + device + "): " + idleTime); } private boolean okToConnect(BluetoothDevice device) { AdapterService adapterService = AdapterService.getAdapterService(); //check if it is inbound connection in Quiet mode, priority and Bond status Loading Loading @@ -701,4 +777,6 @@ public class HidService extends ProfileService { private native boolean getReportNative(byte[]btAddress, byte reportType, byte reportId, int bufferSize); private native boolean setReportNative(byte[] btAddress, byte reportType, String report); private native boolean sendDataNative(byte[] btAddress, String report); private native boolean setIdleTimeNative(byte[] btAddress, byte idleTime); private native boolean getIdleTimeNative(byte[] btAddress); } Loading
android/app/jni/com_android_bluetooth_hid.cpp +59 −2 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ static jmethodID method_onGetProtocolMode; static jmethodID method_onGetReport; static jmethodID method_onHandshake; static jmethodID method_onVirtualUnplug; static jmethodID method_onGetIdleTime; static const bthh_interface_t* sBluetoothHidInterface = NULL; static jobject mCallbacksObj = NULL; Loading Loading @@ -157,12 +158,26 @@ static void handshake_callback(bt_bdaddr_t* bd_addr, bthh_status_t hh_status) { (jint)hh_status); } static void get_idle_time_callback(bt_bdaddr_t* bd_addr, bthh_status_t hh_status, int idle_time) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { ALOGE("%s: Fail to new jbyteArray bd addr", __func__); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIdleTime, addr.get(), (jint)idle_time); } static bthh_callbacks_t sBluetoothHidCallbacks = { sizeof(sBluetoothHidCallbacks), connection_state_callback, NULL, get_protocol_mode_callback, NULL, get_idle_time_callback, get_report_callback, virtual_unplug_callback, handshake_callback}; Loading @@ -177,6 +192,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_onGetReport = env->GetMethodID(clazz, "onGetReport", "([B[BI)V"); method_onHandshake = env->GetMethodID(clazz, "onHandshake", "([BI)V"); method_onVirtualUnplug = env->GetMethodID(clazz, "onVirtualUnplug", "([BI)V"); method_onGetIdleTime = env->GetMethodID(clazz, "onGetIdleTime", "([BI)V"); ALOGI("%s: succeeds", __func__); } Loading Loading @@ -434,7 +450,7 @@ static jboolean sendDataNative(JNIEnv* env, jobject object, jbyteArray address, bt_status_t status = sBluetoothHidInterface->send_data((bt_bdaddr_t*)addr, (char*)c_report); if (status != BT_STATUS_SUCCESS) { ALOGE("Failed set report, status: %d", status); ALOGE("Failed set data, status: %d", status); ret = JNI_FALSE; } env->ReleaseStringUTFChars(report, c_report); Loading @@ -443,6 +459,45 @@ static jboolean sendDataNative(JNIEnv* env, jobject object, jbyteArray address, return ret; } static jboolean getIdleTimeNative(JNIEnv* env, jobject object, jbyteArray address) { if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { ALOGE("%s: Bluetooth device address null", __func__); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->get_idle_time((bt_bdaddr_t*)addr); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed get idle time, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE; } static jboolean setIdleTimeNative(JNIEnv* env, jobject object, jbyteArray address, jbyte idle_time) { if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { ALOGE("%s: Bluetooth device address null", __func__); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->set_idle_time( (bt_bdaddr_t*)addr, idle_time); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed set idle time, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE; } static JNINativeMethod sMethods[] = { {"classInitNative", "()V", (void*)classInitNative}, {"initializeNative", "()V", (void*)initializeNative}, Loading @@ -455,6 +510,8 @@ static JNINativeMethod sMethods[] = { {"getReportNative", "([BBBI)Z", (void*)getReportNative}, {"setReportNative", "([BBLjava/lang/String;)Z", (void*)setReportNative}, {"sendDataNative", "([BLjava/lang/String;)Z", (void*)sendDataNative}, {"getIdleTimeNative", "([B)Z", (void*)getIdleTimeNative}, {"setIdleTimeNative", "([BB)Z", (void*)setIdleTimeNative}, }; int register_com_android_bluetooth_hid(JNIEnv* env) { Loading
android/app/src/com/android/bluetooth/hid/HidService.java 100755 → 100644 +78 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public class HidService extends ProfileService { private static final int MESSAGE_SEND_DATA = 11; private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12; private static final int MESSAGE_ON_HANDSHAKE = 13; private static final int MESSAGE_GET_IDLE_TIME = 14; private static final int MESSAGE_ON_GET_IDLE_TIME = 15; private static final int MESSAGE_SET_IDLE_TIME = 16; static { classInitNative(); Loading Loading @@ -287,6 +290,25 @@ public class HidService extends ProfileService { broadcastVirtualUnplugStatus(device, status); } break; case MESSAGE_GET_IDLE_TIME: { BluetoothDevice device = (BluetoothDevice) msg.obj; if (!getIdleTimeNative(Utils.getByteAddress(device))) { Log.e(TAG, "Error: get idle time native returns false"); } } break; case MESSAGE_ON_GET_IDLE_TIME: { BluetoothDevice device = getDevice((byte[]) msg.obj); int idleTime = msg.arg1; broadcastIdleTime(device, idleTime); } break; case MESSAGE_SET_IDLE_TIME: { BluetoothDevice device = (BluetoothDevice) msg.obj; Bundle data = msg.getData(); byte idleTime = data.getByte(BluetoothInputDevice.EXTRA_IDLE_TIME); if (!setIdleTimeNative(Utils.getByteAddress(device), idleTime)) { Log.e(TAG, "Error: get idle time native returns false"); } } break; } } }; Loading Loading @@ -394,6 +416,18 @@ public class HidService extends ProfileService { if (service == null) return false; return service.sendData(device, report); } public boolean setIdleTime(BluetoothDevice device, byte idleTime) { HidService service = getService(); if (service == null) return false; return service.setIdleTime(device, idleTime); } public boolean getIdleTime(BluetoothDevice device) { HidService service = getService(); if (service == null) return false; return service.getIdleTime(device); } }; //APIs Loading Loading @@ -550,6 +584,32 @@ public class HidService extends ProfileService { return sendDataNative(Utils.getByteAddress(device), report); } boolean getIdleTime(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int state = this.getConnectionState(device); if (state != BluetoothInputDevice.STATE_CONNECTED) { return false; } Message msg = mHandler.obtainMessage(MESSAGE_GET_IDLE_TIME, device); mHandler.sendMessage(msg); return true; } boolean setIdleTime(BluetoothDevice device, byte idleTime) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int state = this.getConnectionState(device); if (state != BluetoothInputDevice.STATE_CONNECTED) { return false; } Message msg = mHandler.obtainMessage(MESSAGE_SET_IDLE_TIME); msg.obj = device; Bundle data = new Bundle(); data.putByte(BluetoothInputDevice.EXTRA_IDLE_TIME, idleTime); msg.setData(data); mHandler.sendMessage(msg); return true; } private void onGetProtocolMode(byte[] address, int mode) { Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE); msg.obj = address; Loading @@ -557,6 +617,13 @@ public class HidService extends ProfileService { mHandler.sendMessage(msg); } private void onGetIdleTime(byte[] address, int idleTime) { Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_IDLE_TIME); msg.obj = address; msg.arg1 = idleTime; mHandler.sendMessage(msg); } private void onGetReport(byte[] address, byte[] report, int rpt_size) { Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_REPORT); msg.obj = address; Loading Loading @@ -645,6 +712,15 @@ public class HidService extends ProfileService { sendBroadcast(intent, BLUETOOTH_PERM); } private void broadcastIdleTime(BluetoothDevice device, int idleTime) { Intent intent = new Intent(BluetoothInputDevice.ACTION_IDLE_TIME_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothInputDevice.EXTRA_IDLE_TIME, idleTime); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); sendBroadcast(intent, BLUETOOTH_PERM); if (DBG) log("Idle time (" + device + "): " + idleTime); } private boolean okToConnect(BluetoothDevice device) { AdapterService adapterService = AdapterService.getAdapterService(); //check if it is inbound connection in Quiet mode, priority and Bond status Loading Loading @@ -701,4 +777,6 @@ public class HidService extends ProfileService { private native boolean getReportNative(byte[]btAddress, byte reportType, byte reportId, int bufferSize); private native boolean setReportNative(byte[] btAddress, byte reportType, String report); private native boolean sendDataNative(byte[] btAddress, String report); private native boolean setIdleTimeNative(byte[] btAddress, byte idleTime); private native boolean getIdleTimeNative(byte[] btAddress); }