1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <jni.h>
20 
21 #include "fcp/base/monitoring.h"
22 #include "fcp/jni/jni_util.h"
23 #include "fcp/protos/federatedcompute/common.pb.h"
24 
25 class MoreJniUtil {
26  public:
GetMethodIdOrAbort(JNIEnv * env,jclass clazz,fcp::jni::JavaMethodSig method)27   static jmethodID GetMethodIdOrAbort(JNIEnv *env, jclass clazz,
28                                       fcp::jni::JavaMethodSig method) {
29     jmethodID id = env->GetMethodID(clazz, method.name, method.signature);
30     FCP_CHECK(!CheckForJniException(env));
31     FCP_CHECK(id != nullptr);
32     return id;
33   }
34 
CheckForJniException(JNIEnv * env)35   static bool CheckForJniException(JNIEnv *env) {
36     if (env->ExceptionCheck()) {
37       env->ExceptionDescribe();
38       env->ExceptionClear();
39       return true;
40     }
41     return false;
42   }
43 
GetExceptionStatus(JNIEnv * env,const char * msg)44   static absl::Status GetExceptionStatus(JNIEnv *env, const char *msg) {
45     if (env->ExceptionCheck()) {
46       FCP_LOG(WARNING) << "GetExceptionStatus [" << msg
47                        << "] Java exception follows";
48       env->ExceptionDescribe();
49       env->ExceptionClear();
50       // We gracefully return AbortedError to c++ code instead of crash app. The
51       // underlying c++ code only checks if status is ok, if not it will return
52       // error status code to java.
53       return absl::AbortedError(absl::StrCat("Got Exception when ", msg));
54     } else {
55       return absl::OkStatus();
56     }
57   }
58 
JStringToString(JNIEnv * env,jstring jstr)59   static std::string JStringToString(JNIEnv *env, jstring jstr) {
60     if (jstr == nullptr) {
61       return std::string();
62     }
63     const char *cstring = env->GetStringUTFChars(jstr, nullptr);
64     FCP_CHECK(!env->ExceptionCheck());
65     std::string result(cstring);
66     env->ReleaseStringUTFChars(jstr, cstring);
67     return result;
68   }
69 
JByteArrayToString(JNIEnv * env,jbyteArray array)70   static std::string JByteArrayToString(JNIEnv *env, jbyteArray array) {
71     FCP_CHECK(array != nullptr);
72     std::string result;
73     int array_length = env->GetArrayLength(array);
74     FCP_CHECK(!env->ExceptionCheck());
75 
76     result.resize(array_length);
77     env->GetByteArrayRegion(
78         array, 0, array_length,
79         reinterpret_cast<jbyte *>(const_cast<char *>(result.data())));
80     FCP_CHECK(!env->ExceptionCheck());
81 
82     return result;
83   }
84 
getJavaVm(JNIEnv * env)85   static JavaVM *getJavaVm(JNIEnv *env) {
86     JavaVM *jvm = nullptr;
87     env->GetJavaVM(&jvm);
88     FCP_CHECK(jvm != nullptr);
89     return jvm;
90   }
91 };
92