Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3267889
D11046.id37008.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D11046.id37008.diff
View Options
diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt
--- a/native/android/app/CMakeLists.txt
+++ b/native/android/app/CMakeLists.txt
@@ -118,6 +118,7 @@
"./src/cpp/StaffUtilsJNIHelper.cpp"
"./src/cpp/AESCrypto.cpp"
"./src/cpp/CommServicesAuthMetadataEmitter.cpp"
+ "./src/cpp/CommMMKV.cpp"
)
list(APPEND GENERATED_NATIVE_CODE
diff --git a/native/android/app/build.gradle b/native/android/app/build.gradle
--- a/native/android/app/build.gradle
+++ b/native/android/app/build.gradle
@@ -652,6 +652,7 @@
}
dependencies {
+ implementation 'com.tencent:mmkv:1.3.3'
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10"
//noinspection GradleDynamicVersion
diff --git a/native/android/app/src/cpp/CommMMKV.cpp b/native/android/app/src/cpp/CommMMKV.cpp
new file mode 100644
--- /dev/null
+++ b/native/android/app/src/cpp/CommMMKV.cpp
@@ -0,0 +1,68 @@
+#include "jniHelpers.h"
+#include <Tools/CommMMKV.h>
+#include <fbjni/fbjni.h>
+
+using namespace facebook::jni;
+
+class CommMMKVJavaClass : public JavaClass<CommMMKVJavaClass> {
+public:
+ static auto constexpr kJavaDescriptor = "Lapp/comm/android/fbjni/CommMMKV;";
+
+ static void initialize() {
+ static const auto cls = javaClassStatic();
+ static auto method = cls->getStaticMethod<void()>("initializeMMKV");
+ method(cls);
+ }
+
+ static void clearSensitiveData() {
+ static const auto cls = javaClassStatic();
+ static auto method = cls->getStaticMethod<void()>("clearSensitiveData");
+ method(cls);
+ }
+
+ static bool setString(std::string key, std::string value) {
+ static const auto cls = javaClassStatic();
+ static auto method =
+ cls->getStaticMethod<jboolean(std::string, std::string)>("setString");
+ return method(cls, key, value);
+ }
+
+ static std::optional<std::string> getString(std::string key) {
+ static const auto cls = javaClassStatic();
+ static auto method =
+ cls->getStaticMethod<JString(std::string)>("getString");
+ const auto result = method(cls, key);
+ if (result) {
+ return result->toStdString();
+ }
+ return std::nullopt;
+ }
+};
+
+namespace comm {
+
+void CommMMKV::initialize() {
+ NativeAndroidAccessProvider::runTask(
+ [=]() { CommMMKVJavaClass::initialize(); });
+}
+
+void CommMMKV::clearSensitiveData() {
+ NativeAndroidAccessProvider::runTask(
+ [=]() { CommMMKVJavaClass::clearSensitiveData(); });
+}
+
+bool CommMMKV::setString(std::string key, std::string value) {
+ bool result;
+ NativeAndroidAccessProvider::runTask(
+ [&]() { result = CommMMKVJavaClass::setString(key, value); });
+ return result;
+}
+
+std::optional<std::string> CommMMKV::getString(std::string key) {
+ std::optional<std::string> result;
+ NativeAndroidAccessProvider::runTask(
+ [&]() { result = CommMMKVJavaClass::getString(key); });
+ return result;
+}
+
+} // namespace comm
\ No newline at end of file
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
--- a/native/android/app/src/main/java/app/comm/android/MainApplication.java
+++ b/native/android/app/src/main/java/app/comm/android/MainApplication.java
@@ -6,6 +6,7 @@
import androidx.annotation.NonNull;
import androidx.multidex.MultiDexApplication;
import app.comm.android.commservices.CommServicesPackage;
+import app.comm.android.fbjni.CommMMKV;
import app.comm.android.fbjni.CommSecureStore;
import app.comm.android.fbjni.DatabaseInitializer;
import app.comm.android.fbjni.GlobalDBSingleton;
@@ -91,6 +92,7 @@
SoLoader.init(this, /* native exopackage */ false);
this.initializeDatabase();
+ CommMMKV.initialize();
ApplicationLifecycleDispatcher.onApplicationCreate(this);
try {
Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java b/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
new file mode 100644
--- /dev/null
+++ b/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
@@ -0,0 +1,81 @@
+package app.comm.android.fbjni;
+
+import app.comm.android.MainApplication;
+import app.comm.android.fbjni.CommSecureStore;
+import app.comm.android.fbjni.PlatformSpecificTools;
+import com.tencent.mmkv.MMKV;
+import java.util.Base64;
+
+public class CommMMKV {
+ private static final String COMM_MMKV_ID = "comm.MMKV";
+ private static final int COMM_MMKV_ENCRYPTION_KEY_SIZE = 16;
+ private static final String SECURE_STORE_MMKV_ENCRYPTION_KEY_ID =
+ "comm.MMKVEncryptionKey";
+
+ private static String mmkvEncryptionKey;
+
+ private static MMKV getMMKVInstance(String mmkvID, String encryptionKey) {
+ MMKV mmkv =
+ MMKV.mmkvWithID(mmkvID, MMKV.SINGLE_PROCESS_MODE, encryptionKey);
+ if (mmkv == null) {
+ throw new RuntimeException("Failed to instantiate MMKV object.");
+ }
+ return mmkv;
+ }
+
+ private static void assignEncryptionKey() {
+ byte[] encryptionKeyBytes = PlatformSpecificTools.generateSecureRandomBytes(
+ COMM_MMKV_ENCRYPTION_KEY_SIZE);
+ String encryptionKey =
+ Base64.getEncoder().encodeToString(encryptionKeyBytes);
+ CommSecureStore.set(SECURE_STORE_MMKV_ENCRYPTION_KEY_ID, encryptionKey);
+ mmkvEncryptionKey = encryptionKey;
+ }
+
+ public static void initialize() {
+ if (mmkvEncryptionKey != null) {
+ return;
+ }
+
+ synchronized (CommMMKV.class) {
+ if (mmkvEncryptionKey != null) {
+ return;
+ }
+
+ String encryptionKey =
+ CommSecureStore.get(SECURE_STORE_MMKV_ENCRYPTION_KEY_ID);
+
+ if (encryptionKey == null) {
+ assignEncryptionKey();
+ } else {
+ mmkvEncryptionKey = encryptionKey;
+ }
+
+ MMKV.initialize(MainApplication.getMainApplicationContext());
+ getMMKVInstance(COMM_MMKV_ID, mmkvEncryptionKey);
+ }
+ }
+
+ public static void clearSensitiveData() {
+ initialize();
+ synchronized (mmkvEncryptionKey) {
+ boolean storageRemoved = MMKV.removeStorage(COMM_MMKV_ID);
+ if (!storageRemoved) {
+ throw new RuntimeException("Failed to remove MMKV storage.");
+ }
+ assignEncryptionKey();
+ MMKV.initialize(MainApplication.getMainApplicationContext());
+ getMMKVInstance(COMM_MMKV_ID, mmkvEncryptionKey);
+ }
+ }
+
+ public static boolean setString(String key, String value) {
+ initialize();
+ return getMMKVInstance(COMM_MMKV_ID, mmkvEncryptionKey).encode(key, value);
+ }
+
+ public static String getString(String key) {
+ initialize();
+ return getMMKVInstance(COMM_MMKV_ID, mmkvEncryptionKey).decodeString(key);
+ }
+}
\ No newline at end of file
diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
@@ -1,8 +1,6 @@
#include "DatabaseManager.h"
#include "../Notifications/BackgroundDataStorage/NotificationsCryptoModule.h"
-#ifdef __APPLE__
#include "../Tools/CommMMKV.h"
-#endif
#include "../Tools/CommSecureStore.h"
#include "Logger.h"
#include "PlatformSpecificTools.h"
@@ -39,9 +37,7 @@
CommSecureStore::set(CommSecureStore::commServicesAccessToken, "");
SQLiteQueryExecutor::clearSensitiveData();
PlatformSpecificTools::removeBackupDirectory();
-#ifdef __APPLE__
CommMMKV::clearSensitiveData();
-#endif
NotificationsCryptoModule::clearSensitiveData();
DatabaseManager::setDatabaseStatusAsWorkable();
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 17, 3:05 AM (21 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2510970
Default Alt Text
D11046.id37008.diff (7 KB)
Attached To
Mode
D11046: Introduce MMKV to Android app
Attached
Detach File
Event Timeline
Log In to Comment