summaryrefslogtreecommitdiff
authoryongguang.hong <yongguang.hong@amlogic.com>2018-03-16 01:25:25 (GMT)
committer jie.yuan <jie.yuan@amlogic.com>2018-03-27 09:01:03 (GMT)
commitfc311a56bb7e7f2cc86e01a8aa389fb7e3f56343 (patch)
tree70ef9fa8c539bebe02e45f7717a5fb6008fee119
parente818c085daa1f937529c3c0196e8131f85bffe0f (diff)
downloadampere-fc311a56bb7e7f2cc86e01a8aa389fb7e3f56343.zip
ampere-fc311a56bb7e7f2cc86e01a8aa389fb7e3f56343.tar.gz
ampere-fc311a56bb7e7f2cc86e01a8aa389fb7e3f56343.tar.bz2
wifi/bt: use short key for RC voice control [1/3]
PD#157669 Change-Id: I178a4442e355de41fcaafdb763f8ef59fb44c955
Diffstat
-rw-r--r--frameworks/core/jni/Android.mk34
-rw-r--r--frameworks/core/jni/droid_logic_RemoteControl.cpp256
-rw-r--r--frameworks/core/res/Android.mk6
-rw-r--r--frameworks/core/res/src/com/droidlogic/DialogBluetoothService.java60
4 files changed, 333 insertions, 23 deletions
diff --git a/frameworks/core/jni/Android.mk b/frameworks/core/jni/Android.mk
index 1d64600..e1b8ac2 100644
--- a/frameworks/core/jni/Android.mk
+++ b/frameworks/core/jni/Android.mk
@@ -1,5 +1,6 @@
LOCAL_PATH:= $(call my-dir)
+ifeq ($(SUPPORT_HDMIIN),true)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -18,8 +19,8 @@ LOCAL_C_INCLUDES += \
external/skia/include/core \
libcore/include \
libcore/include/libsuspend \
- $(call include-path-for, libhardware)/hardware \
- $(call include-path-for, libhardware_legacy)/hardware_legacy
+ $(call include-path-for, libhardware)/hardware \
+ $(call include-path-for, libhardware_legacy)/hardware_legacy
ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny)
LOCAL_C_INCLUDES += external/tinyalsa/include
@@ -61,10 +62,12 @@ endif
include $(BUILD_SHARED_LIBRARY)
+endif
+
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- droid_logic_DisplaySetting.cpp
+ droid_logic_DisplaySetting.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
@@ -113,4 +116,29 @@ endif
include $(BUILD_SHARED_LIBRARY)
+
+########### build libremotecontrol
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ droid_logic_RemoteControl.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_MODULE := libremotecontrol_jni
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libgui \
+ libnativehelper \
+ libandroid_runtime
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
include $(LOCAL_PATH)/hdmi_cec/Android.mk
diff --git a/frameworks/core/jni/droid_logic_RemoteControl.cpp b/frameworks/core/jni/droid_logic_RemoteControl.cpp
new file mode 100644
index 0000000..4cd5e22
--- a/dev/null
+++ b/frameworks/core/jni/droid_logic_RemoteControl.cpp
@@ -0,0 +1,256 @@
+//#define LOG_NDEBUG 0
+#define LOG_TAG "remotecontrol_jni"
+
+#include <jni.h>
+#include <JNIHelp.h>
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <pthread.h>
+
+#include <unistd.h>
+#include <utils/Log.h>
+#include "utils/misc.h"
+#include "android_runtime/AndroidRuntime.h"
+
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+static JNIEnv* callbackEnv = NULL;// jni env
+static jobject sJniObj = NULL;
+static jmethodID method_onSearchStateChanged;
+
+
+#define REMOTE_CONTROL_SOCKET_PATH "/data/misc/bluedroid/.rc_ctrl"
+
+typedef struct {
+ pthread_t tid; //main thread id
+ int server_fd;
+ int client_fd;
+ int max_fd;
+ int signal_fds[2];
+ fd_set active_set;
+}tMain_IPC;
+
+tMain_IPC g_mainIPC;
+static int uipc_init(void);
+static void uipc_deinit(void);
+
+namespace android
+{
+ static void classInitNative(JNIEnv* env, jclass clazz) {
+ ALOGI("%s", __func__);
+
+ //jclass jniCallbackClass = env->FindClass("com/droidlogic/DialogBluetoothService");
+ method_onSearchStateChanged = env->GetMethodID(clazz, "searchStateChanged", "(I)V");
+ }
+
+ static bool initNative(JNIEnv* env, jobject obj) {
+ ALOGI("%s", __func__);
+ sJniObj = env->NewGlobalRef(obj);
+
+ uipc_init();
+
+ return JNI_TRUE;
+ }
+
+ static void setMicEnableCallback(int flag) {
+ ALOGI("%s: flag is: %d", __func__, flag);
+ callbackEnv->CallVoidMethod(sJniObj, method_onSearchStateChanged, (jint)flag);
+ }
+
+ static bool cleanupNative(JNIEnv *env, jobject obj) {
+ env->DeleteGlobalRef(sJniObj);
+ uipc_deinit();
+ return JNI_TRUE;
+ }
+
+ static JNINativeMethod sMethods[] = {
+ {"classInitNative", "()V", (void *) classInitNative},
+ {"initNative", "()Z", (void *) initNative},
+ {"cleanupNative", "()Z", (void*) cleanupNative},
+ };
+
+
+ int register_android_RemoteControl(JNIEnv* env) {
+ ALOGI("%s: ++", __func__);
+ return jniRegisterNativeMethods(env, "com/droidlogic/DialogBluetoothService",
+ sMethods, NELEM(sMethods));
+ }
+} // end namespace android
+
+using namespace android;
+
+static void *listen_task(void *arg) {
+ int ret;
+ fd_set read_fds;
+ char sig_recv = 0;
+ ssize_t readlen = 0;
+
+ ALOGI("%s:main thread run...", __func__);
+
+ //attach java
+ JavaVM* vm = AndroidRuntime::getJavaVM();
+ JavaVMAttachArgs args;
+ char name[] = "Remote control service Callback Thread";
+ args.version = JNI_VERSION_1_4;
+ args.name = name;
+ args.group = NULL;
+ vm->AttachCurrentThread(&callbackEnv, &args);
+
+ while (1) {
+ read_fds = g_mainIPC.active_set;
+ ret = select(g_mainIPC.max_fd + 1, &read_fds, NULL, NULL, NULL);
+ ALOGI("%s:interrupt done, err=%d", __func__, errno);
+ if (ret == -1 && errno == EINTR) continue;
+ if (FD_ISSET(g_mainIPC.signal_fds[0], &read_fds)) {
+ //wakeup interrupt
+ readlen = recv(g_mainIPC.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ if (ret == -1 && errno == EINTR) continue;
+ if (sig_recv == 0) break;
+ }
+ else if (FD_ISSET(g_mainIPC.server_fd, &read_fds)) {
+ //client connect
+ struct sockaddr_un remote;
+ socklen_t len = sizeof(struct sockaddr_un);
+ g_mainIPC.client_fd = accept(g_mainIPC.server_fd, (struct sockaddr *)&remote, &len);
+ if (g_mainIPC.client_fd > 0) {
+ FD_SET(g_mainIPC.client_fd, &g_mainIPC.active_set);
+ g_mainIPC.max_fd = MAX(g_mainIPC.max_fd, g_mainIPC.client_fd);
+ }
+
+ }
+ else if (FD_ISSET(g_mainIPC.client_fd, &read_fds)) {
+ //read data
+ readlen = recv(g_mainIPC.client_fd, &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ ALOGI("%s:rx readlen=%d, err=%d", __func__, readlen, errno);
+ if (readlen == 1 && errno == 0) {
+ setMicEnableCallback((int)sig_recv);
+ }
+ else if (errno != EINTR) {
+ FD_CLR(g_mainIPC.client_fd, &g_mainIPC.active_set);
+ }
+ }
+
+ }
+
+ //detach java
+ vm->DetachCurrentThread();
+
+ //cleanup
+ close(g_mainIPC.signal_fds[0]);
+ close(g_mainIPC.signal_fds[1]);
+ close(g_mainIPC.client_fd);
+ close(g_mainIPC.server_fd);
+ FD_ZERO(&g_mainIPC.active_set);
+
+ return NULL;
+}
+
+
+static int create_server_socket(const char *name) {
+ struct sockaddr_un addr;
+ socklen_t alen;
+ int err, n = 1;
+ size_t namelen;
+ int s = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (s < 0) return -1;
+
+ memset(&addr, 0, sizeof(addr));
+ namelen = strlen(name);
+ if ((namelen + 1) > sizeof(addr.sun_path))
+ return -1;
+
+ /*
+ * Note: The path in this case is *not* supposed to be
+ * '\0'-terminated. ("man 7 unix" for the gory details.)
+ */
+ addr.sun_path[0] = 0;
+ memcpy(addr.sun_path + 1, name, namelen);
+ addr.sun_family = AF_LOCAL;
+ alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ if (bind(s, (struct sockaddr *)&addr, alen) < 0) {
+ ALOGE("bind failed:%d", errno);
+ return -1;
+ }
+
+ if (listen(s, 5) < 0) {
+ ALOGE("listen failed:%d", errno);
+ return -1;
+ }
+
+ ALOGI("%s: socket=%d", __func__, s);
+
+ return s;
+}
+
+pthread_t create_listen_thread() {
+ pthread_t tid;
+
+ if (pthread_create(&tid, (const pthread_attr_t *) NULL, listen_task, NULL) < 0)
+ {
+ ALOGE("create_listen_thread pthread_create failed:%d", errno);
+ return -1;
+ }
+
+ return tid;
+}
+
+static int uipc_init(void) {
+ ALOGI("%s: ++", __func__);
+
+ memset(&g_mainIPC, 0, sizeof(g_mainIPC));
+
+ FD_ZERO(&g_mainIPC.active_set);
+
+ /* setup interrupt socket pair */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_mainIPC.signal_fds) < 0) {
+ return -1;
+ }
+ FD_SET(g_mainIPC.signal_fds[0], &g_mainIPC.active_set);
+ g_mainIPC.max_fd = MAX(g_mainIPC.max_fd, g_mainIPC.signal_fds[0]);
+
+ //create server socket
+ g_mainIPC.server_fd = create_server_socket(REMOTE_CONTROL_SOCKET_PATH);
+ FD_SET(g_mainIPC.server_fd, &g_mainIPC.active_set);
+ g_mainIPC.max_fd = MAX(g_mainIPC.max_fd, g_mainIPC.server_fd);
+
+ g_mainIPC.tid = create_listen_thread();
+
+ return 0;
+}
+
+static void uipc_deinit(void) {
+ //exit thread
+ if (g_mainIPC.signal_fds[1] > 0) {
+ char sig_off = 0;
+ send(g_mainIPC.signal_fds[1], &sig_off, sizeof(sig_off), MSG_NOSIGNAL);
+ }
+ if (g_mainIPC.tid) pthread_join(g_mainIPC.tid, NULL);
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ ALOGI("%s: ++", __func__);
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ ALOGE("GetEnv failed!");
+ return result;
+ }
+
+ register_android_RemoteControl(env);
+
+ return JNI_VERSION_1_4;
+}
+
diff --git a/frameworks/core/res/Android.mk b/frameworks/core/res/Android.mk
index ff4caa1..96959ce 100644
--- a/frameworks/core/res/Android.mk
+++ b/frameworks/core/res/Android.mk
@@ -4,10 +4,10 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_JAVA_LIBRARIES := droidlogic \
- android.hidl.manager-V1.0-java
-
+ android.hidl.manager-V1.0-java
+LOCAL_JNI_SHARED_LIBRARIES := libremotecontrol_jni
LOCAL_STATIC_JAVA_LIBRARIES := android.hidl.base-V1.0-java-static \
- vendor.amlogic.hardware.droidvold-V1.0-java
+ vendor.amlogic.hardware.droidvold-V1.0-java
#LOCAL_SDK_VERSION := current
diff --git a/frameworks/core/res/src/com/droidlogic/DialogBluetoothService.java b/frameworks/core/res/src/com/droidlogic/DialogBluetoothService.java
index 3a46da6..d49d436 100644
--- a/frameworks/core/res/src/com/droidlogic/DialogBluetoothService.java
+++ b/frameworks/core/res/src/com/droidlogic/DialogBluetoothService.java
@@ -75,6 +75,8 @@ public class DialogBluetoothService extends Service {
"DA14582 IR&M&VRemote",
"DA1458x RCU",
"RemoteB008",
+ "Amlogic_RC16",
+ "Amlogic_RC18"
};
// Time to wait before connecting to bonded devices
@@ -113,13 +115,13 @@ public class DialogBluetoothService extends Service {
private static final UUID CLIENT_CONFIG_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
// Ble Remote HID Report Characteristic instance IDs (Audio)
- private static final int HID_STREAM_ENABLE_WRITE_INSTANCE = 59;
- private static final int HID_STREAM_ENABLE_READ_INSTANCE = 62;
- private static final int HID_STREAM_DATA_MIN_INSTANCE = 66;
- private static final int HID_STREAM_DATA_MAX_INSTANCE = 74;
- private static final int HID_STREAM_DATA_REP5_INSTANCE = 66;
- private static final int HID_STREAM_DATA_REP6_INSTANCE = 70;
- private static final int HID_STREAM_DATA_REP7_INSTANCE = 74;
+ private static final int HID_STREAM_ENABLE_WRITE_INSTANCE = 65;//59; hugo modify for huitong rc;
+ private static final int HID_STREAM_ENABLE_READ_INSTANCE = 61;//62;
+ private static final int HID_STREAM_DATA_MIN_INSTANCE = 41;//66;
+ private static final int HID_STREAM_DATA_MAX_INSTANCE = 45;//74;
+ private static final int HID_STREAM_DATA_REP5_INSTANCE = 53;//66;
+ private static final int HID_STREAM_DATA_REP6_INSTANCE = 57;//70;
+ private static final int HID_STREAM_DATA_REP7_INSTANCE = 49;//74;
// Data
private BluetoothManager mBluetoothManager;
@@ -137,6 +139,11 @@ public class DialogBluetoothService extends Service {
private AudioManager mAudioManager;
private int connectedState = 0;
+ static {
+ System.loadLibrary("remotecontrol_jni");
+ classInitNative();
+ }
+
/**
* Used in order for the service to be notified about HID devices connection and bond state.
*/
@@ -294,6 +301,8 @@ public class DialogBluetoothService extends Service {
filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
registerReceiver(receiver, filter);
+ initNative();
+
// On service start, check for supported devices
connectToBondedDevices();
}
@@ -304,6 +313,7 @@ public class DialogBluetoothService extends Service {
mHandler.removeCallbacksAndMessages(null);
unregisterReceiver(receiver);
close();
+ cleanupNative();
}
@Override
@@ -403,11 +413,14 @@ public class DialogBluetoothService extends Service {
*/
public void close() {
Log.w(TAG, "Close called!");
- if (mBluetoothGatt == null) {
- return;
+ if (mBluetoothGatt != null) {
+ mBluetoothGatt.close();
}
- mBluetoothGatt.close();
mBluetoothGatt = null;
+ enableCharacteristic = null;
+ rep5Characteristic = null;
+ rep6Characteristic = null;
+ rep7Characteristic = null;
}
@@ -420,16 +433,17 @@ public class DialogBluetoothService extends Service {
return;
Log.i(TAG,"Write Enable: " + flag);
+ /* masked by hugo
if (flag != 0) {
showToast(AUDIO_STREAM_TEXT_ON);
broadcastUpdate(ACTION_AUDIO_TRANSFER, AUDIO_STREAM_TEXT_ON);
} else {
showToast(AUDIO_STREAM_TEXT_OFF);
broadcastUpdate(ACTION_AUDIO_TRANSFER, AUDIO_STREAM_TEXT_OFF);
- }
+ }*/
prevInstance = 0;
- byte packet[] = new byte[20];
+ byte packet[] = new byte[1];
packet[0] = (byte) flag;
enableCharacteristic.setValue(packet);
mBluetoothGatt.writeCharacteristic(enableCharacteristic);
@@ -515,11 +529,14 @@ public class DialogBluetoothService extends Service {
// Possible audio button report
else if ((HID_REPORT_CHAR.compareTo(characteristic.getUuid()) == 0) && (instance == HID_STREAM_ENABLE_READ_INSTANCE)) {
byte[] value = characteristic.getValue();
- Log.i(TAG,"Enable char "+String.format("%x %x", value[0]&0xff, value[1]&0xff));
- int type = value[1];
- if (type == 0) {
- // got enable/disable
- sendEnable(value[0] != 0 ? 1 : 0);
+ Log.i(TAG,"rx key: "+ String.format("%x %x", value[0], value[1]));
+ if (value[0] == 0x21 && value[1] == 0x02) {
+ Log.i(TAG,"enable RC MIC ");
+ //sendEnable(0x01);
+ }
+ else if (value[0] == 0x42 && value[1] == 0x00) {
+ Log.i(TAG,"disable RC MIC ");
+ //sendEnable(0x00);
}
}
}
@@ -633,6 +650,12 @@ public class DialogBluetoothService extends Service {
};
+ void searchStateChanged(int status) {
+ Log.i(TAG,"state=" + status);
+ sendEnable(status == 0 ? 0 : 1);
+ }
+
+
/*****
* broadcastUpdate functions to send data back to BleActivity
*/
@@ -663,4 +686,7 @@ public class DialogBluetoothService extends Service {
});
}
+ private native static void classInitNative();
+ private native boolean initNative();
+ private native boolean cleanupNative();
}