react-native-update 10.39.0 → 10.40.0-beta.0

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.
Files changed (44) hide show
  1. package/android/build.gradle +0 -6
  2. package/android/jni/Application.mk +1 -1
  3. package/android/lib/arm64-v8a/librnupdate.so +0 -0
  4. package/android/lib/armeabi-v7a/librnupdate.so +0 -0
  5. package/android/lib/x86/librnupdate.so +0 -0
  6. package/android/lib/x86_64/librnupdate.so +0 -0
  7. package/android/src/main/java/cn/reactnative/modules/update/BundledResourceCopier.java +314 -0
  8. package/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java +253 -586
  9. package/android/src/main/java/cn/reactnative/modules/update/NativeUpdateCore.java +1 -9
  10. package/android/src/main/java/cn/reactnative/modules/update/ReactReloadManager.java +220 -0
  11. package/android/src/main/java/cn/reactnative/modules/update/SafeZipFile.java +9 -3
  12. package/android/src/main/java/cn/reactnative/modules/update/UiThreadRunner.java +36 -0
  13. package/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java +36 -26
  14. package/android/src/main/java/cn/reactnative/modules/update/UpdateEventEmitter.java +39 -0
  15. package/android/src/main/java/cn/reactnative/modules/update/UpdateFileUtils.java +74 -0
  16. package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleImpl.java +143 -260
  17. package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleSupport.java +63 -0
  18. package/android/src/main/java/cn/reactnative/modules/update/UpdatePackage.java +1 -5
  19. package/android/src/newarch/cn/reactnative/modules/update/UpdateModule.java +26 -73
  20. package/android/src/oldarch/cn/reactnative/modules/update/UpdateModule.java +28 -242
  21. package/harmony/pushy/src/main/cpp/PushyTurboModule.cpp +89 -135
  22. package/harmony/pushy/src/main/cpp/PushyTurboModule.h +5 -5
  23. package/harmony/pushy/src/main/ets/DownloadTaskParams.ts +7 -7
  24. package/harmony/pushy/src/main/ets/PushyPackage.ets +3 -9
  25. package/harmony/pushy/src/main/ets/PushyPackageCompat.ts +3 -9
  26. package/harmony/pushy/src/main/ets/PushyPackageFactory.ts +14 -0
  27. package/harmony/pushy/src/main/ets/PushyTurboModule.ts +124 -24
  28. package/harmony/pushy/src/main/ets/UpdateContext.ts +92 -70
  29. package/harmony/pushy.har +0 -0
  30. package/ios/Expo/ExpoPushyReactDelegateHandler.swift +6 -26
  31. package/ios/RCTPushy/RCTPushy.mm +315 -259
  32. package/ios/RCTPushy/RCTPushyDownloader.mm +52 -29
  33. package/package.json +2 -2
  34. package/react-native-update.podspec +3 -3
  35. package/harmony/pushy/src/main/ets/UpdateModuleImpl.ts +0 -123
  36. package/ios/ImportReact.h +0 -2
  37. package/ios/RCTPushy/HDiffPatch/HDiffPatch.h +0 -16
  38. package/ios/RCTPushy/HDiffPatch/HDiffPatch.mm +0 -35
  39. package/ios/RCTPushy/RCTPushyManager.h +0 -27
  40. package/ios/RCTPushy/RCTPushyManager.mm +0 -181
  41. package/ios/RCTPushy.xcodeproj/project.pbxproj +0 -479
  42. package/package/harmony/pushy.har +0 -0
  43. package/react-native-update-10.39.0-beta.3.tgz +0 -0
  44. package/scripts/prune-host-stl.sh +0 -6
@@ -162,11 +162,6 @@ android {
162
162
  resValue("string", "pushy_build_time", "0")
163
163
  }
164
164
  }
165
-
166
- packagingOptions {
167
- exclude "**/libc++_shared.so"
168
- }
169
-
170
165
  lintOptions {
171
166
  abortOnError false
172
167
  }
