Page MenuHomePhabricator

D11046.id38065.diff
No OneTemporary

D11046.id38065.diff

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()>("initialize");
+ 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
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,98 @@
+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 int MMKV_ENCRYPTION_KEY_SIZE = 16;
+ private static final int MMKV_ID_SIZE = 8;
+
+ private static final String SECURE_STORE_MMKV_ENCRYPTION_KEY_ID =
+ "comm.mmkvEncryptionKey";
+ private static final String SECURE_STORE_MMKV_IDENTIFIER_KEY_ID =
+ "comm.mmkvID";
+
+ private static String mmkvEncryptionKey;
+ private static String mmkvIdentifier;
+
+ 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 assignInitializationData() {
+ byte[] encryptionKeyBytes = PlatformSpecificTools.generateSecureRandomBytes(
+ MMKV_ENCRYPTION_KEY_SIZE);
+ byte[] identifierBytes =
+ PlatformSpecificTools.generateSecureRandomBytes(MMKV_ID_SIZE);
+ String encryptionKey = Base64.getEncoder()
+ .encodeToString(encryptionKeyBytes)
+ .substring(0, MMKV_ENCRYPTION_KEY_SIZE);
+ String identifier = Base64.getEncoder()
+ .encodeToString(identifierBytes)
+ .substring(0, MMKV_ID_SIZE);
+ CommSecureStore.set(SECURE_STORE_MMKV_ENCRYPTION_KEY_ID, encryptionKey);
+ CommSecureStore.set(SECURE_STORE_MMKV_IDENTIFIER_KEY_ID, identifier);
+ mmkvEncryptionKey = encryptionKey;
+ mmkvIdentifier = identifier;
+ }
+
+ public static void initialize() {
+ if (mmkvEncryptionKey != null && mmkvIdentifier != null) {
+ return;
+ }
+
+ synchronized (CommMMKV.class) {
+ if (mmkvEncryptionKey != null && mmkvIdentifier != null) {
+ return;
+ }
+
+ String encryptionKey =
+ CommSecureStore.get(SECURE_STORE_MMKV_ENCRYPTION_KEY_ID);
+ String identifier =
+ CommSecureStore.get(SECURE_STORE_MMKV_IDENTIFIER_KEY_ID);
+
+ if (encryptionKey == null || identifier == null) {
+ assignInitializationData();
+ } else {
+ mmkvEncryptionKey = encryptionKey;
+ mmkvIdentifier = identifier;
+ }
+
+ MMKV.initialize(MainApplication.getMainApplicationContext());
+ getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+ }
+ }
+
+ public static void clearSensitiveData() {
+ initialize();
+ synchronized (mmkvEncryptionKey) {
+ getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey).clearAll();
+ boolean storageRemoved = MMKV.removeStorage(mmkvIdentifier);
+ if (!storageRemoved) {
+ throw new RuntimeException("Failed to remove MMKV storage.");
+ }
+ assignInitializationData();
+ MMKV.initialize(MainApplication.getMainApplicationContext());
+ getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+ }
+ }
+
+ public static boolean setString(String key, String value) {
+ initialize();
+ return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey)
+ .encode(key, value);
+ }
+
+ public static String getString(String key) {
+ initialize();
+ return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey).decodeString(key);
+ }
+}
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

Mime Type
text/plain
Expires
Sun, Nov 17, 3:31 AM (21 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2509082
Default Alt Text
D11046.id38065.diff (8 KB)

Event Timeline