@srcpush/react-native-code-push 1.0.3-feat-new-architecture.1 → 1.0.3-feat-new-arch.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.
Files changed (96) hide show
  1. package/AlertAdapter.js +21 -2
  2. package/CONTRIBUTING.md +20 -9
  3. package/CodePush.js +17 -2
  4. package/LICENSE.md +2 -2
  5. package/README.md +15 -15
  6. package/SECURITY.md +4 -20
  7. package/android/app/build.gradle +19 -14
  8. package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +52 -10
  9. package/android/app/src/main/java/com/microsoft/codepush/react/{CodePushDialog.java → CodePushDialogImpl.java} +28 -28
  10. package/android/app/src/main/java/com/microsoft/codepush/react/{CodePushNativeModule.java → CodePushNativeModuleImpl.java} +93 -210
  11. package/android/app/src/newarch/java/com/microsoft/codepush/react/CodePushDialog.java +49 -0
  12. package/android/app/src/newarch/java/com/microsoft/codepush/react/CodePushNativeModule.java +143 -0
  13. package/android/app/src/oldarch/java/com/microsoft/codepush/react/CodePushDialog.java +49 -0
  14. package/android/app/src/oldarch/java/com/microsoft/codepush/react/CodePushNativeModule.java +141 -0
  15. package/docs/api-android.md +10 -10
  16. package/docs/api-ios.md +5 -5
  17. package/docs/api-js.md +17 -17
  18. package/docs/multi-deployment-testing-android.md +2 -2
  19. package/docs/multi-deployment-testing-ios.md +1 -1
  20. package/docs/setup-android.md +7 -7
  21. package/docs/setup-ios.md +9 -9
  22. package/docs/setup-windows.md +6 -6
  23. package/package.json +9 -9
  24. package/src/specs/NativeCodePush.ts +56 -0
  25. package/src/specs/NativeCodePushDialog.ts +19 -0
  26. package/tsconfig.json +4 -2
  27. package/tslint.json +21 -13
  28. package/.azurepipelines/build-rn-code-push-1es.yml +0 -104
  29. package/.azurepipelines/test-rn-code-push.yml +0 -94
  30. package/android/app/src/newarch/java/com/microsoft/codepush/react/CodePushNativeModuleSpec.java +0 -9
  31. package/android/app/src/oldarch/java/com/microsoft/codepush/react/CodePushNativeModuleSpec.java +0 -34
  32. package/src/NativeCodePush.ts +0 -39
  33. package/windows/CodePush/CodePush.def +0 -3
  34. package/windows/CodePush/CodePush.vcxproj +0 -198
  35. package/windows/CodePush/CodePush.vcxproj.filters +0 -91
  36. package/windows/CodePush/CodePushConfig.cpp +0 -104
  37. package/windows/CodePush/CodePushConfig.h +0 -66
  38. package/windows/CodePush/CodePushConfig.idl +0 -12
  39. package/windows/CodePush/CodePushDownloadHandler.cpp +0 -73
  40. package/windows/CodePush/CodePushDownloadHandler.h +0 -32
  41. package/windows/CodePush/CodePushNativeModule.cpp +0 -937
  42. package/windows/CodePush/CodePushNativeModule.h +0 -247
  43. package/windows/CodePush/CodePushPackage.cpp +0 -456
  44. package/windows/CodePush/CodePushPackage.h +0 -49
  45. package/windows/CodePush/CodePushTelemetryManager.cpp +0 -213
  46. package/windows/CodePush/CodePushTelemetryManager.h +0 -29
  47. package/windows/CodePush/CodePushUpdateUtils.cpp +0 -86
  48. package/windows/CodePush/CodePushUpdateUtils.h +0 -38
  49. package/windows/CodePush/CodePushUtils.cpp +0 -29
  50. package/windows/CodePush/CodePushUtils.h +0 -18
  51. package/windows/CodePush/FileUtils.cpp +0 -131
  52. package/windows/CodePush/FileUtils.h +0 -28
  53. package/windows/CodePush/PropertySheet.props +0 -16
  54. package/windows/CodePush/ReactPackageProvider.cpp +0 -15
  55. package/windows/CodePush/ReactPackageProvider.h +0 -22
  56. package/windows/CodePush/ReactPackageProvider.idl +0 -9
  57. package/windows/CodePush/miniz/LICENSE +0 -22
  58. package/windows/CodePush/miniz/miniz.c +0 -7657
  59. package/windows/CodePush/miniz/miniz.h +0 -1338
  60. package/windows/CodePush/miniz/readme.md +0 -37
  61. package/windows/CodePush/packages.config +0 -4
  62. package/windows/CodePush/pch.cpp +0 -1
  63. package/windows/CodePush/pch.h +0 -4
  64. package/windows-legacy/CodePush/CodePush.csproj +0 -128
  65. package/windows-legacy/CodePush/CodePushUtils.cs +0 -47
  66. package/windows-legacy/CodePush/FileUtils.cs +0 -40
  67. package/windows-legacy/CodePush/Properties/AssemblyInfo.cs +0 -29
  68. package/windows-legacy/CodePush/Properties/CodePush.rd.xml +0 -33
  69. package/windows-legacy/CodePush/UpdateManager.cs +0 -305
  70. package/windows-legacy/CodePush/UpdateUtils.cs +0 -46
  71. package/windows-legacy/CodePush.Net46/Adapters/Http/HttpProgress.cs +0 -28
  72. package/windows-legacy/CodePush.Net46/Adapters/Storage/ApplicationDataContainer.cs +0 -106
  73. package/windows-legacy/CodePush.Net46/CodePush.Net46.csproj +0 -103
  74. package/windows-legacy/CodePush.Net46/CodePushUtils.cs +0 -158
  75. package/windows-legacy/CodePush.Net46/FileUtils.cs +0 -55
  76. package/windows-legacy/CodePush.Net46/Properties/AssemblyInfo.cs +0 -36
  77. package/windows-legacy/CodePush.Net46/UpdateManager.cs +0 -330
  78. package/windows-legacy/CodePush.Net46/UpdateUtils.cs +0 -70
  79. package/windows-legacy/CodePush.Net46/packages.config +0 -5
  80. package/windows-legacy/CodePush.Net46.Test/ApplicationDataContainerTest.cs +0 -105
  81. package/windows-legacy/CodePush.Net46.Test/CodePush.Net46.Test.csproj +0 -137
  82. package/windows-legacy/CodePush.Net46.Test/Properties/AssemblyInfo.cs +0 -36
  83. package/windows-legacy/CodePush.Net46.Test/TelemetryManagerTest.cs +0 -117
  84. package/windows-legacy/CodePush.Net46.Test/app.config +0 -11
  85. package/windows-legacy/CodePush.Net46.Test/packages.config +0 -4
  86. package/windows-legacy/CodePush.Shared/CodePush.Shared.projitems +0 -22
  87. package/windows-legacy/CodePush.Shared/CodePush.Shared.shproj +0 -13
  88. package/windows-legacy/CodePush.Shared/CodePushConstants.cs +0 -35
  89. package/windows-legacy/CodePush.Shared/CodePushNativeModule.cs +0 -329
  90. package/windows-legacy/CodePush.Shared/CodePushReactPackage.cs +0 -235
  91. package/windows-legacy/CodePush.Shared/CodePushUtils.cs +0 -70
  92. package/windows-legacy/CodePush.Shared/InstallMode.cs +0 -9
  93. package/windows-legacy/CodePush.Shared/MinimumBackgroundListener.cs +0 -44
  94. package/windows-legacy/CodePush.Shared/SettingsManager.cs +0 -148
  95. package/windows-legacy/CodePush.Shared/TelemetryManager.cs +0 -250
  96. package/windows-legacy/CodePush.Shared/UpdateState.cs +0 -9
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
5
5
  import android.os.AsyncTask;
