1 /*
2  * Copyright 2013 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 #include <vector>
21 #include <string>
22 
23 #include <android/log.h>
24 #include <android_native_app_glue.h>
25 
26 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ndk_helper::JNIHelper::GetInstance()->GetAppName(), __VA_ARGS__))
27 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ndk_helper::JNIHelper::GetInstance()->GetAppName(), __VA_ARGS__))
28 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, ndk_helper::JNIHelper::GetInstance()->GetAppName(), __VA_ARGS__))
29 
30 namespace ndk_helper
31 {
32 
33 /******************************************************************
34  * Helper functions for JNI calls
35  * This class wraps JNI calls and provides handy interface calling commonly used features
36  * in Java SDK.
37  * Such as
38  * - loading graphics files (e.g. PNG, JPG)
39  * - character code conversion
40  * - retrieving system properties which only supported in Java SDK
41  *
42  * NOTE: To use this class, add NDKHelper.java as a corresponding helpers in Java code
43  */
44 class JNIHelper
45 {
46 private:
47     std::string app_name_;
48 
49     ANativeActivity* activity_;
50     jobject jni_helper_java_ref_;
51     jclass jni_helper_java_class_;
52 
53     //mutex for synchronization
54     //This class uses singleton pattern and can be invoked from multiple threads,
55     //each methods locks the mutex for a thread safety
56     mutable pthread_mutex_t mutex_;
57 
58     jstring GetExternalFilesDirJString( JNIEnv *env );
59     jclass RetrieveClass( JNIEnv *jni,
60             const char* class_name );
61 
62     JNIHelper();
63     ~JNIHelper();
64     JNIHelper( const JNIHelper& rhs );
65     JNIHelper& operator=( const JNIHelper& rhs );
66 
67 public:
68     /*
69      * To load your own Java classes, JNIHelper requires to be initialized with a ANativeActivity handle.
70      * This methods need to be called before any call to the helper class.
71      * Static member of the class
72      *
73      * arguments:
74      * in: activity, pointer to ANativeActivity. Used internally to set up JNI environment
75      * in: helper_class_name, pointer to Java side helper class name. (e.g. "com/sample/helper/NDKHelper" in samples )
76      */
77     static void Init( ANativeActivity* activity,
78             const char* helper_class_name );
79 
80     /*
81      * Retrieve the singleton object of the helper.
82      * Static member of the class
83 
84      * Methods in the class are designed as thread safe.
85      */
86     static JNIHelper* GetInstance();
87 
88     /*
89      * Read a file from a strorage.
90      * First, the method tries to read the file from an external storage.
91      * If it fails to read, it falls back to use assset manager and try to read the file from APK asset.
92      *
93      * arguments:
94      * in: file_name, file name to read
95      * out: buffer_ref, pointer to a vector buffer to read a file.
96      *      when the call succeeded, the buffer includes contents of specified file
97      *      when the call failed, contents of the buffer remains same
98      * return:
99      * true when file read succeeded
100      * false when it failed to read the file
101      */
102     bool ReadFile( const char* file_name,
103             std::vector<uint8_t>* buffer_ref );
104 
105     /*
106      * Load and create OpenGL texture from given file name.
107      * The method invokes BitmapFactory in Java so it can read jpeg/png formatted files
108      *
109      * The methods creates mip-map and set texture parameters like this,
110      * glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
111      * glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
112      * glGenerateMipmap( GL_TEXTURE_2D );
113      *
114      * arguments:
115      * in: file_name, file name to read, PNG&JPG is supported
116      * return:
117      * OpenGL texture name when the call succeeded
118      * When it failed to load the texture, it returns -1
119      */
120     uint32_t LoadTexture( const char* file_name );
121 
122     /*
123      * Convert string from character code other than UTF-8
124      *
125      * arguments:
126      *  in: str, pointer to a string which is encoded other than UTF-8
127      *  in: encoding, pointer to a character encoding string.
128      *  The encoding string can be any valid java.nio.charset.Charset name
129      *  e.g. "UTF-16", "Shift_JIS"
130      * return: converted input string as an UTF-8 std::string
131      */
132     std::string ConvertString( const char* str,
133             const char* encode );
134     /*
135      * Retrieve external file directory through JNI call
136      *
137      * return: std::string containing external file diretory
138      */
139     std::string GetExternalFilesDir();
140 
141     /*
142      * Audio helper
143      * Retrieves native audio buffer size which is required to achieve low latency audio
144      *
145      * return: Native audio buffer size which is a hint to achieve low latency audio
146      * If the API is not supported (API level < 17), it returns 0
147      */
148     int32_t GetNativeAudioBufferSize();
149 
150     /*
151      * Audio helper
152      * Retrieves native audio sample rate which is required to achieve low latency audio
153      *
154      * return: Native audio sample rate which is a hint to achieve low latency audio
155      */
156     int32_t GetNativeAudioSampleRate();
157 
158     /*
159      * Retrieves application bundle name
160      *
161      * return: pointer to an app name string
162      *
163      */
GetAppName()164     const char* GetAppName()
165     {
166         return app_name_.c_str();
167     }
168 
169 };
170 
171 } //namespace ndkHelper
172