Skip to content

Commit

Permalink
Clipboard copy/paste on single vsock channel
Browse files Browse the repository at this point in the history
Tracked-On: OAM-100054
Signed-off-by: ahs <[email protected]>
  • Loading branch information
amritaintel committed Jul 18, 2022
1 parent 0554c40 commit e8faa8b
Show file tree
Hide file tree
Showing 14 changed files with 1,102 additions and 4 deletions.
4 changes: 2 additions & 2 deletions penguinpeak/ClipboardAgent/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ android_app {
name: "ClipboardAgent",
srcs: ["**/*.java"],
// JNI library built from C++ source code
jni_libs: ["libVsocketClientImpl"],
jni_libs: ["libVsockMsgDispatch", "libVsocketClientImpl"],
optimize: {
enabled: false,
},
sdk_version: "current",
sdk_version: "system_current",
dex_preopt: {
enabled: false,
},
Expand Down
10 changes: 8 additions & 2 deletions penguinpeak/ClipboardAgent/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,31 @@
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
<!-- Need internet permission to create socket -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<!-- TODO: update persistent and allowBackup to be true. -->
<application
android:name=".ClipboardAgent"
android:persistent="true"
android:allowBackup="false">
<activity
android:name=".MainActivity"
android:theme="@android:style/Theme.NoDisplay">
android:theme="@android:style/Theme.NoDisplay"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<service
android:exported="false"
android:name=".GuestVsockCommService">
</service>
<service
android:exported="false"
android:name=".ClipboardService">
</service>

</application>

</manifest>
Binary file not shown.
19 changes: 19 additions & 0 deletions penguinpeak/ClipboardAgent/jni/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cc_library_shared {
// liblog is used to print trace log in C plus plus source code.
shared_libs: ["liblog"],
// No static libraries.
header_libs: ["jni_headers"],
static_libs: [],
cflags: [
"-Wall",
Expand All @@ -35,3 +36,21 @@ cc_library_shared {
stl: "c++_static",
sdk_version: "current",
}

cc_library_shared {
name: "libVsockMsgDispatch",
srcs: [
"VsockMsgDispatcher.cpp",
"DispatchHelper.cpp",
],
header_libs: ["jni_headers"],
cflags: [
"-Wall",
"-Werror",
"-Wno-unused-parameter",
"-Wno-unused-label",
],
shared_libs: ["libbase", "liblog"],
sdk_version: "current",
}

142 changes: 142 additions & 0 deletions penguinpeak/ClipboardAgent/jni/DispatchHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include "VsockMsgDispatcher.h"
#include "DispatchHelper.h"
#include <string.h>
#include <jni.h>

using namespace vsock;
std::map< std::string, std::vector<MSG_TYPE> > comp_msg_map {
{"ClipboardComponent", {MSG_TYPE_CLIPBOARD}},
{"AppstatusComponent", {MSG_TYPE_APPSTATUS}}
};
std::map< std::string, jclass > jclass_map;

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_TYPE> msg_list;
JavaComponent(std::string name) {
std::map< std::string, std::vector<MSG_TYPE> >::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<jlong>(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<void**>(&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);
}


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_TYPE> msg_list;
std::map< std::string, std::vector<MSG_TYPE> >::iterator it;
std::string name = env->GetStringUTFChars(className, 0);
it = comp_msg_map.find(name);
if (it != comp_msg_map.end()) {
msg_list = it->second;
}
if (handle == 0) {
handle = dispatcher->GetHandleForMsgType(msg_list.front());
}
dispatcher->SendMsg(handle, msg_list.front(), payload.c_str(), size);
}


JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_start(JNIEnv *env, jobject thisObject) {
MsgDispatcher* dispatcher = MsgDispatcher::getInstance();
dispatcher->Start();
}

JNIEXPORT void JNICALL Java_com_intel_clipboardagent_DispatchHelper_stop(JNIEnv *env, jobject thisObject) {
MsgDispatcher* dispatcher = MsgDispatcher::getInstance();
dispatcher->Stop();
}
45 changes: 45 additions & 0 deletions penguinpeak/ClipboardAgent/jni/DispatchHelper.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e8faa8b

Please sign in to comment.