6
6
  import android.os.Handler;
7
7
  import android.os.Looper;
8
+ import android.view.Choreographer;
8
9
  import android.view.View;
9
10
 
10
11
  import androidx.annotation.OptIn;
@@ -14,12 +15,10 @@ import com.facebook.react.ReactHost;
14
15
  import com.facebook.react.ReactInstanceManager;
15
16
  import com.facebook.react.ReactRootView;
16
17
  import com.facebook.react.bridge.Arguments;
17
- import com.facebook.react.bridge.BaseJavaModule;
18
18
  import com.facebook.react.bridge.JSBundleLoader;
19
19
  import com.facebook.react.bridge.LifecycleEventListener;
20
20
  import com.facebook.react.bridge.Promise;
21
21
  import com.facebook.react.bridge.ReactApplicationContext;
22
- import com.facebook.react.bridge.ReactMethod;
23
22
  import com.facebook.react.bridge.ReadableMap;
24
23
  import com.facebook.react.bridge.WritableMap;
25
24
  import com.facebook.react.common.annotations.UnstableReactNativeAPI;
@@ -29,7 +28,6 @@ import com.facebook.react.modules.core.ReactChoreographer;
29
28
  import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
30
29
  import com.facebook.react.runtime.ReactHostDelegate;
31
30
  import com.facebook.react.runtime.ReactHostImpl;
32
- import android.view.Choreographer;
33
31
 
34
32
  import org.json.JSONArray;
35
33
  import org.json.JSONException;
@@ -46,30 +44,35 @@ import java.util.Map;
46
44
  import java.util.UUID;
47
45
 
48
46
  @OptIn(markerClass = UnstableReactNativeAPI.class)
