6 Commits

Author SHA1 Message Date
Dan Albert
5bb06e36e1 Merge 62e815351e into c0c80cef49 2025-09-19 19:14:49 +00:00
Dan Albert
62e815351e Migrate camera/basic to RegisterNatives. 2025-09-19 12:14:40 -07:00
Dan Albert
8f104f0c12 Migrate unit-test to RegisterNatives. 2025-09-19 12:14:40 -07:00
Dan Albert
c8e408eed6 Migrate choreographer-30fps to RegisterNatives. 2025-09-19 12:14:40 -07:00
Dan Albert
ab2d2e2ccd Migrate sensor-graph to RegisterNatives. 2025-09-19 12:14:40 -07:00
Dan Albert
ace46d87b0 Migrate sanitizers to RegisterNatives. 2025-09-19 12:14:39 -07:00
15 changed files with 165 additions and 92 deletions

View File

@@ -25,6 +25,7 @@ android {
}
dependencies {
implementation project(":base")
implementation libs.appcompat
implementation project(":camera:camera-utils")
}

View File

@@ -19,6 +19,7 @@ project(CameraBasic LANGUAGES C CXX)
include(AppLibrary)
include(AndroidNdkModules)
find_package(base REQUIRED CONFIG)
find_package(camera-utils REQUIRED CONFIG)
android_ndk_import_module_native_app_glue()
@@ -34,6 +35,7 @@ add_app_library(ndk_camera SHARED
target_link_libraries(ndk_camera
PRIVATE
base::base
camera-utils::camera-utils
android
log

View File

@@ -15,6 +15,7 @@
* limitations under the License.
*/
#include <base/macros.h>
#include <ndksamples/camera/native_debug.h>
#include "camera_engine.h"
@@ -126,30 +127,46 @@ void CameraEngine::OnCameraPermission(jboolean granted) {
* exposure and sensitivity SeekBars
* takePhoto button
*/
extern "C" JNIEXPORT void JNICALL
Java_com_sample_camera_basic_CameraActivity_notifyCameraPermission(
JNIEnv*, jclass, jboolean permission) {
void notifyCameraPermission(JNIEnv*, jclass, jboolean permission) {
std::thread permissionHandler(&CameraEngine::OnCameraPermission,
GetAppEngine(), permission);
permissionHandler.detach();
}
extern "C" JNIEXPORT void JNICALL
Java_com_sample_camera_basic_CameraActivity_TakePhoto(JNIEnv*, jclass) {
void TakePhoto(JNIEnv*, jclass) {
std::thread takePhotoHandler(&CameraEngine::OnTakePhoto, GetAppEngine());
takePhotoHandler.detach();
}
extern "C" JNIEXPORT void JNICALL
Java_com_sample_camera_basic_CameraActivity_OnExposureChanged(
JNIEnv*, jobject, jlong exposurePercent) {
void OnExposureChanged(JNIEnv*, jobject, jlong exposurePercent) {
GetAppEngine()->OnCameraParameterChanged(ACAMERA_SENSOR_EXPOSURE_TIME,
exposurePercent);
}
extern "C" JNIEXPORT void JNICALL
Java_com_sample_camera_basic_CameraActivity_OnSensitivityChanged(
JNIEnv*, jobject, jlong sensitivity) {
void OnSensitivityChanged(JNIEnv*, jobject, jlong sensitivity) {
GetAppEngine()->OnCameraParameterChanged(ACAMERA_SENSOR_SENSITIVITY,
sensitivity);
}
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* _Nonnull vm, void* _Nullable) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jclass c = env->FindClass("com/sample/camera/basic/CameraActivity");
if (c == nullptr) return JNI_ERR;
static const JNINativeMethod methods[] = {
{"notifyCameraPermission", "(Z)V",
reinterpret_cast<void*>(notifyCameraPermission)},
{"TakePhoto", "()V", reinterpret_cast<void*>(TakePhoto)},
{"OnExposureChanged", "(J)V", reinterpret_cast<void*>(OnExposureChanged)},
{"OnSensitivityChanged", "(J)V",
reinterpret_cast<void*>(OnSensitivityChanged)},
};
int rc = env->RegisterNatives(c, methods, arraysize(methods));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}

View File

@@ -55,6 +55,10 @@ android {
"x86_64",
)
}
// Allows buildTypes which inherit from debug to match dependencies
// with the debug buildType.
matchingFallbacks = ["debug"]
}
release {
@@ -136,6 +140,7 @@ android {
}
buildFeatures {
prefab true
viewBinding true
}
@@ -147,6 +152,7 @@ android {
}
dependencies {
implementation project(":base")
implementation libs.appcompat
implementation libs.material
implementation libs.androidx.constraintlayout

View File

@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.22.1)
project(sanitizers LANGUAGES CXX)
include(AppLibrary)
find_package(base CONFIG REQUIRED)
add_app_library(sanitizers SHARED native-lib.cpp)
target_link_libraries(sanitizers PRIVATE log)
target_link_libraries(sanitizers PRIVATE base::base log)
if(SANITIZE)
# For asan and ubsan, we need to copy some files from the NDK into our APK.

View File

@@ -1,10 +1,9 @@
#include <base/macros.h>
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_sanitizers_MainActivity_stringFromJNI(JNIEnv* env,
jobject /* this */) {
jstring StringFromJni(JNIEnv* env, jobject /* this */) {
// Use-after-free error, caught by asan and hwasan.
int* foo = new int;
*foo = 3;
@@ -18,3 +17,23 @@ Java_com_example_sanitizers_MainActivity_stringFromJNI(JNIEnv* env,
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* _Nonnull vm,
void* _Nullable) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jclass c = env->FindClass("com/example/sanitizers/MainActivity");
if (c == nullptr) return JNI_ERR;
static const JNINativeMethod methods[] = {
{"stringFromJNI", "()Ljava/lang/String;",
reinterpret_cast<void*>(StringFromJni)},
};
int rc = env->RegisterNatives(c, methods, arraysize(methods));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}

View File

@@ -19,4 +19,12 @@ android {
path 'src/main/cpp/CMakeLists.txt'
}
}
buildFeatures {
prefab true
}
}
dependencies {
implementation project(":base")
}

View File

@@ -2,10 +2,13 @@ cmake_minimum_required(VERSION 3.22.1)
project(SensorGraph LANGUAGES CXX)
include(AppLibrary)
find_package(base CONFIG REQUIRED)
add_app_library(accelerometergraph SHARED sensorgraph.cpp)
target_link_libraries(accelerometergraph
PRIVATE
base::base
android
GLESv2
log

View File

@@ -41,6 +41,7 @@ const float SENSOR_FILTER_ALPHA = 0.1f;
* Workaround AsensorManager_getInstance() deprecation false alarm
* for Android-N and before, when compiling with NDK-r15
*/
#include <base/macros.h>
#include <dlfcn.h>
const char* kPackageName = "com.android.accelerometergraph";
ASensorManager* AcquireASensorManagerInstance(void) {
@@ -252,53 +253,48 @@ class sensorgraph {
sensorgraph gSensorGraph;
extern "C" {
JNIEXPORT void JNICALL
Java_com_android_accelerometergraph_AccelerometerGraphJNI_init(
JNIEnv* env, jclass type, jobject assetManager) {
(void)type;
void Init(JNIEnv* env, jclass, jobject assetManager) {
AAssetManager* nativeAssetManager = AAssetManager_fromJava(env, assetManager);
gSensorGraph.init(nativeAssetManager);
}
JNIEXPORT void JNICALL
Java_com_android_accelerometergraph_AccelerometerGraphJNI_surfaceCreated(
JNIEnv* env, jclass type) {
(void)env;
(void)type;
gSensorGraph.surfaceCreated();
}
void SurfaceCreated(JNIEnv*, jclass) { gSensorGraph.surfaceCreated(); }
JNIEXPORT void JNICALL
Java_com_android_accelerometergraph_AccelerometerGraphJNI_surfaceChanged(
JNIEnv* env, jclass type, jint width, jint height) {
(void)env;
(void)type;
void SurfaceChanged(JNIEnv*, jclass, jint width, jint height) {
gSensorGraph.surfaceChanged(width, height);
}
JNIEXPORT void JNICALL
Java_com_android_accelerometergraph_AccelerometerGraphJNI_drawFrame(
JNIEnv* env, jclass type) {
(void)env;
(void)type;
void DrawFrame(JNIEnv*, jclass) {
gSensorGraph.update();
gSensorGraph.render();
}
JNIEXPORT void JNICALL
Java_com_android_accelerometergraph_AccelerometerGraphJNI_pause(JNIEnv* env,
jclass type) {
(void)env;
(void)type;
gSensorGraph.pause();
}
void Pause(JNIEnv*, jclass) { gSensorGraph.pause(); }
JNIEXPORT void JNICALL
Java_com_android_accelerometergraph_AccelerometerGraphJNI_resume(JNIEnv* env,
jclass type) {
(void)env;
(void)type;
gSensorGraph.resume();
}
void Resume(JNIEnv*, jclass) { gSensorGraph.resume(); }
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* _Nonnull vm,
void* _Nullable) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jclass c =
env->FindClass("com/android/accelerometergraph/AccelerometerGraphJNI");
if (c == nullptr) return JNI_ERR;
static const JNINativeMethod methods[] = {
{"init", "(Landroid/content/res/AssetManager;)V",
reinterpret_cast<void*>(Init)},
{"surfaceCreated", "()V", reinterpret_cast<void*>(SurfaceCreated)},
{"surfaceChanged", "(II)V", reinterpret_cast<void*>(SurfaceChanged)},
{"drawFrame", "()V", reinterpret_cast<void*>(DrawFrame)},
{"pause", "()V", reinterpret_cast<void*>(Pause)},
{"resume", "()V", reinterpret_cast<void*>(Resume)},
};
int rc = env->RegisterNatives(c, methods, arraysize(methods));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}

View File

@@ -19,9 +19,14 @@ android {
path 'src/main/cpp/CMakeLists.txt'
}
}
buildFeatures {
prefab true
}
}
dependencies {
implementation project(":base")
implementation libs.appcompat
implementation libs.androidx.constraintlayout
}

View File

@@ -18,6 +18,7 @@ cmake_minimum_required(VERSION 3.22.1)
project(ChoreographerNativeActivity LANGUAGES C CXX)
include(AppLibrary)
find_package(base CONFIG REQUIRED)
# build the ndk-helper library
get_filename_component(commonDir ${CMAKE_CURRENT_SOURCE_DIR}/../../../../common ABSOLUTE)
@@ -40,6 +41,6 @@ set_target_properties(${PROJECT_NAME}
# add lib dependencies
target_link_libraries(${PROJECT_NAME}
PRIVATE
base::base
NdkHelper
)

View File

@@ -20,6 +20,7 @@
#include <EGL/egl.h>
#include <android/log.h>
#include <android_native_app_glue.h>
#include <base/macros.h>
#include <dlfcn.h>
#include <condition_variable>
@@ -303,9 +304,7 @@ void Engine::SynchInCallback(jlong frameTimeInNanos) {
}
};
extern "C" JNIEXPORT void JNICALL
Java_com_sample_choreographer_ChoreographerNativeActivity_choregrapherCallback(
JNIEnv*, jobject, jlong frameTimeInNanos) {
void ChoregrapherCallback(JNIEnv*, jobject, jlong frameTimeInNanos) {
g_engine.SynchInCallback(frameTimeInNanos);
}
@@ -611,4 +610,25 @@ void android_main(android_app* state) {
}
g_engine.TermDisplay();
}
}
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* _Nonnull vm,
void* _Nullable) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jclass c =
env->FindClass("com/sample/choreographer/ChoreographerNativeActivity");
if (c == nullptr) return JNI_ERR;
static const JNINativeMethod methods[] = {
{"choregrapherCallback", "(J)V",
reinterpret_cast<void*>(ChoregrapherCallback)},
};
int rc = env->RegisterNatives(c, methods, arraysize(methods));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}

View File

@@ -47,6 +47,7 @@ android {
}
dependencies {
implementation project(":base")
implementation libs.appcompat
implementation libs.material
implementation libs.androidx.constraintlayout

View File

@@ -8,49 +8,25 @@ project("unittest")
include(AppLibrary)
find_package(base REQUIRED CONFIG)
find_package(googletest REQUIRED CONFIG)
find_package(junit-gtest REQUIRED CONFIG)
add_app_library(adder OBJECT adder.cpp)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_app_library( # Sets the name of the library.
add_app_library(
unittest
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
$<TARGET_OBJECTS:adder>
native-lib.cpp)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
native-lib.cpp
)
target_link_libraries( # Specifies the target library.
unittest
# Links the target library to the log library
# included in the NDK.
${log-lib})
PRIVATE
base::base
log
)
add_app_library(app_tests SHARED adder_test.cpp)
target_link_libraries(app_tests

View File

@@ -1,8 +1,25 @@
#include <base/macros.h>
#include <jni.h>
#include "adder.h"
extern "C" JNIEXPORT jint JNICALL
Java_com_example_unittest_MainActivity_add(JNIEnv*, jobject, jint a, jint b) {
return add((int)a, (int)b);
}
jint Add(JNIEnv*, jobject, jint a, jint b) { return add((int)a, (int)b); }
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* _Nonnull vm,
void* _Nullable) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jclass c = env->FindClass("com/example/unittest/MainActivity");
if (c == nullptr) return JNI_ERR;
static const JNINativeMethod methods[] = {
{"add", "(II)I", reinterpret_cast<void*>(Add)},
};
int rc = env->RegisterNatives(c, methods, arraysize(methods));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}