react-native-update 10.59.0 → 10.59.1
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/build.gradle +46 -14
- package/android/jni/Android.mk +2 -1
- package/android/lib/arm64-v8a/librnpushy.so +0 -0
- package/android/lib/armeabi-v7a/librnpushy.so +0 -0
- package/android/lib/x86/librnpushy.so +0 -0
- package/android/lib/x86_64/librnpushy.so +0 -0
- package/android/src/main/java/cn/reactnative/modules/update/ApkInstaller.java +6 -6
- package/android/src/main/java/cn/reactnative/modules/update/BundledResourceCopier.java +4 -4
- package/android/src/main/java/cn/reactnative/modules/update/{CrashRescue.java → CrashHold.java} +12 -12
- package/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java +28 -24
- package/android/src/main/java/cn/reactnative/modules/update/ErrorCodes.java +2 -1
- package/android/src/main/java/cn/reactnative/modules/update/{NativeUpdateFlow.java → FlowBridge.java} +6 -6
- package/android/src/main/java/cn/reactnative/modules/update/HttpUtils.java +6 -3
- package/android/src/main/java/cn/reactnative/modules/update/{NativeUpdateCore.java → NativeCore.java} +4 -4
- package/android/src/main/java/cn/reactnative/modules/update/PushyConfiguration.java +10 -5
- package/android/src/main/java/cn/reactnative/modules/update/PushyRuntime.java +4 -4
- package/android/src/main/java/cn/reactnative/modules/update/ReactReloadManager.java +7 -7
- package/android/src/main/java/cn/reactnative/modules/update/StateSerialRunner.java +1 -1
- package/android/src/main/java/cn/reactnative/modules/update/{NativeCheckOrchestrator.java → SyncCoordinator.java} +79 -75
- package/android/src/main/java/cn/reactnative/modules/update/Texts.java +28 -0
- package/android/src/main/java/cn/reactnative/modules/update/UiThreadRunner.java +1 -1
- package/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java +28 -28
- package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleImpl.java +12 -9
- package/cpp/patch_core/archive_limits.h +5 -0
- package/cpp/patch_core/archive_patch_core.cpp +26 -19
- package/cpp/patch_core/archive_patch_core.h +17 -8
- package/cpp/patch_core/digest.h +6 -1
- package/cpp/patch_core/error_codes.h +8 -1
- package/cpp/patch_core/hbc_transform.h +5 -0
- package/cpp/patch_core/hbc_transform_wire.h +5 -0
- package/cpp/patch_core/install_record.h +5 -0
- package/cpp/patch_core/jni_natives.h +27 -0
- package/cpp/patch_core/jni_registration.cpp +103 -0
- package/cpp/patch_core/obscured_text.h +44 -0
- package/cpp/patch_core/patch_core.cpp +13 -13
- package/cpp/patch_core/patch_core.h +11 -6
- package/cpp/patch_core/patch_core_android.cpp +10 -10
- package/cpp/patch_core/state_core.h +5 -0
- package/cpp/patch_core/state_ops.h +5 -0
- package/cpp/patch_core/update_core_android.cpp +23 -22
- package/cpp/update_flow_core/flow_json.h +6 -1
- package/cpp/update_flow_core/update_flow_core.cpp +35 -18
- package/cpp/update_flow_core/update_flow_core.h +13 -8
- package/cpp/update_flow_core/update_flow_jni.cpp +11 -13
- package/harmony/pushy/src/main/cpp/CMakeLists.txt +8 -8
- package/harmony/pushy/src/main/cpp/pushy.cpp +33 -33
- package/harmony/pushy/src/main/ets/ArchiveLimits.ts +15 -15
- package/harmony/pushy/src/main/ets/DownloadTask.ts +60 -60
- package/harmony/pushy/src/main/ets/ErrorCodes.ts +13 -11
- package/harmony/pushy/src/main/ets/InstallRecord.ts +4 -4
- package/harmony/pushy/src/main/ets/NativePatchCore.ts +9 -9
- package/harmony/pushy/src/main/ets/PathUtils.ts +2 -2
- package/harmony/pushy/src/main/ets/PushyConfiguration.ts +8 -6
- package/harmony/pushy/src/main/ets/PushyFileJSBundleProvider.ets +1 -1
- package/harmony/pushy/src/main/ets/PushyTurboModule.ts +42 -41
- package/harmony/pushy/src/main/ets/{NativeCheckOrchestrator.ts → SyncCoordinator.ts} +33 -32
- package/harmony/pushy/src/main/ets/Texts.ts +28 -0
- package/harmony/pushy/src/main/ets/UpdateContext.ts +31 -30
- package/harmony/pushy.har +0 -0
- package/ios/RCTPushy/RCTPushy.mm +148 -140
- package/ios/RCTPushy/RCTPushyConfiguration.h +8 -0
- package/ios/RCTPushy/RCTPushyConfiguration.mm +32 -5
- package/package.json +1 -1
- package/react-native-update.podspec +15 -3
- package/android/lib/arm64-v8a/librnupdate.so +0 -0
- package/android/lib/armeabi-v7a/librnupdate.so +0 -0
- package/android/lib/x86/librnupdate.so +0 -0
- package/android/lib/x86_64/librnupdate.so +0 -0
|
@@ -19,10 +19,10 @@ import java.util.concurrent.ThreadFactory;
|
|
|
19
19
|
|
|
20
20
|
public class UpdateContext {
|
|
21
21
|
static {
|
|
22
|
-
|
|
22
|
+
NativeCore.ensureLoaded();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
static final String TAG =
|
|
25
|
+
static final String TAG = Texts.LOG_TAG;
|
|
26
26
|
static final boolean DEBUG = BuildConfig.DEBUG;
|
|
27
27
|
|
|
28
28
|
private final Context context;
|
|
@@ -107,13 +107,13 @@ public class UpdateContext {
|
|
|
107
107
|
}
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
-
this.rootDir = new File(this.context.getFilesDir(), "
|
|
110
|
+
this.rootDir = new File(this.context.getFilesDir(), Texts.reveal("0502e4d5af9f6d"));
|
|
111
111
|
|
|
112
112
|
if (!rootDir.exists() && !rootDir.mkdirs() && !rootDir.exists()) {
|
|
113
|
-
throw new IllegalStateException("Failed to create
|
|
113
|
+
throw new IllegalStateException("Failed to create storage root dir: " + rootDir);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
this.sp = this.context.getSharedPreferences("
|
|
116
|
+
this.sp = this.context.getSharedPreferences(Texts.reveal("2f07f0d0ba8e"), Context.MODE_PRIVATE);
|
|
117
117
|
this.packageInfo = lookupPackageInfo(this.context);
|
|
118
118
|
this.reactInstanceManager = pendingReactInstanceManager;
|
|
119
119
|
|
|
@@ -182,7 +182,7 @@ public class UpdateContext {
|
|
|
182
182
|
* to the buildTime heuristic.
|
|
183
183
|
*
|
|
184
184
|
* Deliberately java.security.MessageDigest instead of the C++
|
|
185
|
-
* pushy::digest:
|
|
185
|
+
* pushy::digest: librnpushy.so is a prebuilt artifact and this must not
|
|
186
186
|
* force a rebuild. The NIST vectors in the patch_core tests anchor both
|
|
187
187
|
* implementations to the same standard.
|
|
188
188
|
*/
|
|
@@ -201,7 +201,7 @@ public class UpdateContext {
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
// Package-private: also the native cold-start check's request input
|
|
204
|
-
// (
|
|
204
|
+
// (SyncCoordinator). Blocking — call off the main thread.
|
|
205
205
|
String computeBundleHash() {
|
|
206
206
|
String cachePrefix = getPackageVersion() + "|" + getPackageLastUpdateTime() + "|";
|
|
207
207
|
String cached = sp.getString(KEY_BUNDLE_HASH_CACHE, null);
|
|
@@ -322,7 +322,7 @@ public class UpdateContext {
|
|
|
322
322
|
params.hash = hash;
|
|
323
323
|
params.listener = listener;
|
|
324
324
|
params.deadlineNanos = deadlineNanos;
|
|
325
|
-
params.targetFile = new File(rootDir, hash +
|
|
325
|
+
params.targetFile = new File(rootDir, hash + Texts.reveal("7416e4dae09b69512137"));
|
|
326
326
|
params.unzipDirectory = new File(rootDir, hash);
|
|
327
327
|
enqueue(params);
|
|
328
328
|
return params;
|
|
@@ -350,7 +350,7 @@ public class UpdateContext {
|
|
|
350
350
|
params.originHash = originHash;
|
|
351
351
|
params.listener = listener;
|
|
352
352
|
params.deadlineNanos = deadlineNanos;
|
|
353
|
-
params.targetFile = new File(rootDir, originHash + "-" + hash +
|
|
353
|
+
params.targetFile = new File(rootDir, originHash + "-" + hash + Texts.reveal("7407e4dae09b69512137"));
|
|
354
354
|
params.unzipDirectory = new File(rootDir, hash);
|
|
355
355
|
params.originDirectory = new File(rootDir, originHash);
|
|
356
356
|
enqueue(params);
|
|
@@ -400,7 +400,7 @@ public class UpdateContext {
|
|
|
400
400
|
// A lost state write can mean a missed rollback or a version switch
|
|
401
401
|
// that silently never happens, so this must be visible in release too.
|
|
402
402
|
if (!editor.commit()) {
|
|
403
|
-
Log.e(TAG, "Failed to persist
|
|
403
|
+
Log.e(TAG, "Failed to persist state for " + reason);
|
|
404
404
|
return false;
|
|
405
405
|
}
|
|
406
406
|
return true;
|
|
@@ -414,7 +414,7 @@ public class UpdateContext {
|
|
|
414
414
|
*/
|
|
415
415
|
private void persistEditorOrThrow(SharedPreferences.Editor editor, String reason) {
|
|
416
416
|
if (!persistEditor(editor, reason)) {
|
|
417
|
-
throw new IllegalStateException("Failed to persist
|
|
417
|
+
throw new IllegalStateException("Failed to persist state for " + reason);
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
|
|
@@ -668,7 +668,7 @@ public class UpdateContext {
|
|
|
668
668
|
|
|
669
669
|
public String getBundleUrl(String defaultAssetsUrl) {
|
|
670
670
|
isUsingBundleUrl = true;
|
|
671
|
-
String
|
|
671
|
+
String syncRolledBackVersion = null;
|
|
672
672
|
try {
|
|
673
673
|
// The whole resolution is one read-modify-write on the state
|
|
674
674
|
// (resolve, then possibly roll back missing bundles); see
|
|
@@ -682,7 +682,7 @@ public class UpdateContext {
|
|
|
682
682
|
ignoreRollback,
|
|
683
683
|
true
|
|
684
684
|
);
|
|
685
|
-
|
|
685
|
+
syncRolledBackVersion = launchState.rolledBackVersion;
|
|
686
686
|
if (launchState.didRollback) {
|
|
687
687
|
// The crash-protection rollback: the new version never called
|
|
688
688
|
// markSuccess. Keep this visible in release logs.
|
|
@@ -717,22 +717,22 @@ public class UpdateContext {
|
|
|
717
717
|
if (!bundleFile.exists()) {
|
|
718
718
|
Log.e(TAG, "Bundle version " + currentVersion + " not found.");
|
|
719
719
|
currentVersion = this.rollBack();
|
|
720
|
-
|
|
720
|
+
syncRolledBackVersion = rolledBackVersion();
|
|
721
721
|
continue;
|
|
722
722
|
}
|
|
723
723
|
launchVersion = currentVersion;
|
|
724
|
-
|
|
724
|
+
syncRolledBackVersion = rolledBackVersion();
|
|
725
725
|
return bundleFile.toString();
|
|
726
726
|
}
|
|
727
727
|
|
|
728
|
-
|
|
728
|
+
syncRolledBackVersion = rolledBackVersion();
|
|
729
729
|
return defaultAssetsUrl;
|
|
730
730
|
}
|
|
731
731
|
} finally {
|
|
732
732
|
// Even corrupted state or a state-core exception must not disable
|
|
733
733
|
// the next-launch rescue check. A null snapshot simply omits the
|
|
734
734
|
// rollback guard for this exceptional launch.
|
|
735
|
-
|
|
735
|
+
SyncCoordinator.schedule(this, syncRolledBackVersion);
|
|
736
736
|
}
|
|
737
737
|
}
|
|
738
738
|
|
|
@@ -747,15 +747,15 @@ public class UpdateContext {
|
|
|
747
747
|
|
|
748
748
|
void setNativeConfig(String config) {
|
|
749
749
|
synchronized (commitLock) {
|
|
750
|
-
boolean changed = !config.equals(sp.getString(
|
|
750
|
+
boolean changed = !config.equals(sp.getString(SyncCoordinator.KEY_CONFIG, null));
|
|
751
751
|
SharedPreferences.Editor editor = sp.edit();
|
|
752
752
|
if (changed) {
|
|
753
753
|
// Also invalidate on a failed persistence attempt: an older
|
|
754
754
|
// round must not commit over uncertain configuration state.
|
|
755
755
|
resetGeneration.incrementAndGet();
|
|
756
756
|
nativeConfigGeneration.incrementAndGet();
|
|
757
|
-
editor.remove(
|
|
758
|
-
|
|
757
|
+
editor.remove(SyncCoordinator.KEY_RESP_CACHE);
|
|
758
|
+
SyncCoordinator.recordJsRound(null);
|
|
759
759
|
}
|
|
760
760
|
// A native-only first launch needs a stable gray-release identity
|
|
761
761
|
// before JS initializes. Never replace an existing installation ID.
|
|
@@ -763,12 +763,12 @@ public class UpdateContext {
|
|
|
763
763
|
if (uuid == null || uuid.isEmpty()) {
|
|
764
764
|
editor.putString("uuid", java.util.UUID.randomUUID().toString());
|
|
765
765
|
}
|
|
766
|
-
editor.putString(
|
|
766
|
+
editor.putString(SyncCoordinator.KEY_CONFIG, config);
|
|
767
767
|
// Persist even an equal value: a previous commit may have updated
|
|
768
768
|
// SharedPreferences memory but failed to write its file.
|
|
769
769
|
persistEditorOrThrow(editor, "persist configuration");
|
|
770
770
|
}
|
|
771
|
-
|
|
771
|
+
SyncCoordinator.onConfigured(this);
|
|
772
772
|
}
|
|
773
773
|
|
|
774
774
|
// Native-decision generation: bumped by reset AND configuration replacement.
|
|
@@ -783,7 +783,7 @@ public class UpdateContext {
|
|
|
783
783
|
* no compare-and-act window: either the whole round lands, or the reset
|
|
784
784
|
* wins and none of it does. Returns whether the round was committed.
|
|
785
785
|
*/
|
|
786
|
-
boolean
|
|
786
|
+
boolean commitSyncResult(
|
|
787
787
|
long expectedGeneration,
|
|
788
788
|
String hash,
|
|
789
789
|
String hashInfoJson,
|
|
@@ -792,17 +792,17 @@ public class UpdateContext {
|
|
|
792
792
|
) {
|
|
793
793
|
boolean switching = activate && hash != null;
|
|
794
794
|
if (!switching) {
|
|
795
|
-
return
|
|
795
|
+
return commitSyncResultState(
|
|
796
796
|
expectedGeneration, hash, hashInfoJson, false, responseCacheJson);
|
|
797
797
|
}
|
|
798
798
|
synchronized (versionFilesLock) {
|
|
799
799
|
verifySwitchTarget(hash);
|
|
800
|
-
return
|
|
800
|
+
return commitSyncResultState(
|
|
801
801
|
expectedGeneration, hash, hashInfoJson, true, responseCacheJson);
|
|
802
802
|
}
|
|
803
803
|
}
|
|
804
804
|
|
|
805
|
-
private boolean
|
|
805
|
+
private boolean commitSyncResultState(
|
|
806
806
|
long expectedGeneration,
|
|
807
807
|
String hash,
|
|
808
808
|
String hashInfoJson,
|
|
@@ -821,9 +821,9 @@ public class UpdateContext {
|
|
|
821
821
|
applyState(editor, computeSwitchState(hash));
|
|
822
822
|
}
|
|
823
823
|
if (responseCacheJson != null) {
|
|
824
|
-
editor.putString(
|
|
824
|
+
editor.putString(SyncCoordinator.KEY_RESP_CACHE, responseCacheJson);
|
|
825
825
|
}
|
|
826
|
-
persistEditorOrThrow(editor, "commit
|
|
826
|
+
persistEditorOrThrow(editor, "commit sync result");
|
|
827
827
|
if (switching) {
|
|
828
828
|
ignoreRollback = false;
|
|
829
829
|
}
|
|
@@ -18,6 +18,9 @@ import org.json.JSONTokener;
|
|
|
18
18
|
* overrides and forward here, so the two cannot drift apart.
|
|
19
19
|
*/
|
|
20
20
|
public class UpdateModuleImpl {
|
|
21
|
+
// Download URL option key, stored encoded.
|
|
22
|
+
private static final String OPTION_URL = Texts.reveal("2f07f0d0ba8e5d572e");
|
|
23
|
+
|
|
21
24
|
|
|
22
25
|
public static final String NAME = "Pushy";
|
|
23
26
|
|
|
@@ -55,12 +58,12 @@ public class UpdateModuleImpl {
|
|
|
55
58
|
constants.put("uuid", updateContext.getKv("uuid"));
|
|
56
59
|
int supportedDiffVersion = 0;
|
|
57
60
|
try {
|
|
58
|
-
supportedDiffVersion =
|
|
61
|
+
supportedDiffVersion = NativeCore.supportedDiffVersion();
|
|
59
62
|
} catch (UnsatisfiedLinkError e) {
|
|
60
|
-
// A mismatched
|
|
63
|
+
// A mismatched librnpushy.so (stale manual copy / build cache)
|
|
61
64
|
// must not crash startup via getConstants; 0 simply means "no v2
|
|
62
65
|
// diff track" and the server degrades gracefully.
|
|
63
|
-
Log.e("pushy", "supportedDiffVersion missing from
|
|
66
|
+
Log.e("pushy", "supportedDiffVersion missing from the native library", e);
|
|
64
67
|
}
|
|
65
68
|
constants.put("supportedDiffVersion", supportedDiffVersion);
|
|
66
69
|
return constants;
|
|
@@ -136,7 +139,7 @@ public class UpdateModuleImpl {
|
|
|
136
139
|
// classifies them.
|
|
137
140
|
private static String downloadErrorCode(Throwable error) {
|
|
138
141
|
if (error instanceof PatchFailedException) {
|
|
139
|
-
return ErrorCodes.
|
|
142
|
+
return ErrorCodes.DELTA_FAILED;
|
|
140
143
|
}
|
|
141
144
|
if (error instanceof FileOperationException) {
|
|
142
145
|
return ErrorCodes.FILE_OPERATION_FAILED;
|
|
@@ -145,7 +148,7 @@ public class UpdateModuleImpl {
|
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
public void downloadFullUpdate(final ReadableMap options, final Promise promise) {
|
|
148
|
-
String url = readRequiredString(options,
|
|
151
|
+
String url = readRequiredString(options, OPTION_URL, promise);
|
|
149
152
|
if (url == null) {
|
|
150
153
|
return;
|
|
151
154
|
}
|
|
@@ -201,7 +204,7 @@ public class UpdateModuleImpl {
|
|
|
201
204
|
}
|
|
202
205
|
|
|
203
206
|
public void downloadPatchFromPackage(final ReadableMap options, final Promise promise) {
|
|
204
|
-
String url = readRequiredString(options,
|
|
207
|
+
String url = readRequiredString(options, OPTION_URL, promise);
|
|
205
208
|
if (url == null) {
|
|
206
209
|
return;
|
|
207
210
|
}
|
|
@@ -213,7 +216,7 @@ public class UpdateModuleImpl {
|
|
|
213
216
|
}
|
|
214
217
|
|
|
215
218
|
public void downloadPatchFromPpk(final ReadableMap options, final Promise promise) {
|
|
216
|
-
String url = readRequiredString(options,
|
|
219
|
+
String url = readRequiredString(options, OPTION_URL, promise);
|
|
217
220
|
if (url == null) {
|
|
218
221
|
return;
|
|
219
222
|
}
|
|
@@ -307,7 +310,7 @@ public class UpdateModuleImpl {
|
|
|
307
310
|
* rejects.
|
|
308
311
|
*/
|
|
309
312
|
public void getNativeCheckCache(final Promise promise) {
|
|
310
|
-
String cached = updateContext.getKv(
|
|
313
|
+
String cached = updateContext.getKv(SyncCoordinator.KEY_RESP_CACHE);
|
|
311
314
|
promise.resolve(cached == null ? "" : cached);
|
|
312
315
|
}
|
|
313
316
|
|
|
@@ -322,7 +325,7 @@ public class UpdateModuleImpl {
|
|
|
322
325
|
if (requireNonEmpty(config, "config", promise) == null) {
|
|
323
326
|
return;
|
|
324
327
|
}
|
|
325
|
-
|
|
328
|
+
SyncCoordinator.recordJsRound(config);
|
|
326
329
|
promise.resolve(true);
|
|
327
330
|
}
|
|
328
331
|
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
// - harmony/pushy/src/main/ets/ArchiveLimits.ts
|
|
13
13
|
// iOS (RCTPushy.mm) includes this header directly.
|
|
14
14
|
|
|
15
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
16
|
+
#pragma GCC visibility push(hidden)
|
|
17
|
+
|
|
15
18
|
namespace pushy {
|
|
16
19
|
namespace archive_limits {
|
|
17
20
|
|
|
@@ -41,4 +44,6 @@ constexpr long long kUnknownLengthFreeSpaceProbeBytes = 8LL * 1024 * 1024;
|
|
|
41
44
|
} // namespace archive_limits
|
|
42
45
|
} // namespace pushy
|
|
43
46
|
|
|
47
|
+
#pragma GCC visibility pop
|
|
48
|
+
|
|
44
49
|
#endif // PUSHY_PATCH_CORE_ARCHIVE_LIMITS_H_
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#include "archive_patch_core.h"
|
|
2
2
|
|
|
3
|
+
#include "obscured_text.h"
|
|
4
|
+
|
|
3
5
|
namespace pushy {
|
|
4
6
|
namespace archive_patch {
|
|
5
7
|
namespace {
|
|
@@ -16,6 +18,11 @@ bool HasEntry(const std::vector<std::string>& entry_names, const std::string& na
|
|
|
16
18
|
|
|
17
19
|
} // namespace
|
|
18
20
|
|
|
21
|
+
const std::string& DefaultBundleDeltaEntryName() {
|
|
22
|
+
static const std::string name = text::Reveal("3319f0d4b6c56a502c3b10fcdca0de7d4b3307e9");
|
|
23
|
+
return name;
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
EntryAction ClassifyEntry(
|
|
20
27
|
ArchivePatchType type,
|
|
21
28
|
const std::string& entry_name) {
|
|
@@ -41,17 +48,17 @@ bool TryParseArchivePatchType(int value, ArchivePatchType* out) {
|
|
|
41
48
|
}
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
delta::Status BuildArchivePatchPlan(
|
|
45
52
|
ArchivePatchType type,
|
|
46
|
-
const
|
|
53
|
+
const delta::PatchManifest& manifest,
|
|
47
54
|
const std::vector<std::string>& entry_names,
|
|
48
55
|
ArchivePatchPlan* out_plan,
|
|
49
56
|
const std::string& bundle_patch_entry_name) {
|
|
50
57
|
if (out_plan == nullptr) {
|
|
51
|
-
return
|
|
58
|
+
return delta::Status::Error("Archive plan output is required");
|
|
52
59
|
}
|
|
53
60
|
|
|
54
|
-
|
|
61
|
+
delta::Status manifest_status = delta::ValidateManifest(manifest);
|
|
55
62
|
if (!manifest_status.ok) {
|
|
56
63
|
return manifest_status;
|
|
57
64
|
}
|
|
@@ -63,38 +70,38 @@ patch::Status BuildArchivePatchPlan(
|
|
|
63
70
|
|
|
64
71
|
switch (type) {
|
|
65
72
|
case ArchivePatchType::kFull:
|
|
66
|
-
return
|
|
73
|
+
return delta::Status::Ok();
|
|
67
74
|
case ArchivePatchType::kPatchFromPackage:
|
|
68
75
|
case ArchivePatchType::kPatchFromPpk:
|
|
69
76
|
if (!HasEntry(entry_names, kManifestEntryName)) {
|
|
70
|
-
return
|
|
77
|
+
return delta::Status::Error("diff.json not found");
|
|
71
78
|
}
|
|
72
79
|
if (!HasEntry(entry_names, bundle_patch_entry_name)) {
|
|
73
|
-
return
|
|
80
|
+
return delta::Status::Error("bundle delta not found");
|
|
74
81
|
}
|
|
75
82
|
out_plan->merge_source_subdir =
|
|
76
83
|
type == ArchivePatchType::kPatchFromPackage ? "assets" : "";
|
|
77
84
|
out_plan->enable_merge = true;
|
|
78
|
-
return
|
|
85
|
+
return delta::Status::Ok();
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
return
|
|
88
|
+
return delta::Status::Error("Unknown archive delta type");
|
|
82
89
|
}
|
|
83
90
|
|
|
84
|
-
|
|
85
|
-
const
|
|
91
|
+
delta::Status BuildCopyGroups(
|
|
92
|
+
const delta::PatchManifest& manifest,
|
|
86
93
|
std::vector<CopyGroup>* out_groups) {
|
|
87
94
|
if (out_groups == nullptr) {
|
|
88
|
-
return
|
|
95
|
+
return delta::Status::Error("Copy groups output is required");
|
|
89
96
|
}
|
|
90
97
|
|
|
91
|
-
|
|
98
|
+
delta::Status manifest_status = delta::ValidateManifest(manifest);
|
|
92
99
|
if (!manifest_status.ok) {
|
|
93
100
|
return manifest_status;
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
out_groups->clear();
|
|
97
|
-
for (const
|
|
104
|
+
for (const delta::CopyOperation& copy : manifest.copies) {
|
|
98
105
|
bool appended = false;
|
|
99
106
|
for (CopyGroup& group : *out_groups) {
|
|
100
107
|
if (group.from == copy.from) {
|
|
@@ -111,19 +118,19 @@ patch::Status BuildCopyGroups(
|
|
|
111
118
|
}
|
|
112
119
|
}
|
|
113
120
|
|
|
114
|
-
return
|
|
121
|
+
return delta::Status::Ok();
|
|
115
122
|
}
|
|
116
123
|
|
|
117
|
-
|
|
124
|
+
delta::Status BuildFileSourcePatchOptions(
|
|
118
125
|
const ArchivePatchPlan& plan,
|
|
119
126
|
const std::string& source_root,
|
|
120
127
|
const std::string& target_root,
|
|
121
128
|
const std::string& origin_bundle_path,
|
|
122
129
|
const std::string& bundle_patch_path,
|
|
123
130
|
const std::string& bundle_output_path,
|
|
124
|
-
|
|
131
|
+
delta::FileSourcePatchOptions* out_options) {
|
|
125
132
|
if (out_options == nullptr) {
|
|
126
|
-
return
|
|
133
|
+
return delta::Status::Error("Delta options output is required");
|
|
127
134
|
}
|
|
128
135
|
|
|
129
136
|
out_options->manifest = plan.manifest;
|
|
@@ -134,7 +141,7 @@ patch::Status BuildFileSourcePatchOptions(
|
|
|
134
141
|
out_options->bundle_output_path = bundle_output_path;
|
|
135
142
|
out_options->merge_source_subdir = plan.merge_source_subdir;
|
|
136
143
|
out_options->enable_merge = plan.enable_merge;
|
|
137
|
-
return
|
|
144
|
+
return delta::Status::Ok();
|
|
138
145
|
}
|
|
139
146
|
|
|
140
147
|
} // namespace archive_patch
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
#include "patch_core.h"
|
|
7
7
|
|
|
8
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
9
|
+
#pragma GCC visibility push(hidden)
|
|
10
|
+
|
|
8
11
|
namespace pushy {
|
|
9
12
|
namespace archive_patch {
|
|
10
13
|
|
|
@@ -26,7 +29,7 @@ struct CopyGroup {
|
|
|
26
29
|
|
|
27
30
|
struct ArchivePatchPlan {
|
|
28
31
|
ArchivePatchType type = ArchivePatchType::kFull;
|
|
29
|
-
|
|
32
|
+
delta::PatchManifest manifest;
|
|
30
33
|
std::string merge_source_subdir;
|
|
31
34
|
bool enable_merge = false;
|
|
32
35
|
};
|
|
@@ -40,25 +43,31 @@ EntryAction ClassifyEntry(
|
|
|
40
43
|
// incremental patch as a full package (which would skip validation).
|
|
41
44
|
bool TryParseArchivePatchType(int value, ArchivePatchType* out);
|
|
42
45
|
|
|
43
|
-
patch
|
|
46
|
+
// Name of the bundle delta entry inside a patch archive (index.bundlejs.patch),
|
|
47
|
+
// stored encoded (see obscured_text.h).
|
|
48
|
+
const std::string& DefaultBundleDeltaEntryName();
|
|
49
|
+
|
|
50
|
+
delta::Status BuildArchivePatchPlan(
|
|
44
51
|
ArchivePatchType type,
|
|
45
|
-
const
|
|
52
|
+
const delta::PatchManifest& manifest,
|
|
46
53
|
const std::vector<std::string>& entry_names,
|
|
47
54
|
ArchivePatchPlan* out_plan,
|
|
48
|
-
const std::string& bundle_patch_entry_name =
|
|
55
|
+
const std::string& bundle_patch_entry_name = DefaultBundleDeltaEntryName());
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
const
|
|
57
|
+
delta::Status BuildCopyGroups(
|
|
58
|
+
const delta::PatchManifest& manifest,
|
|
52
59
|
std::vector<CopyGroup>* out_groups);
|
|
53
60
|
|
|
54
|
-
|
|
61
|
+
delta::Status BuildFileSourcePatchOptions(
|
|
55
62
|
const ArchivePatchPlan& plan,
|
|
56
63
|
const std::string& source_root,
|
|
57
64
|
const std::string& target_root,
|
|
58
65
|
const std::string& origin_bundle_path,
|
|
59
66
|
const std::string& bundle_patch_path,
|
|
60
67
|
const std::string& bundle_output_path,
|
|
61
|
-
|
|
68
|
+
delta::FileSourcePatchOptions* out_options);
|
|
62
69
|
|
|
63
70
|
} // namespace archive_patch
|
|
64
71
|
} // namespace pushy
|
|
72
|
+
|
|
73
|
+
#pragma GCC visibility pop
|
package/cpp/patch_core/digest.h
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
#include <cstdint>
|
|
5
5
|
#include <string>
|
|
6
6
|
|
|
7
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
8
|
+
#pragma GCC visibility push(hidden)
|
|
9
|
+
|
|
7
10
|
namespace pushy {
|
|
8
11
|
namespace digest {
|
|
9
12
|
|
|
@@ -12,7 +15,7 @@ namespace digest {
|
|
|
12
15
|
// (IO-6). Streaming because Android/Harmony read the bundle from the package
|
|
13
16
|
// (AssetManager / rawfile) rather than from a plain file.
|
|
14
17
|
//
|
|
15
|
-
// Android intentionally does NOT use this implementation:
|
|
18
|
+
// Android intentionally does NOT use this implementation: librnpushy.so is a
|
|
16
19
|
// prebuilt artifact, so the Java layer hashes with java.security.MessageDigest
|
|
17
20
|
// instead. The NIST vectors in the tests anchor both implementations to the
|
|
18
21
|
// same standard.
|
|
@@ -59,3 +62,5 @@ bool Crc32File(const std::string& path, uint32_t* out);
|
|
|
59
62
|
|
|
60
63
|
} // namespace digest
|
|
61
64
|
} // namespace pushy
|
|
65
|
+
|
|
66
|
+
#pragma GCC visibility pop
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
// Human-readable messages are NOT part of this contract: they may differ per
|
|
15
15
|
// platform and locale. Only the codes are stable.
|
|
16
16
|
|
|
17
|
+
#include "obscured_text.h"
|
|
18
|
+
|
|
19
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
20
|
+
#pragma GCC visibility push(hidden)
|
|
21
|
+
|
|
17
22
|
namespace pushy {
|
|
18
23
|
namespace error_codes {
|
|
19
24
|
|
|
@@ -22,7 +27,7 @@ constexpr const char* kInvalidOptions = "INVALID_OPTIONS";
|
|
|
22
27
|
// Native download failed (network error, bad HTTP status, truncated body).
|
|
23
28
|
constexpr const char* kDownloadFailed = "DOWNLOAD_FAILED";
|
|
24
29
|
// Unzip or hdiff patch application failed.
|
|
25
|
-
|
|
30
|
+
inline const char* const kDeltaFailed = text::RevealStatic("0a36c0f286b44e640b1339dd");
|
|
26
31
|
// Local file or state persistence operation failed.
|
|
27
32
|
constexpr const char* kFileOperationFailed = "FILE_OPERATION_FAILED";
|
|
28
33
|
// switchVersion / setNeedUpdate state transition failed.
|
|
@@ -49,4 +54,6 @@ constexpr const char* kApkInstallFailed = "APK_INSTALL_FAILED";
|
|
|
49
54
|
} // namespace error_codes
|
|
50
55
|
} // namespace pushy
|
|
51
56
|
|
|
57
|
+
#pragma GCC visibility pop
|
|
58
|
+
|
|
52
59
|
#endif // PUSHY_PATCH_CORE_ERROR_CODES_H_
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
#include <cstddef>
|
|
4
4
|
#include <cstdint>
|
|
5
5
|
|
|
6
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
7
|
+
#pragma GCC visibility push(hidden)
|
|
8
|
+
|
|
6
9
|
namespace pushy {
|
|
7
10
|
namespace hbc {
|
|
8
11
|
|
|
@@ -51,3 +54,5 @@ bool TransformHbcInPlace(
|
|
|
51
54
|
|
|
52
55
|
} // namespace hbc
|
|
53
56
|
} // namespace pushy
|
|
57
|
+
|
|
58
|
+
#pragma GCC visibility pop
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
#include "hbc_transform.h"
|
|
8
8
|
|
|
9
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
10
|
+
#pragma GCC visibility push(hidden)
|
|
11
|
+
|
|
9
12
|
namespace pushy {
|
|
10
13
|
namespace hbc {
|
|
11
14
|
|
|
@@ -50,3 +53,5 @@ HbcLayoutDesc BuildLayout(
|
|
|
50
53
|
|
|
51
54
|
} // namespace hbc
|
|
52
55
|
} // namespace pushy
|
|
56
|
+
|
|
57
|
+
#pragma GCC visibility pop
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
// - harmony/pushy/src/main/ets/InstallRecord.ts
|
|
24
24
|
// iOS (RCTPushy.mm) includes this header directly.
|
|
25
25
|
|
|
26
|
+
// Keep the core internal to whichever binary links it (see podspec Core).
|
|
27
|
+
#pragma GCC visibility push(hidden)
|
|
28
|
+
|
|
26
29
|
namespace pushy {
|
|
27
30
|
namespace install_record {
|
|
28
31
|
|
|
@@ -33,4 +36,6 @@ constexpr const char* kStagingSuffix = ".staging";
|
|
|
33
36
|
} // namespace install_record
|
|
34
37
|
} // namespace pushy
|
|
35
38
|
|
|
39
|
+
#pragma GCC visibility pop
|
|
40
|
+
|
|
36
41
|
#endif // PUSHY_PATCH_CORE_INSTALL_RECORD_H_
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#ifndef PUSHY_PATCH_CORE_JNI_NATIVES_H_
|
|
2
|
+
#define PUSHY_PATCH_CORE_JNI_NATIVES_H_
|
|
3
|
+
|
|
4
|
+
#include <jni.h>
|
|
5
|
+
|
|
6
|
+
// Android native methods. They are registered by name from JNI_OnLoad
|
|
7
|
+
// (jni_registration.cpp) instead of being exported as Java_* symbols, so the
|
|
8
|
+
// shared library's dynamic symbol table carries no class or method names.
|
|
9
|
+
namespace pushy {
|
|
10
|
+
namespace jni_natives {
|
|
11
|
+
|
|
12
|
+
jint SupportedDiffVersion(JNIEnv*, jclass);
|
|
13
|
+
jobject SyncStateWithBinaryVersion(JNIEnv* env, jclass, jstring package_version, jstring build_time, jobject state_result);
|
|
14
|
+
jobject RunStateCore(JNIEnv* env, jclass, jint operation, jobject state_result, jstring string_arg, jboolean flag_a, jboolean flag_b);
|
|
15
|
+
jobject BuildArchivePlan(JNIEnv* env, jclass, jint patch_type, jobjectArray entry_names, jobjectArray copy_froms, jobjectArray copy_tos, jobjectArray deletes);
|
|
16
|
+
jobjectArray BuildCopyGroups(JNIEnv* env, jclass, jobjectArray copy_froms, jobjectArray copy_tos);
|
|
17
|
+
void ApplyDeltaFromSource(JNIEnv* env, jclass, jstring source_root, jstring target_root, jstring origin_bundle_path, jstring bundle_patch_path, jstring bundle_output_path, jstring merge_source_subdir, jboolean enable_merge, jobjectArray copy_froms, jobjectArray copy_tos, jobjectArray deletes, jstring hbc_transform_meta);
|
|
18
|
+
void CleanupOldEntries(JNIEnv* env, jclass, jstring root_dir, jstring keep_current, jstring keep_previous, jint max_age_days);
|
|
19
|
+
jstring FlowBuildRequestBody(JNIEnv* env, jclass, jstring inputJson);
|
|
20
|
+
jstring FlowOrderEndpointCandidates(JNIEnv* env, jclass, jstring endpointsJson, jdouble randomSample);
|
|
21
|
+
jboolean FlowIsValidResponse(JNIEnv* env, jclass, jstring responseText);
|
|
22
|
+
jstring FlowHandleResponse(JNIEnv* env, jclass, jstring responseText, jstring identityJson, jstring afterDownload);
|
|
23
|
+
|
|
24
|
+
} // namespace jni_natives
|
|
25
|
+
} // namespace pushy
|
|
26
|
+
|
|
27
|
+
#endif // PUSHY_PATCH_CORE_JNI_NATIVES_H_
|