49
- public class CodePushNativeModule extends CodePushNativeModuleSpec {
47
+ final class CodePushNativeModuleImpl {
50
48
  private String mBinaryContentsHash = null;
51
49
  private String mClientUniqueId = null;
52
50
  private LifecycleEventListener mLifecycleEventListener = null;
53
51
  private int mMinimumBackgroundDuration = 0;
54
52
 
55
- private CodePush mCodePush;
56
- private SettingsManager mSettingsManager;
57
- private CodePushTelemetryManager mTelemetryManager;
58
- private CodePushUpdateManager mUpdateManager;
59
-
60
- private boolean _allowed = true;
61
- private boolean _restartInProgress = false;
62
- private ArrayList<Boolean> _restartQueue = new ArrayList<>();
63
-
64
- public CodePushNativeModule(ReactApplicationContext reactContext, CodePush codePush, CodePushUpdateManager codePushUpdateManager, CodePushTelemetryManager codePushTelemetryManager, SettingsManager settingsManager) {
65
- super(reactContext);
66
-
53
+ private final ReactApplicationContext reactContext;
54
+ private final CodePush mCodePush;
55
+ private final SettingsManager mSettingsManager;
56
+ private final CodePushTelemetryManager mTelemetryManager;
57
+ private final CodePushUpdateManager mUpdateManager;
58
+
59
+ private boolean _allowed = true;
60
+ private boolean _restartInProgress = false;
61
+ private final ArrayList<Boolean> _restartQueue = new ArrayList<>();
62
+
63
+ CodePushNativeModuleImpl(
64
+ ReactApplicationContext reactContext,
65
+ CodePush codePush,
66
+ CodePushUpdateManager codePushUpdateManager,
67
+ CodePushTelemetryManager codePushTelemetryManager,
68
+ SettingsManager settingsManager
69
+ ) {
70
+ this.reactContext = reactContext;
67
71
  mCodePush = codePush;
68
72
  mSettingsManager = settingsManager;
69
73
  mTelemetryManager = codePushTelemetryManager;
70
74
  mUpdateManager = codePushUpdateManager;
71
75
 
72
- // Initialize module state while we have a reference to the current context.
73
76
  mBinaryContentsHash = CodePushUpdateUtils.getHashForBinaryContents(reactContext, mCodePush.isDebugMode());
74
77
 
75
78
  SharedPreferences preferences = codePush.getContext().getSharedPreferences(CodePushConstants.CODE_PUSH_PREFERENCES, 0);
@@ -80,13 +83,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
80
83
  }
81
84
  }
82
85
 
83
- @Override
84
- public Map<String, Object> getConstants() {
85
- return getTypedExportedConstants();
86
- }
87
-
88
- @Override
89
- public Map<String, Object> getTypedExportedConstants() {
86
+ Map<String, Object> getConstants() {
90
87
  final Map<String, Object> constants = new HashMap<>();
91
88
 
92
89
  constants.put("codePushInstallModeImmediate", CodePushInstallMode.IMMEDIATE.getValue());
@@ -101,16 +98,9 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
101
98
  return constants;
102
99
  }
103
100
 
104
- @Override
105
- public String getName() {
106
- return "CodePush";
107
- }
108
-
109
101
  private void loadBundleLegacy() {
110
- final Activity currentActivity = getReactApplicationContext().getCurrentActivity();
102
+ final Activity currentActivity = reactContext.getCurrentActivity();
111
103
  if (currentActivity == null) {
112
- // The currentActivity can be null if it is backgrounded / destroyed, so we simply
113
- // no-op to prevent any null pointer exceptions.
114
104
  return;
115
105
  }
116
106
  mCodePush.invalidateCurrentInstance();
@@ -123,13 +113,11 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
123
113
  });
124
114
  }
125
115
 
126
- // Use reflection to find and set the appropriate fields on ReactInstanceManager. See #556 for a proposal for a less brittle way
127
- // to approach this.
128
116
  private void setJSBundle(ReactInstanceManager instanceManager, String latestJSBundleFile) throws IllegalAccessException {
129
117
  try {
130
118
  JSBundleLoader latestJSBundleLoader;
131
119
  if (latestJSBundleFile.toLowerCase().startsWith("assets://")) {
132
- latestJSBundleLoader = JSBundleLoader.createAssetLoader(getReactApplicationContext(), latestJSBundleFile, false);
120
+ latestJSBundleLoader = JSBundleLoader.createAssetLoader(reactContext, latestJSBundleFile, false);
133
121
  } else {
134
122
  latestJSBundleLoader = JSBundleLoader.createFileLoader(latestJSBundleFile);
135
123
  }
@@ -143,13 +131,11 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
143
131
  }
144
132
  }
145
133
 
146
- // Use reflection to find and set the appropriate fields on ReactHostDelegate. See #556 for a proposal for a less brittle way
147
- // to approach this.
148
134
  private void setJSBundle(ReactHostDelegate reactHostDelegate, String latestJSBundleFile) throws IllegalAccessException {
149
135
  try {
150
136
  JSBundleLoader latestJSBundleLoader;
151
137
  if (latestJSBundleFile.toLowerCase().startsWith("assets://")) {
152
- latestJSBundleLoader = JSBundleLoader.createAssetLoader(getReactApplicationContext(), latestJSBundleFile, false);
138
+ latestJSBundleLoader = JSBundleLoader.createAssetLoader(reactContext, latestJSBundleFile, false);
153
139
  } else {
154
140
  latestJSBundleLoader = JSBundleLoader.createFileLoader(latestJSBundleFile);
155
141
  }
@@ -166,54 +152,42 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
166
152
  private void loadBundle() {
167
153
  clearLifecycleEventListener();
168
154
 
169
- // ReactNative core components are changed on new architecture.
170
155
  if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
171
156
  try {
172
157
  DevSupportManager devSupportManager = null;
173
- ReactHost reactHost = resolveReactHost();
174
- if (reactHost != null) {
175
- devSupportManager = reactHost.getDevSupportManager();
176
- }
158
+ ReactHost reactHost = resolveReactHost();
159
+ if (reactHost != null) {
160
+ devSupportManager = reactHost.getDevSupportManager();
161
+ }
177
162
  boolean isLiveReloadEnabled = isLiveReloadEnabled(devSupportManager);
178
-
179
163
  mCodePush.clearDebugCacheIfNeeded(isLiveReloadEnabled);
180
- } catch(Exception e) {
181
- // If we got error in out reflection we should clear debug cache anyway.
164
+ } catch (Exception e) {
182
165
  mCodePush.clearDebugCacheIfNeeded(false);
183
166
  }
184
167
 
185
168
  try {
186
- // #1) Get the ReactHost instance, which is what includes the
187
- // logic to reload the current React context.
188
169
  final ReactHost reactHost = resolveReactHost();
189
170
  if (reactHost == null) {
190
171
  return;
191
172
  }
192
173
 
193
174
  String latestJSBundleFile = mCodePush.getJSBundleFileInternal(mCodePush.getAssetsBundleFileName());
175
+ ReactHostDelegate delegate = getReactHostDelegate((ReactHostImpl) reactHost);
176
+ if (delegate != null) {
177
+ setJSBundle(delegate, latestJSBundleFile);
178
+ }
194
179
 
195
- // #2) Update the locally stored JS bundle file path
196
- setJSBundle(getReactHostDelegate((ReactHostImpl) reactHost), latestJSBundleFile);
197
-
198
- // #3) Get the context creation method
199
180
  try {
200
181
  reactHost.reload("CodePush triggers reload");
201
182
  mCodePush.initializeUpdateAfterRestart();
202
183
  } catch (Exception e) {
203
- // The recreation method threw an unknown exception
204
- // so just simply fallback to restarting the Activity (if it exists)
205
184
  loadBundleLegacy();
206
185
  }
207
-
208
186
  } catch (Exception e) {
209
- // Our reflection logic failed somewhere
210
- // so fall back to restarting the Activity (if it exists)
211
187
  CodePushUtils.log("Failed to load the bundle, falling back to restarting the Activity (if it exists). " + e.getMessage());
212
188
  loadBundleLegacy();
213
189
  }
214
-
215
190
  } else {
216
-
217
191
  try {
218
192
  DevSupportManager devSupportManager = null;
219
193
  ReactInstanceManager reactInstanceManager = resolveInstanceManager();
@@ -221,53 +195,35 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
221
195
  devSupportManager = reactInstanceManager.getDevSupportManager();
222
196
  }
223
197
  boolean isLiveReloadEnabled = isLiveReloadEnabled(devSupportManager);
224
-
225
198
  mCodePush.clearDebugCacheIfNeeded(isLiveReloadEnabled);
226
- } catch(Exception e) {
227
- // If we got error in out reflection we should clear debug cache anyway.
199
+ } catch (Exception e) {
228
200
  mCodePush.clearDebugCacheIfNeeded(false);
229
201
  }
230
202
 
231
203
  try {
232
- // #1) Get the ReactInstanceManager instance, which is what includes the
233
- // logic to reload the current React context.
234
204
  final ReactInstanceManager instanceManager = resolveInstanceManager();
235
205
  if (instanceManager == null) {
236
206
  return;
237
207
  }
238
208
 
239
209
  String latestJSBundleFile = mCodePush.getJSBundleFileInternal(mCodePush.getAssetsBundleFileName());
240
-
241
- // #2) Update the locally stored JS bundle file path
242
210
  setJSBundle(instanceManager, latestJSBundleFile);
243
211
 
244
- // #3) Get the context creation method and fire it on the UI thread (which RN enforces)
245
212
  new Handler(Looper.getMainLooper()).post(new Runnable() {
246
213
  @Override
247
214
  public void run() {
248
215
  try {
249
- // We don't need to resetReactRootViews anymore
250
- // due the issue https://github.com/facebook/react-native/issues/14533
251
- // has been fixed in RN 0.46.0
252
- //resetReactRootViews(instanceManager);
253
-
254
216
  instanceManager.recreateReactContextInBackground();
255
217
  mCodePush.initializeUpdateAfterRestart();
256
218
  } catch (Exception e) {
257
- // The recreation method threw an unknown exception
258
- // so just simply fallback to restarting the Activity (if it exists)
259
219
  loadBundleLegacy();
260
220
  }
261
221
  }
262
222
  });
263
-
264
223
  } catch (Exception e) {
265
- // Our reflection logic failed somewhere
266
- // so fall back to restarting the Activity (if it exists)
267
224
  CodePushUtils.log("Failed to load the bundle, falling back to restarting the Activity (if it exists). " + e.getMessage());
268
225
  loadBundleLegacy();
269
226
  }
270
-
271
227
  }
272
228
  }
273
229
 
@@ -289,13 +245,11 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
289
245
  return false;
290
246
  }
