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 #include "log_manager_wrapper_impl.h"
18 
19 #include <jni.h>
20 
21 #include <string>
22 
23 #include "fcp/jni/jni_util.h"
24 #include "fcp/protos/federatedcompute/common.pb.h"
25 #include "more_jni_util.h"
26 #include "nativehelper/scoped_local_ref.h"
27 
28 namespace fcp {
29 namespace client {
30 namespace engine {
31 namespace jni {
32 
33 using ::fcp::jni::JavaMethodSig;
34 using ::fcp::jni::ParseProtoFromJByteArray;
35 using ::fcp::jni::ScopedJniEnv;
36 using ::fcp::jni::SerializeProtoToJByteArray;
37 
38 struct LogManagerClassDesc {
39   static constexpr JavaMethodSig kLogProdDiag = {"logProdDiag", "(I)V"};
40   static constexpr JavaMethodSig kLogDebugDiag = {"logDebugDiag", "(I)V"};
41   static constexpr JavaMethodSig kLogToLongHistogram = {"logToLongHistogram",
42                                                         "(IIIIJ)V"};
43   static constexpr JavaMethodSig kLogToLongHistogramWithModelIdentifier = {
44       "logToLongHistogram", "(IIIILjava/lang/String;J)V"};
45 };
46 
LogManagerWrapperImpl(JavaVM * jvm,jobject java_log_manager)47 LogManagerWrapperImpl::LogManagerWrapperImpl(JavaVM* jvm,
48                                              jobject java_log_manager)
49     : jvm_(jvm) {
50   ScopedJniEnv scoped_env(jvm_);
51   JNIEnv* env = scoped_env.env();
52   jthis_ = env->NewGlobalRef(java_log_manager);
53   FCP_CHECK(jthis_ != nullptr);
54 
55   ScopedLocalRef<jclass> java_log_manager_class(
56       env, env->GetObjectClass(java_log_manager));
57   FCP_CHECK(java_log_manager_class.get() != nullptr);
58 
59   log_prod_diag_id_ = MoreJniUtil::GetMethodIdOrAbort(
60       env, java_log_manager_class.get(), LogManagerClassDesc::kLogProdDiag);
61 
62   log_debug_diag_id_ = MoreJniUtil::GetMethodIdOrAbort(
63       env, java_log_manager_class.get(), LogManagerClassDesc::kLogDebugDiag);
64 
65   log_to_long_histogram_id_ =
66       MoreJniUtil::GetMethodIdOrAbort(env, java_log_manager_class.get(),
67                                       LogManagerClassDesc::kLogToLongHistogram);
68   log_to_long_histogram_with_model_identifier_id_ =
69       MoreJniUtil::GetMethodIdOrAbort(
70           env, java_log_manager_class.get(),
71           LogManagerClassDesc::kLogToLongHistogramWithModelIdentifier);
72 }
73 
~LogManagerWrapperImpl()74 LogManagerWrapperImpl::~LogManagerWrapperImpl() {
75   ScopedJniEnv scoped_env(jvm_);
76   JNIEnv* env = scoped_env.env();
77   env->DeleteGlobalRef(jthis_);
78 }
79 
LogDiag(ProdDiagCode diag_code)80 void LogManagerWrapperImpl::LogDiag(ProdDiagCode diag_code) {
81   ScopedJniEnv scoped_env(jvm_);
82   JNIEnv* env = scoped_env.env();
83   env->CallVoidMethod(jthis_, log_prod_diag_id_, static_cast<jint>(diag_code));
84   FCP_CHECK(!MoreJniUtil::CheckForJniException(env));
85 }
86 
LogDiag(DebugDiagCode diag_code)87 void LogManagerWrapperImpl::LogDiag(DebugDiagCode diag_code) {
88   ScopedJniEnv scoped_env(jvm_);
89   JNIEnv* env = scoped_env.env();
90   env->CallVoidMethod(jthis_, log_debug_diag_id_, static_cast<jint>(diag_code));
91   FCP_CHECK(!MoreJniUtil::CheckForJniException(env));
92 }
93 
LogToLongHistogram(HistogramCounters histogram_counter,int execution_index,int epoch_index,DataSourceType data_source_type,int64_t value)94 void LogManagerWrapperImpl::LogToLongHistogram(
95     HistogramCounters histogram_counter, int execution_index, int epoch_index,
96     DataSourceType data_source_type, int64_t value) {
97   ScopedJniEnv scoped_env(jvm_);
98   JNIEnv* env = scoped_env.env();
99   if (model_identifier_.has_value()) {
100     ScopedLocalRef<jstring> model_identifier_jstring(
101         env, env->NewStringUTF(model_identifier_.value().c_str()));
102     FCP_CHECK(!MoreJniUtil::CheckForJniException(env));
103 
104     env->CallVoidMethod(jthis_, log_to_long_histogram_with_model_identifier_id_,
105                         static_cast<jint>(histogram_counter), execution_index,
106                         epoch_index, static_cast<jint>(data_source_type),
107                         model_identifier_jstring.get(),
108                         static_cast<jlong>(value));
109   } else {
110     env->CallVoidMethod(jthis_, log_to_long_histogram_id_,
111                         static_cast<jint>(histogram_counter), execution_index,
112                         epoch_index, static_cast<jint>(data_source_type),
113                         static_cast<jlong>(value));
114   }
115   FCP_CHECK(!MoreJniUtil::CheckForJniException(env));
116 }
117 
SetModelIdentifier(const std::string & model_identifier)118 void LogManagerWrapperImpl::SetModelIdentifier(
119     const std::string& model_identifier) {
120   model_identifier_ = model_identifier;
121 }
122 
123 }  // namespace jni
124 }  // namespace engine
125 }  // namespace client
126 }  // namespace fcp
127