diff --git a/native/android/app/src/cpp/DatabaseInitializerJNIHelper.cpp b/native/android/app/src/cpp/DatabaseInitializerJNIHelper.cpp new file mode 100644 index 000000000..e48c5178d --- /dev/null +++ b/native/android/app/src/cpp/DatabaseInitializerJNIHelper.cpp @@ -0,0 +1,18 @@ +#include +#include + +namespace comm { +void DatabaseInitializerJNIHelper::initializeDatabaseManager( + facebook::jni::alias_ref jThis, + std::string sqliteFilePath) { + DatabaseManager::initializeQueryExecutor(sqliteFilePath); +} + +void DatabaseInitializerJNIHelper::registerNatives() { + javaClassStatic()->registerNatives({ + makeNativeMethod( + "initializeDatabaseManager", + DatabaseInitializerJNIHelper::initializeDatabaseManager), + }); +} +} // namespace comm diff --git a/native/android/app/src/cpp/MessageOperationsUtilitiesJNIHelper.cpp b/native/android/app/src/cpp/MessageOperationsUtilitiesJNIHelper.cpp index 25cee3430..593f955e7 100644 --- a/native/android/app/src/cpp/MessageOperationsUtilitiesJNIHelper.cpp +++ b/native/android/app/src/cpp/MessageOperationsUtilitiesJNIHelper.cpp @@ -1,23 +1,23 @@ -#include +#include #include #include namespace comm { void MessageOperationsUtilitiesJNIHelper::storeMessageInfos( facebook::jni::alias_ref jThis, facebook::jni::JString sqliteFilePath, facebook::jni::JString rawMessageInfosString) { std::string sqliteFilePathCpp = sqliteFilePath.toStdString(); std::string rawMessageInfosStringCpp = rawMessageInfosString.toStdString(); - SQLiteQueryExecutor::initialize(sqliteFilePathCpp); + DatabaseManager::initializeQueryExecutor(sqliteFilePathCpp); MessageOperationsUtilities::storeMessageInfos(rawMessageInfosStringCpp); } void MessageOperationsUtilitiesJNIHelper::registerNatives() { javaClassStatic()->registerNatives({ makeNativeMethod( "storeMessageInfos", MessageOperationsUtilitiesJNIHelper::storeMessageInfos), }); } } // namespace comm diff --git a/native/android/app/src/cpp/ThreadOperationsJNIHelper.cpp b/native/android/app/src/cpp/ThreadOperationsJNIHelper.cpp index ab8d8c9f1..a37b40d0a 100644 --- a/native/android/app/src/cpp/ThreadOperationsJNIHelper.cpp +++ b/native/android/app/src/cpp/ThreadOperationsJNIHelper.cpp @@ -1,22 +1,22 @@ -#include +#include #include #include namespace comm { void ThreadOperationsJNIHelper::updateSQLiteUnreadStatus( facebook::jni::alias_ref jThis, std::string sqliteFilePath, std::string threadID, bool unread) { - SQLiteQueryExecutor::initialize(sqliteFilePath); + DatabaseManager::initializeQueryExecutor(sqliteFilePath); ThreadOperations::updateSQLiteUnreadStatus(threadID, unread); } void ThreadOperationsJNIHelper::registerNatives() { javaClassStatic()->registerNatives({ makeNativeMethod( "updateSQLiteUnreadStatus", ThreadOperationsJNIHelper::updateSQLiteUnreadStatus), }); } } // namespace comm diff --git a/native/android/app/src/cpp/jsiInstaller.cpp b/native/android/app/src/cpp/jsiInstaller.cpp index 831aed1fb..3dd62c186 100644 --- a/native/android/app/src/cpp/jsiInstaller.cpp +++ b/native/android/app/src/cpp/jsiInstaller.cpp @@ -1,61 +1,63 @@ #include "jniHelpers.h" #include #include #include #include +#include #include #include #include #include namespace jni = facebook::jni; namespace jsi = facebook::jsi; namespace react = facebook::react; class CommHybrid : public jni::HybridClass { public: static auto constexpr kJavaDescriptor = "Lapp/comm/android/fbjni/CommHybrid;"; static void initHybrid( jni::alias_ref jThis, jlong jsContext, jni::alias_ref jsCallInvokerHolder, comm::HashMap additionalParameters) { jsi::Runtime *rt = (jsi::Runtime *)jsContext; auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker(); std::shared_ptr nativeModule = std::make_shared(jsCallInvoker); if (rt != nullptr) { rt->global().setProperty( *rt, jsi::PropNameID::forAscii(*rt, "CommCoreModule"), jsi::Object::createFromHostObject(*rt, nativeModule)); } jni::local_ref sqliteFilePathObj = additionalParameters.get("sqliteFilePath"); std::string sqliteFilePath = sqliteFilePathObj->toString(); comm::SQLiteQueryExecutor::initialize(sqliteFilePath); } static void registerNatives() { javaClassStatic()->registerNatives({ makeNativeMethod("initHybrid", CommHybrid::initHybrid), }); } private: friend HybridBase; }; JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *) { return jni::initialize(vm, [] { CommHybrid::registerNatives(); comm::ThreadOperationsJNIHelper::registerNatives(); comm::MessageOperationsUtilitiesJNIHelper::registerNatives(); comm::GlobalDBSingletonJNIHelper::registerNatives(); + comm::DatabaseInitializerJNIHelper::registerNatives(); }); } diff --git a/native/android/app/src/main/java/app/comm/android/MainApplication.java b/native/android/app/src/main/java/app/comm/android/MainApplication.java index df23c5dbc..c7731db03 100644 --- a/native/android/app/src/main/java/app/comm/android/MainApplication.java +++ b/native/android/app/src/main/java/app/comm/android/MainApplication.java @@ -1,101 +1,117 @@ package app.comm.android; import android.content.Context; import android.content.res.Configuration; import android.database.CursorWindow; import androidx.annotation.NonNull; import androidx.multidex.MultiDexApplication; +import app.comm.android.fbjni.CommSecureStore; +import app.comm.android.fbjni.DatabaseInitializer; +import app.comm.android.fbjni.GlobalDBSingleton; import app.comm.android.newarchitecture.MainApplicationReactNativeHost; import app.comm.android.notifications.CommAndroidNotificationsPackage; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JSIModulePackage; import com.facebook.react.config.ReactFeatureFlags; import com.facebook.soloader.SoLoader; import com.wix.reactnativekeyboardinput.KeyboardInputPackage; import expo.modules.ApplicationLifecycleDispatcher; import expo.modules.ReactNativeHostWrapper; +import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.security.Security; import java.util.List; public class MainApplication extends MultiDexApplication implements ReactApplication { static { System.loadLibrary("fbjni"); System.loadLibrary("comm_jni_module"); } private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(this, new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); packages.add(new KeyboardInputPackage(this.getApplication())); packages.add(new CommAndroidNotificationsPackage()); return packages; } @Override protected String getJSMainModuleName() { return "index"; } @Override protected JSIModulePackage getJSIModulePackage() { return new CommCoreJSIModulePackage(); } }); private final ReactNativeHost mNewArchitectureNativeHost = new ReactNativeHostWrapper( this, new MainApplicationReactNativeHost(this)); @Override public ReactNativeHost getReactNativeHost() { if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { return mNewArchitectureNativeHost; } else { return mReactNativeHost; } } @Override public void onCreate() { super.onCreate(); // If you opted-in for the New Architecture, we enable the TurboModule // system ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; Security.insertProviderAt(new org.conscrypt.OpenSSLProvider(), 1); SoLoader.init(this, /* native exopackage */ false); + this.initializeDatabase(); ApplicationLifecycleDispatcher.onApplicationCreate(this); try { Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize"); field.setAccessible(true); field.set(null, 100 * 1024 * 1024); // 100 MiB } catch (Exception e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); } + + private void initializeDatabase() { + File sqliteFile = + this.getApplicationContext().getDatabasePath("comm.sqlite"); + CommSecureStore.getInstance().initialize( + ExpoUtils.createExpoSecureStoreSupplier(this.getApplicationContext())); + + GlobalDBSingleton.scheduleOrRun(() -> { + DatabaseInitializer.initializeDatabaseManager(sqliteFile.getPath()); + }); + } } diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/DatabaseInitializer.java b/native/android/app/src/main/java/app/comm/android/fbjni/DatabaseInitializer.java new file mode 100644 index 000000000..eae377f6a --- /dev/null +++ b/native/android/app/src/main/java/app/comm/android/fbjni/DatabaseInitializer.java @@ -0,0 +1,5 @@ +package app.comm.android.fbjni; + +public class DatabaseInitializer { + public static native void initializeDatabaseManager(String sqliteFilePath); +} diff --git a/native/cpp/CommonCpp/NativeModules/InternalModules/DatabaseInitializerJNIHelper.h b/native/cpp/CommonCpp/NativeModules/InternalModules/DatabaseInitializerJNIHelper.h new file mode 100644 index 000000000..077c0aab4 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/InternalModules/DatabaseInitializerJNIHelper.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace comm { +class DatabaseInitializerJNIHelper + : public facebook::jni::JavaClass { +public: + static auto constexpr kJavaDescriptor = + "Lapp/comm/android/fbjni/DatabaseInitializer;"; + static void initializeDatabaseManager( + facebook::jni::alias_ref jThis, + std::string sqliteFilePath); + static void registerNatives(); +}; +} // namespace comm