291
247
 
292
- // This workaround has been implemented in order to fix https://github.com/facebook/react-native/issues/14533
293
- // resetReactRootViews allows to call recreateReactContextInBackground without any exceptions
294
- // This fix also relates to https://github.com/microsoft/react-native-code-push/issues/878
248
+ @SuppressWarnings("unused")
295
249
  private void resetReactRootViews(ReactInstanceManager instanceManager) throws NoSuchFieldException, IllegalAccessException {
296
250
  Field mAttachedRootViewsField = instanceManager.getClass().getDeclaredField("mAttachedRootViews");
297
251
  mAttachedRootViewsField.setAccessible(true);
298
- List<ReactRootView> mAttachedRootViews = (List<ReactRootView>)mAttachedRootViewsField.get(instanceManager);
252
+ List<ReactRootView> mAttachedRootViews = (List<ReactRootView>) mAttachedRootViewsField.get(instanceManager);
299
253
  for (ReactRootView reactRootView : mAttachedRootViews) {
300
254
  reactRootView.removeAllViews();
301
255
  reactRootView.setId(View.NO_ID);
@@ -304,29 +258,25 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
304
258
  }
305
259
 
306
260
  private void clearLifecycleEventListener() {
307
- // Remove LifecycleEventListener to prevent infinite restart loop
308
261
  if (mLifecycleEventListener != null) {
309
- getReactApplicationContext().removeLifecycleEventListener(mLifecycleEventListener);
262
+ reactContext.removeLifecycleEventListener(mLifecycleEventListener);
310
263
  mLifecycleEventListener = null;
311
264
  }
312
265
  }
313
266
 
314
- // Use reflection to find the ReactInstanceManager. See #556 for a proposal for a less brittle way to approach this.
315
267
  private ReactInstanceManager resolveInstanceManager() throws NoSuchFieldException, IllegalAccessException {
316
268
  ReactInstanceManager instanceManager = CodePush.getReactInstanceManager();
317
269
  if (instanceManager != null) {
318
270
  return instanceManager;
319
271
  }
320
272
 
321
- final Activity currentActivity = getReactApplicationContext().getCurrentActivity();
273
+ final Activity currentActivity = reactContext.getCurrentActivity();
322
274
  if (currentActivity == null) {
323
275
  return null;
324
276
  }
325
277
 
326
278
  ReactApplication reactApplication = (ReactApplication) currentActivity.getApplication();
327
- instanceManager = reactApplication.getReactNativeHost().getReactInstanceManager();
328
-
329
- return instanceManager;
279
+ return reactApplication.getReactNativeHost().getReactInstanceManager();
330
280
  }
331
281
 
332
282
  private ReactHost resolveReactHost() throws NoSuchFieldException, IllegalAccessException {
@@ -335,7 +285,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
335
285
  return reactHost;
336
286
  }
337
287
 
338
- final Activity currentActivity = getReactApplicationContext().getCurrentActivity();
288
+ final Activity currentActivity = reactContext.getCurrentActivity();
339
289
  if (currentActivity == null) {
340
290
  return null;
341
291
  }
@@ -370,8 +320,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
370
320
  }
