[core] Update JNI helper (#440)
This commit is contained in:
parent
eecef24179
commit
a384697655
|
|
@ -91,20 +91,14 @@ public class LogsActivity extends BaseActivity {
|
|||
e.printStackTrace();
|
||||
}
|
||||
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
|
||||
try {
|
||||
OutputStream os = getContentResolver().openOutputStream(uri);
|
||||
if (os == null) {
|
||||
return;
|
||||
}
|
||||
try (var os = getContentResolver().openOutputStream(uri)) {
|
||||
ParcelFileDescriptor parcelFileDescriptor = ConfigManager.getLogs(verbose);
|
||||
if (parcelFileDescriptor == null) {
|
||||
os.close();
|
||||
return;
|
||||
}
|
||||
InputStream is = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
|
||||
try (var is = new FileInputStream(parcelFileDescriptor.getFileDescriptor())) {
|
||||
FileUtils.copy(is, os);
|
||||
os.close();
|
||||
is.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(binding.snackbar, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
|
@ -252,9 +246,7 @@ public class LogsActivity extends BaseActivity {
|
|||
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
|
||||
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
|
||||
File cacheFile = new File(getCacheDir(), filename);
|
||||
try {
|
||||
OutputStream os = new FileOutputStream(cacheFile);
|
||||
InputStream is = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
|
||||
try (var os = new FileOutputStream(cacheFile); var is = new FileInputStream(parcelFileDescriptor.getFileDescriptor())) {
|
||||
FileUtils.copy(is, os);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ val androidTargetSdkVersion by extra(30)
|
|||
val androidMinSdkVersion by extra(27)
|
||||
val androidBuildToolsVersion by extra("30.0.3")
|
||||
val androidCompileSdkVersion by extra(30)
|
||||
val androidCompileNdkVersion by extra("22.0.7026061")
|
||||
val androidCompileNdkVersion by extra("22.1.7171670")
|
||||
val androidSourceCompatibility by extra(JavaVersion.VERSION_11)
|
||||
val androidTargetCompatibility by extra(JavaVersion.VERSION_11)
|
||||
val apiCode by extra(93)
|
||||
|
|
|
|||
|
|
@ -27,107 +27,6 @@
|
|||
|
||||
#define JNI_START JNIEnv *env, [[maybe_unused]] jclass clazz
|
||||
|
||||
ALWAYS_INLINE static void JNIExceptionClear(JNIEnv *env) {
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static bool JNIExceptionCheck(JNIEnv *env) {
|
||||
if (env->ExceptionCheck()) {
|
||||
jthrowable e = env->ExceptionOccurred();
|
||||
env->Throw(e);
|
||||
env->DeleteLocalRef(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void JNIExceptionClearAndDescribe(JNIEnv *env) {
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int ClearException(JNIEnv *env) {
|
||||
jthrowable exception = env->ExceptionOccurred();
|
||||
if (exception != nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define JNI_FindClass(env, name) \
|
||||
env->FindClass(name); \
|
||||
if (ClearException(env)) LOGE("FindClass " #name)
|
||||
|
||||
#define JNI_GetObjectClass(env, obj) \
|
||||
env->GetObjectClass(obj); \
|
||||
if (ClearException(env)) LOGE("GetObjectClass " #obj)
|
||||
|
||||
#define JNI_GetFieldID(env, class, name, sig) \
|
||||
env->GetFieldID(class, name, sig); \
|
||||
if (ClearException(env)) LOGE("GetFieldID " #name)
|
||||
|
||||
#define JNI_GetObjectField(env, class, fieldId) \
|
||||
env->GetObjectField(class, fieldId); \
|
||||
if (ClearException(env)) LOGE("GetObjectField " #fieldId)
|
||||
|
||||
#define JNI_GetMethodID(env, class, name, sig) \
|
||||
env->GetMethodID(class, name, sig); \
|
||||
//if (ClearException(env)) LOGE("GetMethodID " #name)
|
||||
|
||||
#define JNI_CallObjectMethod(env, obj, ...) \
|
||||
env->CallObjectMethod(obj, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("CallObjectMethod " #obj " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_CallVoidMethod(env, obj, ...) \
|
||||
env->CallVoidMethod(obj, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("CallVoidMethod " #obj " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_CallBooleanMethod(env, obj, ...) \
|
||||
env->CallBooleanMethod(obj, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("CallVoidMethod " #obj " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_GetStaticFieldID(env, class, name, sig) \
|
||||
env->GetStaticFieldID(class, name, sig); \
|
||||
if (ClearException(env)) LOGE("GetStaticFieldID " #name " " #sig)
|
||||
|
||||
#define JNI_GetStaticObjectField(env, class, fieldId) \
|
||||
env->GetStaticObjectField(class, fieldId); \
|
||||
if (ClearException(env)) LOGE("GetStaticObjectField " #fieldId)
|
||||
|
||||
#define JNI_GetStaticMethodID(env, class, name, sig) \
|
||||
env->GetStaticMethodID(class, name, sig); \
|
||||
if (ClearException(env)) LOGE("GetStaticMethodID " #name)
|
||||
|
||||
#define JNI_CallStaticVoidMethod(env, obj, ...) \
|
||||
env->CallStaticVoidMethod(obj, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("CallStaticVoidMethod " #obj " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_CallStaticObjectMethod(env, obj, ...) \
|
||||
env->CallStaticObjectMethod(obj, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("CallStaticObjectMethod " #obj " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_CallStaticIntMethod(env, obj, ...) \
|
||||
env->CallStaticIntMethod(obj, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("CallStaticIntMethod " #obj " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_GetArrayLength(env, array) \
|
||||
env->GetArrayLength(array); \
|
||||
if (ClearException(env)) LOGE("GetArrayLength " #array)
|
||||
|
||||
#define JNI_NewObject(env, class, ...) \
|
||||
env->NewObject(class, __VA_ARGS__); \
|
||||
if (ClearException(env)) LOGE("NewObject " #class " " #__VA_ARGS__)
|
||||
|
||||
#define JNI_RegisterNatives(env, class, methods, size) \
|
||||
env->RegisterNatives(class, methods, size); \
|
||||
if (ClearException(env)) LOGE("RegisterNatives " #class)
|
||||
|
||||
class JUTFString {
|
||||
public:
|
||||
inline JUTFString(JNIEnv *env, jstring jstr) : JUTFString(env, jstr, nullptr) {
|
||||
|
|
@ -183,13 +82,17 @@ class ScopedLocalRef {
|
|||
public:
|
||||
ScopedLocalRef(JNIEnv *env, T localRef) : mEnv(env), mLocalRef(localRef) {
|
||||
}
|
||||
|
||||
ScopedLocalRef(ScopedLocalRef &&s) noexcept: mEnv(s.mEnv), mLocalRef(s.release()) {
|
||||
}
|
||||
|
||||
explicit ScopedLocalRef(JNIEnv *env) : mEnv(env), mLocalRef(nullptr) {
|
||||
}
|
||||
|
||||
~ScopedLocalRef() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset(T ptr = NULL) {
|
||||
if (ptr != mLocalRef) {
|
||||
if (mLocalRef != NULL) {
|
||||
|
|
@ -198,14 +101,17 @@ public:
|
|||
mLocalRef = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
T release() __attribute__((warn_unused_result)) {
|
||||
T localRef = mLocalRef;
|
||||
mLocalRef = NULL;
|
||||
return localRef;
|
||||
}
|
||||
|
||||
T get() const {
|
||||
return mLocalRef;
|
||||
}
|
||||
|
||||
// We do not expose an empty constructor as it can easily lead to errors
|
||||
// using common idioms, e.g.:
|
||||
// ScopedLocalRef<...> ref;
|
||||
|
|
@ -216,16 +122,177 @@ public:
|
|||
mEnv = s.mEnv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Allows "if (scoped_ref == nullptr)"
|
||||
bool operator==(std::nullptr_t) const {
|
||||
return mLocalRef == nullptr;
|
||||
}
|
||||
|
||||
// Allows "if (scoped_ref != nullptr)"
|
||||
bool operator!=(std::nullptr_t) const {
|
||||
return mLocalRef != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
JNIEnv *mEnv;
|
||||
T mLocalRef;
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedLocalRef);
|
||||
};
|
||||
|
||||
[[maybe_unused]]
|
||||
inline void JNIExceptionClear(JNIEnv *env) {
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline bool JNIExceptionCheck(JNIEnv *env) {
|
||||
if (env->ExceptionCheck()) {
|
||||
jthrowable e = env->ExceptionOccurred();
|
||||
env->Throw(e);
|
||||
env->DeleteLocalRef(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline void JNIExceptionClearAndDescribe(JNIEnv *env) {
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
inline jstring ClearException(JNIEnv *env) {
|
||||
static jmethodID toString = env->GetMethodID(env->FindClass("java/lang/Object"), "toString",
|
||||
"()Ljava/lang/String;");
|
||||
if (auto exception = env->ExceptionOccurred()) {
|
||||
env->ExceptionClear();
|
||||
return (jstring) env->CallObjectMethod(exception, toString);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[maybe_unused]]
|
||||
inline auto unwrap_sv(T &&x) {
|
||||
if constexpr (std::is_same_v<std::decay_t<T>, std::string_view>) return x.data();
|
||||
else return std::forward<T>(x);
|
||||
}
|
||||
|
||||
template<typename Func, typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_SafeInvoke(JNIEnv *env, Func f, Args &&... args) {
|
||||
static_assert(std::is_member_function_pointer_v<Func>);
|
||||
struct finally {
|
||||
finally(JNIEnv *env) : env_(env) {}
|
||||
|
||||
~finally() {
|
||||
if (auto exception = ClearException(env_)) {
|
||||
LOGE("%s", JUTFString(env_, exception).get());
|
||||
}
|
||||
}
|
||||
|
||||
JNIEnv *env_;
|
||||
} _(env);
|
||||
|
||||
return (env->*f)(unwrap_sv(std::forward<Args>(args))...);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_FindClass(JNIEnv *env, std::string_view name) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::FindClass, name);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_GetObjectClass(JNIEnv *env, jobject obj) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetObjectClass, obj);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_GetFieldID(JNIEnv *env, jclass clazz, std::string_view name, std::string_view sig) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetFieldID, clazz, name, sig);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_GetObjectField(JNIEnv *env, jclass clazz, jfieldID fieldId) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetObjectField, clazz, fieldId);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto
|
||||
JNI_GetMethodID(JNIEnv *env, jclass clazz, std::string_view name, std::string_view sig) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetMethodID, clazz, name, sig);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_CallObjectMethod(JNIEnv *env, jobject obj, Args &&... args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::CallObjectMethod, obj, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_CallVoidMethod(JNIEnv *env, jobject obj, Args &&...args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::CallVoidMethod, obj, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_CallBooleanMethod(JNIEnv *env, jobject obj, Args &&...args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::CallBooleanMethod, obj, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto
|
||||
JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, std::string_view name, std::string_view sig) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetStaticFieldID, clazz, name, sig);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldId) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetStaticObjectField, clazz, fieldId);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto
|
||||
JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, std::string_view name, std::string_view sig) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetStaticMethodID, clazz, name, sig);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz, Args &&...args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::CallStaticVoidMethod, clazz, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz, Args &&...args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::CallStaticObjectMethod, clazz, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_CallStaticIntMethod(JNIEnv *env, jclass clazz, Args &&...args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::CallStaticIntMethod, clazz, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_GetArrayLength(JNIEnv *env, jarray array) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::GetArrayLength, array);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
[[maybe_unused]]
|
||||
inline auto JNI_NewObject(JNIEnv *env, jclass clazz, Args &&...args) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::NewObject, clazz, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
inline auto
|
||||
JNI_RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint size) {
|
||||
return JNI_SafeInvoke(env, &JNIEnv::RegisterNatives, clazz, methods, size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace lspd {
|
|||
const JNINativeMethod *methods,
|
||||
jint method_count) {
|
||||
|
||||
ScopedLocalRef<jclass> clazz(env,
|
||||
ScopedLocalRef clazz(env,
|
||||
Context::GetInstance()->FindClassFromCurrentLoader(env, class_name));
|
||||
if (clazz.get() == nullptr) {
|
||||
LOGF("Couldn't find class: %s", class_name);
|
||||
|
|
@ -43,6 +43,7 @@ namespace lspd {
|
|||
}
|
||||
return JNI_RegisterNatives(env, clazz.get(), methods, method_count);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define _NATIVEHELPER_JNI_MACRO_CAST(to) \
|
||||
reinterpret_cast<to>
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ namespace lspd {
|
|||
return;
|
||||
}
|
||||
|
||||
ScopedLocalRef<jclass> binderClass(env, env->FindClass("android/os/Binder"));
|
||||
ScopedLocalRef binderClass(env, env->FindClass("android/os/Binder"));
|
||||
exec_transact_backup_methodID_ = JNI_GetMethodID(env, binderClass.get(), "execTransact",
|
||||
"(IJJI)Z");
|
||||
auto set_table_override = reinterpret_cast<void (*)(
|
||||
|
|
@ -183,11 +183,9 @@ namespace lspd {
|
|||
|
||||
jobject service = nullptr;
|
||||
if (res) {
|
||||
env->CallVoidMethod(reply, read_exception_method_);
|
||||
if (!ClearException(env)) {
|
||||
JNI_CallVoidMethod(env, reply, read_exception_method_);
|
||||
service = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
|
||||
}
|
||||
}
|
||||
JNI_CallVoidMethod(env, data, recycleMethod_);
|
||||
JNI_CallVoidMethod(env, reply, recycleMethod_);
|
||||
if (service) {
|
||||
|
|
|
|||
|
|
@ -265,7 +265,8 @@ public class BridgeService {
|
|||
try {
|
||||
String processName = data.readString();
|
||||
IBinder heartBeat = data.readStrongBinder();
|
||||
binder = service.requestApplicationService(Binder.getCallingUid(), Binder.getCallingPid(), processName, heartBeat).asBinder();
|
||||
var applicationService = service.requestApplicationService(Binder.getCallingUid(), Binder.getCallingPid(), processName, heartBeat);
|
||||
if (applicationService != null) binder = service.asBinder();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(e));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue