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 "absl/status/status.h"
22 #include "absl/strings/str_cat.h"
23 #include "fcp/base/monitoring.h"
24 #include "fcp/jni/jni_util.h"
25 #include "fcp/protos/federatedcompute/common.pb.h"
26 
27 class MoreJniUtil {
28  public:
GetMethodIdOrAbort(JNIEnv * env,jclass clazz,fcp::jni::JavaMethodSig method)29   static jmethodID GetMethodIdOrAbort(JNIEnv *env, jclass clazz,
30                                       fcp::jni::JavaMethodSig method) {
31     jmethodID id = env->GetMethodID(clazz, method.name, method.signature);
32     FCP_CHECK(!CheckForJniException(env));
33     FCP_CHECK(id != nullptr);
34     return id;
35   }
36 
CheckForJniException(JNIEnv * env)37   static bool CheckForJniException(JNIEnv *env) {
38     if (env->ExceptionCheck()) {
39       env->ExceptionDescribe();
40       env->ExceptionClear();
41       return true;
42     }
43     return false;
44   }
45 
GetExceptionStatus(JNIEnv * env,const char * msg)46   static absl::Status GetExceptionStatus(JNIEnv *env, const char *msg) {
47     if (env->ExceptionCheck()) {
48       FCP_LOG(WARNING) << "GetExceptionStatus [" << msg
49                        << "] Java exception follows";
50       env->ExceptionDescribe();
51       env->ExceptionClear();
52       // We gracefully return AbortedError to c++ code instead of crash app. The
53       // underlying c++ code only checks if status is ok, if not it will return
54       // error status code to java.
55       return absl::AbortedError(absl::StrCat("Got Exception when ", msg));
56     } else {
57       return absl::OkStatus();
58     }
59   }
60 
JStringToString(JNIEnv * env,jstring jstr)61   static std::string JStringToString(JNIEnv *env, jstring jstr) {
62     if (jstr == nullptr) {
63       return std::string();
64     }
65     const char *cstring = env->GetStringUTFChars(jstr, nullptr);
66     FCP_CHECK(!env->ExceptionCheck());
67     std::string result(cstring);
68     env->ReleaseStringUTFChars(jstr, cstring);
69     return result;
70   }
71 
JByteArrayToString(JNIEnv * env,jbyteArray array)72   static std::string JByteArrayToString(JNIEnv *env, jbyteArray array) {
73     FCP_CHECK(array != nullptr);
74     std::string result;
75     int array_length = env->GetArrayLength(array);
76     FCP_CHECK(!env->ExceptionCheck());
77 
78     result.resize(array_length);
79     env->GetByteArrayRegion(
80         array, 0, array_length,
81         reinterpret_cast<jbyte *>(const_cast<char *>(result.data())));
82     FCP_CHECK(!env->ExceptionCheck());
83 
84     return result;
85   }
86 
getJavaVm(JNIEnv * env)87   static JavaVM *getJavaVm(JNIEnv *env) {
88     JavaVM *jvm = nullptr;
89     env->GetJavaVM(&jvm);
90     FCP_CHECK(jvm != nullptr);
91     return jvm;
92   }
93 };
94