@revopush/react-native-code-push 1.4.0 → 2.5.0-rc.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/CodePush.js +8 -5
  2. package/CodePush.podspec +9 -0
  3. package/README.md +7 -6
  4. package/android/build.gradle +52 -40
  5. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  6. package/android/gradle/wrapper/gradle-wrapper.properties +3 -1
  7. package/android/gradle.properties +1 -1
  8. package/android/libs/revopush-diff-release-v0.0.1.aar +0 -0
  9. package/android/proguard-rules.pro +1 -1
  10. package/android/settings.gradle +31 -0
  11. package/android/src/main/java/com/microsoft/codepush/react/CodePush.java +8 -4
  12. package/android/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +11 -7
  13. package/android/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +48 -41
  14. package/android/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +67 -175
  15. package/android/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +7 -244
  16. package/android/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +16 -51
  17. package/android/src/main/java/com/microsoft/codepush/react/FileUtils.java +1 -130
  18. package/ios/CodePush/CodePush.h +1 -30
  19. package/ios/CodePush/CodePush.m +23 -7
  20. package/ios/CodePush/CodePushPackage.m +363 -294
  21. package/ios/CodePush/CodePushUpdateUtils.m +77 -28
  22. package/ios/CodePush.xcodeproj/project.pbxproj +0 -18
  23. package/ios/Frameworks/DiffUpdates.xcframework/Info.plist +44 -0
  24. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/DiffUpdates +0 -0
  25. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/Headers/DiffUpdates.h +61 -0
  26. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/Info.plist +0 -0
  27. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64/DiffUpdates.framework/Modules/module.modulemap +6 -0
  28. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/DiffUpdates +0 -0
  29. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/Headers/DiffUpdates.h +61 -0
  30. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/Info.plist +0 -0
  31. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/Modules/module.modulemap +6 -0
  32. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeDirectory +0 -0
  33. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeRequirements +0 -0
  34. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeRequirements-1 +0 -0
  35. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeResources +132 -0
  36. package/ios/Frameworks/DiffUpdates.xcframework/ios-arm64_x86_64-simulator/DiffUpdates.framework/_CodeSignature/CodeSignature +0 -0
  37. package/package.json +2 -2
  38. package/request-fetch-adapter.js +2 -2
  39. package/scripts/generateBundledResourcesHash.js +102 -65
  40. package/android/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java +0 -72
  41. package/ios/CodePush/CodePushDownloadHandler.m +0 -130
  42. package/ios/CodePush/CodePushErrorUtils.m +0 -20
  43. package/ios/CodePush/CodePushUtils.m +0 -9
  44. package/revopush-react-native-code-push-1.4.0-rc1.tgz +0 -0
package/CodePush.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk";
1
+ import { AcquisitionManager as Sdk } from "@revopush/code-push/script/acquisition-sdk";
2
2
  import { Alert } from "./AlertAdapter";
3
3
  import requestFetchAdapter from "./request-fetch-adapter";
4
4
  import { AppState, Platform } from "react-native";
@@ -45,8 +45,11 @@ async function checkForUpdate(deploymentKey = null, handleBinaryVersionMismatchC
45
45
  queryPackage = localPackage;
46
46
  } else {
47
47
  queryPackage = { appVersion: config.appVersion };
48
- if (Platform.OS === "ios" && config.packageHash) {
49
- queryPackage.packageHash = config.packageHash;
48
+ if (config.packageHash) {
49
+ queryPackage.packageHash = config.packageHash;
50
+ }
51
+ if (config.assetHash) {
52
+ queryPackage.assetHash = config.assetHash;
50
53
  }
51
54
  }
52
55
 
@@ -479,8 +482,8 @@ async function syncInternal(options = {}, syncStatusChangeCallback, downloadProg
479
482
  }
480
483
  });
481
484
  }
482
-
483
- // Since the install button should be placed to the
485
+
486
+ // Since the install button should be placed to the
484
487
  // right of any other button, add it last
