Skip to content

Commit

Permalink
Merge pull request #1461 from Tencent/dev
Browse files Browse the repository at this point in the history
for v2.0.2
  • Loading branch information
lingol authored Dec 27, 2024
2 parents 820c425 + 2323ee4 commit 5019dd8
Show file tree
Hide file tree
Showing 36 changed files with 289 additions and 105 deletions.
2 changes: 1 addition & 1 deletion Android/MMKV/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ org.gradle.jvmargs=-Xmx1536m
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

VERSION_NAME_PREFIX=2.0.1
VERSION_NAME_PREFIX=2.0.2
#VERSION_NAME_SUFFIX=-SNAPSHOT
VERSION_NAME_SUFFIX=

Expand Down
3 changes: 3 additions & 0 deletions Android/MMKV/mmkv/src/main/java/com/tencent/mmkv/MMKV.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ public static String initialize(Context context, String rootDir, LibLoader loade
}

public static String initialize(@NonNull Context context, String rootDir, LibLoader loader, MMKVLogLevel logLevel, MMKVHandler handler) {
if (!android.os.Process.is64Bit()) {
throw new UnsupportedArchitectureException("MMKV 2.0+ requires 64-bit App, use 1.3.x instead.");
}
// disable process mode in release build
// FIXME: Find a better way to getApplicationInfo() without using context.
// If any one knows how, you're welcome to make a contribution.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Tencent is pleased to support the open source community by making
* MMKV available.
*
* Copyright (C) 2018 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of
* the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.tencent.mmkv;

public class UnsupportedArchitectureException extends RuntimeException {
public UnsupportedArchitectureException(String message) {
super(message);
}
}
6 changes: 3 additions & 3 deletions Android/MMKV/mmkvdemo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':mmkv')
// implementation 'com.tencent:mmkv:2.0.1'
// implementation 'com.tencent:mmkv-static:2.0.1' // this is identical to 'com.tencent:mmkv'
// implementation 'com.tencent:mmkv-shared:2.0.1'
// implementation 'com.tencent:mmkv:2.0.2'
// implementation 'com.tencent:mmkv-static:2.0.2' // this is identical to 'com.tencent:mmkv'
// implementation 'com.tencent:mmkv-shared:2.0.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public void onClick(View v) {
kv.checkContentChangedByOuterProcess();
kv.close();

// prepare for backup customize root path
kv = testMMKV("test_backup", "MMKV Backup", false, otherDir);
kv.close();

testAshmem();
testReKey();

Expand Down Expand Up @@ -564,6 +568,15 @@ private void testBackup() {
Log.i("MMKV", "check on backup file[" + mmkv.mmapID() + "] allKeys: " + Arrays.toString(mmkv.allKeys()));
}

// test backup a normal mmkv from custom root path
mmapID = "test_backup";
ret = MMKV.backupOneToDirectory(mmapID, backupRootDir, otherDir);
Log.i("MMKV", "backup one [" + mmapID + "] ret = " + ret);
if (ret) {
MMKV mmkv = MMKV.backedUpMMKVWithID(mmapID, MMKV.SINGLE_PROCESS_MODE, "MMKV Backup", backupRootDir);
Log.i("MMKV", "check on backup file[" + mmkv.mmapID() + "] allKeys: " + Arrays.toString(mmkv.allKeys()));
}

