Skip to content

Commit

Permalink
Initial commit for clipboard-agent
Browse files Browse the repository at this point in the history
Signed-off-by: ahs <[email protected]>
  • Loading branch information
amritaintel committed Aug 2, 2022
0 parents commit aa89497
Show file tree
Hide file tree
Showing 22 changed files with 2,058 additions and 0 deletions.
36 changes: 36 additions & 0 deletions Android.bp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// 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.
//

// This makefile shows how to build a shared library and an activity that
// bundles the shared library and calls it using JNI.

android_app {
name: "ClipboardAgent",
srcs: ["**/*.java"],
// JNI library built from C++ source code
jni_libs: ["libVsockMsgDispatch", "libVsocketClientImpl"],
optimize: {
enabled: false,
},
sdk_version: "system_current",
dex_preopt: {
enabled: false,
},
privileged: true,
// To match the signature
certificate: "platform",
}
38 changes: 38 additions & 0 deletions AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.intel.clipboardagent"
android:sharedUserId="android.uid.system">

<!--uses-sdk android:minSdkVersion="17" android:targetSdkVersion="30"/-->
<!-- Need clipboard access, so get the SYSTEM_WINDOW permissioin -->
<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: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>
56 changes: 56 additions & 0 deletions jni/Android.bp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// Copyright (C) 2008 The Android Open Source Project
//
// 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.
//

// This makefile supplies the rules for building a library of JNI code for
// use by our example of how to bundle a shared library with an APK.

cc_library_shared {
name: "libVsocketClientImpl",
// All of the source files that we will compile.
srcs: ["VsockClientImpl.cpp"],
// All of the shared libraries we link against.
// 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",
"-Werror",
],
// We cannot use stl:"none" here to link libc++ dynamically because
// it caused "'iostream' file not found" build issue.
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",
}

139 changes: 139 additions & 0 deletions jni/DispatchHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#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) {
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() {
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) {
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 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 aa89497

Please sign in to comment.