Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f62c657 authored by Hemant Gupta's avatar Hemant Gupta Committed by Linux Build Service Account
Browse files

HID: Add support for Set Idle and Get Idle commands

This patch adds support for Get Idle and Set Idle command handling
in jni and HidService which will be used to provide interface for
sending thse commands to HID Remote device.

Change-Id: I066d47c022905a39c11d365a9d26d128f94fe2f6
CRs-Fixed: 522511
parent 025c3102
Loading
Loading
Loading
Loading
+74 −3
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@ static jmethodID method_onConnectStateChanged;
static jmethodID method_onGetProtocolMode;
static jmethodID method_onGetProtocolMode;
static jmethodID method_onGetReport;
static jmethodID method_onGetReport;
static jmethodID method_onHandshake;
static jmethodID method_onHandshake;
static jmethodID method_onGetIdleTime;
static jmethodID method_onVirtualUnplug;
static jmethodID method_onVirtualUnplug;


static const bthh_interface_t *sBluetoothHidInterface = NULL;
static const bthh_interface_t *sBluetoothHidInterface = NULL;
@@ -97,6 +98,29 @@ static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_st
    sCallbackEnv->DeleteLocalRef(addr);
    sCallbackEnv->DeleteLocalRef(addr);
}
}


static void get_idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_time) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    if (hh_status != BTHH_OK) {
        ALOGE("BTHH Status is not OK!");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIdleTime, addr, (jint) idle_time);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t *rpt_data, int rpt_size) {
static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t *rpt_data, int rpt_size) {
    jbyteArray addr;
    jbyteArray addr;
    jbyteArray data;
    jbyteArray data;
@@ -187,7 +211,7 @@ static bthh_callbacks_t sBluetoothHidCallbacks = {
    connection_state_callback,
    connection_state_callback,
    NULL,
    NULL,
    get_protocol_mode_callback,
    get_protocol_mode_callback,
    NULL,
    get_idle_time_callback,
    get_report_callback,
    get_report_callback,
    virtual_unplug_callback,
    virtual_unplug_callback,
    handshake_callback
    handshake_callback
@@ -202,9 +226,10 @@ static void classInitNative(JNIEnv* env, jclass clazz) {


    method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged", "([BI)V");
    method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged", "([BI)V");
    method_onGetProtocolMode = env->GetMethodID(clazz, "onGetProtocolMode", "([BI)V");
    method_onGetProtocolMode = env->GetMethodID(clazz, "onGetProtocolMode", "([BI)V");
    method_onGetIdleTime = env->GetMethodID(clazz, "onGetIdleTime", "([BI)V");
    method_onGetReport = env->GetMethodID(clazz, "onGetReport", "([B[BI)V");
    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_onVirtualUnplug = env->GetMethodID(clazz, "onVirtualUnplug", "([BI)V");
    method_onHandshake = env->GetMethodID(clazz, "onHandshake", "([BI)V");


/*
/*
    if ( (btInf = getBluetoothInterface()) == NULL) {
    if ( (btInf = getBluetoothInterface()) == NULL) {
@@ -487,7 +512,7 @@ static jboolean sendDataNative(JNIEnv *env, jobject object, jbyteArray address,
    const char *c_report = env->GetStringUTFChars(report, NULL);
    const char *c_report = env->GetStringUTFChars(report, NULL);
    if ( (status = sBluetoothHidInterface->send_data((bt_bdaddr_t *) addr, (char*) c_report)) !=
    if ( (status = sBluetoothHidInterface->send_data((bt_bdaddr_t *) addr, (char*) c_report)) !=
             BT_STATUS_SUCCESS) {
             BT_STATUS_SUCCESS) {
        ALOGE("Failed set report, status: %d", status);
        ALOGE("Failed send data, status: %d", status);
        ret = JNI_FALSE;
        ret = JNI_FALSE;
    }
    }
    env->ReleaseStringUTFChars(report, c_report);
    env->ReleaseStringUTFChars(report, c_report);
@@ -497,6 +522,50 @@ static jboolean sendDataNative(JNIEnv *env, jobject object, jbyteArray address,


}
}


static jboolean getIdleTimeNative(JNIEnv *env, jobject object, jbyteArray address) {
    bt_status_t status;
    jbyte *addr;
    jboolean ret = JNI_TRUE;
    if (!sBluetoothHidInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        ALOGE("Bluetooth device address null");
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHidInterface->get_idle_time((bt_bdaddr_t *) addr)) !=
         BT_STATUS_SUCCESS) {
        ALOGE("Failed get idle time, status: %d", status);
        ret = JNI_FALSE;
    }
    env->ReleaseByteArrayElements(address, addr, 0);

    return ret;
}

static jboolean setIdleTimeNative(JNIEnv *env, jobject object, jbyteArray address, jbyte idle_time) {
    bt_status_t status;
    jbyte *addr;
    jboolean ret = JNI_TRUE;
    if (!sBluetoothHidInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        ALOGE("Bluetooth device address null");
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHidInterface->set_idle_time((bt_bdaddr_t *) addr, idle_time)) !=
         BT_STATUS_SUCCESS) {
        ALOGE("Failed set idle time, status: %d", status);
        ret = JNI_FALSE;
    }
    env->ReleaseByteArrayElements(address, addr, 0);

    return ret;
}

static JNINativeMethod sMethods[] = {
static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void *) classInitNative},
    {"classInitNative", "()V", (void *) classInitNative},
    {"initializeNative", "()V", (void *) initializeNative},
    {"initializeNative", "()V", (void *) initializeNative},
@@ -509,6 +578,8 @@ static JNINativeMethod sMethods[] = {
    {"getReportNative", "([BBBI)Z", (void *) getReportNative},
    {"getReportNative", "([BBBI)Z", (void *) getReportNative},
    {"setReportNative", "([BBLjava/lang/String;)Z", (void *) setReportNative},
    {"setReportNative", "([BBLjava/lang/String;)Z", (void *) setReportNative},
    {"sendDataNative", "([BLjava/lang/String;)Z", (void *) sendDataNative},
    {"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)
int register_com_android_bluetooth_hid(JNIEnv* env)
+87 −1
Original line number Original line Diff line number Diff line
@@ -68,6 +68,9 @@ public class HidService extends ProfileService {
    private static final int MESSAGE_SEND_DATA = 11;
    private static final int MESSAGE_SEND_DATA = 11;
    private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12;
    private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12;
    private static final int MESSAGE_ON_HANDSHAKE = 13;
    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 {
    static {
        classInitNative();
        classInitNative();
@@ -285,6 +288,31 @@ public class HidService extends ProfileService {
                    broadcastVirtualUnplugStatus(device, status);
                    broadcastVirtualUnplugStatus(device, status);
                }
                }
                break;
                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;
            }
            }
        }
        }
    };
    };
@@ -392,6 +420,18 @@ public class HidService extends ProfileService {
            if (service == null) return false;
            if (service == null) return false;
            return service.sendData(device, report);
            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
    //APIs
@@ -555,6 +595,34 @@ public class HidService extends ProfileService {
        return true ;*/
        return true ;*/
    }
    }


    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) {
    private void onGetProtocolMode(byte[] address, int mode) {
        Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE);
        Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE);
        msg.obj = address;
        msg.obj = address;
@@ -562,6 +630,13 @@ public class HidService extends ProfileService {
        mHandler.sendMessage(msg);
        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) {
    private void onGetReport(byte[] address, byte[] report, int rpt_size) {
        Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_REPORT);
        Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_REPORT);
        msg.obj = address;
        msg.obj = address;
@@ -652,6 +727,15 @@ public class HidService extends ProfileService {
        sendBroadcast(intent, BLUETOOTH_PERM);
        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) {
    private boolean okToConnect(BluetoothDevice device) {
        AdapterService adapterService = AdapterService.getAdapterService();
        AdapterService adapterService = AdapterService.getAdapterService();
        //check if it is inbound connection in Quiet mode, priority and Bond status
        //check if it is inbound connection in Quiet mode, priority and Bond status
@@ -698,4 +782,6 @@ public class HidService extends ProfileService {
    private native boolean getReportNative(byte[]btAddress, byte reportType, byte reportId, int bufferSize);
    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 setReportNative(byte[] btAddress, byte reportType, String report);
    private native boolean sendDataNative(byte[] btAddress, String report);
    private native boolean sendDataNative(byte[] btAddress, String report);
    private native boolean setIdleTimeNative(byte[] btAddress, byte idleTime);
    private native boolean getIdleTimeNative(byte[] btAddress);
}
}