371
321
  }
372
322
 
373
- @ReactMethod
374
- public void allow(Promise promise) {
323
+ void allow(Promise promise) {
375
324
  CodePushUtils.log("Re-allowing restarts");
376
325
  this._allowed = true;
377
326
 
@@ -383,37 +332,30 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
383
332
  }
384
333
 
385
334
  promise.resolve(null);
386
- return;
387
335
  }
388
336
 
389
- @ReactMethod
390
- public void clearPendingRestart(Promise promise) {
337
+ void clearPendingRestart(Promise promise) {
391
338
  this._restartQueue.clear();
392
339
  promise.resolve(null);
393
- return;
394
340
  }
395
341
 
396
- @ReactMethod
397
- public void disallow(Promise promise) {
342
+ void disallow(Promise promise) {
398
343
  CodePushUtils.log("Disallowing restarts");
399
344
  this._allowed = false;
400
345
  promise.resolve(null);
401
- return;
402
346
  }
403
347
 
404
- @ReactMethod
405
- public void restartApp(boolean onlyIfUpdateIsPending, Promise promise) {
348
+ void restartApp(boolean onlyIfUpdateIsPending, Promise promise) {
406
349
  try {
407
350
  restartAppInternal(onlyIfUpdateIsPending);
408
351
  promise.resolve(null);
409
- } catch(CodePushUnknownException e) {
352
+ } catch (CodePushUnknownException e) {
410
353
  CodePushUtils.log(e);
411
354
  promise.reject(e);
412
355
  }
413
356
  }
414
357
 
415
- @ReactMethod
416
- public void downloadUpdate(final ReadableMap updatePackage, final boolean notifyProgress, final Promise promise) {
358
+ void downloadUpdate(final ReadableMap updatePackage, final boolean notifyProgress, final Promise promise) {
417
359
  AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
418
360
  @Override
419
361
  protected Void doInBackground(Void... params) {
@@ -431,7 +373,6 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
431
373
  }
432
374
 
433
375
  latestDownloadProgress = downloadProgress;
434
- // If the download is completed, synchronously send the last event.
435
376
  if (latestDownloadProgress.isCompleted()) {
436
377
  dispatchDownloadProgressEvent();
437
378
  return;
@@ -442,7 +383,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
442
383
  }
443
384
 
444
385
  hasScheduledNextFrame = true;
445
- getReactApplicationContext().runOnUiQueueThread(new Runnable() {
386
+ reactContext.runOnUiQueueThread(new Runnable() {
446
387
  @Override
447
388
  public void run() {
448
389
  ReactChoreographer.getInstance().postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, new Choreographer.FrameCallback() {
@@ -460,7 +401,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
460
401
  }
461
402
 
462
403
  public void dispatchDownloadProgressEvent() {
463
- getReactApplicationContext()
404
+ reactContext
464
405
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
465
406
  .emit(CodePushConstants.DOWNLOAD_PROGRESS_EVENT_NAME, latestDownloadProgress.createWritableMap());
466
407
  }
@@ -484,30 +425,26 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
484
425
  asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
485
426
  }
486
427
 
487
- @ReactMethod
488
- public void getConfiguration(Promise promise) {
428
+ void getConfiguration(Promise promise) {
489
429
  try {
490
- WritableMap configMap = Arguments.createMap();
430
+ WritableMap configMap = Arguments.createMap();
491
431
  configMap.putString("appVersion", mCodePush.getAppVersion());
492
432
  configMap.putString("clientUniqueId", mClientUniqueId);
493
433
  configMap.putString("deploymentKey", mCodePush.getDeploymentKey());
494
434
  configMap.putString("serverUrl", mCodePush.getServerUrl());
495
435
 
496
- // The binary hash may be null in debug builds
497
436
  if (mBinaryContentsHash != null) {
498
437
  configMap.putString(CodePushConstants.PACKAGE_HASH_KEY, mBinaryContentsHash);
499
438
  }
500
439
 
501
440
  promise.resolve(configMap);
502
- } catch(CodePushUnknownException e) {
441
+ } catch (CodePushUnknownException e) {
503
442
  CodePushUtils.log(e);
504
443
  promise.reject(e);
505
444
  }
506
445
  }
507
446
 
508
- @Override
509
- @ReactMethod
510
- public void getUpdateMetadata(final double updateState, final Promise promise) {
447
+ void getUpdateMetadata(final double updateState, final Promise promise) {
511
448
  AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
512
449
  @Override
513
450
  protected Void doInBackground(Void... params) {
@@ -526,43 +463,29 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
526
463
  currentUpdateIsPending = mSettingsManager.isPendingUpdate(currentHash);
527
464
  }
528
465
 
529
- if ((int)updateState == CodePushUpdateState.PENDING.getValue() && !currentUpdateIsPending) {
530
- // The caller wanted a pending update
531
- // but there isn't currently one.
466
+ int updateStateValue = (int) updateState;
467
+ if (updateStateValue == CodePushUpdateState.PENDING.getValue() && !currentUpdateIsPending) {
532
468
  promise.resolve(null);
533
- } else if ((int)updateState == CodePushUpdateState.RUNNING.getValue() && currentUpdateIsPending) {
534
- // The caller wants the running update, but the current
535
- // one is pending, so we need to grab the previous.
469
+ } else if (updateStateValue == CodePushUpdateState.RUNNING.getValue() && currentUpdateIsPending) {
536
470
  JSONObject previousPackage = mUpdateManager.getPreviousPackage();
537
-
538
471
  if (previousPackage == null) {
539
472
  promise.resolve(null);
540
473
  return null;
541
474
  }
542
-
543
475
  promise.resolve(CodePushUtils.convertJsonObjectToWritable(previousPackage));
544
476
  } else {
545
- // The current package satisfies the request:
546
- // 1) Caller wanted a pending, and there is a pending update
547
- // 2) Caller wanted the running update, and there isn't a pending
548
- // 3) Caller wants the latest update, regardless if it's pending or not
549
477
  if (mCodePush.isRunningBinaryVersion()) {
550
- // This only matters in Debug builds. Since we do not clear "outdated" updates,
551
- // we need to indicate to the JS side that somehow we have a current update on
552
- // disk that is not actually running.
553
478
  CodePushUtils.setJSONValueForKey(currentPackage, "_isDebugOnly", true);
554
479
  }
555
480
 
556
- // Enable differentiating pending vs. non-pending updates
557
481
  CodePushUtils.setJSONValueForKey(currentPackage, "isPending", currentUpdateIsPending);
558
482
  promise.resolve(CodePushUtils.convertJsonObjectToWritable(currentPackage));
559
483
  }
560
484
  } catch (CodePushMalformedDataException e) {
561
- // We need to recover the app in case 'codepush.json' is corrupted
562
485
  CodePushUtils.log(e.getMessage());
563
486
  clearUpdates();
564
487
  promise.resolve(null);
565
- } catch(CodePushUnknownException e) {
488
+ } catch (CodePushUnknownException e) {
566
489
  CodePushUtils.log(e);
567
490
  promise.reject(e);
568
491
  }
@@ -574,8 +497,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
574
497
  asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
575
498
  }
576
499
 
577
- @ReactMethod
578
- public void getNewStatusReport(final Promise promise) {
500
+ void getNewStatusReport(final Promise promise) {
579
501
  AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
580
502
  @Override
581
503
  protected Void doInBackground(Void... params) {
@@ -619,8 +541,8 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
619
541
  }
620
542
  }
621
543
 
622
- promise.resolve("");
623
- } catch(CodePushUnknownException e) {
544
+ promise.resolve(null);
545
+ } catch (CodePushUnknownException e) {
624
546
  CodePushUtils.log(e);
625
547
  promise.reject(e);
626
548
  }
@@ -631,9 +553,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
631
553
  asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
632
554
  }
633
555
 
634
- @Override
635
- @ReactMethod
636
- public void installUpdate(final ReadableMap updatePackage, final double installMode, final double minimumBackgroundDuration, final Promise promise) {
556
+ void installUpdate(final ReadableMap updatePackage, final double installMode, final double minimumBackgroundDuration, final Promise promise) {
637
557
  AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
638
558
  @Override
639
559
  protected Void doInBackground(Void... params) {
@@ -644,23 +564,17 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
644
564
  if (pendingHash == null) {
645
565
  throw new CodePushUnknownException("Update package to be installed has no hash.");
646
566
  } else {
647
- mSettingsManager.savePendingUpdate(pendingHash, /* isLoading */false);
567
+ mSettingsManager.savePendingUpdate(pendingHash, /* isLoading */ false);
648
568
  }
649
569
 
650
- if ((int)installMode == CodePushInstallMode.ON_NEXT_RESUME.getValue() ||
651
- // We also add the resume listener if the installMode is IMMEDIATE, because
652
- // if the current activity is backgrounded, we want to reload the bundle when
653
- // it comes back into the foreground.
654
- (int)installMode == CodePushInstallMode.IMMEDIATE.getValue() ||
655
- (int)installMode == CodePushInstallMode.ON_NEXT_SUSPEND.getValue()) {
570
+ int installModeValue = (int) installMode;
571
+ if (installModeValue == CodePushInstallMode.ON_NEXT_RESUME.getValue()
572
+ || installModeValue == CodePushInstallMode.IMMEDIATE.getValue()
573
+ || installModeValue == CodePushInstallMode.ON_NEXT_SUSPEND.getValue()) {
656
574
 
657
- // Store the minimum duration on the native module as an instance
658
- // variable instead of relying on a closure below, so that any
659
- // subsequent resume-based installs could override it.
660
- CodePushNativeModule.this.mMinimumBackgroundDuration = (int)minimumBackgroundDuration;
575
+ CodePushNativeModuleImpl.this.mMinimumBackgroundDuration = (int) minimumBackgroundDuration;
661
576
 
662
577
  if (mLifecycleEventListener == null) {
663
- // Ensure we do not add the listener twice.
664
578
  mLifecycleEventListener = new LifecycleEventListener() {
665
579
  private Date lastPausedDate = null;
666
580
  private Handler appSuspendHandler = new Handler(Looper.getMainLooper());
@@ -675,12 +589,10 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
675
589
  @Override
676
590
  public void onHostResume() {
677
591
  appSuspendHandler.removeCallbacks(loadBundleRunnable);
678
- // As of RN 36, the resume handler fires immediately if the app is in
679
- // the foreground, so explicitly wait for it to be backgrounded first
680
592
  if (lastPausedDate != null) {
681
593
  long durationInBackground = (new Date().getTime() - lastPausedDate.getTime()) / 1000;
682
- if ((int)installMode == CodePushInstallMode.IMMEDIATE.getValue()
683
- || durationInBackground >= CodePushNativeModule.this.mMinimumBackgroundDuration) {
594
+ if (installModeValue == CodePushInstallMode.IMMEDIATE.getValue()
595
+ || durationInBackground >= CodePushNativeModuleImpl.this.mMinimumBackgroundDuration) {
684
596
  CodePushUtils.log("Loading bundle on resume");
685
597
  restartAppInternal(false);
686
598
  }
@@ -689,12 +601,10 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
689
601
 
690
602
  @Override
691
603
  public void onHostPause() {
692
- // Save the current time so that when the app is later
693
- // resumed, we can detect how long it was in the background.
694
604
  lastPausedDate = new Date();
695
605
 
696
- if ((int)installMode == CodePushInstallMode.ON_NEXT_SUSPEND.getValue() && mSettingsManager.isPendingUpdate(null)) {
697
- appSuspendHandler.postDelayed(loadBundleRunnable, (int)minimumBackgroundDuration * 1000);
606
+ if (installModeValue == CodePushInstallMode.ON_NEXT_SUSPEND.getValue() && mSettingsManager.isPendingUpdate(null)) {
607
+ appSuspendHandler.postDelayed(loadBundleRunnable, CodePushNativeModuleImpl.this.mMinimumBackgroundDuration * 1000L);
698
608
  }
699
609
  }
700
610
 
@@ -703,16 +613,12 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
703
613
  }
704
614
  };
705
615
 
706
- getReactApplicationContext().addLifecycleEventListener(mLifecycleEventListener);
616
+ reactContext.addLifecycleEventListener(mLifecycleEventListener);
707
617
  }
708
618
  }
709
619
 
710
- if ((int)installMode == CodePushInstallMode.IMMEDIATE.getValue()) {
711
- loadBundle();
712
- }
713
-
714
620
  promise.resolve(null);
715
- } catch(CodePushUnknownException e) {
621
+ } catch (CodePushUnknownException e) {
716
622
  CodePushUtils.log(e);
717
623
  promise.reject(e);
718
624
  }
@@ -724,8 +630,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
724
630
  asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
725
631
  }
726
632
 
727
- @ReactMethod
728
- public void isFailedUpdate(String packageHash, Promise promise) {
633
+ void isFailedUpdate(String packageHash, Promise promise) {
729
634
  try {
730
635
  promise.resolve(mSettingsManager.isFailedHash(packageHash));
731
636
  } catch (CodePushUnknownException e) {
@@ -734,8 +639,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
734
639
  }
735
640
  }
736
641
 
737
- @ReactMethod
738
- public void getLatestRollbackInfo(Promise promise) {
642
+ void getLatestRollbackInfo(Promise promise) {
739
643
  try {
740
644
  JSONObject latestRollbackInfo = mSettingsManager.getLatestRollbackInfo();
741
645
  if (latestRollbackInfo != null) {
@@ -749,8 +653,7 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
749
653
  }
750
654
  }
751
655
 
752
- @ReactMethod
753
- public void setLatestRollbackInfo(String packageHash, Promise promise) {
656
+ void setLatestRollbackInfo(String packageHash, Promise promise) {
754
657
  try {
755
658
  mSettingsManager.setLatestRollbackInfo(packageHash);
756
659
  promise.resolve(null);
@@ -760,53 +663,46 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
760
663
  }
761
664
  }
762
665
 
763
- @ReactMethod
764
- public void isFirstRun(String packageHash, Promise promise) {
666
+ void isFirstRun(String packageHash, Promise promise) {
765
667
  try {
766
668
  boolean isFirstRun = mCodePush.didUpdate()
767
669
  && packageHash != null
768
670
  && packageHash.length() > 0
769
671
  && packageHash.equals(mUpdateManager.getCurrentPackageHash());
770
672
  promise.resolve(isFirstRun);
771
- } catch(CodePushUnknownException e) {
673
+ } catch (CodePushUnknownException e) {
772
674
  CodePushUtils.log(e);
773
675
  promise.reject(e);
774
676
  }
775
677
  }
776
678
 
777
- @ReactMethod
778
- public void notifyApplicationReady(Promise promise) {
679
+ void notifyApplicationReady(Promise promise) {
779
680
  try {
780
681
  mSettingsManager.removePendingUpdate();
781
- promise.resolve("");
782
- } catch(CodePushUnknownException e) {
682
+ promise.resolve(null);
683
+ } catch (CodePushUnknownException e) {
783
684
  CodePushUtils.log(e);
784
685
  promise.reject(e);
785
686
  }
786
687
  }
787
688
 
788
- @ReactMethod
789
- public void recordStatusReported(ReadableMap statusReport) {
689
+ void recordStatusReported(ReadableMap statusReport) {
790
690
  try {
791
691
  mTelemetryManager.recordStatusReported(statusReport);
792
- } catch(CodePushUnknownException e) {
692
+ } catch (CodePushUnknownException e) {
793
693
  CodePushUtils.log(e);
794
694
  }
795
695
  }
796
696
 
797
- @ReactMethod
798
- public void saveStatusReportForRetry(ReadableMap statusReport) {
697
+ void saveStatusReportForRetry(ReadableMap statusReport) {
799
698
  try {
800
699
  mTelemetryManager.saveStatusReportForRetry(statusReport);
801
- } catch(CodePushUnknownException e) {
700
+ } catch (CodePushUnknownException e) {
802
701
  CodePushUtils.log(e);
803
702
  }
804
703
  }
805
704
 
806
- @ReactMethod
807
- // Replaces the current bundle with the one downloaded from removeBundleUrl.
808
- // It is only to be used during tests. No-ops if the test configuration flag is not set.
809
- public void downloadAndReplaceCurrentBundle(String remoteBundleUrl) {
705
+ void downloadAndReplaceCurrentBundle(String remoteBundleUrl) {
810
706
  try {
811
707
  if (mCodePush.isUsingTestConfiguration()) {
812
708
  try {
@@ -815,43 +711,29 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
815
711
  throw new CodePushUnknownException("Unable to replace current bundle", e);
816
712
  }
817
713
  }
818
- } catch(CodePushUnknownException | CodePushMalformedDataException e) {
714
+ } catch (CodePushUnknownException | CodePushMalformedDataException e) {
819
715
  CodePushUtils.log(e);
820
716
  }
821
717
  }
822
718
 
823
- /**
824
- * This method clears CodePush's downloaded updates.
825
- * It is needed to switch to a different deployment if the current deployment is more recent.
826
- * Note: we don’t recommend to use this method in scenarios other than that (CodePush will call
827
- * this method automatically when needed in other cases) as it could lead to unpredictable
828
- * behavior.
829
- */
830
- @ReactMethod
831
- public void clearUpdates() {
719
+ void clearUpdates() {
832
720
  CodePushUtils.log("Clearing updates.");
833
721
  mCodePush.clearUpdates();
834
722
  }
835
723
 
836
- @Override
837
- @ReactMethod
838
- public void addListener(String eventName) {
839
- // Set up any upstream listeners or background tasks as necessary
724
+ void addListener(String eventName) {
725
+ // no-op
840
726
  }
841
727
 
842
- @Override
843
- @ReactMethod
844
- public void removeListeners(double count) {
845
- // Remove upstream listeners, stop unnecessary background tasks
728
+ void removeListeners(double count) {
729
+ // no-op
846
730
  }
847
731
 
848
- public ReactHostDelegate getReactHostDelegate(ReactHostImpl reactHostImpl) {
732
+ ReactHostDelegate getReactHostDelegate(ReactHostImpl reactHostImpl) {
849
733
  try {
850
734
  Class<?> clazz = reactHostImpl.getClass();
851
735
  Field field = clazz.getDeclaredField("mReactHostDelegate");
852
736
  field.setAccessible(true);
853
-
854
- // Get the value of the field for the provided instance
855
737
  return (ReactHostDelegate) field.get(reactHostImpl);
856
738
  } catch (NoSuchFieldException | IllegalAccessException e) {
857
739
  e.printStackTrace();
@@ -859,3 +741,4 @@ public class CodePushNativeModule extends CodePushNativeModuleSpec {
859
741
  }
860
742
  }
861
743
  }
744
+