485
488
  dialogButtons.push({
486
489
  text: installButtonText,
package/CodePush.podspec CHANGED
@@ -18,6 +18,15 @@ Pod::Spec.new do |s|
18
18
  s.public_header_files = ['ios/CodePush/CodePush.h']
19
19
  s.pod_target_xcconfig = { "DEFINES_MODULE" => "YES" }
20
20
 
21
+ s.user_target_xcconfig = {
22
+ 'SOURCEMAP_FILE' => '$(DERIVED_FILE_DIR)/main.jsbundle.map'
23
+ }
24
+
25
+ s.vendored_frameworks = 'ios/Frameworks/DiffUpdates.xcframework'
26
+ s.preserve_paths = 'ios/Frameworks/DiffUpdates.xcframework'
27
+
28
+
29
+
21
30
  # Note: Even though there are copy/pasted versions of some of these dependencies in the repo,
22
31
  # we explicitly let CocoaPods pull in the versions below so all dependencies are resolved and
23
32
  # linked properly at a parent workspace level.
package/README.md CHANGED
@@ -47,12 +47,13 @@ In order to ensure that your end users always have a functioning version of your
47
47
 
48
48
  We try our best to maintain backwards compatibility of our plugin with previous versions of React Native, but due to the nature of the platform, and the existence of breaking changes between releases, it is possible that you need to use a specific version of the CodePush plugin in order to support the exact version of React Native you are using. The following table outlines which CodePush plugin versions officially support the respective React Native versions:
49
49
 
50
- | React Native version(s) | Supporting CodePush version(s) |
51
- |-------------------------|---------------------------------------------------------------------------------------------|
52
- | <v0.76 | Use [microsoft/code-push-react-native](https://github.com/microsoft/react-native-code-push) |
53
- | 0.76, 0.77, 0.78, 0.79 | v1.0+ *(Support both New and Old Architectures)* |
54
- | v0.80 | v1.2 |
55
- | Expo sdk 52 | v1.3 |
50
+ | React Native version(s) | Supporting CodePush version(s) |
51
+ |-------------------------|------------------------------------------------------------------------------------------------------|
52
+ | <v0.76 | Use original [microsoft/code-push-react-native](https://github.com/microsoft/react-native-code-push) |
53
+ | 0.76, 0.77, 0.78, 0.79 | v1.0+ *(Support both New and Old Architectures)* |
54
+ | v0.80 | v1.2 |
55
+ | Expo sdk 52 | v1.3 |
56
+ | v0.81 | v1.5 |
56
57
 
57
58
 
58
59
  We work hard to respond to new RN releases, but they do occasionally break us. We will update this chart with each RN release, so that users can check to see what our "official" support is.
@@ -1,61 +1,73 @@
1
- buildscript {
2
- repositories {
3
- google()
4
- mavenCentral()
5
- }
6
- dependencies {
7
- classpath 'com.android.tools.build:gradle:1.3.0'
8
-
9
- // NOTE: Do not place your application dependencies here; they belong
10
- // in the individual module build.gradle files
11
- }
12
- }
13
-
14
- apply plugin: "com.android.library"
1
+ plugins {
2
+ id("com.android.library")
15
3
 
16
- def isNewArchitectureEnabled() {
17
- // To opt-in for the New Architecture, you can either:
18
- // - Set `newArchEnabled` to true inside the `gradle.properties` file
19
- // - Invoke gradle with `-newArchEnabled=true`
20
- // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
21
- return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
4
+ id "com.facebook.react" apply false
22
5
  }
23
6
 
24
- def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled()
25
-
26
- if (IS_NEW_ARCHITECTURE_ENABLED) {
7
+ if (isNewArchitectureEnabled()) {
27
8
  apply plugin: "com.facebook.react"
28
9
  }
29
10
 
30
- def DEFAULT_COMPILE_SDK_VERSION = 26
31
- def DEFAULT_BUILD_TOOLS_VERSION = "26.0.3"
32
- def DEFAULT_TARGET_SDK_VERSION = 26
33
- def DEFAULT_MIN_SDK_VERSION = 16
11
+ repositories {
12
+ mavenCentral()
13
+ google()
14
+ }
34
15
 
35
16
  android {
36
17
  namespace "com.microsoft.codepush.react"
37
18
 
38
- compileSdkVersion rootProject.hasProperty('compileSdkVersion') ? rootProject.compileSdkVersion : DEFAULT_COMPILE_SDK_VERSION
39
- buildToolsVersion rootProject.hasProperty('buildToolsVersion') ? rootProject.buildToolsVersion : DEFAULT_BUILD_TOOLS_VERSION
19
+ // TODO check if needed. RN gradle plugin set these
20
+ compileSdk = getExtOrIntegerDefault('compileSdkVersion', 34)
40
21
 
41
22
  defaultConfig {
42
- minSdkVersion rootProject.hasProperty('minSdkVersion') ? rootProject.minSdkVersion : DEFAULT_MIN_SDK_VERSION
43
- targetSdkVersion rootProject.hasProperty('targetSdkVersion') ? rootProject.targetSdkVersion : DEFAULT_TARGET_SDK_VERSION
44
- versionCode 1
45
- versionName "1.0"
46
- buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString()
23
+ // TODO check if needed. RN gradle plugin set these
24
+ minSdk = getExtOrIntegerDefault('minSdkVersion', 21)
25
+ // TODO check if needed. RN gradle plugin set these
26
+ targetSdk = getExtOrIntegerDefault('targetSdkVersion', 34)
27
+ // TODO check if needed. RN gradle plugin set these
28
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
29
+ consumerProguardFiles 'proguard-rules.pro'
47
30
  }
48
31
 
49
- lintOptions {
50
- abortOnError false
32
+ sourceSets {
33
+ main {
34
+ jniLibs.srcDirs = ['src/main/jniLibs']
35
+ }
51
36
  }
52
37
 
53
- defaultConfig {
54
- consumerProguardFiles 'proguard-rules.pro'
38
+ // TODO check if needed. RN gradle plugin set these
39
+ buildFeatures {
40
+ buildConfig = true
41
+ }
42
+
43
+ lint {
44
+ abortOnError = false
55
45
  }
56
46
  }
57
47
 
58
48
  dependencies {
59
- implementation "com.facebook.react:react-native:+"
60
- implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3'
49
+ if (boolProp("REACT_NATIVE_REVOPUSH_DEV_MODE", false)) {
50
+ // for local dev only
51
+ implementation("org.revopush:revopush-diff")
52
+ implementation 'com.facebook.react:react-android:0.79.6'
53
+ // end of local dev only
54
+ } else {
55
+ implementation fileTree(dir: "libs", include: ["*.aar", "*.jar"])
56
+ // For < 0.71, this will be from the local maven repo
57
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
58
+ //noinspection GradleDynamicVersion
59
+ implementation "com.facebook.react:react-native:+"
60
+ }
61
+ }
62
+
63
+ def getExtOrIntegerDefault(name, defaultValue) {
64
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : defaultValue.toInteger()
65
+ }
66
+
67
+ def isNewArchitectureEnabled() {
68
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
69
+ }
70
+
71
+ def boolProp(name, defaultVal){
72
+ return (project.findProperty(name) ?: System.getenv(name.toUpperCase()) ?: defaultVal.toString()).toString().toBoolean()
61
73
  }
@@ -1,5 +1,7 @@
1
1
  distributionBase=GRADLE_USER_HOME
2
2
  distributionPath=wrapper/dists
3
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
4
+ networkTimeout=10000
5
+ validateDistributionUrl=true
3
6
  zipStoreBase=GRADLE_USER_HOME
4
7
  zipStorePath=wrapper/dists
5
- distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
@@ -17,4 +17,4 @@
17
17
  # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18
18
  # org.gradle.parallel=true
19
19
 
20
- android.useDeprecatedNdk=true
20
+ #android.useDeprecatedNdk=true
@@ -22,7 +22,7 @@
22
22
  }
23
23
 
24
24
  -keepclassmembers class com.facebook.react.runtime.ReactHostImpl {
25
- private final ** mReactHostDelegate;
25
+ private final ** reactHostDelegate;
26
26
  }
27
27
 
28
28
  -keep interface com.facebook.react.runtime.ReactHostDelegate { *; }
@@ -0,0 +1,31 @@
1
+ pluginManagement {
2
+ repositories {
3
+ mavenCentral()
4
+ google()
5
+ gradlePluginPortal()
6
+ }
7
+
8
+ plugins {
9
+ // to satisfy plugin id("com.android.library")
10
+ id("com.android.library") version "8.8.2" apply false
11
+ }
12
+
13
+ // to satisfy apply plugin: "com.facebook.react" as a part of monorepo
14
+ def gradlePluginPath = getProperty("REACT_NATIVE_GRADLE_PLUGIN_PATH")
15
+ if (gradlePluginPath != null) {
16
+ includeBuild(gradlePluginPath)
17
+ }
18
+ }
19
+
20
+ def diffPath = getProperty("REACT_NATIVE_REVOPUSH_DIFF_PATH")
21
+ if (diffPath != null) {
22
+ includeBuild(diffPath) {
23
+ dependencySubstitution {
24
+ substitute(module("org.revopush:revopush-diff")).using(project(":revopush-diff"))
25
+ }
26
+ }
27
+ }
28
+
29
+ def getProperty(propName) {
30
+ return settings[propName] ?: System.getenv(propName)
31
+ }
@@ -15,6 +15,7 @@ import com.facebook.react.uimanager.ViewManager;
15
15
 
16
16
  import org.json.JSONException;
17
17
  import org.json.JSONObject;
18
+ import org.revopush.ota.NativeBundleManager;
18
19
 
19
20
  import java.io.File;
20
21
  import java.util.ArrayList;
@@ -23,6 +24,7 @@ import java.util.List;
23
24
  public class CodePush implements ReactPackage {
24
25
  private static final Object LOCK = new Object();
25
26
  private static volatile CodePush mCurrentInstance;
27
+
26
28
  public static CodePush getInstance(String deploymentKey, Context context, boolean isDebugMode) {
27
29
  if (mCurrentInstance == null) {
28
30
  synchronized (LOCK) {
@@ -47,6 +49,7 @@ public class CodePush implements ReactPackage {
47
49
  private CodePushUpdateManager mUpdateManager;
48
50
  private CodePushTelemetryManager mTelemetryManager;
49
51
  private SettingsManager mSettingsManager;
52
+ private NativeBundleManager bundleMetadataManager;
50
53
 
51
54
  // Config properties.
52
55
  private String mDeploymentKey;
@@ -72,11 +75,12 @@ public class CodePush implements ReactPackage {
72
75
  private CodePush(String deploymentKey, Context context, boolean isDebugMode) {
73
76
  mContext = context.getApplicationContext();
74
77
 
75
- mUpdateManager = new CodePushUpdateManager(context.getFilesDir().getAbsolutePath());
78
+ mUpdateManager = new CodePushUpdateManager(context, isDebugMode);
76
79
  mTelemetryManager = new CodePushTelemetryManager(mContext);
77
80
  mDeploymentKey = deploymentKey;
78
81
  mIsDebugMode = isDebugMode;
79
82
  mSettingsManager = new SettingsManager(mContext);
83
+ bundleMetadataManager = new NativeBundleManager(mContext);
80
84
 
81
85
  if (sAppVersion == null) {
82
86
  try {
@@ -121,7 +125,7 @@ public class CodePush implements ReactPackage {
121
125
  mServerUrl = serverUrl;
122
126
  }
123
127
 
124
- private String getPublicKeyByResourceDescriptor(int publicKeyResourceDescriptor){
128
+ private String getPublicKeyByResourceDescriptor(int publicKeyResourceDescriptor) {
125
129
  String publicKey;
126
130
  try {
127
131
  publicKey = mContext.getString(publicKeyResourceDescriptor);
@@ -192,7 +196,7 @@ public class CodePush implements ReactPackage {
192
196
  int codePushApkBuildTimeId = this.mContext.getResources().getIdentifier(CodePushConstants.CODE_PUSH_APK_BUILD_TIME_KEY, "string", packageName);
193
197
  // replace double quotes needed for correct restoration of long value from strings.xml
194
198
  // https://github.com/microsoft/cordova-plugin-code-push/issues/264
195
- String codePushApkBuildTime = this.mContext.getResources().getString(codePushApkBuildTimeId).replaceAll("\"","");
199
+ String codePushApkBuildTime = this.mContext.getResources().getString(codePushApkBuildTimeId).replaceAll("\"", "");
196
200
  return Long.parseLong(codePushApkBuildTime);
197
201
  } catch (Exception e) {
198
202
  throw new CodePushUnknownException("Error in getting binary resources modified time", e);
@@ -423,7 +427,7 @@ public class CodePush implements ReactPackage {
423
427
 
424
428
  @Override
425
429
  public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
426
- CodePushNativeModule codePushModule = new CodePushNativeModule(reactApplicationContext, this, mUpdateManager, mTelemetryManager, mSettingsManager);
430
+ CodePushNativeModule codePushModule = new CodePushNativeModule(reactApplicationContext, this, mUpdateManager, mTelemetryManager, mSettingsManager, bundleMetadataManager);
427
431
  CodePushDialog dialogModule = new CodePushDialog(reactApplicationContext);
428
432
 
429
433
  List<NativeModule> nativeModules = new ArrayList<>();
@@ -1,21 +1,26 @@
1
1
  package com.microsoft.codepush.react;
2
2
 
3
+ import org.revopush.ota.BundleManager;
4
+
3
5
  public class CodePushConstants {
4
6
  public static final String ASSETS_BUNDLE_PREFIX = "assets://";
5
7
  public static final String BINARY_MODIFIED_TIME_KEY = "binaryModifiedTime";
6
- public static final String CODE_PUSH_FOLDER_PREFIX = "CodePush";
7
- public static final String CODE_PUSH_HASH_FILE_NAME = "CodePushHash";
8
- public static final String CODE_PUSH_OLD_HASH_FILE_NAME = "CodePushHash.json";
8
+ public static final String CODE_PUSH_FOLDER_PREFIX = BundleManager.CODE_PUSH_FOLDER_PREFIX;
9
+ public static final String CODE_PUSH_PACKAGE_HASH = "packageHash";
10
+ public static final String CODE_PUSH_BUNDLE_HASH = "bundleHash";
11
+ public static final String CODE_PUSH_ASSET_HASH = BundleManager.CODE_PUSH_ASSET_HASH;
9
12
  public static final String CODE_PUSH_PREFERENCES = "CodePush";
10
13
  public static final String CURRENT_PACKAGE_KEY = "currentPackage";
11
14
  public static final String DEFAULT_JS_BUNDLE_NAME = "index.android.bundle";
12
- public static final String DIFF_MANIFEST_FILE_NAME = "hotcodepush.json";
13
15
  public static final int DOWNLOAD_BUFFER_SIZE = 1024 * 256;
14
- public static final String DOWNLOAD_FILE_NAME = "download.zip";
15
16
  public static final String DOWNLOAD_PROGRESS_EVENT_NAME = "CodePushDownloadProgress";
16
17
  public static final String DOWNLOAD_URL_KEY = "downloadUrl";
18
+ public static final String ASSET_DOWNLOAD_URL_KEY = "assetDownloadUrl";
19
+ public static final String BUNDLE_DOWNLOAD_URL_KEY = "bundleBlobUrl";
20
+ public static final String BUNDLE_DIFF_DOWNLOAD_URL_KEY = "bundleDiffBlobUrl";
21
+
17
22
  public static final String FAILED_UPDATES_KEY = "CODE_PUSH_FAILED_UPDATES";
18
- public static final String PACKAGE_FILE_NAME = "app.json";
23
+ public static final String PACKAGE_FILE_NAME = BundleManager.PACKAGE_FILE_NAME;
19
24
  public static final String PACKAGE_HASH_KEY = "packageHash";
20
25
  public static final String PENDING_UPDATE_HASH_KEY = "hash";
21
26
  public static final String PENDING_UPDATE_IS_LOADING_KEY = "isLoading";
@@ -26,7 +31,6 @@ public class CodePushConstants {
26
31
  public static final String STATUS_FILE = "codepush.json";
27
32
  public static final String UNZIPPED_FOLDER_NAME = "unzipped";
28
33
  public static final String CODE_PUSH_APK_BUILD_TIME_KEY = "CODE_PUSH_APK_BUILD_TIME";
29
- public static final String BUNDLE_JWT_FILE = ".codepushrelease";
30
34
  public static final String LATEST_ROLLBACK_INFO_KEY = "LATEST_ROLLBACK_INFO";
31
35
  public static final String LATEST_ROLLBACK_PACKAGE_HASH_KEY = "packageHash";
32
36
  public static final String LATEST_ROLLBACK_TIME_KEY = "time";
@@ -34,6 +34,8 @@ import com.facebook.react.runtime.ReactHostImpl;
34
34
  import org.json.JSONArray;
35
35
  import org.json.JSONException;
36
36
  import org.json.JSONObject;
37
+ import org.revopush.ota.NativeBundleManager;
38
+ import org.revopush.ota.NativeBundleManager.NativeBundleHash;
37
39
 
38
40
  import java.io.IOException;
39
41
  import java.lang.reflect.Field;
@@ -47,7 +49,7 @@ import java.util.UUID;
47
49
 
48
50
  @OptIn(markerClass = UnstableReactNativeAPI.class)
49
51
  public class CodePushNativeModule extends BaseJavaModule {
50
- private String mBinaryContentsHash = null;
52
+ private NativeBundleHash mNativeBundleHash = null;
51
53
  private String mClientUniqueId = null;
52
54
  private LifecycleEventListener mLifecycleEventListener = null;
53
55
  private int mMinimumBackgroundDuration = 0;
@@ -57,21 +59,20 @@ public class CodePushNativeModule extends BaseJavaModule {
57
59
  private CodePushTelemetryManager mTelemetryManager;
58
60
  private CodePushUpdateManager mUpdateManager;
59
61
 
60
- private boolean _allowed = true;
61
- private boolean _restartInProgress = false;
62
- private ArrayList<Boolean> _restartQueue = new ArrayList<>();
62
+ private boolean _allowed = true;
63
+ private boolean _restartInProgress = false;
64
+ private ArrayList<Boolean> _restartQueue = new ArrayList<>();
63
65
 
64
- public CodePushNativeModule(ReactApplicationContext reactContext, CodePush codePush, CodePushUpdateManager codePushUpdateManager, CodePushTelemetryManager codePushTelemetryManager, SettingsManager settingsManager) {
66
+ public CodePushNativeModule(ReactApplicationContext reactContext, CodePush codePush, CodePushUpdateManager codePushUpdateManager, CodePushTelemetryManager codePushTelemetryManager, SettingsManager settingsManager, NativeBundleManager bundleMetadataManager) {
65
67
  super(reactContext);
66
68
 
67
69
  mCodePush = codePush;
68
70
  mSettingsManager = settingsManager;
69
71
  mTelemetryManager = codePushTelemetryManager;
70
72
  mUpdateManager = codePushUpdateManager;
71
-
72
73
  // Initialize module state while we have a reference to the current context.
73
- mBinaryContentsHash = CodePushUpdateUtils.getHashForBinaryContents(reactContext, mCodePush.isDebugMode());
74
74
 
75
+ mNativeBundleHash = bundleMetadataManager.getNativeBundleHash();
75
76
  SharedPreferences preferences = codePush.getContext().getSharedPreferences(CodePushConstants.CODE_PUSH_PREFERENCES, 0);
76
77
  mClientUniqueId = preferences.getString(CodePushConstants.CLIENT_UNIQUE_ID_KEY, null);
77
78
  if (mClientUniqueId == null) {
@@ -152,11 +153,9 @@ public class CodePushNativeModule extends BaseJavaModule {
152
153
  Field bundleLoaderField = reactHostDelegate.getClass().getDeclaredField("jsBundleLoader");
153
154
  bundleLoaderField.setAccessible(true);
154
155
  bundleLoaderField.set(reactHostDelegate, latestJSBundleLoader);
155
- }
156
- catch (NoSuchFieldException noSuchFileFound) {
156
+ } catch (NoSuchFieldException noSuchFileFound) {
157
157
  // Ignore this error for Expo
158
- }
159
- catch (Exception e) {
158
+ } catch (Exception e) {
160
159
  CodePushUtils.log("Unable to set JSBundle of ReactHostDelegate - CodePush may not support this version of React Native");
161
160
  throw new IllegalAccessException("Could not setJSBundle");
162
161
  }
@@ -169,14 +168,14 @@ public class CodePushNativeModule extends BaseJavaModule {
169
168
  if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
170
169
  try {
171
170
  DevSupportManager devSupportManager = null;
172
- ReactHost reactHost = resolveReactHost();
173
- if (reactHost != null) {
174
- devSupportManager = reactHost.getDevSupportManager();
175
- }
171
+ ReactHost reactHost = resolveReactHost();
172
+ if (reactHost != null) {
173
+ devSupportManager = reactHost.getDevSupportManager();
174
+ }
176
175
  boolean isLiveReloadEnabled = isLiveReloadEnabled(devSupportManager);
177
176
 
178
177
  mCodePush.clearDebugCacheIfNeeded(isLiveReloadEnabled);
179
- } catch(Exception e) {
178
+ } catch (Exception e) {
180
179
  // If we got error in out reflection we should clear debug cache anyway.
181
180
  mCodePush.clearDebugCacheIfNeeded(false);
182
181
  }
@@ -232,7 +231,7 @@ public class CodePushNativeModule extends BaseJavaModule {
232
231
  boolean isLiveReloadEnabled = isLiveReloadEnabled(devSupportManager);
233
232
 
234
233
  mCodePush.clearDebugCacheIfNeeded(isLiveReloadEnabled);
235
- } catch(Exception e) {
234
+ } catch (Exception e) {
236
235
  // If we got error in out reflection we should clear debug cache anyway.
237
236
  mCodePush.clearDebugCacheIfNeeded(false);
238
237
  }
@@ -304,7 +303,7 @@ public class CodePushNativeModule extends BaseJavaModule {
304
303
  private void resetReactRootViews(ReactInstanceManager instanceManager) throws NoSuchFieldException, IllegalAccessException {
305
304
  Field mAttachedRootViewsField = instanceManager.getClass().getDeclaredField("mAttachedRootViews");
306
305
  mAttachedRootViewsField.setAccessible(true);
307
- List<ReactRootView> mAttachedRootViews = (List<ReactRootView>)mAttachedRootViewsField.get(instanceManager);
306
+ List<ReactRootView> mAttachedRootViews = (List<ReactRootView>) mAttachedRootViewsField.get(instanceManager);
308
307
  for (ReactRootView reactRootView : mAttachedRootViews) {
309
308
  reactRootView.removeAllViews();
310
309
  reactRootView.setId(View.NO_ID);
@@ -415,7 +414,7 @@ public class CodePushNativeModule extends BaseJavaModule {
415
414
  try {
416
415
  restartAppInternal(onlyIfUpdateIsPending);
417
416
  promise.resolve(null);
418
- } catch(CodePushUnknownException e) {
417
+ } catch (CodePushUnknownException e) {
419
418
  CodePushUtils.log(e);
420
419
  promise.reject(e);
421
420
  }
@@ -477,11 +476,13 @@ public class CodePushNativeModule extends BaseJavaModule {
477
476
 
478
477
  JSONObject newPackage = mUpdateManager.getPackage(CodePushUtils.tryGetString(updatePackage, CodePushConstants.PACKAGE_HASH_KEY));
479
478
  promise.resolve(CodePushUtils.convertJsonObjectToWritable(newPackage));
480
- } catch (CodePushInvalidUpdateException e) {
479
+ } catch (CodePushInvalidUpdateException |
480
+ org.revopush.ota.exceptions.CodePushInvalidUpdateException e) {
481
481
  CodePushUtils.log(e);
482
482
  mSettingsManager.saveFailedUpdate(CodePushUtils.convertReadableToJsonObject(updatePackage));
483
483
  promise.reject(e);
484
- } catch (IOException | CodePushUnknownException e) {
484
+ } catch (IOException | CodePushUnknownException |
485
+ org.revopush.ota.exceptions.CodePushUnknownException e) {
485
486
  CodePushUtils.log(e);
486
487
  promise.reject(e);
487
488
  }
@@ -496,19 +497,18 @@ public class CodePushNativeModule extends BaseJavaModule {
496
497
  @ReactMethod
497
498
  public void getConfiguration(Promise promise) {
498
499
  try {
499
- WritableMap configMap = Arguments.createMap();
500
+ WritableMap configMap = Arguments.createMap();
500
501
  configMap.putString("appVersion", mCodePush.getAppVersion());
501
502
  configMap.putString("clientUniqueId", mClientUniqueId);
502
503
  configMap.putString("deploymentKey", mCodePush.getDeploymentKey());
503
504
  configMap.putString("serverUrl", mCodePush.getServerUrl());
504
505
 
505
- // The binary hash may be null in debug builds
506
- if (mBinaryContentsHash != null) {
507
- configMap.putString(CodePushConstants.PACKAGE_HASH_KEY, mBinaryContentsHash);
508
- }
506
+ configMap.putString(CodePushConstants.PACKAGE_HASH_KEY, mNativeBundleHash.getPackageHash());
507
+ configMap.putString(CodePushConstants.CODE_PUSH_ASSET_HASH, mNativeBundleHash.getAssetHash());
508
+ configMap.putString(CodePushConstants.CODE_PUSH_BUNDLE_HASH, mNativeBundleHash.getBundleHash());
509
509
 
510
510
  promise.resolve(configMap);
511
- } catch(CodePushUnknownException e) {
511
+ } catch (CodePushUnknownException e) {
512
512
  CodePushUtils.log(e);
513
513
  promise.reject(e);
514
514
  }
@@ -570,7 +570,7 @@ public class CodePushNativeModule extends BaseJavaModule {
570
570
  CodePushUtils.log(e.getMessage());
571
571
  clearUpdates();
572
572
  promise.resolve(null);
573
- } catch(CodePushUnknownException e) {
573
+ } catch (CodePushUnknownException e) {
574
574
  CodePushUtils.log(e);
575
575
  promise.reject(e);
576
576
  }
@@ -628,7 +628,7 @@ public class CodePushNativeModule extends BaseJavaModule {
628
628
  }
629
629
 
630
630
  promise.resolve("");
631
- } catch(CodePushUnknownException e) {
631
+ } catch (CodePushUnknownException e) {
632
632
  CodePushUtils.log(e);
633
633
  promise.reject(e);
634
634
  }
@@ -655,11 +655,11 @@ public class CodePushNativeModule extends BaseJavaModule {
655
655
  }
656
656
 
657
657
  if (installMode == CodePushInstallMode.ON_NEXT_RESUME.getValue() ||
658
- // We also add the resume listener if the installMode is IMMEDIATE, because
659
- // if the current activity is backgrounded, we want to reload the bundle when
660
- // it comes back into the foreground.
661
- installMode == CodePushInstallMode.IMMEDIATE.getValue() ||
662
- installMode == CodePushInstallMode.ON_NEXT_SUSPEND.getValue()) {
658
+ // We also add the resume listener if the installMode is IMMEDIATE, because
659
+ // if the current activity is backgrounded, we want to reload the bundle when
660
+ // it comes back into the foreground.
661
+ installMode == CodePushInstallMode.IMMEDIATE.getValue() ||
662
+ installMode == CodePushInstallMode.ON_NEXT_SUSPEND.getValue()) {
663
663
 
664
664
  // Store the minimum duration on the native module as an instance
665
665
  // variable instead of relying on a closure below, so that any
@@ -715,7 +715,7 @@ public class CodePushNativeModule extends BaseJavaModule {
715
715
  }
716
716
 
717
717
  promise.resolve("");
718
- } catch(CodePushUnknownException e) {
718
+ } catch (CodePushUnknownException e) {
719
719
  CodePushUtils.log(e);
720
720
  promise.reject(e);
721
721
  }
@@ -771,7 +771,7 @@ public class CodePushNativeModule extends BaseJavaModule {
771
771
  && packageHash.length() > 0
772
772
  && packageHash.equals(mUpdateManager.getCurrentPackageHash());
773
773
  promise.resolve(isFirstRun);
774
- } catch(CodePushUnknownException e) {
774
+ } catch (CodePushUnknownException e) {
775
775
  CodePushUtils.log(e);
776
776
  promise.reject(e);
777
777
  }
@@ -782,7 +782,7 @@ public class CodePushNativeModule extends BaseJavaModule {
782
782
  try {
783
783
  mSettingsManager.removePendingUpdate();
784
784
  promise.resolve("");
785
- } catch(CodePushUnknownException e) {
785
+ } catch (CodePushUnknownException e) {
786
786
  CodePushUtils.log(e);
787
787
  promise.reject(e);
788
788
  }
@@ -792,7 +792,7 @@ public class CodePushNativeModule extends BaseJavaModule {
792
792
  public void recordStatusReported(ReadableMap statusReport) {
793
793
  try {
794
794
  mTelemetryManager.recordStatusReported(statusReport);
795
- } catch(CodePushUnknownException e) {
795
+ } catch (CodePushUnknownException e) {
796
796
  CodePushUtils.log(e);
797
797
  }
798
798
  }
@@ -801,7 +801,7 @@ public class CodePushNativeModule extends BaseJavaModule {
801
801
  public void saveStatusReportForRetry(ReadableMap statusReport) {
802
802
  try {
803
803
  mTelemetryManager.saveStatusReportForRetry(statusReport);
804
- } catch(CodePushUnknownException e) {
804
+ } catch (CodePushUnknownException e) {
805
805
  CodePushUtils.log(e);
806
806
  }
807
807
  }
@@ -818,7 +818,7 @@ public class CodePushNativeModule extends BaseJavaModule {
818
818
  throw new CodePushUnknownException("Unable to replace current bundle", e);
819
819
  }
820
820
  }
821
- } catch(CodePushUnknownException | CodePushMalformedDataException e) {
821
+ } catch (CodePushUnknownException | CodePushMalformedDataException e) {
822
822
  CodePushUtils.log(e);
823
823
  }
824
824
  }
@@ -849,7 +849,14 @@ public class CodePushNativeModule extends BaseJavaModule {
849
849
  public ReactHostDelegate getReactHostDelegate(ReactHostImpl reactHostImpl) {
850
850
  try {
851
851
  Class<?> clazz = reactHostImpl.getClass();
852
- Field field = clazz.getDeclaredField("mReactHostDelegate");
852
+ Field field;
853
+ try {
854
+ // RN < 0.81
855
+ field = clazz.getDeclaredField("mReactHostDelegate");
856
+ } catch (NoSuchFieldException e) {
857
+ // RN >= 0.81
858
+ field = clazz.getDeclaredField("reactHostDelegate");
859
+ }
853
860
  field.setAccessible(true);
854
861
 
855
862
  // Get the value of the field for the provided instance