Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FirebaseAndroid: introduce the new JNI module for Android support #56

Merged
merged 1 commit into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
cmake_minimum_required(VERSION 3.25)
project(swift-firebase
LANGUAGES Swift)
if(ANDROID)
enable_language(C)
include(FindJava)
include(UseJava)
endif()

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
Expand Down Expand Up @@ -39,6 +44,10 @@ else()
message(FATAL_ERROR "unsupported firebase-cpp-sdk platform")
endif()

if(ANDROID)
add_subdirectory(Sources/FirebaseAndroid)
endif()

add_library(FirebaseCore SHARED
Sources/FirebaseCore/FirebaseApp+Swift.swift
Sources/FirebaseCore/FirebaseConfiguration.swift
Expand All @@ -55,6 +64,10 @@ target_link_libraries(FirebaseCore PRIVATE
firebase_app
flatbuffers
zlibstatic)
if(ANDROID)
target_link_libraries(FirebaseCore PRIVATE
FirebaseAndroidJNI)
endif()

add_library(FirebaseAuth SHARED
Sources/FirebaseAuth/AuthStateDidChangeListenerHandle.swift
Expand Down
9 changes: 9 additions & 0 deletions Sources/FirebaseAndroid/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: BSD-3-Clause

add_library(FirebaseAndroidJNI SHARED
jni.c)
target_include_directories(FirebaseAndroidJNI PUBLIC
include)
target_link_libraries(FirebaseAndroidJNI PRIVATE
log)

12 changes: 12 additions & 0 deletions Sources/FirebaseAndroid/abi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: BSD-3-Clause */

#ifndef SwiftFirebase_FirebaseAndroidShim_abi_h
#define SwiftFirebase_FirebaseAndroidShim_abi_h

#if defined(FirebaseAndroidJNI_EXPORTS)
#define FIREBASE_ANDROID_ABI __attribute__((__visibility__("default")))
#else
#define FIREBASE_ANDROID_ABI __attribute__((__visibility__("default")))
#endif

#endif
20 changes: 20 additions & 0 deletions Sources/FirebaseAndroid/include/FirebaseAndroid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: BSD-3-Clause */

#ifndef SwiftFirebase_FirebaseAndroidShim_FirebaseAndroid_h
#define SwiftFirebase_FirebaseAndroidShim_FirebaseAndroid_h

#include <jni.h>

#if defined(__cplusplus)
extern "C" {
#endif

jobject _Nullable SwiftFirebase_GetActivity(void);
JNIEnv * _Nullable SwiftFirebase_GetJavaEnvironment(void);
JavaVM * _Nullable SwiftFirebase_GetJVM(void);

#if defined(__cplusplus)
}
#endif

#endif
6 changes: 6 additions & 0 deletions Sources/FirebaseAndroid/include/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause */

module FirebaseAndroid {
header "FirebaseAndroid.h"
compnerd marked this conversation as resolved.
Show resolved Hide resolved
export *
}
79 changes: 79 additions & 0 deletions Sources/FirebaseAndroid/jni.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: BSD-3-Clause */

#include "FirebaseAndroid.h"
#include "abi.h"
#include "log.h"

#include <assert.h>

static JavaVM *g_VM;
static JNIEnv *g_Env;
static jobject *g_Activity;

#define N_ELEMENTS(array) (sizeof((array)) / sizeof(*(array)))

static const char kClassPath[] = "company/thebrowser/Native";

static jboolean
SwiftFirebase_RegisterActivity(JNIEnv *env, jobject *this, jobject *activity)
{
assert(g_Activity == NULL && "re-registeration of activity");
if (g_Activity) return JNI_FALSE;

g_Activity = activity;
return JNI_TRUE;
}

static JNINativeMethod kMethods[] = {
{ "RegisterActivity", "()Z", SwiftFirebase_RegisterActivity },
};

static void
RegisterNativeMethods(JNIEnv *env)
{
jclass class;
jint result;

class = (*env)->FindClass(env, kClassPath);
if (class == NULL) {
LOG_ERROR("unable to find class '%s'", kClassPath);
return;
}
LOG_DEBUG("located class path '%s': %p", kClassPath, class);

result = (*env)->RegisterNatives(env, class, kMethods, N_ELEMENTS(kMethods));
if (result < 0) {
LOG_ERROR("JVM.RegisterNatives(%s): %u", kClassPath, result);
return;
}
LOG_DEBUG("registered %u methods", N_ELEMENTS(kMethods));
}

FIREBASE_ANDROID_ABI
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
g_VM = vm;
if ((*g_VM)->GetEnv(g_VM, (void **)&g_Env, JNI_VERSION_1_6) == JNI_OK)
return JNI_VERSION_1_6;
RegisterNativeMethods(g_Env);
return -1;
}

FIREBASE_ANDROID_ABI
jobject SwiftFirebase_GetActivity(void)
{
assert(g_Activity && "`GetActivity` invoked before `RegisterActivity`");
return *g_Activity;
}

FIREBASE_ANDROID_ABI
JNIEnv *SwiftFirebase_GetJavaEnvironment(void)
{
return g_Env;
}

FIREBASE_ANDROID_ABI
JavaVM *SwiftFirebase_GetJVM(void)
{
return g_VM;
}
17 changes: 17 additions & 0 deletions Sources/FirebaseAndroid/log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: BSD-3-Clause */

#ifndef SwiftFirebase_FirebaseAndroidShim_logging_h
#define SwiftFirebase_FirebaseAndroidShim_logging_h

#include <android/log.h>

#define FIREBASE_ANDROID_LOG(level, tag, ...) __android_log_print(level, tag, __VA_ARGS__)
#define FIREBASE_ANDROID_TAG "company.thebrowser.firebase"

#define LOG_DEBUG(...) FIREBASE_ANDROID_LOG(ANDROID_LOG_DEBUG, FIREBASE_ANDROID_TAG, __VA_ARGS__)
#define LOG_VERBOSE(...) FIREBASE_ANDROID_LOG(ANDROID_LOG_VERBOSE, FIREBASE_ANDROID_TAG, __VA_ARGS__)
#define LOG_INFO(...) FIREBASE_ANDROID_LOG(ANDROID_LOG_INFO, FIREBASE_ANDROID_TAG, __VA_ARGS__)
#define LOG_WARN(...) FIREBASE_ANDROID_LOG(ANDROID_LOG_WARN, FIREBASE_ANDROID_TAG, __VA_ARGS__)
#define LOG_ERROR(...) FIREBASE_ANDROID_LOG(ANDROID_LOG_ERROR, FIREBASE_ANDROID_TAG, __VA_ARGS__)

#endif
Loading