mirror of
				https://github.com/android/ndk-samples
				synced 2025-11-04 14:27:06 +08:00 
			
		
		
		
	Merge 62e815351e into c0c80cef49
				
					
				
			This commit is contained in:
		@@ -19,8 +19,13 @@ android {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    namespace 'com.google.sample.echo'
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(echo LANGUAGES C CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(echo
 | 
			
		||||
    SHARED
 | 
			
		||||
@@ -10,17 +11,20 @@ add_app_library(echo
 | 
			
		||||
    audio_recorder.cpp
 | 
			
		||||
    audio_effect.cpp
 | 
			
		||||
    audio_common.cpp
 | 
			
		||||
    debug_utils.cpp)
 | 
			
		||||
    debug_utils.cpp
 | 
			
		||||
    jni.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
#include libraries needed for echo lib
 | 
			
		||||
target_link_libraries(echo
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    OpenSLES
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
    atomic)
 | 
			
		||||
    atomic
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if (ANDROID_ABI STREQUAL riscv64)
 | 
			
		||||
if(ANDROID_ABI STREQUAL riscv64)
 | 
			
		||||
    # This sample uses OpenSLES, which was deprecated in API 26. Our
 | 
			
		||||
    # minSdkVersion is 21, but we also build for riscv64, which isn't a
 | 
			
		||||
    # supported ABI yet and so that configuration is built for the latest API
 | 
			
		||||
@@ -32,4 +36,4 @@ if (ANDROID_ABI STREQUAL riscv64)
 | 
			
		||||
    # measurement in this sample that should be moved to the Oboe sample before
 | 
			
		||||
    # we delete it though.
 | 
			
		||||
    target_compile_options(echo PRIVATE -Wno-deprecated-declarations)
 | 
			
		||||
endif ()
 | 
			
		||||
endif()
 | 
			
		||||
 
 | 
			
		||||
@@ -51,9 +51,8 @@ static EchoAudioEngine engine;
 | 
			
		||||
 | 
			
		||||
bool EngineService(void* ctx, uint32_t msg, void* data);
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_createSLEngine(
 | 
			
		||||
    JNIEnv*, jclass, jint sampleRate, jint framesPerBuf, jlong delayInMs,
 | 
			
		||||
    jfloat decay) {
 | 
			
		||||
void CreateSlEngine(JNIEnv*, jclass, jint sampleRate, jint framesPerBuf,
 | 
			
		||||
                    jlong delayInMs, jfloat decay) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  memset(&engine, 0, sizeof(engine));
 | 
			
		||||
 | 
			
		||||
@@ -102,10 +101,7 @@ JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_createSLEngine(
 | 
			
		||||
  assert(engine.delayEffect_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_configureEcho(JNIEnv*, jclass,
 | 
			
		||||
                                                       jint delayInMs,
 | 
			
		||||
                                                       jfloat decay) {
 | 
			
		||||
jboolean ConfigureEcho(JNIEnv*, jclass, jint delayInMs, jfloat decay) {
 | 
			
		||||
  engine.echoDelay_ = delayInMs;
 | 
			
		||||
  engine.echoDecay_ = decay;
 | 
			
		||||
 | 
			
		||||
@@ -114,9 +110,7 @@ Java_com_google_sample_echo_MainActivity_configureEcho(JNIEnv*, jclass,
 | 
			
		||||
  return JNI_FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass) {
 | 
			
		||||
jboolean CreateSlBufferQueueAudioPlayer(JNIEnv*, jclass) {
 | 
			
		||||
  SampleFormat sampleFormat;
 | 
			
		||||
  memset(&sampleFormat, 0, sizeof(sampleFormat));
 | 
			
		||||
  sampleFormat.pcmFormat_ = (uint16_t)engine.bitsPerSample_;
 | 
			
		||||
@@ -136,17 +130,14 @@ Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(
 | 
			
		||||
  return JNI_TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_deleteSLBufferQueueAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass) {
 | 
			
		||||
void DeleteSlBufferQueueAudioPlayer(JNIEnv*, jclass) {
 | 
			
		||||
  if (engine.player_) {
 | 
			
		||||
    delete engine.player_;
 | 
			
		||||
    engine.player_ = nullptr;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
jboolean CreateAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
  SampleFormat sampleFormat;
 | 
			
		||||
  memset(&sampleFormat, 0, sizeof(sampleFormat));
 | 
			
		||||
  sampleFormat.pcmFormat_ = static_cast<uint16_t>(engine.bitsPerSample_);
 | 
			
		||||
@@ -164,15 +155,13 @@ Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
  return JNI_TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_deleteAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
void DeleteAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
  if (engine.recorder_) delete engine.recorder_;
 | 
			
		||||
 | 
			
		||||
  engine.recorder_ = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv*, jclass) {
 | 
			
		||||
void StartPlay(JNIEnv*, jclass) {
 | 
			
		||||
  engine.frameCount_ = 0;
 | 
			
		||||
  /*
 | 
			
		||||
   * start player: make it into waitForData state
 | 
			
		||||
@@ -184,8 +173,7 @@ Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv*, jclass) {
 | 
			
		||||
  engine.recorder_->Start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv*, jclass) {
 | 
			
		||||
void StopPlay(JNIEnv*, jclass) {
 | 
			
		||||
  engine.recorder_->Stop();
 | 
			
		||||
  engine.player_->Stop();
 | 
			
		||||
 | 
			
		||||
@@ -195,8 +183,7 @@ Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv*, jclass) {
 | 
			
		||||
  engine.player_ = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_deleteSLEngine(JNIEnv*, jclass) {
 | 
			
		||||
void DeleteSlEngine(JNIEnv*, jclass) {
 | 
			
		||||
  delete engine.recBufQueue_;
 | 
			
		||||
  delete engine.freeBufQueue_;
 | 
			
		||||
  releaseSampleBufs(engine.bufs_, engine.bufCount_);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								audio-echo/app/src/main/cpp/jni.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								audio-echo/app/src/main/cpp/jni.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
// Copyright (C) 2025 The Android Open Source Project
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
#include "jni_interface.h"
 | 
			
		||||
 | 
			
		||||
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/google/sample/echo/MainActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"createSLEngine", "(IIJF)V", reinterpret_cast<void*>(CreateSlEngine)},
 | 
			
		||||
      {"deleteSLEngine", "()V", reinterpret_cast<void*>(DeleteSlEngine)},
 | 
			
		||||
      {"createSLBufferQueueAudioPlayer", "()Z",
 | 
			
		||||
       reinterpret_cast<void*>(CreateSlBufferQueueAudioPlayer)},
 | 
			
		||||
      {"deleteSLBufferQueueAudioPlayer", "()V",
 | 
			
		||||
       reinterpret_cast<void*>(DeleteSlBufferQueueAudioPlayer)},
 | 
			
		||||
      {"createAudioRecorder", "()Z",
 | 
			
		||||
       reinterpret_cast<void*>(CreateAudioRecorder)},
 | 
			
		||||
      {"deleteAudioRecorder", "()V",
 | 
			
		||||
       reinterpret_cast<void*>(DeleteAudioRecorder)},
 | 
			
		||||
      {"startPlay", "()V", reinterpret_cast<void*>(StartPlay)},
 | 
			
		||||
      {"stopPlay", "()V", reinterpret_cast<void*>(StopPlay)},
 | 
			
		||||
      {"configureEcho", "(IF)Z", reinterpret_cast<void*>(ConfigureEcho)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
@@ -13,42 +13,19 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef JNI_INTERFACE_H
 | 
			
		||||
#define JNI_INTERFACE_H
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
void CreateSlEngine(JNIEnv* env, jclass, jint, jint, jlong delayInMs,
 | 
			
		||||
                    jfloat decay);
 | 
			
		||||
void DeleteSlEngine(JNIEnv* env, jclass type);
 | 
			
		||||
jboolean CreateSlBufferQueueAudioPlayer(JNIEnv* env, jclass);
 | 
			
		||||
void DeleteSlBufferQueueAudioPlayer(JNIEnv* env, jclass type);
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_createSLEngine(
 | 
			
		||||
    JNIEnv* env, jclass, jint, jint, jlong delayInMs, jfloat decay);
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_deleteSLEngine(
 | 
			
		||||
    JNIEnv* env, jclass type);
 | 
			
		||||
JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(
 | 
			
		||||
    JNIEnv* env, jclass);
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_deleteSLBufferQueueAudioPlayer(
 | 
			
		||||
    JNIEnv* env, jclass type);
 | 
			
		||||
 | 
			
		||||
JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv* env,
 | 
			
		||||
                                                             jclass type);
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_deleteAudioRecorder(JNIEnv* env,
 | 
			
		||||
                                                             jclass type);
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv* env, jclass type);
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv* env, jclass type);
 | 
			
		||||
JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_google_sample_echo_MainActivity_configureEcho(JNIEnv* env, jclass type,
 | 
			
		||||
                                                       jint delayInMs,
 | 
			
		||||
                                                       jfloat decay);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // JNI_INTERFACE_H
 | 
			
		||||
jboolean CreateAudioRecorder(JNIEnv* env, jclass type);
 | 
			
		||||
void DeleteAudioRecorder(JNIEnv* env, jclass type);
 | 
			
		||||
void StartPlay(JNIEnv* env, jclass type);
 | 
			
		||||
void StopPlay(JNIEnv* env, jclass type);
 | 
			
		||||
jboolean ConfigureEcho(JNIEnv* env, jclass type, jint delayInMs, jfloat decay);
 | 
			
		||||
 
 | 
			
		||||
@@ -12,4 +12,12 @@ android {
 | 
			
		||||
            path 'src/main/cpp/CMakeLists.txt'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,12 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(BitmapPlasma LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(plasma SHARED plasma.cpp)
 | 
			
		||||
add_app_library(plasma SHARED jni.cpp plasma.cpp)
 | 
			
		||||
 | 
			
		||||
# Include libraries needed for plasma lib
 | 
			
		||||
target_link_libraries(plasma
 | 
			
		||||
    base::base
 | 
			
		||||
    android
 | 
			
		||||
    jnigraphics
 | 
			
		||||
    log
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								bitmap-plasma/app/src/main/cpp/jni.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								bitmap-plasma/app/src/main/cpp/jni.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// Copyright (C) 2025 The Android Open Source Project
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
#include "plasma.h"
 | 
			
		||||
 | 
			
		||||
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/example/plasma/PlasmaView");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"renderPlasma", "(Landroid/graphics/Bitmap;J)V",
 | 
			
		||||
       reinterpret_cast<void*>(RenderPlasma)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
@@ -327,8 +327,7 @@ static void stats_endFrame(Stats* s) {
 | 
			
		||||
  s->lastTime = now;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_example_plasma_PlasmaView_renderPlasma(
 | 
			
		||||
    JNIEnv* env, jclass, jobject bitmap, jlong time_ms) {
 | 
			
		||||
void RenderPlasma(JNIEnv* env, jclass, jobject bitmap, jlong time_ms) {
 | 
			
		||||
  AndroidBitmapInfo info;
 | 
			
		||||
  void* pixels;
 | 
			
		||||
  int ret;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								bitmap-plasma/app/src/main/cpp/plasma.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								bitmap-plasma/app/src/main/cpp/plasma.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
// Copyright (C) 2025 The Android Open Source Project
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
void RenderPlasma(JNIEnv* env, jclass, jobject bitmap, jlong time_ms);
 | 
			
		||||
@@ -25,6 +25,7 @@ android {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation project(":camera:camera-utils")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,5 +27,6 @@ android {
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation libs.androidx.core
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation project(":camera:camera-utils")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,13 +18,9 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(CameraTextureView LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base REQUIRED CONFIG)
 | 
			
		||||
find_package(camera-utils REQUIRED CONFIG)
 | 
			
		||||
 | 
			
		||||
# Export ANativeActivity_onCreate(),
 | 
			
		||||
# Refer to: https://github.com/android-ndk/ndk/issues/381.
 | 
			
		||||
set(CMAKE_SHARED_LINKER_FLAGS
 | 
			
		||||
    "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
 | 
			
		||||
 | 
			
		||||
add_app_library(camera_textureview SHARED
 | 
			
		||||
    android_main.cpp
 | 
			
		||||
    camera_manager.cpp
 | 
			
		||||
@@ -32,9 +28,9 @@ add_app_library(camera_textureview SHARED
 | 
			
		||||
    camera_listeners.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# add lib dependencies
 | 
			
		||||
target_link_libraries(camera_textureview
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    camera-utils::camera-utils
 | 
			
		||||
    dl
 | 
			
		||||
    android
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
 *     Tested:
 | 
			
		||||
 *         Google Pixel and Nexus 6 phones
 | 
			
		||||
 */
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <ndksamples/camera/native_debug.h>
 | 
			
		||||
 | 
			
		||||
@@ -49,9 +50,7 @@ CameraAppEngine* pEngineObj = nullptr;
 | 
			
		||||
 * portrait mode.
 | 
			
		||||
 * @return application object instance ( not used in this sample )
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT jlong JNICALL
 | 
			
		||||
Java_com_sample_textureview_ViewActivity_createCamera(JNIEnv* env, jobject,
 | 
			
		||||
                                                      jint width, jint height) {
 | 
			
		||||
jlong CreateCamera(JNIEnv* env, jobject, jint width, jint height) {
 | 
			
		||||
  pEngineObj = new CameraAppEngine(env, width, height);
 | 
			
		||||
  return reinterpret_cast<jlong>(pEngineObj);
 | 
			
		||||
}
 | 
			
		||||
@@ -61,9 +60,7 @@ Java_com_sample_textureview_ViewActivity_createCamera(JNIEnv* env, jobject,
 | 
			
		||||
 *   releases native application object, which
 | 
			
		||||
 *   triggers native camera object be released
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_sample_textureview_ViewActivity_deleteCamera(JNIEnv*, jobject,
 | 
			
		||||
                                                      jlong ndkCameraObj) {
 | 
			
		||||
void DeleteCamera(JNIEnv*, jobject, jlong ndkCameraObj) {
 | 
			
		||||
  if (!pEngineObj || !ndkCameraObj) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
@@ -87,9 +84,8 @@ Java_com_sample_textureview_ViewActivity_deleteCamera(JNIEnv*, jobject,
 | 
			
		||||
 *   3) textureView size is stretched when previewing image
 | 
			
		||||
 *      on display device
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT jobject JNICALL
 | 
			
		||||
Java_com_sample_textureview_ViewActivity_getMinimumCompatiblePreviewSize(
 | 
			
		||||
    JNIEnv* env, jobject, jlong ndkCameraObj) {
 | 
			
		||||
jobject GetMinimumCompatiblePreviewSize(JNIEnv* env, jobject,
 | 
			
		||||
                                        jlong ndkCameraObj) {
 | 
			
		||||
  if (!ndkCameraObj) {
 | 
			
		||||
    return nullptr;
 | 
			
		||||
  }
 | 
			
		||||
@@ -102,28 +98,14 @@ Java_com_sample_textureview_ViewActivity_getMinimumCompatiblePreviewSize(
 | 
			
		||||
  return previewSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * getCameraSensorOrientation()
 | 
			
		||||
 * @ return camera sensor orientation angle relative to Android device's
 | 
			
		||||
 * display orientation. This sample only deal to back facing camera.
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT jint JNICALL
 | 
			
		||||
Java_com_sample_textureview_ViewActivity_getCameraSensorOrientation(
 | 
			
		||||
    JNIEnv*, jobject, jlong ndkCameraObj) {
 | 
			
		||||
  ASSERT(ndkCameraObj, "NativeObject should not be null Pointer");
 | 
			
		||||
  CameraAppEngine* pApp = reinterpret_cast<CameraAppEngine*>(ndkCameraObj);
 | 
			
		||||
  return pApp->GetCameraSensorOrientation(ACAMERA_LENS_FACING_BACK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OnPreviewSurfaceCreated()
 | 
			
		||||
 *   Notification to native camera that java TextureView is ready
 | 
			
		||||
 *   to preview video. Simply create cameraSession and
 | 
			
		||||
 *   start camera preview
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_sample_textureview_ViewActivity_onPreviewSurfaceCreated(
 | 
			
		||||
    JNIEnv*, jobject, jlong ndkCameraObj, jobject surface) {
 | 
			
		||||
void OnPreviewSurfaceCreated(JNIEnv*, jobject, jlong ndkCameraObj,
 | 
			
		||||
                             jobject surface) {
 | 
			
		||||
  ASSERT(ndkCameraObj && (jlong)pEngineObj == ndkCameraObj,
 | 
			
		||||
         "NativeObject should not be null Pointer");
 | 
			
		||||
  CameraAppEngine* pApp = reinterpret_cast<CameraAppEngine*>(ndkCameraObj);
 | 
			
		||||
@@ -137,9 +119,8 @@ Java_com_sample_textureview_ViewActivity_onPreviewSurfaceCreated(
 | 
			
		||||
 *   Native camera would:
 | 
			
		||||
 *      * stop preview
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_sample_textureview_ViewActivity_onPreviewSurfaceDestroyed(
 | 
			
		||||
    JNIEnv* env, jobject, jlong ndkCameraObj, jobject surface) {
 | 
			
		||||
void OnPreviewSurfaceDestroyed(JNIEnv* env, jobject, jlong ndkCameraObj,
 | 
			
		||||
                               jobject surface) {
 | 
			
		||||
  CameraAppEngine* pApp = reinterpret_cast<CameraAppEngine*>(ndkCameraObj);
 | 
			
		||||
  ASSERT(ndkCameraObj && pEngineObj == pApp,
 | 
			
		||||
         "NativeObject should not be null Pointer");
 | 
			
		||||
@@ -162,3 +143,29 @@ Java_com_sample_textureview_ViewActivity_onPreviewSurfaceDestroyed(
 | 
			
		||||
 | 
			
		||||
  pApp->StartPreview(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/textureview/ViewActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"createCamera", "(II)J", reinterpret_cast<void*>(CreateCamera)},
 | 
			
		||||
      {"deleteCamera", "(JLandroid/view/Surface;)V",
 | 
			
		||||
       reinterpret_cast<void*>(DeleteCamera)},
 | 
			
		||||
      {"getMinimumCompatiblePreviewSize", "(J)Landroid/util/Size;",
 | 
			
		||||
       reinterpret_cast<void*>(GetMinimumCompatiblePreviewSize)},
 | 
			
		||||
      {"onPreviewSurfaceCreated", "(JLandroid/view/Surface;)V",
 | 
			
		||||
       reinterpret_cast<void*>(OnPreviewSurfaceCreated)},
 | 
			
		||||
      {"onPreviewSurfaceDestroyed", "(JLandroid/view/Surface;)V",
 | 
			
		||||
       reinterpret_cast<void*>(OnPreviewSurfaceDestroyed)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ android {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
        viewBinding true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -27,4 +28,5 @@ dependencies {
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.material
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(exceptions LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(
 | 
			
		||||
    exceptions
 | 
			
		||||
@@ -12,5 +13,7 @@ add_app_library(
 | 
			
		||||
 | 
			
		||||
target_link_libraries(
 | 
			
		||||
    exceptions
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    log
 | 
			
		||||
)
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
@@ -6,9 +7,7 @@
 | 
			
		||||
 | 
			
		||||
void might_throw() { throw std::runtime_error("A C++ runtime_error"); }
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_exceptions_MainActivity_throwsException(JNIEnv* env,
 | 
			
		||||
                                                         jobject /* this */) {
 | 
			
		||||
void ThrowsException(JNIEnv* env, jobject /* this */) {
 | 
			
		||||
  try {
 | 
			
		||||
    might_throw();
 | 
			
		||||
  } catch (std::exception& e) {
 | 
			
		||||
@@ -18,4 +17,22 @@ Java_com_example_exceptions_MainActivity_throwsException(JNIEnv* env,
 | 
			
		||||
    // catch-all.
 | 
			
		||||
    jniThrowRuntimeException(env, "Catch-all");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/example/exceptions/MainActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"throwsException", "()V", reinterpret_cast<void*>(ThrowsException)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,4 +19,12 @@ android {
 | 
			
		||||
            path 'src/main/cpp/CMakeLists.txt'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(Gles3Jni LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(gles3jni SHARED
 | 
			
		||||
    ${GL3STUB_SRC}
 | 
			
		||||
@@ -10,8 +11,8 @@ add_app_library(gles3jni SHARED
 | 
			
		||||
    RendererES3.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Include libraries needed for gles3jni lib
 | 
			
		||||
target_link_libraries(gles3jni
 | 
			
		||||
    base::base
 | 
			
		||||
    GLESv3
 | 
			
		||||
    android
 | 
			
		||||
    EGL
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
 | 
			
		||||
#include "gles3jni.h"
 | 
			
		||||
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
@@ -227,21 +228,11 @@ void Renderer::render() {
 | 
			
		||||
 | 
			
		||||
static Renderer* g_renderer = NULL;
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv* env,
 | 
			
		||||
                                                                  jobject obj);
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_resize(
 | 
			
		||||
    JNIEnv* env, jobject obj, jint width, jint height);
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv* env,
 | 
			
		||||
                                                                  jobject obj);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(DYNAMIC_ES3)
 | 
			
		||||
static GLboolean gl3stubInit() { return GL_TRUE; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv*,
 | 
			
		||||
                                                                  jobject) {
 | 
			
		||||
void Init(JNIEnv*, jclass) {
 | 
			
		||||
  if (g_renderer) {
 | 
			
		||||
    delete g_renderer;
 | 
			
		||||
    g_renderer = NULL;
 | 
			
		||||
@@ -262,16 +253,34 @@ JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv*,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_resize(
 | 
			
		||||
    JNIEnv*, jobject, jint width, jint height) {
 | 
			
		||||
void Resize(JNIEnv*, jclass, jint width, jint height) {
 | 
			
		||||
  if (g_renderer) {
 | 
			
		||||
    g_renderer->resize(width, height);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv*,
 | 
			
		||||
                                                                  jobject) {
 | 
			
		||||
void Step(JNIEnv*, jclass) {
 | 
			
		||||
  if (g_renderer) {
 | 
			
		||||
    g_renderer->render();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/android/gles3jni/GLES3JNILib");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"init", "()V", reinterpret_cast<void*>(Init)},
 | 
			
		||||
      {"resize", "(II)V", reinterpret_cast<void*>(Resize)},
 | 
			
		||||
      {"step", "()V", reinterpret_cast<void*>(Step)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,4 +20,12 @@ android {
 | 
			
		||||
            path 'src/main/cpp/CMakeLists.txt'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,13 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(HelloGl2 LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(gl2jni SHARED gl_code.cpp)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(gl2jni
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
    EGL
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
#include <GLES2/gl2.h>
 | 
			
		||||
#include <GLES2/gl2ext.h>
 | 
			
		||||
#include <android/log.h>
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@@ -163,15 +164,27 @@ void renderFrame() {
 | 
			
		||||
  checkGlError("glDrawArrays");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv*, jobject,
 | 
			
		||||
                                                              jint width,
 | 
			
		||||
                                                              jint height) {
 | 
			
		||||
void Init(JNIEnv*, jclass, jint width, jint height) {
 | 
			
		||||
  setupGraphics(width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv*,
 | 
			
		||||
                                                              jobject) {
 | 
			
		||||
  renderFrame();
 | 
			
		||||
}
 | 
			
		||||
void Step(JNIEnv*, jclass) { renderFrame(); }
 | 
			
		||||
 | 
			
		||||
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/android/gl2jni/GL2JNILib");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"init", "(II)V", reinterpret_cast<void*>(Init)},
 | 
			
		||||
      {"step", "()V", reinterpret_cast<void*>(Step)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,14 @@ android {
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        viewBinding true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,15 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project("hello-jni" LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(hello-jni SHARED
 | 
			
		||||
    hello-jni.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(hello-jni
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,13 +14,31 @@
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT jstring JNICALL
 | 
			
		||||
Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env,
 | 
			
		||||
                                                 jobject /* this */) {
 | 
			
		||||
jstring StringFromJni(JNIEnv* env, jobject) {
 | 
			
		||||
  std::string hello = "Hello from JNI.";
 | 
			
		||||
  return env->NewStringUTF(hello.c_str());
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/example/hellojni/HelloJni");
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,14 @@ android {
 | 
			
		||||
            path "src/main/cpp/CMakeLists.txt"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,13 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(HelloJniCallback LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(hello-jnicallback SHARED hello-jnicallback.cpp)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(hello-jnicallback
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
 */
 | 
			
		||||
#include <android/log.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
@@ -132,40 +133,6 @@ void queryRuntimeInfo(JNIEnv* env, jobject instance) {
 | 
			
		||||
  (void)result;  // silence the compiler warning
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * processing one time initialization:
 | 
			
		||||
 *     Cache the javaVM into our context
 | 
			
		||||
 *     Find class ID for JniHandler
 | 
			
		||||
 *     Create an instance of JniHandler
 | 
			
		||||
 *     Make global reference since we are using them from a native thread
 | 
			
		||||
 * Note:
 | 
			
		||||
 *     All resources allocated here are never released by application
 | 
			
		||||
 *     we rely on system to free all global refs when it goes away;
 | 
			
		||||
 *     the pairing function JNI_OnUnload() never gets called at all.
 | 
			
		||||
 */
 | 
			
		||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
 | 
			
		||||
  JNIEnv* env;
 | 
			
		||||
  memset(&g_ctx, 0, sizeof(g_ctx));
 | 
			
		||||
 | 
			
		||||
  g_ctx.javaVM = vm;
 | 
			
		||||
  if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
 | 
			
		||||
    return JNI_ERR;  // JNI version not supported.
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  jclass clz = env->FindClass("com/example/hellojnicallback/JniHandler");
 | 
			
		||||
  g_ctx.jniHandlerClz = static_cast<jclass>(env->NewGlobalRef(clz));
 | 
			
		||||
 | 
			
		||||
  jmethodID jniHandlerCtor =
 | 
			
		||||
      env->GetMethodID(g_ctx.jniHandlerClz, "<init>", "()V");
 | 
			
		||||
  jobject handler = env->NewObject(g_ctx.jniHandlerClz, jniHandlerCtor);
 | 
			
		||||
  g_ctx.jniHandlerObj = env->NewGlobalRef(handler);
 | 
			
		||||
  queryRuntimeInfo(env, g_ctx.jniHandlerObj);
 | 
			
		||||
 | 
			
		||||
  g_ctx.done = 0;
 | 
			
		||||
  g_ctx.mainActivityObj = NULL;
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A helper function to wrap java JniHandler::updateStatus(String msg)
 | 
			
		||||
 * JNI allow us to call this function via an instance even it is
 | 
			
		||||
@@ -248,9 +215,7 @@ void* UpdateTicks(void* context) {
 | 
			
		||||
/*
 | 
			
		||||
 * Interface to Java side to start ticks, caller is from onResume()
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_hellojnicallback_MainActivity_startTicks(JNIEnv* env,
 | 
			
		||||
                                                          jobject instance) {
 | 
			
		||||
void StartTicks(JNIEnv* env, jobject instance) {
 | 
			
		||||
  pthread_t threadInfo_;
 | 
			
		||||
  pthread_attr_t threadAttr_;
 | 
			
		||||
 | 
			
		||||
@@ -276,8 +241,7 @@ Java_com_example_hellojnicallback_MainActivity_startTicks(JNIEnv* env,
 | 
			
		||||
 *    we need to hold and make sure our native thread has finished before return
 | 
			
		||||
 *    for a clean shutdown. The caller is from onPause
 | 
			
		||||
 */
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_hellojnicallback_MainActivity_StopTicks(JNIEnv* env, jobject) {
 | 
			
		||||
void StopTicks(JNIEnv* env, jobject) {
 | 
			
		||||
  pthread_mutex_lock(&g_ctx.lock);
 | 
			
		||||
  g_ctx.done = 1;
 | 
			
		||||
  pthread_mutex_unlock(&g_ctx.lock);
 | 
			
		||||
@@ -298,3 +262,48 @@ Java_com_example_hellojnicallback_MainActivity_StopTicks(JNIEnv* env, jobject) {
 | 
			
		||||
 | 
			
		||||
  pthread_mutex_destroy(&g_ctx.lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * processing one time initialization:
 | 
			
		||||
 *     Cache the javaVM into our context
 | 
			
		||||
 *     Register native methods
 | 
			
		||||
 *     Find class ID for JniHandler
 | 
			
		||||
 *     Create an instance of JniHandler
 | 
			
		||||
 *     Make global reference since we are using them from a native thread
 | 
			
		||||
 * Note:
 | 
			
		||||
 *     All resources allocated here are never released by application
 | 
			
		||||
 *     we rely on system to free all global refs when it goes away;
 | 
			
		||||
 *     the pairing function JNI_OnUnload() never gets called at all.
 | 
			
		||||
 */
 | 
			
		||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
 | 
			
		||||
  JNIEnv* env;
 | 
			
		||||
  memset(&g_ctx, 0, sizeof(g_ctx));
 | 
			
		||||
 | 
			
		||||
  g_ctx.javaVM = vm;
 | 
			
		||||
  if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
 | 
			
		||||
    return JNI_ERR;  // JNI version not supported.
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  jclass c = env->FindClass("com/example/hellojnicallback/MainActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"startTicks", "()V", reinterpret_cast<void*>(StartTicks)},
 | 
			
		||||
      {"StopTicks", "()V", reinterpret_cast<void*>(StopTicks)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  jclass clz = env->FindClass("com/example/hellojnicallback/JniHandler");
 | 
			
		||||
  g_ctx.jniHandlerClz = static_cast<jclass>(env->NewGlobalRef(clz));
 | 
			
		||||
 | 
			
		||||
  jmethodID jniHandlerCtor =
 | 
			
		||||
      env->GetMethodID(g_ctx.jniHandlerClz, "<init>", "()V");
 | 
			
		||||
  jobject handler = env->NewObject(g_ctx.jniHandlerClz, jniHandlerCtor);
 | 
			
		||||
  g_ctx.jniHandlerObj = env->NewGlobalRef(handler);
 | 
			
		||||
  queryRuntimeInfo(env, g_ctx.jniHandlerObj);
 | 
			
		||||
 | 
			
		||||
  g_ctx.done = 0;
 | 
			
		||||
  g_ctx.mainActivityObj = NULL;
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
# Sample removed
 | 
			
		||||
 | 
			
		||||
This sample has been removed in favor of the new `vectorization` sample, which
 | 
			
		||||
demonstrates more options for vectorization and includes a benchmark to
 | 
			
		||||
highlight that performance decisions cannot be made correctly unless you measure
 | 
			
		||||
them.
 | 
			
		||||
@@ -33,6 +33,7 @@ android {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
    implementation libs.oboe
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(hello-oboe LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
# add oboe pre-release lib hosted at https://maven.google.com/web/index.html
 | 
			
		||||
# under com.google.oboe:oboe. For documentation about oboe pre-built lib, refer to
 | 
			
		||||
@@ -25,7 +26,7 @@ find_package(oboe REQUIRED CONFIG)
 | 
			
		||||
 | 
			
		||||
# build application with the oboe lib
 | 
			
		||||
add_app_library(${PROJECT_NAME} SHARED hello-oboe.cpp)
 | 
			
		||||
target_link_libraries(${PROJECT_NAME} oboe::oboe android log)
 | 
			
		||||
target_link_libraries(${PROJECT_NAME} base::base oboe::oboe android log)
 | 
			
		||||
 | 
			
		||||
# Enable optimization flags: if having problems with source level debugging,
 | 
			
		||||
# disable -Ofast ( and debug ), re-enable after done debugging.
 | 
			
		||||
 
 | 
			
		||||
@@ -15,27 +15,23 @@
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
#include "OboeSinePlayer.h"
 | 
			
		||||
 | 
			
		||||
static OboeSinePlayer* oboePlayer = nullptr;
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
/* Create Oboe playback stream
 | 
			
		||||
 * Returns:  0 - success
 | 
			
		||||
 *          -1 - failed
 | 
			
		||||
 */
 | 
			
		||||
JNIEXPORT jint JNICALL
 | 
			
		||||
Java_com_google_example_hellooboe_MainActivity_createStream(
 | 
			
		||||
    JNIEnv* /* env */, jobject /* this */) {
 | 
			
		||||
jint CreateStream(JNIEnv* /* env */, jobject /* this */) {
 | 
			
		||||
  oboePlayer = new OboeSinePlayer();
 | 
			
		||||
 | 
			
		||||
  return oboePlayer ? 0 : -1;
 | 
			
		||||
}
 | 
			
		||||
JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_google_example_hellooboe_MainActivity_destroyStream(
 | 
			
		||||
    JNIEnv* /* env */, jobject /* this */) {
 | 
			
		||||
void DestroyStream(JNIEnv* /* env */, jobject /* this */) {
 | 
			
		||||
  if (oboePlayer) {
 | 
			
		||||
    delete oboePlayer;
 | 
			
		||||
    oboePlayer = nullptr;
 | 
			
		||||
@@ -46,8 +42,7 @@ Java_com_google_example_hellooboe_MainActivity_destroyStream(
 | 
			
		||||
 * returns:  0  - success
 | 
			
		||||
 *          -1  - failed (stream has not created yet )
 | 
			
		||||
 */
 | 
			
		||||
JNIEXPORT jint JNICALL Java_com_google_example_hellooboe_MainActivity_playSound(
 | 
			
		||||
    JNIEnv* /* env */, jobject /* this */, jboolean enable) {
 | 
			
		||||
jint PlaySound(JNIEnv* /* env */, jobject /* this */, jboolean enable) {
 | 
			
		||||
  jint result = 0;
 | 
			
		||||
  if (oboePlayer) {
 | 
			
		||||
    oboePlayer->enable(enable);
 | 
			
		||||
@@ -56,4 +51,23 @@ JNIEXPORT jint JNICALL Java_com_google_example_hellooboe_MainActivity_playSound(
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/google/example/hellooboe/MainActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"createStream", "()I", reinterpret_cast<void*>(CreateStream)},
 | 
			
		||||
      {"destroyStream", "()V", reinterpret_cast<void*>(DestroyStream)},
 | 
			
		||||
      {"playSound", "(Z)I", reinterpret_cast<void*>(PlaySound)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,11 @@ android {
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        buildConfig = true
 | 
			
		||||
        prefab = true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(NativeAudio LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(native-audio-jni SHARED
 | 
			
		||||
    native-audio-jni.cpp
 | 
			
		||||
@@ -9,6 +10,8 @@ add_app_library(native-audio-jni SHARED
 | 
			
		||||
 | 
			
		||||
# Include libraries needed for native-audio-jni lib
 | 
			
		||||
target_link_libraries(native-audio-jni
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
    OpenSLES
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -234,8 +235,7 @@ void bqRecorderCallback([[maybe_unused]] SLAndroidSimpleBufferQueueItf bq,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create the engine and output mix objects
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_createEngine(JNIEnv*, jclass) {
 | 
			
		||||
void CreateEngine(JNIEnv*, jclass) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // create engine
 | 
			
		||||
@@ -286,9 +286,8 @@ Java_com_example_nativeaudio_NativeAudio_createEngine(JNIEnv*, jclass) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create buffer queue audio player
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_createBufferQueueAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jint sampleRate, jint bufSize) {
 | 
			
		||||
void CreateBufferQueueAudioPlayer(JNIEnv*, jclass, jint sampleRate,
 | 
			
		||||
                                  jint bufSize) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  if (sampleRate >= 0 && bufSize >= 0) {
 | 
			
		||||
    bqPlayerSampleRate = sampleRate * 1000;
 | 
			
		||||
@@ -395,10 +394,7 @@ Java_com_example_nativeaudio_NativeAudio_createBufferQueueAudioPlayer(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create URI audio player
 | 
			
		||||
extern "C" JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_createUriAudioPlayer(JNIEnv* env,
 | 
			
		||||
                                                              jclass,
 | 
			
		||||
                                                              jstring uri) {
 | 
			
		||||
jboolean CreateUriAudioPlayer(JNIEnv* env, jclass, jstring uri) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // convert Java string to UTF-8
 | 
			
		||||
@@ -471,9 +467,7 @@ Java_com_example_nativeaudio_NativeAudio_createUriAudioPlayer(JNIEnv* env,
 | 
			
		||||
 | 
			
		||||
// set the playing state for the URI audio player
 | 
			
		||||
// to PLAYING (true) or PAUSED (false)
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setPlayingUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jboolean isPlaying) {
 | 
			
		||||
void SetPlayingUriAudioPlayer(JNIEnv*, jclass, jboolean isPlaying) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // make sure the URI audio player was created
 | 
			
		||||
@@ -488,9 +482,7 @@ Java_com_example_nativeaudio_NativeAudio_setPlayingUriAudioPlayer(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set the whole file looping state for the URI audio player
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setLoopingUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jboolean isLooping) {
 | 
			
		||||
void SetLoopingUriAudioPlayer(JNIEnv*, jclass, jboolean isLooping) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // make sure the URI audio player was created
 | 
			
		||||
@@ -515,9 +507,7 @@ static SLMuteSoloItf getMuteSolo() {
 | 
			
		||||
    return bqPlayerMuteSolo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setChannelMuteUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jint chan, jboolean mute) {
 | 
			
		||||
void SetChannelMuteUriAudioPlayer(JNIEnv*, jclass, jint chan, jboolean mute) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLMuteSoloItf muteSoloItf = getMuteSolo();
 | 
			
		||||
  if (NULL != muteSoloItf) {
 | 
			
		||||
@@ -527,9 +517,7 @@ Java_com_example_nativeaudio_NativeAudio_setChannelMuteUriAudioPlayer(
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setChannelSoloUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jint chan, jboolean solo) {
 | 
			
		||||
void SetChannelSoloUriAudioPlayer(JNIEnv*, jclass, jint chan, jboolean solo) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLMuteSoloItf muteSoloItf = getMuteSolo();
 | 
			
		||||
  if (NULL != muteSoloItf) {
 | 
			
		||||
@@ -539,9 +527,7 @@ Java_com_example_nativeaudio_NativeAudio_setChannelSoloUriAudioPlayer(
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT jint JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_getNumChannelsUriAudioPlayer(JNIEnv*,
 | 
			
		||||
                                                                      jclass) {
 | 
			
		||||
jint GetNumChannelsUriAudioPlayer(JNIEnv*, jclass) {
 | 
			
		||||
  SLuint8 numChannels;
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLMuteSoloItf muteSoloItf = getMuteSolo();
 | 
			
		||||
@@ -570,9 +556,7 @@ static SLVolumeItf getVolume() {
 | 
			
		||||
    return bqPlayerVolume;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setVolumeUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jint millibel) {
 | 
			
		||||
void SetVolumeUriAudioPlayer(JNIEnv*, jclass, jint millibel) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLVolumeItf volumeItf = getVolume();
 | 
			
		||||
  if (NULL != volumeItf) {
 | 
			
		||||
@@ -582,9 +566,7 @@ Java_com_example_nativeaudio_NativeAudio_setVolumeUriAudioPlayer(
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setMuteUriAudioPlayer(JNIEnv*, jclass,
 | 
			
		||||
                                                               jboolean mute) {
 | 
			
		||||
void SetMuteUriAudioPlayer(JNIEnv*, jclass, jboolean mute) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLVolumeItf volumeItf = getVolume();
 | 
			
		||||
  if (NULL != volumeItf) {
 | 
			
		||||
@@ -594,9 +576,7 @@ Java_com_example_nativeaudio_NativeAudio_setMuteUriAudioPlayer(JNIEnv*, jclass,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_enableStereoPositionUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jboolean enable) {
 | 
			
		||||
void EnableStereoPositionUriAudioPlayer(JNIEnv*, jclass, jboolean enable) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLVolumeItf volumeItf = getVolume();
 | 
			
		||||
  if (NULL != volumeItf) {
 | 
			
		||||
@@ -606,9 +586,7 @@ Java_com_example_nativeaudio_NativeAudio_enableStereoPositionUriAudioPlayer(
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setStereoPositionUriAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jint permille) {
 | 
			
		||||
void SetStereoPositionUriAudioPlayer(JNIEnv*, jclass, jint permille) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
  SLVolumeItf volumeItf = getVolume();
 | 
			
		||||
  if (NULL != volumeItf) {
 | 
			
		||||
@@ -619,9 +597,7 @@ Java_com_example_nativeaudio_NativeAudio_setStereoPositionUriAudioPlayer(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// enable reverb on the buffer queue player
 | 
			
		||||
extern "C" JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_enableReverb(JNIEnv*, jclass,
 | 
			
		||||
                                                      jboolean enabled) {
 | 
			
		||||
jboolean EnableReverb(JNIEnv*, jclass, jboolean enabled) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // we might not have been able to add environmental reverb to the output mix
 | 
			
		||||
@@ -649,9 +625,7 @@ Java_com_example_nativeaudio_NativeAudio_enableReverb(JNIEnv*, jclass,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// select the desired clip and play count, and enqueue the first buffer if idle
 | 
			
		||||
extern "C" JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_selectClip(JNIEnv*, jclass, jint which,
 | 
			
		||||
                                                    jint count) {
 | 
			
		||||
jboolean SelectClip(JNIEnv*, jclass, jint which, jint count) {
 | 
			
		||||
  if (pthread_mutex_trylock(&audioEngineLock)) {
 | 
			
		||||
    // If we could not acquire audio engine lock, reject this request and client
 | 
			
		||||
    // should re-try
 | 
			
		||||
@@ -722,9 +696,8 @@ Java_com_example_nativeaudio_NativeAudio_selectClip(JNIEnv*, jclass, jint which,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create asset audio player
 | 
			
		||||
extern "C" JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_createAssetAudioPlayer(
 | 
			
		||||
    JNIEnv* env, jclass, jobject assetManager, jstring filename) {
 | 
			
		||||
jboolean CreateAssetAudioPlayer(JNIEnv* env, jclass, jobject assetManager,
 | 
			
		||||
                                jstring filename) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // convert Java string to UTF-8
 | 
			
		||||
@@ -811,9 +784,7 @@ Java_com_example_nativeaudio_NativeAudio_createAssetAudioPlayer(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set the playing state for the asset audio player
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_setPlayingAssetAudioPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jboolean isPlaying) {
 | 
			
		||||
void SetPlayingAssetAudioPlayer(JNIEnv*, jclass, jboolean isPlaying) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // make sure the asset audio player was created
 | 
			
		||||
@@ -830,8 +801,7 @@ Java_com_example_nativeaudio_NativeAudio_setPlayingAssetAudioPlayer(
 | 
			
		||||
// create audio recorder: recorder is not in fast path
 | 
			
		||||
//    like to avoid excessive re-sampling while playing back from Hello &
 | 
			
		||||
//    Android clip
 | 
			
		||||
extern "C" JNIEXPORT jboolean JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_createAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
jboolean CreateAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  // configure audio source
 | 
			
		||||
@@ -891,8 +861,7 @@ Java_com_example_nativeaudio_NativeAudio_createAudioRecorder(JNIEnv*, jclass) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set the recording state for the audio recorder
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_startRecording(JNIEnv*, jclass) {
 | 
			
		||||
void StartRecording(JNIEnv*, jclass) {
 | 
			
		||||
  SLresult result;
 | 
			
		||||
 | 
			
		||||
  if (pthread_mutex_trylock(&audioEngineLock)) {
 | 
			
		||||
@@ -929,8 +898,7 @@ Java_com_example_nativeaudio_NativeAudio_startRecording(JNIEnv*, jclass) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// shut down the native audio system
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_nativeaudio_NativeAudio_shutdown(JNIEnv*, jclass) {
 | 
			
		||||
void Shutdown(JNIEnv*, jclass) {
 | 
			
		||||
  // destroy buffer queue audio player object, and invalidate all associated
 | 
			
		||||
  // interfaces
 | 
			
		||||
  if (bqPlayerObject != NULL) {
 | 
			
		||||
@@ -988,3 +956,55 @@ Java_com_example_nativeaudio_NativeAudio_shutdown(JNIEnv*, jclass) {
 | 
			
		||||
 | 
			
		||||
  pthread_mutex_destroy(&audioEngineLock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/nativeaudio/NativeAudio");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"createEngine", "()V", reinterpret_cast<void*>(CreateEngine)},
 | 
			
		||||
      {"createBufferQueueAudioPlayer", "(II)V",
 | 
			
		||||
       reinterpret_cast<void*>(CreateBufferQueueAudioPlayer)},
 | 
			
		||||
      {"createUriAudioPlayer", "(Ljava/lang/String;)Z",
 | 
			
		||||
       reinterpret_cast<void*>(CreateUriAudioPlayer)},
 | 
			
		||||
      {"setPlayingUriAudioPlayer", "(Z)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetPlayingUriAudioPlayer)},
 | 
			
		||||
      {"setLoopingUriAudioPlayer", "(Z)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetLoopingUriAudioPlayer)},
 | 
			
		||||
      {"setChannelMuteUriAudioPlayer", "(IZ)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetChannelMuteUriAudioPlayer)},
 | 
			
		||||
      {"setChannelSoloUriAudioPlayer", "(IZ)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetChannelSoloUriAudioPlayer)},
 | 
			
		||||
      {"getNumChannelsUriAudioPlayer", "()I",
 | 
			
		||||
       reinterpret_cast<void*>(GetNumChannelsUriAudioPlayer)},
 | 
			
		||||
      {"setVolumeUriAudioPlayer", "(I)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetVolumeUriAudioPlayer)},
 | 
			
		||||
      {"setMuteUriAudioPlayer", "(Z)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetMuteUriAudioPlayer)},
 | 
			
		||||
      {"enableStereoPositionUriAudioPlayer", "(Z)V",
 | 
			
		||||
       reinterpret_cast<void*>(EnableStereoPositionUriAudioPlayer)},
 | 
			
		||||
      {"setStereoPositionUriAudioPlayer", "(I)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetStereoPositionUriAudioPlayer)},
 | 
			
		||||
      {"enableReverb", "(Z)Z", reinterpret_cast<void*>(EnableReverb)},
 | 
			
		||||
      {"selectClip", "(II)Z", reinterpret_cast<void*>(SelectClip)},
 | 
			
		||||
      {"createAssetAudioPlayer",
 | 
			
		||||
       "(Landroid/content/res/AssetManager;Ljava/lang/String;)Z",
 | 
			
		||||
       reinterpret_cast<void*>(CreateAssetAudioPlayer)},
 | 
			
		||||
      {"setPlayingAssetAudioPlayer", "(Z)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetPlayingAssetAudioPlayer)},
 | 
			
		||||
      {"createAudioRecorder", "()Z",
 | 
			
		||||
       reinterpret_cast<void*>(CreateAudioRecorder)},
 | 
			
		||||
      {"startRecording", "()V", reinterpret_cast<void*>(StartRecording)},
 | 
			
		||||
      {"shutdown", "()V", reinterpret_cast<void*>(Shutdown)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,4 +19,12 @@ android {
 | 
			
		||||
            path 'src/main/cpp/CMakeLists.txt'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(NativeCodec LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(native-codec-jni SHARED
 | 
			
		||||
    looper.cpp
 | 
			
		||||
@@ -9,6 +10,8 @@ add_app_library(native-codec-jni SHARED
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(native-codec-jni
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
    mediandk
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@
 | 
			
		||||
#include <android/asset_manager.h>
 | 
			
		||||
#include <android/asset_manager_jni.h>
 | 
			
		||||
#include <android/native_window_jni.h>
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int fd;
 | 
			
		||||
@@ -196,10 +197,8 @@ void mylooper::handle(int what, void* obj) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
jboolean Java_com_example_nativecodec_NativeCodec_createStreamingMediaPlayer(
 | 
			
		||||
    JNIEnv* env, jclass, jobject assetMgr, jstring filename) {
 | 
			
		||||
jboolean CreateStreamingMediaPlayer(JNIEnv* env, jclass, jobject assetMgr,
 | 
			
		||||
                                    jstring filename) {
 | 
			
		||||
  LOGV("@@@ create");
 | 
			
		||||
 | 
			
		||||
  // convert Java string to UTF-8
 | 
			
		||||
@@ -268,8 +267,7 @@ jboolean Java_com_example_nativecodec_NativeCodec_createStreamingMediaPlayer(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set the playing state for the streaming media player
 | 
			
		||||
void Java_com_example_nativecodec_NativeCodec_setPlayingStreamingMediaPlayer(
 | 
			
		||||
    JNIEnv*, jclass, jboolean isPlaying) {
 | 
			
		||||
void SetPlayingStreamingMediaPlayer(JNIEnv*, jclass, jboolean isPlaying) {
 | 
			
		||||
  LOGV("@@@ playpause: %d", isPlaying);
 | 
			
		||||
  if (mlooper) {
 | 
			
		||||
    if (isPlaying) {
 | 
			
		||||
@@ -281,7 +279,7 @@ void Java_com_example_nativecodec_NativeCodec_setPlayingStreamingMediaPlayer(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// shut down the native media system
 | 
			
		||||
void Java_com_example_nativecodec_NativeCodec_shutdown(JNIEnv*, jclass) {
 | 
			
		||||
void Shutdown(JNIEnv*, jclass) {
 | 
			
		||||
  LOGV("@@@ shutdown");
 | 
			
		||||
  if (mlooper) {
 | 
			
		||||
    mlooper->post(kMsgDecodeDone, &data, true /* flush */);
 | 
			
		||||
@@ -296,8 +294,7 @@ void Java_com_example_nativecodec_NativeCodec_shutdown(JNIEnv*, jclass) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set the surface
 | 
			
		||||
void Java_com_example_nativecodec_NativeCodec_setSurface(JNIEnv* env, jclass,
 | 
			
		||||
                                                         jobject surface) {
 | 
			
		||||
void SetSurface(JNIEnv* env, jclass, jobject surface) {
 | 
			
		||||
  // obtain a native window from a Java surface
 | 
			
		||||
  if (data.window) {
 | 
			
		||||
    ANativeWindow_release(data.window);
 | 
			
		||||
@@ -308,11 +305,37 @@ void Java_com_example_nativecodec_NativeCodec_setSurface(JNIEnv* env, jclass,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// rewind the streaming media player
 | 
			
		||||
void Java_com_example_nativecodec_NativeCodec_rewindStreamingMediaPlayer(
 | 
			
		||||
    JNIEnv*, jclass) {
 | 
			
		||||
void RewindStreamingMediaPlayer(JNIEnv*, jclass) {
 | 
			
		||||
  LOGV("@@@ rewind");
 | 
			
		||||
  if (mlooper) {
 | 
			
		||||
    mlooper->post(kMsgSeek, &data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/nativecodec/NativeCodec");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"createStreamingMediaPlayer",
 | 
			
		||||
       "(Landroid/content/res/AssetManager;Ljava/lang/String;)Z",
 | 
			
		||||
       reinterpret_cast<void*>(CreateStreamingMediaPlayer)},
 | 
			
		||||
      {"setPlayingStreamingMediaPlayer", "(Z)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetPlayingStreamingMediaPlayer)},
 | 
			
		||||
      {"shutdown", "()V", reinterpret_cast<void*>(Shutdown)},
 | 
			
		||||
      {"setSurface", "(Landroid/view/Surface;)V",
 | 
			
		||||
       reinterpret_cast<void*>(SetSurface)},
 | 
			
		||||
      {"rewindStreamingMediaPlayer", "()V",
 | 
			
		||||
       reinterpret_cast<void*>(RewindStreamingMediaPlayer)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ plugins {
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    namespace 'com.example.nativemidi'
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        applicationId "com.example.nativemidi"
 | 
			
		||||
        minSdkVersion 29
 | 
			
		||||
@@ -22,9 +22,14 @@ android {
 | 
			
		||||
            path "src/main/cpp/CMakeLists.txt"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(native_midi LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
add_app_library(${PROJECT_NAME}
 | 
			
		||||
    SHARED
 | 
			
		||||
@@ -9,4 +10,11 @@ add_app_library(${PROJECT_NAME}
 | 
			
		||||
    MainActivity.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(${PROJECT_NAME} PRIVATE amidi OpenSLES android log)
 | 
			
		||||
target_link_libraries(${PROJECT_NAME}
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    base::base
 | 
			
		||||
    amidi
 | 
			
		||||
    OpenSLES
 | 
			
		||||
    android
 | 
			
		||||
    log
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,10 +14,9 @@
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
// Data callback stuff
 | 
			
		||||
JavaVM* theJvm;
 | 
			
		||||
jobject dataCallbackObj;
 | 
			
		||||
@@ -27,8 +26,7 @@ jmethodID midDataCallback;
 | 
			
		||||
 * Initializes JNI interface stuff, specifically the info needed to call back
 | 
			
		||||
 * into the Java layer when MIDI data is received.
 | 
			
		||||
 */
 | 
			
		||||
JNICALL void Java_com_example_nativemidi_MainActivity_initNative(
 | 
			
		||||
    JNIEnv* env, jobject instance) {
 | 
			
		||||
void InitNative(JNIEnv* env, jobject instance) {
 | 
			
		||||
  env->GetJavaVM(&theJvm);
 | 
			
		||||
 | 
			
		||||
  // Setup the receive data callback (into Java)
 | 
			
		||||
@@ -39,4 +37,21 @@ JNICALL void Java_com_example_nativemidi_MainActivity_initNative(
 | 
			
		||||
      env->GetMethodID(clsMainActivity, "onNativeMessageReceive", "([B)V");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // extern "C"
 | 
			
		||||
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/nativemidi/MainActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"initNative", "()V", reinterpret_cast<void*>(InitNative)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,11 +26,13 @@ android {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
        viewBinding true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.material
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.22.1)
 | 
			
		||||
project(OrderfileDemo CXX)
 | 
			
		||||
 | 
			
		||||
include(AppLibrary)
 | 
			
		||||
find_package(base CONFIG REQUIRED)
 | 
			
		||||
 | 
			
		||||
# We have setup build variables that you can just comment or uncomment to use.
 | 
			
		||||
# Make sure to have only one build variable uncommented at a time.
 | 
			
		||||
@@ -13,7 +14,7 @@ set(GENERATE_PROFILES ON)
 | 
			
		||||
#set(USE_PROFILE "${CMAKE_SOURCE_DIR}/demo.orderfile")
 | 
			
		||||
 | 
			
		||||
add_app_library(orderfiledemo SHARED orderfile.cpp)
 | 
			
		||||
target_link_libraries(orderfiledemo log)
 | 
			
		||||
target_link_libraries(orderfiledemo PRIVATE base::base log)
 | 
			
		||||
 | 
			
		||||
if(GENERATE_PROFILES)
 | 
			
		||||
    # Generating profiles requires any optimization flag aside from -O0.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
#include <android/log.h>
 | 
			
		||||
#include <base/macros.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <linux/limits.h>
 | 
			
		||||
@@ -46,9 +47,26 @@ void DumpProfileDataIfNeeded(const char* temp_dir) {
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" JNIEXPORT void JNICALL
 | 
			
		||||
Java_com_example_orderfiledemo_MainActivity_runWorkload(JNIEnv* env,
 | 
			
		||||
                                                        jobject /* this */,
 | 
			
		||||
                                                        jstring temp_dir) {
 | 
			
		||||
void RunWorkload(JNIEnv* env, jobject /* this */, jstring temp_dir) {
 | 
			
		||||
  DumpProfileDataIfNeeded(env->GetStringUTFChars(temp_dir, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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/orderfiledemo/MainActivity");
 | 
			
		||||
  if (c == nullptr) return JNI_ERR;
 | 
			
		||||
 | 
			
		||||
  static const JNINativeMethod methods[] = {
 | 
			
		||||
      {"runWorkload", "(Ljava/lang/String;)V",
 | 
			
		||||
       reinterpret_cast<void*>(RunWorkload)},
 | 
			
		||||
  };
 | 
			
		||||
  int rc = env->RegisterNatives(c, methods, arraysize(methods));
 | 
			
		||||
  if (rc != JNI_OK) return rc;
 | 
			
		||||
 | 
			
		||||
  return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,4 +19,12 @@ android {
 | 
			
		||||
            path 'src/main/cpp/CMakeLists.txt'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        prefab true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,7 @@ android {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation project(":base")
 | 
			
		||||
    implementation libs.appcompat
 | 
			
		||||
    implementation libs.material
 | 
			
		||||
    implementation libs.androidx.constraintlayout
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user