/*{
MMKV mmkv = MMKV.mmkvWithID("imported");
mmkv.close();
Expand Down Expand Up @@ -603,6 +616,17 @@ private void testRestore() {
Log.i("MMKV", "after restore [" + mmkv.mmapID() + "] allKeys: " + Arrays.toString(mmkv.allKeys()));
}

// test backup a normal mmkv from custom root path
mmapID = "test_backup";
mmkv = MMKV.mmkvWithID(mmapID, MMKV.SINGLE_PROCESS_MODE, "MMKV Backup", otherDir);
mmkv.encode("test_restore", 1024);
Log.i("MMKV", "before restore [" + mmkv.mmapID() + "] allKeys: " + Arrays.toString(mmkv.allKeys()));
ret = MMKV.restoreOneMMKVFromDirectory(mmapID, backupRootDir, otherDir);
Log.i("MMKV", "backup one [" + mmapID + "] ret = " + ret);
if (ret) {
Log.i("MMKV", "check on backup file[" + mmkv.mmapID() + "] allKeys: " + Arrays.toString(mmkv.allKeys()));
}

/*{
mmkv = MMKV.mmkvWithID("imported");
mmkv.close();
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
# MMKV Change Log
## v2.0.2 / 2024-12-27
Mary holiday and a happy new year!
### Changes for All platforms
* Fix a bug that MMKV might fail to backup/restore across different filesystems.
* Add protection from invalid value size of auto-key-expire mmkv.

### Android
* If the running App is 32-bit only, warn about it (by throwing `UnsupportedArchitectureException`) before trying to load native lib.
* Add forward support for the correct filename with a custom root path.

### HarmonyOS NEXT
* Obfuscation fully supported.
* Use atomic file rename on OHOS.
* Add forward support for the correct filename with a custom root path.

### Win32
* Only `mmap()` on `ftruncate()`/`zeroFillFile()` failure iff we have a valid file mapping before.

## v2.0.1 / 2024-11-12
**This is a hotfix release.**
### Changes for All platforms
Expand Down
24 changes: 16 additions & 8 deletions Core/MMKV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,7 @@ void MMKV::close() {
SCOPED_LOCK(g_instanceLock);
m_lock->lock();

#ifndef MMKV_ANDROID
auto itr = g_instanceDic->find(m_mmapKey);
#else
auto itr = g_instanceDic->find(m_mmapID);
#endif
if (itr != g_instanceDic->end()) {
g_instanceDic->erase(itr);
}
Expand Down Expand Up @@ -1308,8 +1304,14 @@ bool MMKV::backupOneToDirectory(const string &mmapID, const MMKVPath_t &dstDir,
auto dstPath = dstDir + MMKV_PATH_SLASH + encodePath;
auto mmapKey = mmapedKVKey(mmapID, rootPath);
#ifdef MMKV_ANDROID
// historically Android mistakenly use mmapKey as mmapID
auto srcPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath);
string srcPath;
auto correctPath = *rootPath + MMKV_PATH_SLASH + encodePath;
if (srcDir && isFileExist(correctPath)) {
srcPath = correctPath;
} else {
// historically Android mistakenly use mmapKey as mmapID
srcPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath);
}
#else
auto srcPath = *rootPath + MMKV_PATH_SLASH + encodePath;
#endif
Expand Down Expand Up @@ -1491,8 +1493,14 @@ bool MMKV::restoreOneFromDirectory(const string &mmapID, const MMKVPath_t &srcDi
auto srcPath = srcDir + MMKV_PATH_SLASH + encodePath;
auto mmapKey = mmapedKVKey(mmapID, rootPath);
#ifdef MMKV_ANDROID
// historically Android mistakenly use mmapKey as mmapID
auto dstPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath);
string dstPath;
auto correctPath = *rootPath + MMKV_PATH_SLASH + encodePath;
if (dstDir && isFileExist(correctPath)) {
dstPath = correctPath;
} else {
// historically Android mistakenly use mmapKey as mmapID
dstPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath);
}
#else
auto dstPath = *rootPath + MMKV_PATH_SLASH + encodePath;
#endif
Expand Down
16 changes: 8 additions & 8 deletions Core/MMKV.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,20 @@ concept MMKV_SUPPORTED_VALUE_TYPE = MMKV_SUPPORTED_PRIMITIVE_VALUE_TYPE<T> || MM

class MMKV {
#ifndef MMKV_ANDROID
std::string m_mmapKey;
MMKV(const std::string &mmapID, MMKVMode mode, std::string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity = 0);
#else // defined(MMKV_ANDROID)
mmkv::FileLock *m_fileModeLock;
mmkv::InterProcessLock *m_sharedProcessModeLock;
mmkv::InterProcessLock *m_exclusiveProcessModeLock;

MMKV(const std::string &mmapID, int size, MMKVMode mode, std::string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity = 0);
MMKV(const std::string &mmapID, int size, MMKVMode mode, const std::string *cryptKey, const MMKVPath_t *rootPath, size_t expectedCapacity = 0);

MMKV(const std::string &mmapID, int ashmemFD, int ashmemMetaFd, std::string *cryptKey = nullptr);
MMKV(const std::string &mmapID, int ashmemFD, int ashmemMetaFd, const std::string *cryptKey = nullptr);
#endif

~MMKV();

std::string m_mmapKey;
std::string m_mmapID;
const MMKVMode m_mode;
MMKVPath_t m_path;
Expand Down Expand Up @@ -226,7 +226,7 @@ class MMKV {
void notifyContentChanged();

#if defined(MMKV_ANDROID) && !defined(MMKV_DISABLE_CRYPT)
void checkReSetCryptKey(int fd, int metaFD, std::string *cryptKey);
void checkReSetCryptKey(int fd, int metaFD, const std::string *cryptKey);
#endif
static bool backupOneToDirectory(const std::string &mmapKey, const MMKVPath_t &dstPath, const MMKVPath_t &srcPath, bool compareFullPath);
static size_t backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &srcDir, bool isInSpecialDir);
Expand Down Expand Up @@ -270,11 +270,11 @@ class MMKV {
static MMKV *mmkvWithID(const std::string &mmapID,
int size = mmkv::DEFAULT_MMAP_SIZE,
MMKVMode mode = MMKV_SINGLE_PROCESS,
std::string *cryptKey = nullptr,
MMKVPath_t *rootPath = nullptr,
const std::string *cryptKey = nullptr,
const MMKVPath_t *rootPath = nullptr,
size_t expectedCapacity = 0);

static MMKV *mmkvWithAshmemFD(const std::string &mmapID, int fd, int metaFD, std::string *cryptKey = nullptr);
static MMKV *mmkvWithAshmemFD(const std::string &mmapID, int fd, int metaFD, const std::string *cryptKey = nullptr);

int ashmemFD();

Expand Down Expand Up @@ -591,5 +591,5 @@ bool MMKV::getVector(MMKVKey_t key, T &result) {

MMKV_NAMESPACE_END

#endif
#endif // __cplusplus
#endif // MMKV_MMKV_H
2 changes: 1 addition & 1 deletion Core/MMKVPredef.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include <vector>
#include <unordered_map>

constexpr auto MMKV_VERSION = "v2.0.1";
constexpr auto MMKV_VERSION = "v2.0.2";

#ifdef DEBUG
# define MMKV_DEBUG
Expand Down
26 changes: 19 additions & 7 deletions Core/MMKV_Android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ using namespace mmkv;
extern unordered_map<string, MMKV *> *g_instanceDic;
extern ThreadLock *g_instanceLock;

MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, string *cryptKey, string *rootPath, size_t expectedCapacity)
: m_mmapID((mode & MMKV_BACKUP) ? mmapID : mmapedKVKey(mmapID, rootPath)) // historically Android mistakenly use mmapKey as mmapID
MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, const string *cryptKey, const string *rootPath, size_t expectedCapacity)
: m_mmapID(mmapID)
, m_mode(mode)
, m_path(mappedKVPathWithID(m_mmapID, mode, rootPath))
, m_crcPath(crcPathWithID(m_mmapID, mode, rootPath))
Expand Down Expand Up @@ -88,7 +88,7 @@ MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, string *cryptKey, stri
}*/
}

MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, string *cryptKey)
MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, const string *cryptKey)
: m_mmapID(mmapID)
, m_mode(MMKV_ASHMEM)
, m_path(mappedKVPathWithID(m_mmapID, MMKV_ASHMEM, nullptr))
Expand Down Expand Up @@ -137,7 +137,7 @@ MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, string *cryptKe
}*/
}

MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, string *cryptKey, string *rootPath, size_t expectedCapacity) {
MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, const string *cryptKey, const string *rootPath, size_t expectedCapacity) {
if (mmapID.empty() || !g_instanceLock) {
return nullptr;
}
Expand All @@ -157,12 +157,23 @@ MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, string *cr
}
MMKVInfo("prepare to load %s (id %s) from rootPath %s", mmapID.c_str(), mmapKey.c_str(), rootPath->c_str());
}
auto kv = new MMKV(mmapID, size, mode, cryptKey, rootPath, expectedCapacity);

string realID;
auto correctPath = mappedKVPathWithID(mmapID, mode, rootPath);
if ((mode & MMKV_BACKUP) || (rootPath && isFileExist(correctPath))) {
// it's successfully migrated to the correct path by newer version of MMKV
realID = mmapID;
} else {
// historically Android mistakenly use mmapKey as mmapID
realID = mmapKey;
}
auto kv = new MMKV(realID, size, mode, cryptKey, rootPath, expectedCapacity);
kv->m_mmapKey = mmapKey;
(*g_instanceDic)[mmapKey] = kv;
return kv;
}

MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, string *cryptKey) {
MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, const string *cryptKey) {

if (fd < 0 || !g_instanceLock) {
return nullptr;
Expand All @@ -178,6 +189,7 @@ MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, string *c
return kv;
}
auto kv = new MMKV(mmapID, fd, metaFD, cryptKey);
kv->m_mmapKey = mmapID;
(*g_instanceDic)[mmapID] = kv;
return kv;
}
Expand All @@ -191,7 +203,7 @@ int MMKV::ashmemMetaFD() {
}

# ifndef MMKV_DISABLE_CRYPT
void MMKV::checkReSetCryptKey(int fd, int metaFD, string *cryptKey) {
void MMKV::checkReSetCryptKey(int fd, int metaFD, const string *cryptKey) {
SCOPED_LOCK(m_lock);

checkReSetCryptKey(cryptKey);
Expand Down
Loading

0 comments on commit 5019dd8

Please sign in to comment.