Skip to content

Commit

Permalink
mobile: Move the JNI initialization and shutdown into separate functi…
Browse files Browse the repository at this point in the history
…ons (envoyproxy#38499)

This is needed so that we can initialize and shutdown the JNI code in a
custom `JNI_OnLoad` and `JNI_OnUnLoad`.

Risk Level: low
Testing: CI
Docs Changes: n/a
Release Notes: n/a
Platform Specific Features: android

Signed-off-by: Fredy Wijaya <[email protected]>
  • Loading branch information
fredyw authored Feb 20, 2025
1 parent a1cdaed commit 5098cae
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 68 deletions.
17 changes: 17 additions & 0 deletions mobile/library/jni/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ envoy_cc_library(
],
)

envoy_cc_library(
name = "jni_init_lib",
srcs = [
"jni_init.cc",
],
hdrs = [
"jni_init.h",
],
repository = "@envoy",
deps = [
":jni_helper_lib",
":jni_utility_lib",
],
alwayslink = True,
)

# Implementations of the various "native" Java methods for classes
# in library/java/io/envoyproxy/envoymobile.
envoy_cc_library(
Expand All @@ -59,6 +75,7 @@ envoy_cc_library(
repository = "@envoy",
deps = [
":android_network_utility_lib",
":jni_init_lib",
":jni_utility_lib",
"//library/cc:engine_builder_lib",
"//library/common:internal_engine_lib",
Expand Down
1 change: 1 addition & 0 deletions mobile/library/jni/jni_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void JniHelper::finalize() {
for (const auto& [_, clazz] : jclass_cache_map) {
env->DeleteGlobalRef(clazz);
}
java_vm_cache_ = nullptr;
}

void JniHelper::addToCache(absl::string_view class_name, const std::vector<Method>& methods,
Expand Down
71 changes: 3 additions & 68 deletions mobile/library/jni/jni_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,20 @@
#include "library/common/types/managed_envoy_headers.h"
#include "library/jni/android_network_utility.h"
#include "library/jni/jni_helper.h"
#include "library/jni/jni_init.h"
#include "library/jni/jni_utility.h"

using Envoy::Platform::EngineBuilder;

// NOLINT(namespace-envoy)

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
Envoy::JNI::JniHelper::initialize(vm);
Envoy::JNI::JniUtility::initCache();
Envoy::JNI::JniHelper::addToCache(
"io/envoyproxy/envoymobile/utilities/AndroidNetworkLibrary",
/* methods= */ {},
/* static_methods= */
{
{"isCleartextTrafficPermitted", "(Ljava/lang/String;)Z"},
{"tagSocket", "(III)V"},
{"verifyServerCertificates",
"([[B[B[B)Lio/envoyproxy/envoymobile/utilities/AndroidCertVerifyResult;"},
{"addTestRootCertificate", "([B)V"},
{"clearTestRootCertificates", "()V"},

},
/* fields= */ {}, /* static_fields= */ {});
Envoy::JNI::JniHelper::addToCache("io/envoyproxy/envoymobile/utilities/AndroidCertVerifyResult",
/* methods= */
{
{"isIssuedByKnownRoot", "()Z"},
{"getStatus", "()I"},
{"getCertificateChainEncoded", "()[[B"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
Envoy::JNI::JniHelper::addToCache("io/envoyproxy/envoymobile/engine/types/EnvoyOnEngineRunning",
/* methods= */
{
{"invokeOnEngineRunning", "()Ljava/lang/Object;"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
Envoy::JNI::JniHelper::addToCache("io/envoyproxy/envoymobile/engine/types/EnvoyLogger",
/* methods= */
{
{"log", "(ILjava/lang/String;)V"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
Envoy::JNI::JniHelper::addToCache("io/envoyproxy/envoymobile/engine/types/EnvoyEventTracker",
/* methods= */
{
{"track", "(Ljava/util/Map;)V"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
Envoy::JNI::JniHelper::addToCache(
"io/envoyproxy/envoymobile/engine/types/EnvoyHTTPCallbacks",
/* methods= */
{
{"onHeaders",
"(Ljava/util/Map;ZLio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
{"onData",
"(Ljava/nio/ByteBuffer;ZLio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
{"onTrailers",
"(Ljava/util/Map;Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
{"onComplete", "(Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;Lio/envoyproxy/"
"envoymobile/engine/types/EnvoyFinalStreamIntel;)V"},
{"onError",
"(ILjava/lang/String;ILio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;Lio/"
"envoyproxy/envoymobile/engine/types/EnvoyFinalStreamIntel;)V"},
{"onCancel", "(Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;Lio/envoyproxy/"
"envoymobile/engine/types/EnvoyFinalStreamIntel;)V"},
{"onSendWindowAvailable", "(Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
Envoy::JNI::initialize(vm);
return Envoy::JNI::JniHelper::getVersion();
}

extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM*, void* /* reserved */) {
Envoy::JNI::JniHelper::finalize();
Envoy::JNI::finalize();
}

extern "C" JNIEXPORT void JNICALL
Expand Down
82 changes: 82 additions & 0 deletions mobile/library/jni/jni_init.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "library/jni/jni_init.h"

#include "library/jni/jni_helper.h"
#include "library/jni/jni_utility.h"

namespace Envoy {
namespace JNI {

void initialize(JavaVM* jvm) {
JniHelper::initialize(jvm);
JniUtility::initCache();
JniHelper::addToCache(
"io/envoyproxy/envoymobile/utilities/AndroidNetworkLibrary",
/* methods= */ {},
/* static_methods= */
{
{"isCleartextTrafficPermitted", "(Ljava/lang/String;)Z"},
{"tagSocket", "(III)V"},
{"verifyServerCertificates",
"([[B[B[B)Lio/envoyproxy/envoymobile/utilities/AndroidCertVerifyResult;"},
{"addTestRootCertificate", "([B)V"},
{"clearTestRootCertificates", "()V"},

},
/* fields= */ {}, /* static_fields= */ {});
JniHelper::addToCache("io/envoyproxy/envoymobile/utilities/AndroidCertVerifyResult",
/* methods= */
{
{"isIssuedByKnownRoot", "()Z"},
{"getStatus", "()I"},
{"getCertificateChainEncoded", "()[[B"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
JniHelper::addToCache("io/envoyproxy/envoymobile/engine/types/EnvoyOnEngineRunning",
/* methods= */
{
{"invokeOnEngineRunning", "()Ljava/lang/Object;"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
JniHelper::addToCache("io/envoyproxy/envoymobile/engine/types/EnvoyLogger",
/* methods= */
{
{"log", "(ILjava/lang/String;)V"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
JniHelper::addToCache("io/envoyproxy/envoymobile/engine/types/EnvoyEventTracker",
/* methods= */
{
{"track", "(Ljava/util/Map;)V"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
JniHelper::addToCache(
"io/envoyproxy/envoymobile/engine/types/EnvoyHTTPCallbacks",
/* methods= */
{
{"onHeaders",
"(Ljava/util/Map;ZLio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
{"onData",
"(Ljava/nio/ByteBuffer;ZLio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
{"onTrailers",
"(Ljava/util/Map;Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
{"onComplete", "(Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;Lio/envoyproxy/"
"envoymobile/engine/types/EnvoyFinalStreamIntel;)V"},
{"onError",
"(ILjava/lang/String;ILio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;Lio/"
"envoyproxy/envoymobile/engine/types/EnvoyFinalStreamIntel;)V"},
{"onCancel", "(Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;Lio/envoyproxy/"
"envoymobile/engine/types/EnvoyFinalStreamIntel;)V"},
{"onSendWindowAvailable", "(Lio/envoyproxy/envoymobile/engine/types/EnvoyStreamIntel;)V"},
},
/* static_methods= */ {},
/* fields= */ {}, /* static_fields= */ {});
}

void finalize() { JniHelper::finalize(); }

} // namespace JNI
} // namespace Envoy
15 changes: 15 additions & 0 deletions mobile/library/jni/jni_init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <jni.h>

namespace Envoy {
namespace JNI {

/** Initializes the JNI code for Envoy Mobile. This is typically called in `JNI_OnLoad`. */
void initialize(JavaVM* jvm);

/** Performs a cleanup in the JNI code. This is typically called in `JNI_OnUnload`. */
void finalize();

} // namespace JNI
} // namespace Envoy

0 comments on commit 5098cae

Please sign in to comment.