From 975216788e686afd0ad8779d036b55f415606b32 Mon Sep 17 00:00:00 2001 From: ahs Date: Fri, 10 Jun 2022 14:57:09 +0530 Subject: [PATCH] grpc impl for AppStatus and notification sync Signed-off-by: ahs --- .../ClipboardAgent/AndroidManifest.xml | 8 + penguinpeak/ClipboardAgent/jni/Android.bp | 91 ++++- .../ClipboardAgent/jni/DispatchHelper.cpp | 150 ++----- .../ClipboardAgent/jni/DispatchHelper.h | 4 +- .../ClipboardAgent/jni/VsockMsgDispatcher.cpp | 368 ------------------ .../ClipboardAgent/jni/VsockMsgDispatcher.h | 173 -------- penguinpeak/ClipboardAgent/jni/adapter.cpp | 197 ++++++++++ penguinpeak/ClipboardAgent/jni/adapter.h | 116 ++++++ penguinpeak/ClipboardAgent/jni/appstatus.cpp | 33 ++ .../ClipboardAgent/jni/notification.cpp | 39 ++ .../jni/proto/appstatus-protogen.inp | 11 + .../ClipboardAgent/jni/proto/appstatus.proto | 12 + .../jni/proto/notification-protogen.inp | 11 + .../jni/proto/notification.proto | 15 + .../intel/clipboardagent/AppStatusData.java | 5 + .../clipboardagent/AppstatusComponent.java | 78 ++-- .../intel/clipboardagent/ClipboardAgent.java | 3 +- .../intel/clipboardagent/DispatchHelper.java | 2 +- .../clipboardagent/GuestVsockCommService.java | 1 + .../clipboardagent/NotificationComponent.java | 86 ++++ .../clipboardagent/NotificationData.java | 9 + .../clipboardagent/NotificationListener.java | 73 ++++ 22 files changed, 776 insertions(+), 709 deletions(-) delete mode 100755 penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.cpp delete mode 100755 penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.h create mode 100644 penguinpeak/ClipboardAgent/jni/adapter.cpp create mode 100644 penguinpeak/ClipboardAgent/jni/adapter.h create mode 100644 penguinpeak/ClipboardAgent/jni/appstatus.cpp create mode 100644 penguinpeak/ClipboardAgent/jni/notification.cpp create mode 100644 penguinpeak/ClipboardAgent/jni/proto/appstatus-protogen.inp create mode 100644 penguinpeak/ClipboardAgent/jni/proto/appstatus.proto create mode 100644 penguinpeak/ClipboardAgent/jni/proto/notification-protogen.inp create mode 100644 penguinpeak/ClipboardAgent/jni/proto/notification.proto create mode 100644 penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppStatusData.java create mode 100644 penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationComponent.java create mode 100644 penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationData.java create mode 100644 penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationListener.java diff --git a/penguinpeak/ClipboardAgent/AndroidManifest.xml b/penguinpeak/ClipboardAgent/AndroidManifest.xml index 95e7315..3764a52 100644 --- a/penguinpeak/ClipboardAgent/AndroidManifest.xml +++ b/penguinpeak/ClipboardAgent/AndroidManifest.xml @@ -10,6 +10,7 @@ + + + + + + diff --git a/penguinpeak/ClipboardAgent/jni/Android.bp b/penguinpeak/ClipboardAgent/jni/Android.bp index 816eb11..8f31ae9 100644 --- a/penguinpeak/ClipboardAgent/jni/Android.bp +++ b/penguinpeak/ClipboardAgent/jni/Android.bp @@ -36,11 +36,84 @@ cc_library_shared { sdk_version: "current", } +genrule { + name: "pgp-proto", + tool_files: [ ":TAF-proto-gen", ":TAF-templates", ":TAF-proto-gen-deps",], + srcs: [ + "proto/appstatus-protogen.inp", + "proto/notification-protogen.inp", + ], + out: [ + "proto/appstatus-gen.proto", + "proto/notification-gen.proto", + ], + cmd: "$(location) -I vendor/intel/external/apps/penguinpeak/ClipboardAgent/jni/ -o $(genDir) -i $(in) --proto", +} + +genrule { + name: "pgp-headers", + tool_files: [ ":TAF-proto-gen", ":TAF-templates", ":TAF-proto-gen-deps",], + srcs: [ + "proto/appstatus-protogen.inp", + "proto/notification-protogen.inp", + ], + out: [ + "proto/appstatus.h", + "proto/notification.h", + ], + cmd: "$(location) -I vendor/intel/external/apps/penguinpeak/ClipboardAgent/jni/ -o $(genDir) -i $(in) --header", +} + + +genrule { + name: "pgp-gRPCGenStub_h", + tools: [ + "aprotoc", + "protoc-gen-grpc-cpp-plugin", + ], + cmd: "$(location aprotoc) -Iout/soong/.intermediates/vendor/intel/external/apps/penguinpeak/ClipboardAgent/jni/pgp-proto/gen -Ivendor/intel/external/apps/penguinpeak/ClipboardAgent/jni -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)", + srcs: [ ":pgp-proto", + "proto/appstatus.proto", + "proto/notification.proto", + ], + out: [ + "proto/appstatus.pb.h", + "proto/appstatus-gen.pb.h", + "proto/appstatus-gen.grpc.pb.h", + "proto/notification.pb.h", + "proto/notification-gen.pb.h", + "proto/notification-gen.grpc.pb.h", + ], +} + +genrule { + name: "pgp-gRPCGenStub_cc", + tools: [ + "aprotoc", + "protoc-gen-grpc-cpp-plugin", + ], + cmd: "$(location aprotoc) -Iout/soong/.intermediates/vendor/intel/external/apps/penguinpeak/ClipboardAgent/jni/pgp-proto/gen -Ivendor/intel/external/apps/penguinpeak/ClipboardAgent/jni -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)", + srcs: [ + ":pgp-proto", + "proto/appstatus.proto", + "proto/notification.proto", + ], + out: [ + "proto/appstatus.pb.cc", + "proto/appstatus-gen.pb.cc", + "proto/appstatus-gen.grpc.pb.cc", + "proto/notification.pb.cc", + "proto/notification-gen.pb.cc", + "proto/notification-gen.grpc.pb.cc", + ], +} + cc_library_shared { name: "libVsockMsgDispatch", + defaults: ["TAF-defaults",], srcs: [ - "VsockMsgDispatcher.cpp", "DispatchHelper.cpp", + "adapter.cpp", ], cflags: [ "-Wall", @@ -48,7 +121,19 @@ cc_library_shared { "-Wno-unused-parameter", "-Wno-unused-label", ], - shared_libs: ["libbase", "liblog"], + generated_headers: [ "pgp-headers", "pgp-gRPCGenStub_h", ], + generated_sources: [ "pgp-gRPCGenStub_cc", ], sdk_version: "current", } - + +cc_binary { + name: "comm_host_agent", + host_supported: true, + defaults: ["TAF-defaults",], + srcs: [ + "appstatus.cpp", + "notification.cpp", + ], + generated_headers: [ "pgp-headers", "pgp-gRPCGenStub_h", ], + generated_sources: [ "pgp-gRPCGenStub_cc", ], +} diff --git a/penguinpeak/ClipboardAgent/jni/DispatchHelper.cpp b/penguinpeak/ClipboardAgent/jni/DispatchHelper.cpp index e32132f..0aa16d1 100644 --- a/penguinpeak/ClipboardAgent/jni/DispatchHelper.cpp +++ b/penguinpeak/ClipboardAgent/jni/DispatchHelper.cpp @@ -1,142 +1,46 @@ -#include "VsockMsgDispatcher.h" #include "DispatchHelper.h" #include #include +#include "adapter.h" -using namespace vsock; -std::map< std::string, std::vector > comp_msg_map { - {"ClipboardComponent", {MSG_TYPE_CLIPBOARD}}, - {"AppstatusComponent", {MSG_TYPE_APPSTATUS}} -}; -std::map< std::string, jclass > jclass_map; +#undef LOG_TAG +#define LOG_TAG "DispatchHelper" -static JavaVM* gVm = nullptr; -JNIEnv* getenv() { - JNIEnv *env = nullptr; - int getEnvStat = gVm->GetEnv((void **)&env, JNI_VERSION_1_6); - if (getEnvStat == JNI_EDETACHED) { - LOGIT("GetEnv: not attached"); - if (gVm->AttachCurrentThread(&env, NULL) != 0) { - LOGIT("Failed to attach"); - } - } else if (getEnvStat == JNI_OK) { - // - } else if (getEnvStat == JNI_EVERSION) { - LOGIT("GetEnv: version not supported"); - } - return env; -} - -class JavaComponent:public Component { - public: - std::string java_class_name; - std::vector msg_list; - JavaComponent(std::string name) { - std::map< std::string, std::vector >::iterator it; - java_class_name = name; - it = comp_msg_map.find(name); - if (it != comp_msg_map.end()) { - msg_list = it->second; - } - } - virtual ~JavaComponent(){ - JNIEnv* env = getenv(); - jclass reqClass = GetJClass(); - jobject singleInstance = GetSingletonInstance(reqClass); - jmethodID reqMethod = env->GetMethodID(reqClass, "stop", "()V"); - env->CallVoidMethod(singleInstance, reqMethod); - - } - virtual void init() { - LOGIT("init"); - JNIEnv* env = getenv(); - jclass reqClass = GetJClass(); - jobject singleInstance = GetSingletonInstance(reqClass); - jmethodID reqMethod = env->GetMethodID(reqClass, "init", "()V"); - env->CallVoidMethod(singleInstance, reqMethod); - } - - virtual void ProcessMsg(Message& msg, uint64_t hndl) { - LOGIT("Process msg - %s\n", msg.payload); - JNIEnv *env = getenv(); - jclass reqClass = GetJClass(); - jobject singleInstance = GetSingletonInstance(reqClass); - jmethodID reqMethod = env->GetMethodID(reqClass, "processMsg", "(Ljava/lang/String;J)V"); - jstring str = env->NewStringUTF(msg.payload); - env->CallVoidMethod(singleInstance, reqMethod, str, static_cast(hndl)); - } - private: - jclass GetJClass() { - std::map< std::string, jclass >::iterator it; - jclass reqClass = nullptr; - it = jclass_map.find(java_class_name.c_str()); - if (it != jclass_map.end()) { - reqClass = it->second; - } - return reqClass; - } - - jobject GetSingletonInstance(jclass reqClass) { - JNIEnv *env = getenv(); - std::string sig = "()Lcom/intel/clipboardagent/"+java_class_name+";"; - jmethodID instMethod = env->GetStaticMethodID(reqClass, "getInstance", sig.c_str()); - jobject singleInstance = env->CallStaticObjectMethod(reqClass, instMethod); - return singleInstance; - } -}; - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { - LOGIT("In OnLoad, failed to GetEnv"); - return JNI_ERR; - } - jclass tmp = nullptr; - tmp = env->FindClass("com/intel/clipboardagent/ClipboardComponent"); - if (tmp!= nullptr) { - jclass_map.insert({"ClipboardComponent", (jclass)env->NewGlobalRef(tmp)}); - } - tmp = env->FindClass("com/intel/clipboardagent/AppstatusComponent"); - if (tmp!= nullptr) { - jclass_map.insert({"AppstatusComponent", (jclass)env->NewGlobalRef(tmp)}); - } - return JNI_VERSION_1_6; -} - - JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_registerComponent(JNIEnv *env, jobject thisObject, jstring className) { - MsgDispatcher* dispatcher = MsgDispatcher::getInstance(); env->GetJavaVM(&gVm); std::string name = env->GetStringUTFChars(className, 0); - JavaComponent* javaComponent = new JavaComponent(name); - dispatcher->RegisterComponent(javaComponent->msg_list, javaComponent); + LOG_INFO("About to register Service %s\n", name.c_str()); + ServiceAdapter* adapter = AdapterFactory::GetAdapter(name); + if (adapter != nullptr) { + LOG_INFO("Found adapter for Service %s\n", name.c_str()); + adapter->Register(); + LOG_INFO("Registered Service %s\n", name.c_str()); + } else { + LOG_INFO("FATAL!! Service adapter not found for %s\n", name.c_str()); + } } - -JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_sendMsg(JNIEnv *env, jobject thisObject, jstring className, jstring msg, jlong handle) { - MsgDispatcher* dispatcher = MsgDispatcher::getInstance(); - std::string payload = env->GetStringUTFChars(msg, 0); - int size = env->GetStringUTFLength(msg); - std::vector msg_list; - std::map< std::string, std::vector >::iterator it; +JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_sendMsg(JNIEnv *env, jobject thisObject, jstring className, jobject msg, jlong handle) { + JavaObjectHelper jobjHelper(msg); std::string name = env->GetStringUTFChars(className, 0); - it = comp_msg_map.find(name); - if (it != comp_msg_map.end()) { - msg_list = it->second; + ServiceAdapter* adapter = AdapterFactory::GetAdapter(name); + if (adapter == nullptr) { + LOG_INFO("FATAL!! Service adapter not found for %s\n", name.c_str()); + return; } - if (handle == 0) { - handle = dispatcher->GetHandleForMsgType(msg_list.front()); - } - dispatcher->SendMsg(handle, msg_list.front(), payload.c_str(), size); + adapter->SendResponse(&jobjHelper); } - JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_start(JNIEnv *env, jobject thisObject) { - MsgDispatcher* dispatcher = MsgDispatcher::getInstance(); - dispatcher->Start(); + if (!g_server_->Start()) { + LOG_INFO("FATAL! Failed to start server"); + } } JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_stop(JNIEnv *env, jobject thisObject) { - MsgDispatcher* dispatcher = MsgDispatcher::getInstance(); - dispatcher->Stop(); + g_server_->Stop(); + delete g_server_; + g_server_ = nullptr; + AdapterFactory::RemoveAll(); } + diff --git a/penguinpeak/ClipboardAgent/jni/DispatchHelper.h b/penguinpeak/ClipboardAgent/jni/DispatchHelper.h index 3b67be4..4b9708b 100644 --- a/penguinpeak/ClipboardAgent/jni/DispatchHelper.h +++ b/penguinpeak/ClipboardAgent/jni/DispatchHelper.h @@ -18,10 +18,10 @@ JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_registerComp /* * Class: com_intel_clipboardagent_DispatchHelper * Method: sendMsg - * Signature: (Ljava/lang/String;Ljava/lang/String;J)V + * Signature: (Ljava/lang/String;Ljava/lang/Object;J)V */ JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_sendMsg - (JNIEnv *, jobject, jstring, jstring, jlong); + (JNIEnv *, jobject, jstring, jobject, jlong); /* * Class: com_intel_clipboardagent_DispatchHelper diff --git a/penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.cpp b/penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.cpp deleted file mode 100755 index a9a39a1..0000000 --- a/penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.cpp +++ /dev/null @@ -1,368 +0,0 @@ -#include "VsockMsgDispatcher.h" -#include -#include -#include -#include -#include - -namespace vsock { -#ifdef MSG_SERVER -static const bool gServer = true; -#else -static const bool gServer = false; -#endif - -#define VMADDR_CID_HOST 2 -#define VSOCK_PORT 77788 -#define CHUNK_SIZE 8192 - -MsgDispatcher *MsgDispatcher::instance = nullptr; -MsgDispatcher::MsgDispatcher() { - std::vector empty_vector; - fd_ = socket(AF_VSOCK, SOCK_STREAM, 0); - if (fd_ <= 0) { - LOGIT("FAILED TO CREATE SOCKET"); - ERR("Socket Create:"); - } - nclients_ = 0; - m_bStop = false; - msg_type_map[MSG_TYPE_INVALID] = empty_vector; -} - -bool MsgDispatcher::Start() { - struct sockaddr_vm sock_addr; - memset(&sock_addr, 0, sizeof(struct sockaddr_vm)); - sock_addr.svm_family = AF_VSOCK; - sock_addr.svm_port = VSOCK_PORT; - sock_addr.svm_cid = VMADDR_CID_HOST; - - if (gServer) { - int ret; - LOGIT("Binding as server\n"); - if ((ret = bind(fd_, (struct sockaddr*)&sock_addr, sizeof(sock_addr))) < 0) { - ERR("Socket bind:"); - return ret; - } - - //Bind succesful, so start accepting connections on a separate thread - Channel* channel = new Channel(this, fd_, 0); - channels_.emplace_back(channel); - LOGIT("Start Listen thread\n"); - CHECK_PTHREAD_CALL(pthread_create, (&t_main_, nullptr, &Listen, channel), "Failed to create server listener thread"); - - } else { - bool bConnected = true; - LOGIT("Connecting as client\n"); - bConnected = connect(fd_, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_vm)); - while(!bConnected) { - LOGIT("Failed to connect to server. Waiting to try again..."); - sleep(1); - ERR("Socket connect:"); - bConnected = connect(fd_, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_vm)); - } - - //Connected to server, start msg xchange - Channel* channel = new Channel(this, fd_, 0); - channels_.emplace_back(channel); - LOGIT("Start Run thread\n"); - CHECK_PTHREAD_CALL(pthread_create, (&t_main_, nullptr, &Run, channel), "Failed to create leader thread"); - } - - //Create workers - for (int i = 0; i < WORKER_POOL; ++i) { - LOGIT("Start worker thread-%d\n", i); - CHECK_PTHREAD_CALL(pthread_create, (&t_workers_[i], nullptr, &WorkerStart, this), "Failed to create worker thread"); - } - - return true; -} - -void* MsgDispatcher::Listen(void* arg) { - Channel* channel = reinterpret_cast(arg); - MsgDispatcher* dispatcher = channel->dispatcher_; - - struct sockaddr_vm sock_addr; - memset(&sock_addr, 0, sizeof(struct sockaddr_vm)); - sock_addr.svm_family = AF_VSOCK; - sock_addr.svm_port = VSOCK_PORT; - sock_addr.svm_cid = VMADDR_CID_HOST; - size_t sock_addr_len = sizeof(struct sockaddr_vm); - - if (!gServer) { - return (void*)-1; - } - - int client_fd = -1; - - while (!dispatcher->m_bStop) { - if (listen(channel->fd_, 2) < 0) { - ERR("Socket listen:"); - } - LOGIT("ACCEPTING..\n"); - //TODO: Make accept non-blocking - if((client_fd = accept(channel->fd_, (struct sockaddr*)&sock_addr, (socklen_t*)&sock_addr_len)) < 0) { - // if (errno == EAGAIN || errno == EWOULDBLOCK) { - // sleep(1); - // } else { - ERR("Socket accept:"); - // } - return (void *)-1; - } - if (dispatcher->t_clients_.size() == MAX_CLIENT_CONNECTIONS) { - close(client_fd); - LOGIT("Max connections exceeded. Closing client connection."); - continue; - } - // start msg xchange - pthread_t thread; - dispatcher->nclients_++; - Channel* channel = new Channel(dispatcher, client_fd, dispatcher->nclients_); - dispatcher->channels_.emplace_back(channel); - LOGIT("Start Run thread\n"); - CHECK_PTHREAD_CALL(pthread_create, (&thread, nullptr, &Run, channel), "Failed to create client handler thread"); - dispatcher->t_clients_[dispatcher->nclients_] = thread; - } - LOGIT("Exiting Listen thread"); - pthread_exit(nullptr); - return (void*)0; -} - -void* MsgDispatcher::Run(void* arg) { - Channel* channel = reinterpret_cast(arg); - MsgDispatcher* dispatcher = channel->dispatcher_; - LOGIT("In Run thread\n"); - if (gServer) { - SendCapabilities(channel); - } - dispatcher->InitComponentsIfReq(); - MessageHeader hdr; - //TODO: Make recv non-blocking - do { - int nread = (int) recv(channel->fd_, &hdr, sizeof(MessageHeader), 0); - if (nread != sizeof(MessageHeader)) { - LOGIT("Failed to recv header:%d", nread); - ERR("Socket recv header:"); - break; - } - int remaining = ntohl(hdr._size); - LOGIT("Reading payload - %d", remaining); - // allocate a buffer to read the payload - char* payload = new char[remaining + 1]; - payload[remaining] = 0; - Message msg = {hdr, payload}; - while (nread > 0 && remaining != 0) { - nread = (int) recv(channel->fd_, payload, (remaining > CHUNK_SIZE) ? CHUNK_SIZE : remaining, 0); - payload += nread; - remaining -= nread; - } - - if (nread < 0) { - LOGIT("Failed to recv... will reconnect...\n"); - ERR("Socket recv:"); - break; - } - LOGIT("Recvd payload - %s\n", payload); - switch(hdr._type) { - MSG_TYPE_CAPABILITIES: SaveCapabilities(channel); - if (!gServer) { - SendCapabilities(channel); - } - break; - default: if (ValidateMsg(channel, hdr)) { - LOGIT("Enqueue message"); - Enqueue(channel, msg); - } else { - // Msg dropped - } - break; - } - - } while (!dispatcher->m_bStop); - - // 0 is reserved for the main channel - if (channel->id_ > 0) { - //Mark the end of this thread - dispatcher->t_clients_.erase(channel->id_); - //Close the channel - std::lock_guard lock(dispatcher->q_lock_); - for (auto it = dispatcher->channels_.begin(); it != dispatcher->channels_.end(); ++it) { - if (*it == channel) { - dispatcher->channels_.erase(it); - delete channel; - break; - } - } - } else if (!dispatcher->m_bStop) { - //We may want to reconnect - close(channel->fd_); - dispatcher->fd_ = socket(AF_VSOCK, SOCK_STREAM, 0); - sleep(1); - bool bConnected = true; - struct sockaddr_vm sock_addr; - memset(&sock_addr, 0, sizeof(struct sockaddr_vm)); - sock_addr.svm_family = AF_VSOCK; - sock_addr.svm_port = VSOCK_PORT; - sock_addr.svm_cid = VMADDR_CID_HOST; - LOGIT("Reconnecting...\n"); - bConnected = connect(dispatcher->fd_, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_vm)); - while(!bConnected) { - LOGIT("Failed to connect to server. Waiting to try again..."); - ERR("Socket connect:"); - sleep(1); - bConnected = connect(dispatcher->fd_, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_vm)); - } - channel->fd_ = dispatcher->fd_; - return Run(arg); - } - LOGIT("Exiting Run thread"); - pthread_exit(nullptr); - return (void*)0; -} - -void* MsgDispatcher::WorkerStart(void* arg) { - MsgDispatcher* dispatcher = reinterpret_cast(arg); - while (!dispatcher->m_bStop) { - Message msg; - Channel* channel = nullptr; - bool bMsg = false; - { - std::lock_guard lock(dispatcher->q_lock_); - for (auto& chnl : dispatcher->channels_) { - if (chnl->msg_queue.size() > 0) { - msg = chnl->msg_queue.front(); - chnl->msg_queue.pop(); - channel = chnl; - bMsg = true; - } - } - } - if (bMsg) { - for (auto& component : dispatcher->GetComponentsForMsgType(msg.header._type)) { - LOGIT("Worker Dispatch msg - %s\n", msg.payload); - component->ProcessMsg(msg, reinterpret_cast(channel)); - } - delete msg.payload; - msg.payload = nullptr; - channel = nullptr; - } else { - sleep(1); - } - } - LOGIT("Exiting WorkerStart thread"); - pthread_exit(nullptr); - return (void*)0; -} - -void MsgDispatcher::Enqueue(Channel* channel, Message& msg) { - std::queue& mq = channel->msg_queue; - // No need of locks, only a single thread does the queing - while (mq.size() >= Q_SIZE) { - // Sleep for the queue to free up - sleep(1); - } - - mq.push(msg); -} - -void MsgDispatcher::Stop() { - m_bStop = true; - for (auto it = t_clients_.begin(); it != t_clients_.end(); ++it) { - CHECK_PTHREAD_CALL(pthread_join, (it->second, nullptr), "Failed to join on client thread"); - } - for (int i = 0; i < WORKER_POOL; ++i) { - LOGIT("Stop worker thread-%d\n", i); - CHECK_PTHREAD_CALL(pthread_join, (t_workers_[i], nullptr), "Failed to join on worker thread"); - } - LOGIT("Stop main thread"); - CHECK_PTHREAD_CALL(pthread_join, (t_main_, nullptr), "Failed to join on the main thread"); - - //Clear all the channels - std::lock_guard lock(q_lock_); - for(auto& channel : channels_) { - delete channel; - } - channels_.clear(); - for(auto& comp : components_) { - delete comp; - } - components_.clear(); - -} - -bool MsgDispatcher::SendMsg(uint64_t hndl, MSG_TYPE msg_type, const char* buffer, int size) { - MessageHeader header; - Channel* channel = reinterpret_cast(hndl); - bool bValidChannel = false; - for (auto it = channels_.begin(); it != channels_.end(); ++it) { - if (*it == channel) { - bValidChannel = true; - break; - } - } - if (!bValidChannel) { - LOGIT("Failed to send msg: Invalid Channel"); - return false; - } - - header._ver = MSG_VERSION; - header._type = msg_type; - header._id = 0; - header._size = htonl(size); - int nsent = (int)send(channel->fd_, &header, sizeof(MessageHeader), 0); - if (nsent != sizeof(MessageHeader)) { - LOGIT("Failed to send header:%d", nsent); - ERR("Socket send hdr:"); - return false; - } - while (nsent > 0 && size > 0) { - nsent = (int)send(channel->fd_, buffer, (size > CHUNK_SIZE) ? CHUNK_SIZE : size, 0); - size -= nsent; - buffer += nsent; - } - if (nsent < 0) { - ERR("Socket send:"); - } - return (nsent >= 0); -} - -std::vector& MsgDispatcher::GetComponentsForMsgType(MSG_TYPE msg_type) { - auto search = msg_type_map.find(msg_type); - if (search != msg_type_map.end()) { - return search->second; - } else { - return msg_type_map.find(MSG_TYPE_INVALID)->second; - } -} - -void MsgDispatcher::RegisterComponent(std::vector& msg_list, Component* component) { - LOGIT("Registering component"); - components_.emplace_back(component); - for (auto type : msg_list) { - if (type == MSG_TYPE_INVALID) { - continue; - } - auto search = msg_type_map.find(type); - if (search != msg_type_map.end()) { - search->second.emplace_back(component); - } else { - std::vector comp_vector; - comp_vector.emplace_back(component); - msg_type_map[type] = comp_vector; - } - } -} - -uint64_t MsgDispatcher::GetHandleForMsgType(MSG_TYPE msg_type) { - return reinterpret_cast(channels_.back()); -} - -void MsgDispatcher::InitComponentsIfReq() { - LOGIT("Looping components"); - for (auto component : components_) { - LOGIT("Initializing component"); - component->setDispatcher(this); - component->Initialize(); - } -} - -} diff --git a/penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.h b/penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.h deleted file mode 100755 index 4b9071f..0000000 --- a/penguinpeak/ClipboardAgent/jni/VsockMsgDispatcher.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef VSOCK_MSG_DISPATCHER_H -#define VSOCK_MSG_DISPATCHER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NODEBUG 0 //set this to 0 to turn on logging - -#ifdef __ANDROID__ -#define LOG_TAG "vsock" -#include -#include - -#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) -#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) -#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) -#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) - -#ifdef NODEBUG -#define LOGIT(...) -#else -#define LOGIT(...) ALOGV(__VA_ARGS__) -#endif -#else -#define CHECK_PTHREAD_CALL(call, args, what) \ - do { \ - int rc = call args; \ - if (rc != 0) { \ - errno = rc; \ - std::cout << #call << " failed for " << (what); \ - exit(-1); \ - } \ - } while (false) -#ifdef NODEBUG -#define LOGIT(...) -#else -#define LOGIT(...) printf(__VA_ARGS__); -#endif -#endif - -#define ERR(msg) perror(msg); - -#define MSG_VERSION 1 -#define MAX_CLIENT_CONNECTIONS 4 -#define WORKER_POOL 4 -#define Q_SIZE 32 - -namespace vsock { - -enum MSG_TYPE : char { - MSG_TYPE_CAPABILITY, - MSG_TYPE_CLIPBOARD, - MSG_TYPE_APPSTATUS, - MSG_TYPE_INVALID, -}; - - -struct MessageHeader { - char _ver; - MSG_TYPE _type; - int _id; - int _size; -}; - -struct Message { - MessageHeader header; - char* payload; -}; - -class MsgDispatcher; -class Component { - public: - Component () { m_bInitDone = false; } - MsgDispatcher* GetDispatcher() { return dispatcher_; } - - virtual ~Component() {} - virtual void ProcessMsg(Message& msg, uint64_t hndl) {} - virtual void init() {} - private: - void setDispatcher(MsgDispatcher* dispatcher) { dispatcher_ = dispatcher; } - void Initialize() { - if (!m_bInitDone) { - init(); - } - m_bInitDone = true; - } - bool m_bInitDone; - MsgDispatcher* dispatcher_; - friend class MsgDispatcher; -}; - - -class MsgDispatcher { - public: - MsgDispatcher(); - bool Start(); - void Stop(); - void RegisterComponent(std::vector& msg_list, Component* component); - bool SendMsg(uint64_t hndl, MSG_TYPE msg_type, const char* buffer, int size); - uint64_t GetHandleForMsgType(MSG_TYPE msg_type); - static MsgDispatcher *instance; - static MsgDispatcher *getInstance() { - if (instance == nullptr) { - instance = new MsgDispatcher(); - } - return instance; - } - private: - - class Channel { - public: - Channel(MsgDispatcher* dispatcher, int fd, int id) { - dispatcher_ = dispatcher; - fd_ = fd; - id_ = id; - } - - ~Channel() { - close(fd_); - while(!msg_queue.empty()) { - auto msg = msg_queue.front(); - delete msg.payload; - msg.payload = nullptr; - msg_queue.pop(); - } - } - private: - MsgDispatcher* dispatcher_; - int fd_; - int id_; - std::queue msg_queue; - friend class MsgDispatcher; - }; - - static void Enqueue(Channel* channel, Message& msg); - - static void* Listen(void* arg); - static void* Run(void* arg); - static void* WorkerStart(void* arg); - - static void SaveCapabilities(Channel* ) {} - static void SendCapabilities(Channel* ) {} - - static bool ValidateMsg(Channel* channel, MessageHeader hdr) { return true; } - void InitComponentsIfReq(); - std::vector& GetComponentsForMsgType(MSG_TYPE msg_type); - - //Dont close, managed by a channel - int fd_; - bool m_bStop; - pthread_t t_main_; - pthread_t t_workers_[WORKER_POOL]; - std::map t_clients_; - int nclients_; - std::vector channels_; - std::vector components_; - std::map> msg_type_map; - - std::mutex client_lock_; - std::mutex q_lock_; -}; -} - - -#endif //VSOCK_MSG_DISPATCHER_H diff --git a/penguinpeak/ClipboardAgent/jni/adapter.cpp b/penguinpeak/ClipboardAgent/jni/adapter.cpp new file mode 100644 index 0000000..6881446 --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/adapter.cpp @@ -0,0 +1,197 @@ +#include "adapter.h" + +JavaVM* gVm = nullptr; +taf::gRPCServer* g_server_ = nullptr; +std::map AdapterFactory::jadapter_map; + +static std::map< std::string, jclass > jclass_map; + +JNIEnv* getenv() { + JNIEnv *env = nullptr; + int getEnvStat = gVm->GetEnv((void **)&env, JNI_VERSION_1_6); + if (getEnvStat == JNI_EDETACHED) { + LOG_INFO("GetEnv: not attached"); + if (gVm->AttachCurrentThread(&env, NULL) != 0) { + LOG_INFO("Failed to attach"); + } + } else if (getEnvStat == JNI_OK) { + // + } else if (getEnvStat == JNI_EVERSION) { + LOG_INFO("GetEnv: version not supported"); + } + return env; +} + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { + JNIEnv *env; + std::string compName; + LOG_INFO("JNI_OnLoad\n"); + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + LOG_INFO("In OnLoad, failed to GetEnv"); + return JNI_ERR; + } + jclass tmp = nullptr; + tmp = env->FindClass("com/intel/clipboardagent/ClipboardComponent"); + if (tmp!= nullptr) { + jclass_map.insert({"ClipboardComponent", (jclass)env->NewGlobalRef(tmp)}); + } + tmp = env->FindClass("com/intel/clipboardagent/AppstatusComponent"); + if (tmp!= nullptr) { + compName = "AppstatusComponent"; + jclass_map.insert({compName , (jclass)env->NewGlobalRef(tmp)}); + AdapterFactory::AddAdapter(compName, new AppStatusAdapter(compName)); + } + tmp = env->FindClass("com/intel/clipboardagent/NotificationComponent"); + if (tmp!= nullptr) { + compName = "NotificationComponent"; + jclass_map.insert({compName , (jclass)env->NewGlobalRef(tmp)}); + AdapterFactory::AddAdapter(compName, new NotificationAdapter(compName)); + } + // Setup gRPC Server + LOG_INFO("Creating gRPC Server\n"); + g_server_ = new taf::gRPCServer("vsock:-1:50051"); + //g_server_ = new taf::gRPCServer("127.0.0.1:8787"); + LOG_INFO("Created gRPC Server\n"); + return JNI_VERSION_1_6; +} + +void AdapterFactory::AddAdapter(std::string& name, ServiceAdapter* adapter) { + if (GetAdapter(name) == nullptr) { + jadapter_map.insert({name, adapter}); + } +} + +ServiceAdapter* AdapterFactory::GetAdapter(std::string& name) { + std::map< std::string, ServiceAdapter*>::iterator it; + it = jadapter_map.find(name); + return (it != jadapter_map.end()) ? it->second: nullptr; +} + +void AdapterFactory::RemoveAll() { + for (auto adapter : jadapter_map) { + delete adapter.second; + } + jadapter_map.clear(); +} + +JavaComponent::~JavaComponent(){ + JNIEnv* env = getenv(); + jclass reqClass = GetJClass(); + jobject singleInstance = GetSingletonInstance(reqClass); + jmethodID reqMethod = env->GetMethodID(reqClass, "stop", "()V"); + env->CallVoidMethod(singleInstance, reqMethod); +} + +void JavaComponent::init() { + LOG_INFO("init"); + JNIEnv* env = getenv(); + jclass reqClass = GetJClass(); + jobject singleInstance = GetSingletonInstance(reqClass); + jmethodID reqMethod = env->GetMethodID(reqClass, "init", "()V"); + env->CallVoidMethod(singleInstance, reqMethod); +} + +void JavaComponent::ProcessMsg(std::string& msg, uint64_t hndl) { + LOG_INFO("Process msg - %s\n", msg.c_str()); + JNIEnv *env = getenv(); + jclass reqClass = GetJClass(); + jobject singleInstance = GetSingletonInstance(reqClass); + jmethodID reqMethod = env->GetMethodID(reqClass, "processMsg", "(Ljava/lang/String;J)V"); + jstring str = env->NewStringUTF(msg.c_str()); + env->CallVoidMethod(singleInstance, reqMethod, str, static_cast(hndl)); +} + +jclass JavaComponent::GetJClass() { + std::map< std::string, jclass >::iterator it; + jclass reqClass = nullptr; + it = jclass_map.find(java_class_name.c_str()); + if (it != jclass_map.end()) { + reqClass = it->second; + } + return reqClass; +} + +jobject JavaComponent::GetSingletonInstance(jclass reqClass) { + JNIEnv *env = getenv(); + std::string sig = "()Lcom/intel/clipboardagent/"+java_class_name+";"; + jmethodID instMethod = env->GetStaticMethodID(reqClass, "getInstance", sig.c_str()); + jobject singleInstance = env->CallStaticObjectMethod(reqClass, instMethod); + return singleInstance; +} + +void JavaObjectHelper::init() { + JNIEnv *env = getenv(); + class_ = env->GetObjectClass(obj_); +} + +int JavaObjectHelper::GetIntField(const char* fldNm) { + JNIEnv *env = getenv(); + jfieldID fld = env->GetFieldID(class_, fldNm, "I"); + return env->GetIntField(obj_, fld); +} + +const char* JavaObjectHelper::GetStringField(const char* fldNm) { + JNIEnv *env = getenv(); + jfieldID fld = env->GetFieldID(class_, fldNm, "Ljava/lang/String;"); + jstring str = (jstring) env->GetObjectField(obj_, fld); + return env->GetStringUTFChars(str, 0); +} + +void AppStatusAdapter::SendResponse(JavaObjectHelper* jobjHelper) { + AppStatusResponse resp; + resp.set_app_name(jobjHelper->GetStringField("app_name")); + if (svc_ != nullptr) { + if (!svc_->GetDispatcher()->Observe_Response(&resp)) { + // Something wrong with the stream, end the call + svc_->GET_API_STREAM(Observe)->WritesDone(); + svc_->GET_API_STREAM(Observe)->Finish(); + } + } +} + +taf::Service* AppStatusAdapter::GetService() { + if (svc_ == nullptr) { + LOG_INFO("Creating Service AppStatus\n"); + svc_ = new AppStatusAdapter::Service(this); + LOG_INFO("Obtained Service %p\n", svc_); + } + return svc_; +} + +bool AppStatusAdapter::Service::Observe(const AppStatusRequest* /*msg*/) { + LOG_INFO("Initializing AppStatus"); + adapter_->init(); + return true; +} + +void NotificationAdapter::SendResponse(JavaObjectHelper* jobjHelper) { + NotificationResponse resp; + resp.set_package(jobjHelper->GetStringField("packageName")); + resp.set_key(jobjHelper->GetStringField("key")); + resp.set_group_key(jobjHelper->GetStringField("groupKey")); + resp.set_message(jobjHelper->GetStringField("message")); + resp.set_priority(jobjHelper->GetIntField("priority")); + if (svc_ != nullptr) { + if (!svc_->GetDispatcher()->Observe_Response(&resp)) { + // Something wrong with the stream, end the call + svc_->GET_API_STREAM(Observe)->WritesDone(); + svc_->GET_API_STREAM(Observe)->Finish(); + } + } +} + +taf::Service* NotificationAdapter::GetService() { + if (svc_ == nullptr) { + LOG_INFO("Creating Service Notification\n"); + svc_ = new NotificationAdapter::Service(this); + LOG_INFO("Obtained Service %p\n", svc_); + } + return svc_; +} + +bool NotificationAdapter::Service::Observe(const NotificationRequest* /*msg*/) { + LOG_INFO("Initializing Notification sync"); + adapter_->init(); + return true; +} + diff --git a/penguinpeak/ClipboardAgent/jni/adapter.h b/penguinpeak/ClipboardAgent/jni/adapter.h new file mode 100644 index 0000000..55b729b --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/adapter.h @@ -0,0 +1,116 @@ +#include +#include "proto/appstatus.h" +#include "proto/notification.h" +#include "grpc/server.h" + +extern JavaVM* gVm; +extern taf::gRPCServer* g_server_; + +using namespace com::android::guest; + +class JavaComponent { +public: + JavaComponent(std::string name) { java_class_name = name; } + ~JavaComponent(); + void init(); + void ProcessMsg(std::string& msg, uint64_t hndl); +private: + jclass GetJClass(); + jobject GetSingletonInstance(jclass reqClass); + + std::string java_class_name; +}; + +class JavaObjectHelper { +public: + JavaObjectHelper(jobject obj) { obj_ = obj; init(); } + int GetIntField(const char* fldNm); + const char* GetStringField(const char* fldNm); +private: + void init(); + + jobject obj_; + jclass class_; +}; + +class ServiceAdapter { +public: + ServiceAdapter(std::string& name) { comp_ = new JavaComponent(name); } + virtual ~ServiceAdapter() { + delete comp_; + comp_ = nullptr; + } + virtual void SendResponse(JavaObjectHelper* payload) = 0; + inline void Register() { + LOG_INFO("GetService for registration\n"); + g_server_->RegisterService(GetService()); + } + inline void init() { comp_->init(); } + +protected: + inline void ProcessRequest(std::string& payload) { + comp_->ProcessMsg(payload, 0); + } + virtual taf::Service* GetService() = 0; + JavaComponent* comp_; +}; + +class AppStatusAdapter : public ServiceAdapter { +public: + AppStatusAdapter(std::string& name) : ServiceAdapter(name), svc_(nullptr) { } + virtual ~AppStatusAdapter() { + if (svc_ != nullptr) { + delete svc_; + svc_ = nullptr; + } + } + void SendResponse(JavaObjectHelper* payload) override; + + class Service : public AppStatusImpl::Service { + public: + Service(ServiceAdapter* adapter) { adapter_ = adapter; } + bool Observe(const AppStatusRequest*) override; + + ServiceAdapter* adapter_; + }; + +protected: + taf::Service* GetService() override; +private: + Service* svc_; +}; + +class NotificationAdapter : public ServiceAdapter { +public: + NotificationAdapter(std::string& name) : ServiceAdapter(name), svc_(nullptr) { } + virtual ~NotificationAdapter() { + if (svc_ != nullptr) { + delete svc_; + svc_ = nullptr; + } + } + void SendResponse(JavaObjectHelper* payload) override; + + class Service : public NotificationImpl::Service { + public: + Service(ServiceAdapter* adapter) { adapter_ = adapter; } + bool Observe(const NotificationRequest* /*msg*/) override; + + ServiceAdapter* adapter_; + }; + +protected: + taf::Service* GetService() override; +private: + Service* svc_; +}; + +class AdapterFactory { +public: + static void AddAdapter(std::string& name, ServiceAdapter* adapter); + static ServiceAdapter* GetAdapter(std::string& name); + static void RemoveAll(); +private: + static std::map jadapter_map; +}; + diff --git a/penguinpeak/ClipboardAgent/jni/appstatus.cpp b/penguinpeak/ClipboardAgent/jni/appstatus.cpp new file mode 100644 index 0000000..c7979bb --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/appstatus.cpp @@ -0,0 +1,33 @@ +#include +#include +#include "grpc/client.h" + +#include "proto/appstatus.h" + +using namespace ::com::android::guest; + +bool AppStatusImpl::Stub::Observe_Response(const AppStatusResponse* msg) { + if (msg != nullptr) { + std::cout << "In Observe_Response, received message:" << msg->app_name() << std::endl; + char cmd[512]; + snprintf(cmd, sizeof(cmd), "/opt/cfc/mwc/bin/msg_agent localhost 3000 CRASHAPP %s", msg->app_name().c_str()); + std::cout << "Running cmd: " << cmd << std::endl; + system(cmd); + } + return true; +} + +/*int main() { + taf::gRPCClient client("vsock:3:50051"); + //taf::gRPCClient client("127.0.0.1:8787"); + AppStatusImpl::Stub appStatusStub(&client); + std::cout << "Registering Stub" << std::endl; + client.RegisterStub(&appStatusStub); + AppStatusRequest req; + std::cout << "Invoking API" << std::endl; + std::cout << "Invocation result : " << appStatusStub.GetDispatcher()->Observe(&req) << std::endl; + while(1) { + std::cout << "Sleeping..." << std::endl; + sleep(10); + } +} */ diff --git a/penguinpeak/ClipboardAgent/jni/notification.cpp b/penguinpeak/ClipboardAgent/jni/notification.cpp new file mode 100644 index 0000000..0b994fb --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/notification.cpp @@ -0,0 +1,39 @@ +#include +#include +#include "grpc/client.h" + +#include "proto/appstatus.h" +#include "proto/notification.h" + +using namespace ::com::android::guest; + +bool NotificationImpl::Stub::Observe_Response(const NotificationResponse* msg) { + if (msg != nullptr) { + std::cout << "In Observe_Response, received message:" << msg->message() << std::endl; + char cmd[512]; + //snprintf(cmd, sizeof(cmd), "notify-send -a %s '%s'", msg->package().c_str(), msg->message().c_str()); + snprintf(cmd, sizeof(cmd), "python3 /home/kylin/AHS/notify.py -P %s -k '%s' -g '%s' -m '%s' -p %d", msg->package().c_str(), msg->key().c_str(), msg->group_key().c_str(), msg->message().c_str(), msg->priority()); + std::cout << "Running cmd: " << cmd << std::endl; + system(cmd); + } + return true; +} + +int main() { + taf::gRPCClient client("vsock:3:50051"); + //taf::gRPCClient client("127.0.0.1:8787"); + AppStatusImpl::Stub appStatusStub(&client); + NotificationImpl::Stub notificationStub(&client); + std::cout << "Registering Stub" << std::endl; + client.RegisterStub(&appStatusStub); + client.RegisterStub(¬ificationStub); + AppStatusRequest req; + NotificationRequest notificationReq; + std::cout << "Invoking API" << std::endl; + std::cout << "Invocation result : " << appStatusStub.GetDispatcher()->Observe(&req) << std::endl; + std::cout << notificationStub.GetDispatcher()->Observe(¬ificationReq) << std::endl; + while(1) { + std::cout << "Sleeping..." << std::endl; + sleep(10); + } +} diff --git a/penguinpeak/ClipboardAgent/jni/proto/appstatus-protogen.inp b/penguinpeak/ClipboardAgent/jni/proto/appstatus-protogen.inp new file mode 100644 index 0000000..69da964 --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/proto/appstatus-protogen.inp @@ -0,0 +1,11 @@ +[Template] +Path=./../../../../../taf-grpc/core/templates/observer.template + +[TemplateParams] +Class_ServiceName=AppStatus +Type_ObserveReq=AppStatusRequest +Type_ObserveResp=AppStatusResponse + +[Proto] +MessagePath=proto/appstatus.proto +PackageName=com.android.guest diff --git a/penguinpeak/ClipboardAgent/jni/proto/appstatus.proto b/penguinpeak/ClipboardAgent/jni/proto/appstatus.proto new file mode 100644 index 0000000..240eaa0 --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/proto/appstatus.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package com.android.guest; + +message AppStatusRequest { + int32 req_num = 1; +} + +message AppStatusResponse { + string app_name = 1; +} + diff --git a/penguinpeak/ClipboardAgent/jni/proto/notification-protogen.inp b/penguinpeak/ClipboardAgent/jni/proto/notification-protogen.inp new file mode 100644 index 0000000..75df9ea --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/proto/notification-protogen.inp @@ -0,0 +1,11 @@ +[Template] +Path=./../../../../../taf-grpc/core/templates/observer.template + +[TemplateParams] +Class_ServiceName=Notification +Type_ObserveReq=NotificationRequest +Type_ObserveResp=NotificationResponse + +[Proto] +MessagePath=proto/notification.proto +PackageName=com.android.guest diff --git a/penguinpeak/ClipboardAgent/jni/proto/notification.proto b/penguinpeak/ClipboardAgent/jni/proto/notification.proto new file mode 100644 index 0000000..dc08963 --- /dev/null +++ b/penguinpeak/ClipboardAgent/jni/proto/notification.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package com.android.guest; + +message NotificationRequest { + int32 req_num = 1; +} + +message NotificationResponse { + string package = 1; + string key = 2; + string group_key = 3; + string message = 4; + int32 priority = 5; +} diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppStatusData.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppStatusData.java new file mode 100644 index 0000000..7907f09 --- /dev/null +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppStatusData.java @@ -0,0 +1,5 @@ +package com.intel.clipboardagent; + +public class AppStatusData { + String app_name; +} \ No newline at end of file diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppstatusComponent.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppstatusComponent.java index 7b783ca..cad6866 100644 --- a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppstatusComponent.java +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/AppstatusComponent.java @@ -94,8 +94,8 @@ private boolean killLG(String appName) { List recentTasks = mActivityManager.getRecentTasks(10, 0); boolean kill = true; for (ActivityManager.RecentTaskInfo taskInfo : recentTasks) { - Log.d(TAG, "In AHSFunc, taskinfo.isRunning " + taskInfo.isRunning); - Log.d(TAG, "In AHSFunc, taskinfo.isVisible " + taskInfo.isVisible()); + //Log.d(TAG, "In AHSFunc, taskinfo.isRunning " + taskInfo.isRunning); + //Log.d(TAG, "In AHSFunc, taskinfo.isVisible " + taskInfo.isVisible()); if ((taskInfo.baseActivity != null) && taskInfo.isRunning && taskInfo.isVisible() && appName.equals(taskInfo.baseActivity.getPackageName())) { kill = false; break; @@ -114,41 +114,45 @@ private void dumpTaskInfo() { private final ActivityManager.OnUidImportanceListener mOnUidImportanceListener = new ActivityManager.OnUidImportanceListener() { @Override - public void onUidImportance(final int uid, final int importance){ - Log.d(TAG, "In onUidImportance event, uid = " + uid + " and importance = " + importance); - String appName = getPackageName(uid); - if (appName.isEmpty()) { - Log.d(TAG, "No app associated with uid, so return"); - return; - } - Log.d(TAG, "In onUidImportance Listener, processing App = " + appName); - dumpTaskInfo(); - if (uidPrevImpMap.containsKey(uid)) { - int prevImp = uidPrevImpMap.get(uid); - Log.d(TAG, "prev imp value of uid " + uid + " is " + prevImp); - if (prevImp == IMPORTANCE_FOREGROUND) { - if (importance == IMPORTANCE_GONE) { - Log.d(TAG, "App with uid " + uid + " killed, send message to host"); - Log.d(TAG, "1:: Sending message to host"); - dH.sendMsg("AppstatusComponent", appName, 0); - } else if(importance >= IMPORTANCE_VISIBLE) { // && importance <= IMPORTANCE_CACHED) { - Log.d(TAG, "App with uid " + uid + " moved from foreground to background"); - if (killLG(appName)) { - Log.d(TAG, "2:: Sending message to host"); - dH.sendMsg("AppstatusComponent", appName, 0); - } - } - } - if (importance == IMPORTANCE_GONE) { - Log.d(TAG, "App with uid " + uid + " killed, remove from the map"); - uidPrevImpMap.remove(uid); - } else { - uidPrevImpMap.put(uid, importance); - } - } else { - uidPrevImpMap.put(uid, importance); - } - } + public void onUidImportance(final int uid, final int importance){ + Log.d(TAG, "In onUidImportance event, uid = " + uid + " and importance = " + importance); + String appName = getPackageName(uid); + if (appName.isEmpty()) { + Log.d(TAG, "No app associated with uid, so return"); + return; + } + Log.d(TAG, "In onUidImportance Listener, processing App = " + appName); + // dumpTaskInfo(); + if (uidPrevImpMap.containsKey(uid)) { + int prevImp = uidPrevImpMap.get(uid); + Log.d(TAG, "prev imp value of uid " + uid + " is " + prevImp); + if (prevImp == IMPORTANCE_FOREGROUND) { + if (importance == IMPORTANCE_GONE) { + Log.d(TAG, "App with uid " + uid + " killed, send message to host"); + Log.d(TAG, "1:: Sending message to host"); + AppStatusData appstatusData = new AppStatusData(); + appstatusData.app_name = appName; + dH.sendMsg("AppstatusComponent", appstatusData, 0); + } else if(importance >= IMPORTANCE_VISIBLE) { // && importance <= IMPORTANCE_CACHED) { + Log.d(TAG, "App with uid " + uid + " moved from foreground to background"); + if (killLG(appName)) { + AppStatusData appstatusData = new AppStatusData(); + appstatusData.app_name = appName; + Log.d(TAG, "2:: Sending message to host"); + dH.sendMsg("AppstatusComponent", appstatusData, 0); + } + } + } + if (importance == IMPORTANCE_GONE) { + Log.d(TAG, "App with uid " + uid + " killed, remove from the map"); + uidPrevImpMap.remove(uid); + } else { + uidPrevImpMap.put(uid, importance); + } + } else { + uidPrevImpMap.put(uid, importance); + } + } }; /*public void processMsg(String content, long handle) { diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/ClipboardAgent.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/ClipboardAgent.java index d3be993..638f8bd 100644 --- a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/ClipboardAgent.java +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/ClipboardAgent.java @@ -20,8 +20,6 @@ import android.app.Application; import android.content.Intent; import android.util.Log; -import com.intel.clipboardagent.GuestVsockCommService; -import com.intel.clipboardagent.ClipboardService; public class ClipboardAgent extends Application { private static final String TAG = "ClipboardAgent"; @@ -34,6 +32,7 @@ public void onCreate() { startService(new Intent(this, ClipboardService.class)); startService(new Intent(this, GuestVsockCommService.class)); + startService(new Intent(this, NotificationListener.class)); } public void onTerminate() { diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/DispatchHelper.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/DispatchHelper.java index d2c82ac..e4026dc 100644 --- a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/DispatchHelper.java +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/DispatchHelper.java @@ -35,7 +35,7 @@ public static DispatchHelper getInstance() { } public native void registerComponent(String className); - public native void sendMsg(String className, String msg, long handle); + public native void sendMsg(String className, Object msg, long handle); public native void start(); public native void stop(); diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/GuestVsockCommService.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/GuestVsockCommService.java index f916e12..8094f52 100644 --- a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/GuestVsockCommService.java +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/GuestVsockCommService.java @@ -38,6 +38,7 @@ public void onCreate() { dH.mContext = this.getApplicationContext(); dH.registerComponent("ClipboardComponent"); dH.registerComponent("AppstatusComponent"); + dH.registerComponent("NotificationComponent"); dH.start(); } diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationComponent.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationComponent.java new file mode 100644 index 0000000..243e746 --- /dev/null +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationComponent.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2021 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.clipboardagent; + +import android.app.Service; +import android.content.Intent; +import android.util.Log; +import com.intel.clipboardagent.DispatchHelper; +import android.content.Context; +import android.app.ActivityManager; +import android.content.pm.PackageManager; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; +import android.content.ComponentName; +import android.app.NotificationManager; +import java.util.List; + +public class NotificationComponent { + //private static final String TAG = "NotificationComponent"; + private static final String TAG = "AHS-NLS"; + private static NotificationComponent single_instance = null; + private DispatchHelper dH; + private NotificationListener mListener; + + private NotificationComponent(){ + } + + public static NotificationComponent getInstance() { + if (single_instance == null) { + single_instance = new NotificationComponent(); + } + return single_instance; + } + + public void init() { + dH = DispatchHelper.getInstance(); + Log.d(TAG, "In init"); + mListener = new NotificationListener(); + mListener.setNotificationsChangedListener(mNotificationsChangedListener); + ComponentName cn = ComponentName.unflattenFromString("com.intel.clipboardagent/com.intel.clipboardagent.NotificationListener"); + NotificationManager nm = dH.mContext.getSystemService(NotificationManager.class); + if (nm.isNotificationListenerAccessGranted(cn)) { + Log.d(TAG, "Has notification acess"); + } + } + + public void stop() { + Log.d(TAG, "In stop"); + if (mListener != null) { + mListener.removeNotificationsChangedListener(); + } + } + + private final NotificationListener.NotificationsChangedListener mNotificationsChangedListener = new NotificationListener.NotificationsChangedListener() { + @Override + public void onNotificationPosted(StatusBarNotification sbn) { + Log.d(TAG, "In NotificationComponent onNotificationPosted"); + Log.d(TAG, "ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText +"\t" + sbn.getPackageName()); + Log.d(TAG, "ID :" + sbn.isGroup() + "\t" + sbn.getKey() +"\t" + sbn.toString() +"\t" + sbn.getNotification().priority); + NotificationData notificationdata = new NotificationData(); + notificationdata.packageName = sbn.getPackageName(); + notificationdata.key = sbn.getKey(); + notificationdata.groupKey = sbn.getGroupKey(); + notificationdata.message = sbn.getNotification().tickerText.toString(); + notificationdata.priority = sbn.getNotification().priority; + dH.sendMsg("NotificationComponent", notificationdata, 0); + } + }; + +} + diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationData.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationData.java new file mode 100644 index 0000000..cfe09f6 --- /dev/null +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationData.java @@ -0,0 +1,9 @@ +package com.intel.clipboardagent; + +public class NotificationData { + String packageName; + String key; + String groupKey; + String message; + int priority; +} diff --git a/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationListener.java b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationListener.java new file mode 100644 index 0000000..1c897ff --- /dev/null +++ b/penguinpeak/ClipboardAgent/src/com/intel/clipboardagent/NotificationListener.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2021 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.clipboardagent; + +import android.app.Service; +import android.content.Intent; +import android.util.Log; +import com.intel.clipboardagent.DispatchHelper; +import android.content.Context; +import android.app.ActivityManager; +import android.content.pm.PackageManager; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; +import android.content.ComponentName; + +public class NotificationListener extends NotificationListenerService { + private static final String TAG = "ClipboardAgent - NotificationListener"; + private static NotificationsChangedListener sNotificationsChangedListener; + + public interface NotificationsChangedListener { + void onNotificationPosted(StatusBarNotification sbn); + } + + public NotificationListener() { + Log.d("AHS-NLS", "In NotificationListener constructor"); + sNotificationsChangedListener = null; + } + + public static void setNotificationsChangedListener(NotificationsChangedListener listener) { + Log.d("AHS-NLS", "In setNotificationsChangedListener"); + sNotificationsChangedListener = listener; + } + + public static void removeNotificationsChangedListener() { + sNotificationsChangedListener = null; + } + + @Override + public void onCreate() { + Log.d("AHS-NLS", "onCreate"); + super.onCreate(); + } + + @Override + public void onDestroy() { + Log.d("AHS-NLS", "onDestroy"); + super.onDestroy(); + } + + @Override + public void onNotificationPosted(StatusBarNotification sbn) { + Log.d("AHS-NLS", "In onNotificationPosted"); + if (sNotificationsChangedListener != null) { + sNotificationsChangedListener.onNotificationPosted(sbn); + } + } +} +