@onekeyfe/react-native-app-update 3.0.58 → 3.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/margelo/nitro/reactnativeappupdate/ReactNativeAppUpdate.kt +71 -22
- package/ios/ReactNativeAppUpdate.swift +7 -0
- package/lib/typescript/src/ReactNativeAppUpdate.nitro.d.ts +1 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeAppUpdateSpec.cpp +15 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeAppUpdateSpec.hpp +1 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeappupdate/HybridReactNativeAppUpdateSpec.kt +4 -0
- package/nitrogen/generated/ios/c++/HybridReactNativeAppUpdateSpecSwift.hpp +8 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeAppUpdateSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeAppUpdateSpec_cxx.swift +19 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeAppUpdateSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeAppUpdateSpec.hpp +1 -0
- package/package.json +1 -1
- package/src/ReactNativeAppUpdate.nitro.ts +4 -0
package/android/src/main/java/com/margelo/nitro/reactnativeappupdate/ReactNativeAppUpdate.kt
CHANGED
|
@@ -1191,6 +1191,53 @@ n2DMz6gqk326W6SFynYtvuiXo7wG4Cmn3SuIU8xfv9rJqunpZGYchMd7nZektmEJ
|
|
|
1191
1191
|
return result
|
|
1192
1192
|
}
|
|
1193
1193
|
|
|
1194
|
+
/**
|
|
1195
|
+
* Delete every file in cacheDir/apks/ (.apk / .partial / .progress /
|
|
1196
|
+
* .SHA256SUMS.asc). Tolerates a missing directory and per-file delete
|
|
1197
|
+
* failures (e.g. the OS reclaimed the cache mid-pass — see
|
|
1198
|
+
* verifyExistingApk's Indeterminate handling for the same defensive
|
|
1199
|
+
* stance). Pure file I/O: does NOT touch download/verification state, so
|
|
1200
|
+
* it is safe to share between clearCache (full reset) and clearApkCache
|
|
1201
|
+
* (JS-gated, no in-flight download to cancel). The [tag] flows into the
|
|
1202
|
+
* log lines so the two callers stay distinguishable in logcat.
|
|
1203
|
+
*/
|
|
1204
|
+
private fun wipeApkCacheFiles(tag: String, protectedPaths: Set<String> = emptySet()) {
|
|
1205
|
+
val context = NitroModules.applicationContext
|
|
1206
|
+
if (context == null) {
|
|
1207
|
+
OneKeyLog.warn("AppUpdate", "$tag: application context unavailable, skipping file cleanup")
|
|
1208
|
+
return
|
|
1209
|
+
}
|
|
1210
|
+
val apkDir = File(context.cacheDir, "apks")
|
|
1211
|
+
if (!apkDir.exists()) {
|
|
1212
|
+
OneKeyLog.info("AppUpdate", "$tag: apks cache directory does not exist, nothing to clean")
|
|
1213
|
+
return
|
|
1214
|
+
}
|
|
1215
|
+
val filesToDelete = apkDir.listFiles() ?: emptyArray()
|
|
1216
|
+
OneKeyLog.info("AppUpdate", "$tag: found ${filesToDelete.size} cached file(s) to delete in ${apkDir.absolutePath}")
|
|
1217
|
+
var deletedCount = 0
|
|
1218
|
+
var skippedCount = 0
|
|
1219
|
+
filesToDelete.forEach { file ->
|
|
1220
|
+
// Never delete a verified, pending-install APK (its canonical path is
|
|
1221
|
+
// still in verifiedFiles). Protects the install flow from a racing
|
|
1222
|
+
// cleanup that slipped past the JS status gate.
|
|
1223
|
+
if (protectedPaths.isNotEmpty() && file.canonicalPath in protectedPaths) {
|
|
1224
|
+
OneKeyLog.info("AppUpdate", "$tag: skipping verified pending-install file ${file.name}")
|
|
1225
|
+
skippedCount++
|
|
1226
|
+
return@forEach
|
|
1227
|
+
}
|
|
1228
|
+
val size = file.length()
|
|
1229
|
+
// The file may already be gone (concurrent OS cache reclaim);
|
|
1230
|
+
// treat a non-existent file as nothing to do, not a failure.
|
|
1231
|
+
if (!file.exists() || file.delete()) {
|
|
1232
|
+
OneKeyLog.debug("AppUpdate", "$tag: deleted ${file.name} (${size} bytes)")
|
|
1233
|
+
deletedCount++
|
|
1234
|
+
} else {
|
|
1235
|
+
OneKeyLog.warn("AppUpdate", "$tag: failed to delete ${file.name}")
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
OneKeyLog.info("AppUpdate", "$tag: completed, deleted $deletedCount/${filesToDelete.size} files (skipped $skippedCount protected)")
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1194
1241
|
override fun clearCache(): Promise<Unit> {
|
|
1195
1242
|
return Promise.async {
|
|
1196
1243
|
OneKeyLog.info("AppUpdate", "clearCache: starting cleanup...")
|
|
@@ -1200,29 +1247,31 @@ n2DMz6gqk326W6SFynYtvuiXo7wG4Cmn3SuIU8xfv9rJqunpZGYchMd7nZektmEJ
|
|
|
1200
1247
|
OneKeyLog.info("AppUpdate", "clearCache: reset download state, cleared $verifiedCount verified file entries")
|
|
1201
1248
|
|
|
1202
1249
|
// Clean up downloaded APK and ASC files from cacheDir/apks/ directory
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
OneKeyLog.info("AppUpdate", "clearCache: apks cache directory does not exist, nothing to clean")
|
|
1222
|
-
}
|
|
1223
|
-
} else {
|
|
1224
|
-
OneKeyLog.warn("AppUpdate", "clearCache: application context unavailable, skipping file cleanup")
|
|
1250
|
+
wipeApkCacheFiles("clearCache")
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
override fun clearApkCache(): Promise<Unit> {
|
|
1255
|
+
return Promise.async {
|
|
1256
|
+
// Wipe downloaded APK artifacts from cacheDir/apks/ only. The JS
|
|
1257
|
+
// layer gates on app-update status before calling, but that read is
|
|
1258
|
+
// not atomic with this delete, so guard natively too:
|
|
1259
|
+
// - bail entirely if a download is in flight (would yank its
|
|
1260
|
+
// .partial/.progress out from under the writer);
|
|
1261
|
+
// - never delete a verified, pending-install APK (still tracked in
|
|
1262
|
+
// verifiedFiles) so an open installer keeps a readable file.
|
|
1263
|
+
// Deliberately do NOT touch isDownloading / verifiedFiles state here
|
|
1264
|
+
// (that's clearCache's job). Missing dir/files are tolerated.
|
|
1265
|
+
if (isDownloading.get()) {
|
|
1266
|
+
OneKeyLog.info("AppUpdate", "clearApkCache: download in progress, skipping APK cache cleanup")
|
|
1267
|
+
return@async
|
|
1225
1268
|
}
|
|
1269
|
+
val protectedPaths = synchronized(verifiedFiles) { verifiedFiles.keys.toSet() }
|
|
1270
|
+
OneKeyLog.info(
|
|
1271
|
+
"AppUpdate",
|
|
1272
|
+
"clearApkCache: starting stale APK cache cleanup (protecting ${protectedPaths.size} verified file(s))...",
|
|
1273
|
+
)
|
|
1274
|
+
wipeApkCacheFiles("clearApkCache", protectedPaths)
|
|
1226
1275
|
}
|
|
1227
1276
|
}
|
|
1228
1277
|
}
|
|
@@ -54,6 +54,13 @@ class ReactNativeAppUpdate: HybridReactNativeAppUpdateSpec {
|
|
|
54
54
|
return Promise.resolved(withResult: ())
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
func clearApkCache() throws -> Promise<Void> {
|
|
58
|
+
// APK is Android-only; nothing to wipe on iOS. Safe no-op so the
|
|
59
|
+
// cross-platform Nitro spec stays satisfied.
|
|
60
|
+
OneKeyLog.debug("AppUpdate", "clearApkCache not available on iOS")
|
|
61
|
+
return Promise.resolved(withResult: ())
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
func addDownloadListener(callback: @escaping (DownloadEvent) -> Void) throws -> Double {
|
|
58
65
|
let id = nextListenerId
|
|
59
66
|
nextListenerId += 1
|
|
@@ -22,6 +22,7 @@ export interface ReactNativeAppUpdate extends HybridObject<{
|
|
|
22
22
|
verifyAPK(params: AppUpdateFileParams): Promise<void>;
|
|
23
23
|
installAPK(params: AppUpdateFileParams): Promise<void>;
|
|
24
24
|
clearCache(): Promise<void>;
|
|
25
|
+
clearApkCache(): Promise<void>;
|
|
25
26
|
testVerification(): Promise<boolean>;
|
|
26
27
|
testSkipVerification(): Promise<boolean>;
|
|
27
28
|
isSkipGpgVerificationAllowed(): boolean;
|
|
@@ -149,6 +149,21 @@ namespace margelo::nitro::reactnativeappupdate {
|
|
|
149
149
|
return __promise;
|
|
150
150
|
}();
|
|
151
151
|
}
|
|
152
|
+
std::shared_ptr<Promise<void>> JHybridReactNativeAppUpdateSpec::clearApkCache() {
|
|
153
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("clearApkCache");
|
|
154
|
+
auto __result = method(_javaPart);
|
|
155
|
+
return [&]() {
|
|
156
|
+
auto __promise = Promise<void>::create();
|
|
157
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
158
|
+
__promise->resolve();
|
|
159
|
+
});
|
|
160
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
161
|
+
jni::JniException __jniError(__throwable);
|
|
162
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
163
|
+
});
|
|
164
|
+
return __promise;
|
|
165
|
+
}();
|
|
166
|
+
}
|
|
152
167
|
std::shared_ptr<Promise<bool>> JHybridReactNativeAppUpdateSpec::testVerification() {
|
|
153
168
|
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("testVerification");
|
|
154
169
|
auto __result = method(_javaPart);
|
|
@@ -60,6 +60,7 @@ namespace margelo::nitro::reactnativeappupdate {
|
|
|
60
60
|
std::shared_ptr<Promise<void>> verifyAPK(const AppUpdateFileParams& params) override;
|
|
61
61
|
std::shared_ptr<Promise<void>> installAPK(const AppUpdateFileParams& params) override;
|
|
62
62
|
std::shared_ptr<Promise<void>> clearCache() override;
|
|
63
|
+
std::shared_ptr<Promise<void>> clearApkCache() override;
|
|
63
64
|
std::shared_ptr<Promise<bool>> testVerification() override;
|
|
64
65
|
std::shared_ptr<Promise<bool>> testSkipVerification() override;
|
|
65
66
|
bool isSkipGpgVerificationAllowed() override;
|
|
@@ -70,6 +70,10 @@ abstract class HybridReactNativeAppUpdateSpec: HybridObject() {
|
|
|
70
70
|
@Keep
|
|
71
71
|
abstract fun clearCache(): Promise<Unit>
|
|
72
72
|
|
|
73
|
+
@DoNotStrip
|
|
74
|
+
@Keep
|
|
75
|
+
abstract fun clearApkCache(): Promise<Unit>
|
|
76
|
+
|
|
73
77
|
@DoNotStrip
|
|
74
78
|
@Keep
|
|
75
79
|
abstract fun testVerification(): Promise<Boolean>
|
|
@@ -118,6 +118,14 @@ namespace margelo::nitro::reactnativeappupdate {
|
|
|
118
118
|
auto __value = std::move(__result.value());
|
|
119
119
|
return __value;
|
|
120
120
|
}
|
|
121
|
+
inline std::shared_ptr<Promise<void>> clearApkCache() override {
|
|
122
|
+
auto __result = _swiftPart.clearApkCache();
|
|
123
|
+
if (__result.hasError()) [[unlikely]] {
|
|
124
|
+
std::rethrow_exception(__result.error());
|
|
125
|
+
}
|
|
126
|
+
auto __value = std::move(__result.value());
|
|
127
|
+
return __value;
|
|
128
|
+
}
|
|
121
129
|
inline std::shared_ptr<Promise<bool>> testVerification() override {
|
|
122
130
|
auto __result = _swiftPart.testVerification();
|
|
123
131
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -20,6 +20,7 @@ public protocol HybridReactNativeAppUpdateSpec_protocol: HybridObject {
|
|
|
20
20
|
func verifyAPK(params: AppUpdateFileParams) throws -> Promise<Void>
|
|
21
21
|
func installAPK(params: AppUpdateFileParams) throws -> Promise<Void>
|
|
22
22
|
func clearCache() throws -> Promise<Void>
|
|
23
|
+
func clearApkCache() throws -> Promise<Void>
|
|
23
24
|
func testVerification() throws -> Promise<Bool>
|
|
24
25
|
func testSkipVerification() throws -> Promise<Bool>
|
|
25
26
|
func isSkipGpgVerificationAllowed() throws -> Bool
|
|
@@ -231,6 +231,25 @@ open class HybridReactNativeAppUpdateSpec_cxx {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
@inline(__always)
|
|
235
|
+
public final func clearApkCache() -> bridge.Result_std__shared_ptr_Promise_void___ {
|
|
236
|
+
do {
|
|
237
|
+
let __result = try self.__implementation.clearApkCache()
|
|
238
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_Promise_void__ in
|
|
239
|
+
let __promise = bridge.create_std__shared_ptr_Promise_void__()
|
|
240
|
+
let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_void__(__promise)
|
|
241
|
+
__result
|
|
242
|
+
.then({ __result in __promiseHolder.resolve() })
|
|
243
|
+
.catch({ __error in __promiseHolder.reject(__error.toCpp()) })
|
|
244
|
+
return __promise
|
|
245
|
+
}()
|
|
246
|
+
return bridge.create_Result_std__shared_ptr_Promise_void___(__resultCpp)
|
|
247
|
+
} catch (let __error) {
|
|
248
|
+
let __exceptionPtr = __error.toCpp()
|
|
249
|
+
return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
234
253
|
@inline(__always)
|
|
235
254
|
public final func testVerification() -> bridge.Result_std__shared_ptr_Promise_bool___ {
|
|
236
255
|
do {
|
|
@@ -20,6 +20,7 @@ namespace margelo::nitro::reactnativeappupdate {
|
|
|
20
20
|
prototype.registerHybridMethod("verifyAPK", &HybridReactNativeAppUpdateSpec::verifyAPK);
|
|
21
21
|
prototype.registerHybridMethod("installAPK", &HybridReactNativeAppUpdateSpec::installAPK);
|
|
22
22
|
prototype.registerHybridMethod("clearCache", &HybridReactNativeAppUpdateSpec::clearCache);
|
|
23
|
+
prototype.registerHybridMethod("clearApkCache", &HybridReactNativeAppUpdateSpec::clearApkCache);
|
|
23
24
|
prototype.registerHybridMethod("testVerification", &HybridReactNativeAppUpdateSpec::testVerification);
|
|
24
25
|
prototype.registerHybridMethod("testSkipVerification", &HybridReactNativeAppUpdateSpec::testSkipVerification);
|
|
25
26
|
prototype.registerHybridMethod("isSkipGpgVerificationAllowed", &HybridReactNativeAppUpdateSpec::isSkipGpgVerificationAllowed);
|
|
@@ -63,6 +63,7 @@ namespace margelo::nitro::reactnativeappupdate {
|
|
|
63
63
|
virtual std::shared_ptr<Promise<void>> verifyAPK(const AppUpdateFileParams& params) = 0;
|
|
64
64
|
virtual std::shared_ptr<Promise<void>> installAPK(const AppUpdateFileParams& params) = 0;
|
|
65
65
|
virtual std::shared_ptr<Promise<void>> clearCache() = 0;
|
|
66
|
+
virtual std::shared_ptr<Promise<void>> clearApkCache() = 0;
|
|
66
67
|
virtual std::shared_ptr<Promise<bool>> testVerification() = 0;
|
|
67
68
|
virtual std::shared_ptr<Promise<bool>> testSkipVerification() = 0;
|
|
68
69
|
virtual bool isSkipGpgVerificationAllowed() = 0;
|
package/package.json
CHANGED
|
@@ -24,6 +24,10 @@ export interface ReactNativeAppUpdate
|
|
|
24
24
|
verifyAPK(params: AppUpdateFileParams): Promise<void>;
|
|
25
25
|
installAPK(params: AppUpdateFileParams): Promise<void>;
|
|
26
26
|
clearCache(): Promise<void>;
|
|
27
|
+
// Wipe downloaded APK artifacts from cacheDir/apks (.apk / .partial /
|
|
28
|
+
// .SHA256SUMS.asc). Android-only; the JS layer gates on update status before
|
|
29
|
+
// calling so this does NOT cancel an in-flight download. iOS is a no-op stub.
|
|
30
|
+
clearApkCache(): Promise<void>;
|
|
27
31
|
|
|
28
32
|
// Verification & testing
|
|
29
33
|
testVerification(): Promise<boolean>;
|