@capgo/capacitor-updater 8.47.5 → 8.47.7
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/README.md +13 -20
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +380 -92
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +279 -259
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +23 -26
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +111 -62
- package/dist/docs.json +5 -5
- package/dist/esm/definitions.d.ts +16 -24
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +343 -46
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +25 -8
- package/package.json +1 -1
|
@@ -115,6 +115,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
115
115
|
private static final int SPLASH_SCREEN_RETRY_DELAY_MS = 100;
|
|
116
116
|
private static final int SPLASH_SCREEN_MAX_RETRIES = 20;
|
|
117
117
|
private static final long PENDING_BUNDLE_APP_READY_MIN_TIMEOUT_MS = 30000L;
|
|
118
|
+
private static final long PREVIEW_TRANSITION_LOADER_TIMEOUT_MS = 60000L;
|
|
118
119
|
static final int APPLICATION_EXIT_REASON_UNKNOWN = 0;
|
|
119
120
|
static final int APPLICATION_EXIT_REASON_EXIT_SELF = 1;
|
|
120
121
|
static final int APPLICATION_EXIT_REASON_SIGNALED = 2;
|
|
@@ -128,7 +129,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
128
129
|
static final int APPLICATION_EXIT_REASON_USER_REQUESTED = 10;
|
|
129
130
|
static final int APPLICATION_EXIT_REASON_DEPENDENCY_DIED = 12;
|
|
130
131
|
|
|
131
|
-
private final String pluginVersion = "8.47.
|
|
132
|
+
private final String pluginVersion = "8.47.7";
|
|
132
133
|
private static final String DELAY_CONDITION_PREFERENCES = "";
|
|
133
134
|
|
|
134
135
|
private SharedPreferences.Editor editor;
|
|
@@ -159,9 +160,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
159
160
|
private volatile boolean onLaunchDirectUpdateUsed = false;
|
|
160
161
|
Boolean shakeMenuEnabled = false;
|
|
161
162
|
Boolean shakeChannelSelectorEnabled = false;
|
|
162
|
-
Boolean previewSessionEnabled = false;
|
|
163
|
+
volatile Boolean previewSessionEnabled = false;
|
|
163
164
|
private Boolean previewSessionAlertPending = false;
|
|
164
|
-
private Boolean isLeavingPreviewForIncomingLink = false;
|
|
165
|
+
private volatile Boolean isLeavingPreviewForIncomingLink = false;
|
|
165
166
|
private Boolean allowManualBundleError = false;
|
|
166
167
|
private Boolean allowPreview = false;
|
|
167
168
|
Boolean allowSetDefaultChannel = true;
|
|
@@ -170,6 +171,30 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
170
171
|
return this.updateUrl;
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
private boolean isPreviewSessionStateActive() {
|
|
175
|
+
return (
|
|
176
|
+
Boolean.TRUE.equals(this.previewSessionEnabled) ||
|
|
177
|
+
Boolean.TRUE.equals(this.isLeavingPreviewForIncomingLink) ||
|
|
178
|
+
(this.implementation != null && this.implementation.previewSession)
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private boolean shouldBlockAutoUpdateForPreviewSession() {
|
|
183
|
+
if (!this.isPreviewSessionStateActive()) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
logger.info("Preview session is active. Skipping normal auto-update work.");
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private void clearIncomingPreviewTransition() {
|
|
192
|
+
this.isLeavingPreviewForIncomingLink = false;
|
|
193
|
+
if (!Boolean.TRUE.equals(this.previewSessionEnabled) && this.implementation != null) {
|
|
194
|
+
this.implementation.previewSession = false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
173
198
|
// Used for activity-based foreground/background detection on Android < 14
|
|
174
199
|
private Boolean isPreviousMainActivity = true;
|
|
175
200
|
|
|
@@ -198,6 +223,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
198
223
|
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
199
224
|
private FrameLayout splashscreenLoaderOverlay;
|
|
200
225
|
private Runnable splashscreenTimeoutRunnable;
|
|
226
|
+
private FrameLayout previewTransitionLoaderOverlay;
|
|
227
|
+
private Runnable previewTransitionLoaderTimeoutRunnable;
|
|
228
|
+
private boolean previewTransitionLoaderRequested = false;
|
|
201
229
|
private WebViewListener webViewStatsListener;
|
|
202
230
|
|
|
203
231
|
private static final class FireAndForgetPluginCall extends PluginCall {
|
|
@@ -513,7 +541,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
513
541
|
logger.info("Using preview appId " + previewAppId);
|
|
514
542
|
}
|
|
515
543
|
this.shakeMenuEnabled = true;
|
|
516
|
-
this.shakeChannelSelectorEnabled =
|
|
544
|
+
this.shakeChannelSelectorEnabled = this.prefs.contains(PREVIEW_PREVIOUS_SHAKE_CHANNEL_SELECTOR_PREF_KEY)
|
|
545
|
+
? this.prefs.getBoolean(PREVIEW_PREVIOUS_SHAKE_CHANNEL_SELECTOR_PREF_KEY, false)
|
|
546
|
+
: this.shakeChannelSelectorEnabled;
|
|
517
547
|
}
|
|
518
548
|
boolean resetWhenUpdate = this.getConfig().getBoolean("resetWhenUpdate", true);
|
|
519
549
|
|
|
@@ -658,6 +688,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
658
688
|
if (this.autoSplashscreen) {
|
|
659
689
|
this.hideSplashscreen();
|
|
660
690
|
}
|
|
691
|
+
this.hidePreviewTransitionLoader("app-ready");
|
|
661
692
|
}
|
|
662
693
|
|
|
663
694
|
private void hideSplashscreen() {
|
|
@@ -769,6 +800,38 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
769
800
|
return requestToken == this.splashscreenInvocationToken;
|
|
770
801
|
}
|
|
771
802
|
|
|
803
|
+
private FrameLayout createLoaderOverlay(final Activity activity, final boolean blocksTouches, final int backgroundColor) {
|
|
804
|
+
final ProgressBar progressBar = new ProgressBar(activity);
|
|
805
|
+
progressBar.setIndeterminate(true);
|
|
806
|
+
|
|
807
|
+
final FrameLayout overlay = new FrameLayout(activity);
|
|
808
|
+
overlay.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
|
809
|
+
overlay.setClickable(blocksTouches);
|
|
810
|
+
overlay.setFocusable(blocksTouches);
|
|
811
|
+
overlay.setBackgroundColor(backgroundColor);
|
|
812
|
+
overlay.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
|
813
|
+
|
|
814
|
+
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
|
|
815
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
816
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
817
|
+
);
|
|
818
|
+
params.gravity = Gravity.CENTER;
|
|
819
|
+
overlay.addView(progressBar, params);
|
|
820
|
+
return overlay;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
private void attachLoaderOverlay(final Activity activity, final FrameLayout overlay) {
|
|
824
|
+
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
|
825
|
+
decorView.addView(overlay);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
private void removeLoaderOverlay(final FrameLayout overlay) {
|
|
829
|
+
final ViewGroup parent = (ViewGroup) overlay.getParent();
|
|
830
|
+
if (parent != null) {
|
|
831
|
+
parent.removeView(overlay);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
772
835
|
private void addSplashscreenLoaderIfNeeded() {
|
|
773
836
|
if (!Boolean.TRUE.equals(this.autoSplashscreenLoader)) {
|
|
774
837
|
return;
|
|
@@ -785,26 +848,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
785
848
|
return;
|
|
786
849
|
}
|
|
787
850
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
FrameLayout overlay = new FrameLayout(activity);
|
|
792
|
-
overlay.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
|
793
|
-
overlay.setClickable(false);
|
|
794
|
-
overlay.setFocusable(false);
|
|
795
|
-
overlay.setBackgroundColor(Color.TRANSPARENT);
|
|
796
|
-
overlay.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
|
797
|
-
|
|
798
|
-
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
|
|
799
|
-
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
800
|
-
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
801
|
-
);
|
|
802
|
-
params.gravity = Gravity.CENTER;
|
|
803
|
-
overlay.addView(progressBar, params);
|
|
804
|
-
|
|
805
|
-
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
|
806
|
-
decorView.addView(overlay);
|
|
807
|
-
|
|
851
|
+
FrameLayout overlay = createLoaderOverlay(activity, false, Color.TRANSPARENT);
|
|
852
|
+
attachLoaderOverlay(activity, overlay);
|
|
808
853
|
this.splashscreenLoaderOverlay = overlay;
|
|
809
854
|
};
|
|
810
855
|
|
|
@@ -818,10 +863,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
818
863
|
private void removeSplashscreenLoader() {
|
|
819
864
|
Runnable removeLoader = () -> {
|
|
820
865
|
if (this.splashscreenLoaderOverlay != null) {
|
|
821
|
-
|
|
822
|
-
if (parent != null) {
|
|
823
|
-
parent.removeView(this.splashscreenLoaderOverlay);
|
|
824
|
-
}
|
|
866
|
+
removeLoaderOverlay(this.splashscreenLoaderOverlay);
|
|
825
867
|
this.splashscreenLoaderOverlay = null;
|
|
826
868
|
}
|
|
827
869
|
};
|
|
@@ -833,6 +875,84 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
833
875
|
}
|
|
834
876
|
}
|
|
835
877
|
|
|
878
|
+
private void showPreviewTransitionLoader(final String reason) {
|
|
879
|
+
this.previewTransitionLoaderRequested = true;
|
|
880
|
+
final Runnable showLoader = () -> {
|
|
881
|
+
if (!this.previewTransitionLoaderRequested) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
if (this.previewTransitionLoaderOverlay != null) {
|
|
886
|
+
cancelPreviewTransitionLoaderTimeout();
|
|
887
|
+
schedulePreviewTransitionLoaderTimeout();
|
|
888
|
+
this.previewTransitionLoaderOverlay.bringToFront();
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
final Activity activity = getActivity();
|
|
893
|
+
if (activity == null) {
|
|
894
|
+
logger.warn("Preview transition loader unavailable: activity missing for " + reason);
|
|
895
|
+
this.previewTransitionLoaderRequested = false;
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
cancelPreviewTransitionLoaderTimeout();
|
|
900
|
+
schedulePreviewTransitionLoaderTimeout();
|
|
901
|
+
|
|
902
|
+
final FrameLayout overlay = createLoaderOverlay(activity, true, Color.argb(46, 0, 0, 0));
|
|
903
|
+
attachLoaderOverlay(activity, overlay);
|
|
904
|
+
this.previewTransitionLoaderOverlay = overlay;
|
|
905
|
+
logger.info("Preview transition loader shown: " + reason);
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
909
|
+
showLoader.run();
|
|
910
|
+
} else {
|
|
911
|
+
this.mainHandler.post(showLoader);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
private void hidePreviewTransitionLoader(final String reason) {
|
|
916
|
+
if (
|
|
917
|
+
!this.previewTransitionLoaderRequested &&
|
|
918
|
+
this.previewTransitionLoaderOverlay == null &&
|
|
919
|
+
this.previewTransitionLoaderTimeoutRunnable == null
|
|
920
|
+
) {
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
final Runnable hideLoader = () -> {
|
|
925
|
+
this.previewTransitionLoaderRequested = false;
|
|
926
|
+
cancelPreviewTransitionLoaderTimeout();
|
|
927
|
+
if (this.previewTransitionLoaderOverlay == null) {
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
removeLoaderOverlay(this.previewTransitionLoaderOverlay);
|
|
932
|
+
this.previewTransitionLoaderOverlay = null;
|
|
933
|
+
logger.info("Preview transition loader hidden: " + reason);
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
937
|
+
hideLoader.run();
|
|
938
|
+
} else {
|
|
939
|
+
this.mainHandler.post(hideLoader);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
private void schedulePreviewTransitionLoaderTimeout() {
|
|
944
|
+
cancelPreviewTransitionLoaderTimeout();
|
|
945
|
+
this.previewTransitionLoaderTimeoutRunnable = () -> hidePreviewTransitionLoader("preview-transition-timeout");
|
|
946
|
+
this.mainHandler.postDelayed(this.previewTransitionLoaderTimeoutRunnable, PREVIEW_TRANSITION_LOADER_TIMEOUT_MS);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
private void cancelPreviewTransitionLoaderTimeout() {
|
|
950
|
+
if (this.previewTransitionLoaderTimeoutRunnable != null) {
|
|
951
|
+
this.mainHandler.removeCallbacks(this.previewTransitionLoaderTimeoutRunnable);
|
|
952
|
+
this.previewTransitionLoaderTimeoutRunnable = null;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
836
956
|
private void scheduleSplashscreenTimeout() {
|
|
837
957
|
if (this.autoSplashscreenTimeout == null || this.autoSplashscreenTimeout <= 0) {
|
|
838
958
|
return;
|
|
@@ -1329,9 +1449,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1329
1449
|
);
|
|
1330
1450
|
}
|
|
1331
1451
|
} else {
|
|
1332
|
-
final boolean enabled =
|
|
1333
|
-
|
|
1334
|
-
|
|
1452
|
+
final boolean enabled =
|
|
1453
|
+
configuredMode != null
|
|
1454
|
+
? "true".equals(configuredMode)
|
|
1455
|
+
: Boolean.TRUE.equals(this.getConfig().getBoolean("autoUpdate", true));
|
|
1335
1456
|
this.autoUpdateMode = enabled
|
|
1336
1457
|
? autoUpdateModeForLegacyDirectUpdateMode(this.resolveLegacyDirectUpdateModeFromConfig())
|
|
1337
1458
|
: AUTO_UPDATE_MODE_OFF;
|
|
@@ -1506,6 +1627,12 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1506
1627
|
void scheduleDirectUpdateFinish(final BundleInfo latest) {
|
|
1507
1628
|
startNewThread(() -> {
|
|
1508
1629
|
try {
|
|
1630
|
+
if (this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
1631
|
+
logger.info("Skipping direct update install while preview session state is active");
|
|
1632
|
+
this.implementation.directUpdate = false;
|
|
1633
|
+
this.clearBackgroundDownloadState();
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1509
1636
|
Activity currentActivity = this.getActivity();
|
|
1510
1637
|
if (currentActivity != null) {
|
|
1511
1638
|
this.implementation.activity = currentActivity;
|
|
@@ -1520,14 +1647,52 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1520
1647
|
}
|
|
1521
1648
|
|
|
1522
1649
|
private void directUpdateFinish(final BundleInfo latest) {
|
|
1650
|
+
if (this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
1651
|
+
logger.info("Skipping direct update finish while preview session state is active");
|
|
1652
|
+
this.implementation.directUpdate = false;
|
|
1653
|
+
this.clearBackgroundDownloadState();
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1523
1656
|
if ("onLaunch".equals(this.directUpdateMode)) {
|
|
1524
1657
|
this.onLaunchDirectUpdateUsed = true;
|
|
1525
1658
|
this.implementation.directUpdate = false;
|
|
1526
1659
|
}
|
|
1527
|
-
if (
|
|
1660
|
+
if (this.applyDownloadedBundleForDirectUpdate(latest)) {
|
|
1661
|
+
this.implementation.setNextBundle(null);
|
|
1528
1662
|
this.notifyBundleSet(latest);
|
|
1529
1663
|
sendReadyToJs(latest, "update installed", true);
|
|
1664
|
+
} else {
|
|
1665
|
+
this.implementation.setNextBundle(latest.getId());
|
|
1666
|
+
final JSObject ret = new JSObject();
|
|
1667
|
+
ret.put("bundle", InternalUtils.mapToJSObject(latest.toJSONMap()));
|
|
1668
|
+
this.notifyListeners("updateAvailable", ret);
|
|
1669
|
+
sendReadyToJs(
|
|
1670
|
+
this.implementation.getCurrentBundle(),
|
|
1671
|
+
"Direct update reload failed, update will install next background",
|
|
1672
|
+
false
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
private boolean applyDownloadedBundleForDirectUpdate(final BundleInfo latest) {
|
|
1678
|
+
final CapgoUpdater.ResetState previousState = this.implementation.captureResetState();
|
|
1679
|
+
final String previousBundleName = this.implementation.getCurrentBundle().getVersionName();
|
|
1680
|
+
|
|
1681
|
+
if (!this.implementation.stagePendingReload(latest)) {
|
|
1682
|
+
this.implementation.restoreResetState(previousState);
|
|
1683
|
+
logger.error("Direct update failed to stage downloaded bundle: " + latest.toString());
|
|
1684
|
+
return false;
|
|
1530
1685
|
}
|
|
1686
|
+
|
|
1687
|
+
if (this._reload()) {
|
|
1688
|
+
this.implementation.finalizePendingReload(latest, previousBundleName);
|
|
1689
|
+
return true;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
this.implementation.restoreResetState(previousState);
|
|
1693
|
+
this.restoreLiveBundleStateAfterFailedReload();
|
|
1694
|
+
logger.error("Direct update reload failed after staging bundle: " + latest.toString());
|
|
1695
|
+
return false;
|
|
1531
1696
|
}
|
|
1532
1697
|
|
|
1533
1698
|
private void cleanupObsoleteVersions() {
|
|
@@ -2135,6 +2300,15 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2135
2300
|
return this.semaphoreWait(phase, waitTimeMs);
|
|
2136
2301
|
}
|
|
2137
2302
|
|
|
2303
|
+
protected boolean reloadWithoutWaitingForAppReady() {
|
|
2304
|
+
this.applyCurrentBundleToBridge();
|
|
2305
|
+
|
|
2306
|
+
final long waitTimeMs = this.resolveAppReadyCheckTimeoutMs();
|
|
2307
|
+
this.checkAppReady(waitTimeMs);
|
|
2308
|
+
this.notifyListeners("appReloaded", new JSObject());
|
|
2309
|
+
return true;
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2138
2312
|
@PluginMethod
|
|
2139
2313
|
public void reload(final PluginCall call) {
|
|
2140
2314
|
startNewThread(() -> {
|
|
@@ -2142,7 +2316,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2142
2316
|
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
2143
2317
|
final BundleInfo next = this.implementation.getNextBundle();
|
|
2144
2318
|
|
|
2145
|
-
if (next != null && !next.isErrorStatus() && !next.getId().equals(current.getId())) {
|
|
2319
|
+
if (!this.isPreviewSessionStateActive() && next != null && !next.isErrorStatus() && !next.getId().equals(current.getId())) {
|
|
2146
2320
|
final CapgoUpdater.ResetState previousState = this.implementation.captureResetState();
|
|
2147
2321
|
final String previousBundleName = this.implementation.getCurrentBundle().getVersionName();
|
|
2148
2322
|
logger.info("Applying pending bundle before reload: " + next.getVersionName());
|
|
@@ -2222,6 +2396,12 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2222
2396
|
if (!this.implementation.set(id)) {
|
|
2223
2397
|
logger.info("No such bundle " + id);
|
|
2224
2398
|
call.reject("Update failed, id " + id + " does not exist.");
|
|
2399
|
+
} else if (Boolean.TRUE.equals(this.previewSessionEnabled)) {
|
|
2400
|
+
logger.info("Preview session set active bundle " + id + " without waiting for preview app readiness");
|
|
2401
|
+
this.reloadWithoutWaitingForAppReady();
|
|
2402
|
+
this.notifyBundleSet(this.implementation.getBundleInfo(id));
|
|
2403
|
+
this.showPreviewSessionNoticeIfNeeded();
|
|
2404
|
+
call.resolve();
|
|
2225
2405
|
} else if (!this._reload()) {
|
|
2226
2406
|
logger.error("Reload failed after setting bundle " + id);
|
|
2227
2407
|
call.reject("Reload failed after setting bundle " + id);
|
|
@@ -2241,6 +2421,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2241
2421
|
@PluginMethod
|
|
2242
2422
|
public void startPreviewSession(final PluginCall call) {
|
|
2243
2423
|
if (!Boolean.TRUE.equals(this.allowPreview)) {
|
|
2424
|
+
this.hidePreviewTransitionLoader("preview-session-not-allowed");
|
|
2244
2425
|
logger.error("startPreviewSession not allowed set allowPreview in your config to true to enable it");
|
|
2245
2426
|
call.reject("startPreviewSession not allowed");
|
|
2246
2427
|
return;
|
|
@@ -2249,6 +2430,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2249
2430
|
final String rawPayloadUrl = call.getString("payloadUrl");
|
|
2250
2431
|
final String previewPayloadUrl = this.normalizePreviewPayloadUrl(rawPayloadUrl);
|
|
2251
2432
|
if (this.hasPreviewPayloadUrl(rawPayloadUrl) && previewPayloadUrl == null) {
|
|
2433
|
+
this.hidePreviewTransitionLoader("preview-session-invalid-payload");
|
|
2252
2434
|
logger.error("startPreviewSession called with invalid payloadUrl");
|
|
2253
2435
|
call.reject("Invalid preview payloadUrl");
|
|
2254
2436
|
return;
|
|
@@ -2258,6 +2440,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2258
2440
|
if (!Boolean.TRUE.equals(this.previewSessionEnabled)) {
|
|
2259
2441
|
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
2260
2442
|
if (!this.implementation.setPreviewFallbackBundle(current.getId())) {
|
|
2443
|
+
this.hidePreviewTransitionLoader("preview-session-fallback-failed");
|
|
2261
2444
|
logger.error("Could not save current bundle as preview fallback");
|
|
2262
2445
|
call.reject("Could not save current bundle as preview fallback");
|
|
2263
2446
|
return;
|
|
@@ -2302,17 +2485,18 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2302
2485
|
this.editor.remove(PREVIEW_PAYLOAD_URL_PREF_KEY);
|
|
2303
2486
|
}
|
|
2304
2487
|
|
|
2488
|
+
this.hidePreviewTransitionLoader("preview-session-started");
|
|
2305
2489
|
this.previewSessionEnabled = true;
|
|
2306
2490
|
this.previewSessionAlertPending = true;
|
|
2307
2491
|
this.implementation.previewSession = true;
|
|
2308
2492
|
this.shakeMenuEnabled = true;
|
|
2309
|
-
this.shakeChannelSelectorEnabled = false;
|
|
2310
2493
|
this.editor.putBoolean(PREVIEW_SESSION_PREF_KEY, true);
|
|
2311
2494
|
this.editor.putBoolean(PREVIEW_SESSION_ALERT_PENDING_PREF_KEY, true);
|
|
2312
2495
|
this.editor.apply();
|
|
2313
2496
|
this.ensureShakeMenuStarted();
|
|
2314
2497
|
call.resolve();
|
|
2315
2498
|
} catch (final Exception e) {
|
|
2499
|
+
this.hidePreviewTransitionLoader("preview-session-failed");
|
|
2316
2500
|
logger.error("Could not start preview session " + e.getMessage());
|
|
2317
2501
|
call.reject("Could not start preview session", e);
|
|
2318
2502
|
}
|
|
@@ -2322,8 +2506,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2322
2506
|
public boolean leavePreviewSessionFromShakeMenu() {
|
|
2323
2507
|
final BundleInfo previewBundle = this.implementation.getCurrentBundle();
|
|
2324
2508
|
|
|
2509
|
+
this.showPreviewTransitionLoader("leave-preview-session");
|
|
2325
2510
|
final boolean didReset = this.resetToPreviewFallbackBundle();
|
|
2326
2511
|
if (!didReset) {
|
|
2512
|
+
this.hidePreviewTransitionLoader("leave-preview-session-failed");
|
|
2327
2513
|
return false;
|
|
2328
2514
|
}
|
|
2329
2515
|
|
|
@@ -2334,6 +2520,47 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2334
2520
|
return true;
|
|
2335
2521
|
}
|
|
2336
2522
|
|
|
2523
|
+
private boolean leavePreviewSessionForIncomingPreviewLink() {
|
|
2524
|
+
this.showPreviewTransitionLoader("incoming-preview-deeplink");
|
|
2525
|
+
final BundleInfo previewBundle = this.implementation.getCurrentBundle();
|
|
2526
|
+
final BundleInfo previewFallbackBundle = this.implementation.getPreviewFallbackBundle();
|
|
2527
|
+
boolean didReload = false;
|
|
2528
|
+
|
|
2529
|
+
try {
|
|
2530
|
+
if (previewFallbackBundle == null || previewFallbackBundle.isErrorStatus()) {
|
|
2531
|
+
logger.error("No preview fallback bundle available");
|
|
2532
|
+
return false;
|
|
2533
|
+
}
|
|
2534
|
+
if (!this.implementation.canSet(previewFallbackBundle)) {
|
|
2535
|
+
logger.error("Preview fallback bundle is not installable");
|
|
2536
|
+
return false;
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
final CapgoUpdater.ResetState previousState = this.implementation.captureResetState();
|
|
2540
|
+
if (!this.implementation.stagePreviewFallbackReload(previewFallbackBundle)) {
|
|
2541
|
+
logger.error("Could not stage preview fallback bundle");
|
|
2542
|
+
return false;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
if (!this._reload()) {
|
|
2546
|
+
this.implementation.restoreResetState(previousState);
|
|
2547
|
+
this.restoreLiveBundleStateAfterFailedReload();
|
|
2548
|
+
return false;
|
|
2549
|
+
}
|
|
2550
|
+
didReload = true;
|
|
2551
|
+
|
|
2552
|
+
this.endPreviewSession(true);
|
|
2553
|
+
final BundleInfo restoredNextBundle = this.implementation.getNextBundle();
|
|
2554
|
+
this.deletePreviewBundleIfUnused(previewBundle, previewFallbackBundle, restoredNextBundle);
|
|
2555
|
+
return true;
|
|
2556
|
+
} finally {
|
|
2557
|
+
this.clearIncomingPreviewTransition();
|
|
2558
|
+
if (!didReload) {
|
|
2559
|
+
this.hidePreviewTransitionLoader("incoming-preview-deeplink-failed");
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2337
2564
|
private void leavePreviewSessionForLaunchIntentIfNeeded() {
|
|
2338
2565
|
final Intent intent = getActivity() == null ? null : getActivity().getIntent();
|
|
2339
2566
|
if (
|
|
@@ -2348,14 +2575,20 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2348
2575
|
}
|
|
2349
2576
|
|
|
2350
2577
|
this.isLeavingPreviewForIncomingLink = true;
|
|
2578
|
+
this.showPreviewTransitionLoader("preview-launch-deeplink");
|
|
2351
2579
|
logger.info("Preview deeplink launch detected while preview session is active; restoring fallback before initial load");
|
|
2352
2580
|
if (!this.leavePreviewSessionWithoutReload()) {
|
|
2353
2581
|
logger.error("Could not leave preview session before initial preview deeplink routing");
|
|
2354
2582
|
this.isLeavingPreviewForIncomingLink = false;
|
|
2583
|
+
this.hidePreviewTransitionLoader("preview-launch-deeplink-failed");
|
|
2355
2584
|
}
|
|
2356
2585
|
}
|
|
2357
2586
|
|
|
2358
2587
|
private boolean leavePreviewSessionWithoutReload() {
|
|
2588
|
+
return this.leavePreviewSessionWithoutReload(false);
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
private boolean leavePreviewSessionWithoutReload(final boolean keepPreviewGuard) {
|
|
2359
2592
|
final BundleInfo previewBundle = this.implementation.getCurrentBundle();
|
|
2360
2593
|
final BundleInfo previewFallbackBundle = this.implementation.getPreviewFallbackBundle();
|
|
2361
2594
|
if (previewFallbackBundle == null || previewFallbackBundle.isErrorStatus()) {
|
|
@@ -2371,7 +2604,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2371
2604
|
return false;
|
|
2372
2605
|
}
|
|
2373
2606
|
|
|
2374
|
-
this.endPreviewSession();
|
|
2607
|
+
this.endPreviewSession(keepPreviewGuard);
|
|
2375
2608
|
final BundleInfo restoredNextBundle = this.implementation.getNextBundle();
|
|
2376
2609
|
this.deletePreviewBundleIfUnused(previewBundle, previewFallbackBundle, restoredNextBundle);
|
|
2377
2610
|
return true;
|
|
@@ -2396,12 +2629,19 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2396
2629
|
}
|
|
2397
2630
|
|
|
2398
2631
|
public boolean reloadPreviewSessionFromShakeMenu() {
|
|
2632
|
+
this.showPreviewTransitionLoader("reload-preview-session");
|
|
2633
|
+
final boolean didReload;
|
|
2399
2634
|
final String payloadUrl = this.storedPreviewPayloadUrl();
|
|
2400
2635
|
if (payloadUrl != null) {
|
|
2401
|
-
|
|
2636
|
+
didReload = this.refreshPreviewSessionFromPayloadUrl(payloadUrl);
|
|
2637
|
+
} else {
|
|
2638
|
+
didReload = this.reloadWithoutWaitingForAppReady();
|
|
2402
2639
|
}
|
|
2403
2640
|
|
|
2404
|
-
|
|
2641
|
+
if (!didReload) {
|
|
2642
|
+
this.hidePreviewTransitionLoader("reload-preview-session-failed");
|
|
2643
|
+
}
|
|
2644
|
+
return didReload;
|
|
2405
2645
|
}
|
|
2406
2646
|
|
|
2407
2647
|
public boolean hasActivePreviewSession() {
|
|
@@ -2433,6 +2673,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2433
2673
|
}
|
|
2434
2674
|
|
|
2435
2675
|
private void endPreviewSession() {
|
|
2676
|
+
this.endPreviewSession(false);
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
private void endPreviewSession(final boolean keepPreviewGuard) {
|
|
2436
2680
|
final boolean previousShakeMenuEnabled = this.prefs.getBoolean(
|
|
2437
2681
|
PREVIEW_PREVIOUS_SHAKE_MENU_PREF_KEY,
|
|
2438
2682
|
this.getConfig().getBoolean("shakeMenu", false)
|
|
@@ -2447,10 +2691,14 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2447
2691
|
|
|
2448
2692
|
this.previewSessionEnabled = false;
|
|
2449
2693
|
this.previewSessionAlertPending = false;
|
|
2450
|
-
|
|
2451
|
-
|
|
2694
|
+
if (keepPreviewGuard) {
|
|
2695
|
+
this.implementation.previewSession = true;
|
|
2696
|
+
} else {
|
|
2697
|
+
this.clearIncomingPreviewTransition();
|
|
2698
|
+
}
|
|
2452
2699
|
this.shakeMenuEnabled = previousShakeMenuEnabled;
|
|
2453
2700
|
this.shakeChannelSelectorEnabled = previousShakeChannelSelectorEnabled;
|
|
2701
|
+
this.syncShakeMenuLifecycle();
|
|
2454
2702
|
this.implementation.setPreviewFallbackBundle(null);
|
|
2455
2703
|
this.clearPreviewSessionPreferences();
|
|
2456
2704
|
logger.info("Preview session ended");
|
|
@@ -2459,9 +2707,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2459
2707
|
private void clearPreviewSessionBecauseDisabled() {
|
|
2460
2708
|
logger.info("Preview session disabled by config; restoring preview fallback");
|
|
2461
2709
|
final BundleInfo fallback = this.implementation.getPreviewFallbackBundle();
|
|
2462
|
-
final BundleInfo bundleToRestore =
|
|
2463
|
-
? this.implementation.getBundleInfo(BundleInfo.ID_BUILTIN)
|
|
2464
|
-
: fallback;
|
|
2710
|
+
final BundleInfo bundleToRestore =
|
|
2711
|
+
fallback == null || fallback.isErrorStatus() ? this.implementation.getBundleInfo(BundleInfo.ID_BUILTIN) : fallback;
|
|
2465
2712
|
|
|
2466
2713
|
if (this.implementation.canSet(bundleToRestore)) {
|
|
2467
2714
|
this.implementation.stagePreviewFallbackReload(bundleToRestore);
|
|
@@ -2476,8 +2723,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2476
2723
|
this.previewSessionAlertPending = false;
|
|
2477
2724
|
this.isLeavingPreviewForIncomingLink = false;
|
|
2478
2725
|
this.implementation.previewSession = false;
|
|
2726
|
+
this.hidePreviewTransitionLoader("preview-session-disabled");
|
|
2479
2727
|
this.shakeMenuEnabled = this.getConfig().getBoolean("shakeMenu", false);
|
|
2480
2728
|
this.shakeChannelSelectorEnabled = this.getConfig().getBoolean("allowShakeChannelSelector", false);
|
|
2729
|
+
this.syncShakeMenuLifecycle();
|
|
2481
2730
|
this.clearPreviewSessionPreferences();
|
|
2482
2731
|
}
|
|
2483
2732
|
|
|
@@ -2670,7 +2919,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2670
2919
|
|
|
2671
2920
|
if (version.equals(this.implementation.getCurrentBundle().getVersionName())) {
|
|
2672
2921
|
logger.info("Preview payload unchanged, reloading current bundle");
|
|
2673
|
-
return this.
|
|
2922
|
+
return this.reloadWithoutWaitingForAppReady();
|
|
2674
2923
|
}
|
|
2675
2924
|
|
|
2676
2925
|
final BundleInfo next = this.downloadPreviewPayloadBundle(payload);
|
|
@@ -2682,7 +2931,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2682
2931
|
}
|
|
2683
2932
|
|
|
2684
2933
|
this.notifyBundleSet(next);
|
|
2685
|
-
return this.
|
|
2934
|
+
return this.reloadWithoutWaitingForAppReady();
|
|
2686
2935
|
} catch (final Exception err) {
|
|
2687
2936
|
logger.error("Could not refresh preview session: " + err.getMessage());
|
|
2688
2937
|
return false;
|
|
@@ -2700,6 +2949,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2700
2949
|
this.implementation.previewSession = false;
|
|
2701
2950
|
this.shakeMenuEnabled = this.getConfig().getBoolean("shakeMenu", false);
|
|
2702
2951
|
this.shakeChannelSelectorEnabled = this.getConfig().getBoolean("allowShakeChannelSelector", false);
|
|
2952
|
+
this.syncShakeMenuLifecycle();
|
|
2703
2953
|
this.restorePreviewPreviousAppId();
|
|
2704
2954
|
this.restorePreviewPreviousDefaultChannel();
|
|
2705
2955
|
this.implementation.setPreviewFallbackBundle(null);
|
|
@@ -2730,6 +2980,24 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2730
2980
|
}
|
|
2731
2981
|
}
|
|
2732
2982
|
|
|
2983
|
+
private void syncShakeMenuLifecycle() {
|
|
2984
|
+
if (this.shouldListenForShake()) {
|
|
2985
|
+
this.ensureShakeMenuStarted();
|
|
2986
|
+
} else if (shakeMenu != null) {
|
|
2987
|
+
try {
|
|
2988
|
+
shakeMenu.stop();
|
|
2989
|
+
shakeMenu = null;
|
|
2990
|
+
logger.info("Shake menu stopped");
|
|
2991
|
+
} catch (Exception e) {
|
|
2992
|
+
logger.error("Failed to stop shake menu: " + e.getMessage());
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
private boolean shouldListenForShake() {
|
|
2998
|
+
return Boolean.TRUE.equals(this.shakeMenuEnabled) || Boolean.TRUE.equals(this.shakeChannelSelectorEnabled);
|
|
2999
|
+
}
|
|
3000
|
+
|
|
2733
3001
|
private void showPreviewSessionNoticeIfNeeded() {
|
|
2734
3002
|
if (!Boolean.TRUE.equals(this.previewSessionEnabled) || !Boolean.TRUE.equals(this.previewSessionAlertPending)) {
|
|
2735
3003
|
return;
|
|
@@ -2738,33 +3006,30 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2738
3006
|
this.editor.putBoolean(PREVIEW_SESSION_ALERT_PENDING_PREF_KEY, false);
|
|
2739
3007
|
this.editor.apply();
|
|
2740
3008
|
|
|
2741
|
-
new Handler(Looper.getMainLooper()).postDelayed(
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
if (getActivity() == null || getActivity().isFinishing()) {
|
|
2748
|
-
this.previewSessionAlertPending = true;
|
|
2749
|
-
this.editor.putBoolean(PREVIEW_SESSION_ALERT_PENDING_PREF_KEY, true);
|
|
2750
|
-
this.editor.apply();
|
|
2751
|
-
return;
|
|
2752
|
-
}
|
|
2753
|
-
|
|
2754
|
-
new AlertDialog.Builder(getActivity())
|
|
2755
|
-
.setTitle("Preview started")
|
|
2756
|
-
.setMessage("Shake your device anytime to reload or leave the test app.")
|
|
2757
|
-
.setPositiveButton("Got it", (dialog, which) -> dialog.dismiss())
|
|
2758
|
-
.show();
|
|
2759
|
-
} catch (final Exception e) {
|
|
3009
|
+
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
|
3010
|
+
try {
|
|
3011
|
+
if (!Boolean.TRUE.equals(this.previewSessionEnabled)) {
|
|
3012
|
+
return;
|
|
3013
|
+
}
|
|
3014
|
+
if (getActivity() == null || getActivity().isFinishing()) {
|
|
2760
3015
|
this.previewSessionAlertPending = true;
|
|
2761
3016
|
this.editor.putBoolean(PREVIEW_SESSION_ALERT_PENDING_PREF_KEY, true);
|
|
2762
3017
|
this.editor.apply();
|
|
2763
|
-
|
|
3018
|
+
return;
|
|
2764
3019
|
}
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
3020
|
+
|
|
3021
|
+
new AlertDialog.Builder(getActivity())
|
|
3022
|
+
.setTitle("Preview started")
|
|
3023
|
+
.setMessage("Shake your device anytime to reload or leave the test app.")
|
|
3024
|
+
.setPositiveButton("Got it", (dialog, which) -> dialog.dismiss())
|
|
3025
|
+
.show();
|
|
3026
|
+
} catch (final Exception e) {
|
|
3027
|
+
this.previewSessionAlertPending = true;
|
|
3028
|
+
this.editor.putBoolean(PREVIEW_SESSION_ALERT_PENDING_PREF_KEY, true);
|
|
3029
|
+
this.editor.apply();
|
|
3030
|
+
logger.warn("Could not show preview session notice: " + e.getMessage());
|
|
3031
|
+
}
|
|
3032
|
+
}, 600);
|
|
2768
3033
|
}
|
|
2769
3034
|
|
|
2770
3035
|
@PluginMethod
|
|
@@ -2970,6 +3235,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2970
3235
|
logger.error("Error no url or wrong format");
|
|
2971
3236
|
return "unavailable";
|
|
2972
3237
|
}
|
|
3238
|
+
if (this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
3239
|
+
return "preview_session";
|
|
3240
|
+
}
|
|
2973
3241
|
if (this.isDownloadStuckOrTimedOut()) {
|
|
2974
3242
|
logger.info("Download already in progress, skipping duplicate download request");
|
|
2975
3243
|
return "already_running";
|
|
@@ -3138,7 +3406,13 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3138
3406
|
@Override
|
|
3139
3407
|
public void run() {
|
|
3140
3408
|
try {
|
|
3409
|
+
if (CapacitorUpdaterPlugin.this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
3410
|
+
return;
|
|
3411
|
+
}
|
|
3141
3412
|
CapacitorUpdaterPlugin.this.implementation.getLatest(CapacitorUpdaterPlugin.this.updateUrl, null, (res) -> {
|
|
3413
|
+
if (CapacitorUpdaterPlugin.this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3142
3416
|
JSObject jsRes = InternalUtils.mapToJSObject(res);
|
|
3143
3417
|
if (jsRes.has("error") || jsRes.has("kind")) {
|
|
3144
3418
|
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
@@ -3201,6 +3475,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3201
3475
|
logger.info("semaphoreReady countDown");
|
|
3202
3476
|
this.semaphoreDown();
|
|
3203
3477
|
logger.info("semaphoreReady countDown done");
|
|
3478
|
+
this.clearIncomingPreviewTransition();
|
|
3479
|
+
this.hidePreviewTransitionLoader("notify-app-ready");
|
|
3204
3480
|
final JSObject ret = new JSObject();
|
|
3205
3481
|
ret.put("bundle", InternalUtils.mapToJSObject(bundle.toJSONMap()));
|
|
3206
3482
|
call.resolve(ret);
|
|
@@ -3248,6 +3524,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3248
3524
|
}
|
|
3249
3525
|
|
|
3250
3526
|
private Boolean _isAutoUpdateEnabled() {
|
|
3527
|
+
if (this.isPreviewSessionStateActive()) {
|
|
3528
|
+
return false;
|
|
3529
|
+
}
|
|
3251
3530
|
final CapConfig config = CapConfig.loadDefault(this.getActivity());
|
|
3252
3531
|
String serverUrl = config.getServerUrl();
|
|
3253
3532
|
if (serverUrl != null && !serverUrl.isEmpty()) {
|
|
@@ -3446,6 +3725,11 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3446
3725
|
logger.info("endBackGroundTaskWithNotif " + msg);
|
|
3447
3726
|
}
|
|
3448
3727
|
|
|
3728
|
+
private void clearBackgroundDownloadState() {
|
|
3729
|
+
this.backgroundDownloadTask = null;
|
|
3730
|
+
this.downloadStartTimeMs = 0;
|
|
3731
|
+
}
|
|
3732
|
+
|
|
3449
3733
|
private boolean isDownloadStuckOrTimedOut() {
|
|
3450
3734
|
if (this.backgroundDownloadTask == null || !this.backgroundDownloadTask.isAlive()) {
|
|
3451
3735
|
return false;
|
|
@@ -3472,6 +3756,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3472
3756
|
}
|
|
3473
3757
|
|
|
3474
3758
|
private Thread backgroundDownload() {
|
|
3759
|
+
if (this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
3760
|
+
return null;
|
|
3761
|
+
}
|
|
3475
3762
|
final boolean plannedDirectUpdate = this.shouldUseDirectUpdate();
|
|
3476
3763
|
final boolean initialDirectUpdateAllowed = this.isDirectUpdateCurrentlyAllowed(plannedDirectUpdate);
|
|
3477
3764
|
final String messageUpdate = initialDirectUpdateAllowed
|
|
@@ -3482,9 +3769,17 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3482
3769
|
Thread newTask = startNewThread(() -> {
|
|
3483
3770
|
// Wait for cleanup to complete before starting download
|
|
3484
3771
|
waitForCleanupIfNeeded();
|
|
3772
|
+
if (CapacitorUpdaterPlugin.this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
3773
|
+
CapacitorUpdaterPlugin.this.clearBackgroundDownloadState();
|
|
3774
|
+
return;
|
|
3775
|
+
}
|
|
3485
3776
|
logger.info("Check for update via: " + CapacitorUpdaterPlugin.this.updateUrl);
|
|
3486
3777
|
try {
|
|
3487
3778
|
CapacitorUpdaterPlugin.this.implementation.getLatest(CapacitorUpdaterPlugin.this.updateUrl, null, (res) -> {
|
|
3779
|
+
if (CapacitorUpdaterPlugin.this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
3780
|
+
CapacitorUpdaterPlugin.this.clearBackgroundDownloadState();
|
|
3781
|
+
return;
|
|
3782
|
+
}
|
|
3488
3783
|
JSObject jsRes = InternalUtils.mapToJSObject(res);
|
|
3489
3784
|
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
3490
3785
|
|
|
@@ -3709,6 +4004,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3709
4004
|
: initialDirectUpdateAllowed;
|
|
3710
4005
|
startNewThread(() -> {
|
|
3711
4006
|
try {
|
|
4007
|
+
if (CapacitorUpdaterPlugin.this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
4008
|
+
CapacitorUpdaterPlugin.this.clearBackgroundDownloadState();
|
|
4009
|
+
return;
|
|
4010
|
+
}
|
|
3712
4011
|
logger.info(
|
|
3713
4012
|
"New bundle: " +
|
|
3714
4013
|
latestVersionName +
|
|
@@ -3795,6 +4094,9 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3795
4094
|
|
|
3796
4095
|
private void installNext() {
|
|
3797
4096
|
try {
|
|
4097
|
+
if (this.shouldBlockAutoUpdateForPreviewSession()) {
|
|
4098
|
+
return;
|
|
4099
|
+
}
|
|
3798
4100
|
String delayUpdatePreferences = prefs.getString(DelayUpdateUtils.DELAY_CONDITION_PREFERENCES, "[]");
|
|
3799
4101
|
ArrayList<DelayCondition> delayConditionList = delayUpdateUtils.parseDelayConditions(delayUpdatePreferences);
|
|
3800
4102
|
if (!delayConditionList.isEmpty()) {
|
|
@@ -3830,6 +4132,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3830
4132
|
logger.info("Built-in bundle is active. We skip the check for notifyAppReady.");
|
|
3831
4133
|
return;
|
|
3832
4134
|
}
|
|
4135
|
+
if (this.isPreviewSessionStateActive()) {
|
|
4136
|
+
logger.info("Preview session is active. We skip the check for notifyAppReady.");
|
|
4137
|
+
return;
|
|
4138
|
+
}
|
|
3833
4139
|
logger.debug("Current bundle is: " + current);
|
|
3834
4140
|
|
|
3835
4141
|
if (BundleStatus.SUCCESS != current.getStatus()) {
|
|
@@ -4019,15 +4325,17 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
4019
4325
|
}
|
|
4020
4326
|
|
|
4021
4327
|
this.isLeavingPreviewForIncomingLink = true;
|
|
4328
|
+
this.showPreviewTransitionLoader("incoming-preview-deeplink");
|
|
4022
4329
|
if (getActivity() != null) {
|
|
4023
4330
|
getActivity().setIntent(intent);
|
|
4024
4331
|
}
|
|
4025
4332
|
logger.info("Preview deeplink received while preview session is active; restoring fallback before routing");
|
|
4026
4333
|
startNewThread(() -> {
|
|
4027
|
-
final boolean didLeave = this.
|
|
4334
|
+
final boolean didLeave = this.leavePreviewSessionForIncomingPreviewLink();
|
|
4028
4335
|
if (!didLeave) {
|
|
4029
4336
|
logger.error("Could not leave preview session before routing incoming preview deeplink");
|
|
4030
4337
|
this.isLeavingPreviewForIncomingLink = false;
|
|
4338
|
+
this.hidePreviewTransitionLoader("incoming-preview-deeplink-failed");
|
|
4031
4339
|
}
|
|
4032
4340
|
});
|
|
4033
4341
|
}
|
|
@@ -4048,13 +4356,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
4048
4356
|
}
|
|
4049
4357
|
|
|
4050
4358
|
// Initialize shake menu if enabled and activity is BridgeActivity
|
|
4051
|
-
if (
|
|
4052
|
-
|
|
4053
|
-
shakeMenu = new ShakeMenu(this, (com.getcapacitor.BridgeActivity) getActivity(), logger);
|
|
4054
|
-
logger.info("Shake menu initialized");
|
|
4055
|
-
} catch (Exception e) {
|
|
4056
|
-
logger.error("Failed to initialize shake menu: " + e.getMessage());
|
|
4057
|
-
}
|
|
4359
|
+
if (this.shouldListenForShake()) {
|
|
4360
|
+
this.ensureShakeMenuStarted();
|
|
4058
4361
|
}
|
|
4059
4362
|
} catch (Exception e) {
|
|
4060
4363
|
logger.error("Failed to run handleOnStart: " + e.getMessage());
|
|
@@ -4113,23 +4416,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
4113
4416
|
this.shakeMenuEnabled = enabled;
|
|
4114
4417
|
logger.info("Shake menu " + (enabled ? "enabled" : "disabled"));
|
|
4115
4418
|
|
|
4116
|
-
|
|
4117
|
-
if (enabled && getActivity() instanceof com.getcapacitor.BridgeActivity && shakeMenu == null) {
|
|
4118
|
-
try {
|
|
4119
|
-
shakeMenu = new ShakeMenu(this, (com.getcapacitor.BridgeActivity) getActivity(), logger);
|
|
4120
|
-
logger.info("Shake menu initialized");
|
|
4121
|
-
} catch (Exception e) {
|
|
4122
|
-
logger.error("Failed to initialize shake menu: " + e.getMessage());
|
|
4123
|
-
}
|
|
4124
|
-
} else if (!enabled && shakeMenu != null) {
|
|
4125
|
-
try {
|
|
4126
|
-
shakeMenu.stop();
|
|
4127
|
-
shakeMenu = null;
|
|
4128
|
-
logger.info("Shake menu stopped");
|
|
4129
|
-
} catch (Exception e) {
|
|
4130
|
-
logger.error("Failed to stop shake menu: " + e.getMessage());
|
|
4131
|
-
}
|
|
4132
|
-
}
|
|
4419
|
+
this.syncShakeMenuLifecycle();
|
|
4133
4420
|
|
|
4134
4421
|
call.resolve();
|
|
4135
4422
|
}
|
|
@@ -4157,6 +4444,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
4157
4444
|
|
|
4158
4445
|
this.shakeChannelSelectorEnabled = enabled;
|
|
4159
4446
|
logger.info("Shake channel selector " + (enabled ? "enabled" : "disabled"));
|
|
4447
|
+
this.syncShakeMenuLifecycle();
|
|
4160
4448
|
call.resolve();
|
|
4161
4449
|
}
|
|
4162
4450
|
|