@@ -181,7 +176,6 @@ repositories {
181
176
 
182
177
  dependencies {
183
178
  implementation 'com.facebook.react:react-native:+'
184
- implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
185
179
  }
186
180
  if (isNewArchitectureEnabled()) {
187
181
  react {
@@ -7,4 +7,4 @@ APP_CPPFLAGS += -std=c++17 -Oz -fno-exceptions -fno-rtti -fno-unwind-tables -fno
7
7
  APP_LDFLAGS += -Wl,--gc-sections -Wl,--exclude-libs,ALL
8
8
  APP_BUILD_SCRIPT := Android.mk
9
9
  APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
10
- APP_STL := c++_shared
10
+ APP_STL := c++_static
Binary file
Binary file
@@ -0,0 +1,314 @@
1
+ package cn.reactnative.modules.update;
2
+
3
+ import android.content.Context;
4
+ import android.content.pm.ApplicationInfo;
5
+ import android.content.pm.PackageManager;
6
+ import android.content.res.Resources;
7
+ import android.os.Build;
8
+ import android.util.DisplayMetrics;
9
+ import android.util.Log;
10
+ import android.util.TypedValue;
11
+ import java.io.File;
12
+ import java.io.IOException;
13
+ import java.io.InputStream;
14
+ import java.util.ArrayList;
15
+ import java.util.Enumeration;
16
+ import java.util.HashMap;
17
+ import java.util.zip.ZipEntry;
18
+ import java.util.regex.Pattern;
19
+
20
+ final class BundledResourceCopier {
21
+ private static final Pattern VERSION_QUALIFIER_PATTERN = Pattern.compile("-v\\d+(?=/)");
22
+ private static final String AAB_BASE_PREFIX = "base/";
23
+
24
+ private final Context context;
25
+
26
+ private static final class ResolvedResourceSource {
27
+ final int resourceId;
28
+ final String assetPath;
29
+
30
+ ResolvedResourceSource(int resourceId, String assetPath) {
31
+ this.resourceId = resourceId;
32
+ this.assetPath = assetPath;
33
+ }
34
+ }
35
+
36
+ BundledResourceCopier(Context context) {
37
+ this.context = context.getApplicationContext();
38
+ }
39
+
40
+ void copyFromResource(HashMap<String, ArrayList<File>> resToCopy) throws IOException {
41
+ if (UpdateContext.DEBUG) {
42
+ Log.d(UpdateContext.TAG, "copyFromResource called, resToCopy size: " + resToCopy.size());
43
+ }
44
+
45
+ ArrayList<String> apkPaths = collectApkPaths();
46
+ HashMap<String, ZipEntry> availableEntries = new HashMap<String, ZipEntry>();
47
+ HashMap<String, SafeZipFile> zipFileMap = new HashMap<String, SafeZipFile>();
48
+ HashMap<String, SafeZipFile> entryToZipFileMap = new HashMap<String, SafeZipFile>();
49
+
50
+ try {
51
+ for (String apkPath : apkPaths) {
52
+ SafeZipFile zipFile = new SafeZipFile(new File(apkPath));
53
+ zipFileMap.put(apkPath, zipFile);
54
+ Enumeration<? extends ZipEntry> entries = zipFile.entries();
55
+ while (entries.hasMoreElements()) {
56
+ ZipEntry ze = entries.nextElement();
57
+ String entryName = ze.getName();
58
+ if (!availableEntries.containsKey(entryName)) {
59
+ availableEntries.put(entryName, ze);
60
+ entryToZipFileMap.put(entryName, zipFile);
61
+ }
62
+ }
63
+ }
64
+
65
+ HashMap<String, String> normalizedEntryMap = new HashMap<String, String>();
66
+ for (String entryName : availableEntries.keySet()) {
67
+ String normalized = normalizeResPath(entryName);
68
+ normalizedEntryMap.putIfAbsent(normalized, entryName);
69
+ }
70
+
71
+ SafeZipFile baseZipFile = zipFileMap.get(context.getPackageResourcePath());
72
+ HashMap<String, ArrayList<File>> remainingFiles =
73
+ new HashMap<String, ArrayList<File>>(resToCopy);
74
+
75
+ for (String fromPath : new ArrayList<String>(remainingFiles.keySet())) {
76
+ if (UpdateContext.DEBUG) {
77
+ Log.d(UpdateContext.TAG, "Processing fromPath: " + fromPath);
78
+ }
79
+
80
+ ArrayList<File> targets = remainingFiles.get(fromPath);
81
+ if (targets == null || targets.isEmpty()) {
82
+ continue;
83
+ }
84
+
85
+ ZipEntry entry = availableEntries.get(fromPath);
86
+ String actualSourcePath = fromPath;
87
+ ResolvedResourceSource resolvedResource = null;
88
+
89
+ if (entry == null) {
90
+ String normalizedFrom = normalizeResPath(fromPath);
91
+ String actualEntry = normalizedEntryMap.get(normalizedFrom);
92
+ if (actualEntry != null) {
93
+ entry = availableEntries.get(actualEntry);
94
+ actualSourcePath = actualEntry;
95
+ if (UpdateContext.DEBUG) {
96
+ Log.d(UpdateContext.TAG, "Normalized match: " + fromPath + " -> " + actualEntry);
97
+ }
98
+ }
99
+ }
100
+
101
+ if (entry == null) {
102
+ resolvedResource = resolveBundledResource(fromPath);
103
+ if (resolvedResource != null) {
104
+ actualSourcePath = resolvedResource.assetPath;
105
+ }
106
+ }
107
+
108
+ if (entry == null && resolvedResource == null) {
109
+ continue;
110
+ }
111
+
112
+ File lastTarget = null;
113
+ for (File target : targets) {
114
+ if (UpdateContext.DEBUG) {
115
+ Log.d(UpdateContext.TAG, "Copying from resource " + actualSourcePath + " to " + target);
116
+ }
117
+ try {
118
+ if (lastTarget != null) {
119
+ UpdateFileUtils.copyFile(lastTarget, target);
120
+ } else if (entry != null) {
121
+ SafeZipFile sourceZipFile = entryToZipFileMap.get(actualSourcePath);
122
+ if (sourceZipFile == null) {
123
+ sourceZipFile = baseZipFile;
124
+ }
125
+ sourceZipFile.unzipToFile(entry, target);
126
+ } else {
127
+ InputStream in = openResolvedResourceStream(resolvedResource);
128
+ UpdateFileUtils.copyInputStreamToFile(in, target);
129
+ }
130
+ lastTarget = target;
131
+ } catch (IOException e) {
132
+ if (UpdateContext.DEBUG) {
133
+ Log.w(
134
+ UpdateContext.TAG,
135
+ "Failed to copy resource "
136
+ + actualSourcePath
137
+ + " to "
138
+ + target
139
+ + ": "
140
+ + e.getMessage()
141
+ );
142
+ }
143
+ }
144
+ }
145
+ remainingFiles.remove(fromPath);
146
+ }
147
+
148
+ if (!remainingFiles.isEmpty() && UpdateContext.DEBUG) {
149
+ for (String fromPath : remainingFiles.keySet()) {
150
+ Log.w(UpdateContext.TAG, "Resource not found and no fallback available: " + fromPath);
151
+ }
152
+ }
153
+ } finally {
154
+ closeZipFiles(zipFileMap);
155
+ }
156
+ }
157
+
158
+ private String normalizeResPath(String path) {
159
+ String result = path;
160
+ if (result.startsWith(AAB_BASE_PREFIX)) {
161
+ result = result.substring(AAB_BASE_PREFIX.length());
162
+ }
163
+ return VERSION_QUALIFIER_PATTERN.matcher(result).replaceAll("");
164
+ }
165
+
166
+ private String extractResourceType(String directoryName) {
167
+ int qualifierIndex = directoryName.indexOf('-');
168
+ if (qualifierIndex == -1) {
169
+ return directoryName;
170
+ }
171
+ return directoryName.substring(0, qualifierIndex);
172
+ }
173
+
174
+ private String extractResourceName(String fileName) {
175
+ if (fileName.endsWith(".9.png")) {
176
+ return fileName.substring(0, fileName.length() - ".9.png".length());
177
+ }
178
+ int extensionIndex = fileName.lastIndexOf('.');
179
+ if (extensionIndex == -1) {
180
+ return fileName;
181
+ }
182
+ return fileName.substring(0, extensionIndex);
183
+ }
184
+
185
+ private Integer parseDensityQualifier(String directoryName) {
186
+ String[] qualifiers = directoryName.split("-");
187
+ for (String qualifier : qualifiers) {
188
+ if ("ldpi".equals(qualifier)) {
189
+ return DisplayMetrics.DENSITY_LOW;
190
+ }
191
+ if ("mdpi".equals(qualifier)) {
192
+ return DisplayMetrics.DENSITY_MEDIUM;
193
+ }
194
+ if ("hdpi".equals(qualifier)) {
195
+ return DisplayMetrics.DENSITY_HIGH;
196
+ }
197
+ if ("xhdpi".equals(qualifier)) {
198
+ return DisplayMetrics.DENSITY_XHIGH;
199
+ }
200
+ if ("xxhdpi".equals(qualifier)) {
201
+ return DisplayMetrics.DENSITY_XXHIGH;
202
+ }
203
+ if ("xxxhdpi".equals(qualifier)) {
204
+ return DisplayMetrics.DENSITY_XXXHIGH;
205
+ }
206
+ if ("tvdpi".equals(qualifier)) {
207
+ return DisplayMetrics.DENSITY_TV;
208
+ }
209
+ }
210
+ return null;
211
+ }
212
+
213
+ private ResolvedResourceSource resolveBundledResource(String resourcePath) {
214
+ String normalizedPath = normalizeResPath(resourcePath);
215
+ if (normalizedPath.startsWith("res/")) {
216
+ normalizedPath = normalizedPath.substring("res/".length());
217
+ }
218
+
219
+ int slash = normalizedPath.indexOf('/');
220
+ if (slash == -1 || slash == normalizedPath.length() - 1) {
221
+ return null;
222
+ }
223
+
224
+ String directoryName = normalizedPath.substring(0, slash);
225
+ String fileName = normalizedPath.substring(slash + 1);
226
+ String resourceType = extractResourceType(directoryName);
227
+ String resourceName = extractResourceName(fileName);
228
+ if (resourceType == null || resourceType.isEmpty() || resourceName.isEmpty()) {
229
+ return null;
230
+ }
231
+
232
+ Resources resources = context.getResources();
233
+ int resourceId = resources.getIdentifier(resourceName, resourceType, context.getPackageName());
234
+ if (resourceId == 0) {
235
+ return null;
236
+ }
237
+
238
+ TypedValue typedValue = new TypedValue();
239
+ try {
240
+ Integer density = parseDensityQualifier(directoryName);
241
+ if (density != null) {
242
+ resources.getValueForDensity(resourceId, density, typedValue, true);
243
+ } else {
244
+ resources.getValue(resourceId, typedValue, true);
245
+ }
246
+ } catch (Resources.NotFoundException e) {
247
+ if (UpdateContext.DEBUG) {
248
+ Log.d(
249
+ UpdateContext.TAG,
250
+ "Failed to resolve resource value for " + resourcePath + ": " + e.getMessage()
251
+ );
252
+ }
253
+ return null;
254
+ }
255
+
256
+ if (typedValue.string == null) {
257
+ return null;
258
+ }
259
+
260
+ String assetPath = typedValue.string.toString();
261
+ if (assetPath.startsWith("/")) {
262
+ assetPath = assetPath.substring(1);
263
+ }
264
+
265
+ if (UpdateContext.DEBUG) {
266
+ Log.d(UpdateContext.TAG, "Resolved resource path " + resourcePath + " -> " + assetPath);
267
+ }
268
+ return new ResolvedResourceSource(resourceId, assetPath);
269
+ }
270
+
271
+ private InputStream openResolvedResourceStream(ResolvedResourceSource source) throws IOException {
272
+ try {
273
+ return context.getResources().openRawResource(source.resourceId);
274
+ } catch (Resources.NotFoundException e) {
275
+ throw new IOException("Unable to open resolved resource: " + source.assetPath, e);
276
+ }
277
+ }
278
+
279
+ private ArrayList<String> collectApkPaths() {
280
+ ArrayList<String> apkPaths = new ArrayList<String>();
281
+ apkPaths.add(context.getPackageResourcePath());
282
+
283
+ try {
284
+ ApplicationInfo appInfo =
285
+ context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
286
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && appInfo.splitSourceDirs != null) {
287
+ for (String splitPath : appInfo.splitSourceDirs) {
288
+ apkPaths.add(splitPath);
289
+ if (UpdateContext.DEBUG) {
290
+ Log.d(UpdateContext.TAG, "Found split APK: " + splitPath);
291
+ }
292
+ }
293
+ }
294
+ } catch (PackageManager.NameNotFoundException e) {
295
+ if (UpdateContext.DEBUG) {
296
+ Log.w(UpdateContext.TAG, "Failed to get application info: " + e.getMessage());
297
+ }
298
+ }
299
+
300
+ return apkPaths;
301
+ }
302
+
303
+ private void closeZipFiles(HashMap<String, SafeZipFile> zipFileMap) {
304
+ for (SafeZipFile zipFile : zipFileMap.values()) {
305
+ try {
306
+ zipFile.close();
307
+ } catch (IOException e) {
308
+ if (UpdateContext.DEBUG) {
309
+ Log.w(UpdateContext.TAG, "Failed to close zip file", e);
310
+ }
311
+ }
312
+ }
313
+ }
314
+ }