1 /*
2  * Copyright 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 <future>
22 #include <map>
23 #include <mutex>
24 #include <vector>
25 
26 #include "external/android_native_app_glue.h"
27 
28 class JNIManager {
29 public:
30     // Used to send results from the native side to the Java app
31     static void sendResultsToJava(std::map<std::string, std::string> data);
32     // Used to receive data in native code about the test configuration from Java
33     static void sendConfigToNative(JNIEnv* env, jobject thisObj, jobjectArray data);
34 
getInstance()35     static JNIManager& getInstance() {
36         static JNIManager instance;
37         return instance;
38     }
39 
~JNIManager()40     ~JNIManager() {
41         JNIEnv* env = AttachCurrentThread();
42         env->DeleteGlobalRef(mainActivityClassGlobalRef_);
43         DetachCurrentThread();
44     }
45 
setApp(android_app * app)46     void setApp(android_app* app) { app_ = app; }
47 
AttachCurrentThread()48     JNIEnv* AttachCurrentThread() {
49         JNIEnv* env;
50         JavaVM* vm = app_->activity->vm;
51         if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) == JNI_OK) return env;
52         vm->AttachCurrentThread(&env, NULL);
53         return env;
54     }
55 
useHintSession()56     bool useHintSession() {
57         std::lock_guard lock(mutex_);
58         return hintSessionEnabled_;
59     }
60 
setMainActivityClassGlobalRef(jclass c)61     void setMainActivityClassGlobalRef(jclass c) { mainActivityClassGlobalRef_ = c; }
62 
getMainActivityClass()63     jclass getMainActivityClass() { return mainActivityClassGlobalRef_; }
64 
DetachCurrentThread()65     void DetachCurrentThread() { app_->activity->vm->DetachCurrentThread(); }
66 
67     std::vector<std::string> getTestNames();
68 
69 private:
70     std::mutex mutex_;
71     jclass mainActivityClassGlobalRef_;
72     android_app* app_;
73     bool hintSessionEnabled_;
74     static JNIManager& instance;
75     std::promise<std::vector<std::string>> testNames_;
76 };
77 
78 // #endif
79