@capgo/capacitor-updater 8.44.0 → 8.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -5
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +217 -91
- package/dist/docs.json +54 -2
- package/dist/esm/definitions.d.ts +21 -1
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +277 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -467,6 +467,7 @@ export default config;
|
|
|
467
467
|
* [`addListener('breakingAvailable', ...)`](#addlistenerbreakingavailable-)
|
|
468
468
|
* [`addListener('majorAvailable', ...)`](#addlistenermajoravailable-)
|
|
469
469
|
* [`addListener('updateFailed', ...)`](#addlistenerupdatefailed-)
|
|
470
|
+
* [`addListener('set', ...)`](#addlistenerset-)
|
|
470
471
|
* [`addListener('setNext', ...)`](#addlistenersetnext-)
|
|
471
472
|
* [`addListener('downloadFailed', ...)`](#addlistenerdownloadfailed-)
|
|
472
473
|
* [`addListener('appReloaded', ...)`](#addlistenerappreloaded-)
|
|
@@ -1408,6 +1409,28 @@ Listen for update fail event in the App, let you know when update has fail to in
|
|
|
1408
1409
|
--------------------
|
|
1409
1410
|
|
|
1410
1411
|
|
|
1412
|
+
#### addListener('set', ...)
|
|
1413
|
+
|
|
1414
|
+
```typescript
|
|
1415
|
+
addListener(eventName: 'set', listenerFunc: (state: SetEvent) => void) => Promise<PluginListenerHandle>
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1418
|
+
Listen for set event in the App, let you know when a bundle has been applied successfully.
|
|
1419
|
+
This event is retained natively until JavaScript consumes it, so if the app reloads before your
|
|
1420
|
+
listener is attached, the last pending `set` event is delivered once the listener subscribes.
|
|
1421
|
+
|
|
1422
|
+
| Param | Type |
|
|
1423
|
+
| ------------------ | ----------------------------------------------------------------- |
|
|
1424
|
+
| **`eventName`** | <code>'set'</code> |
|
|
1425
|
+
| **`listenerFunc`** | <code>(state: <a href="#setevent">SetEvent</a>) => void</code> |
|
|
1426
|
+
|
|
1427
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
1428
|
+
|
|
1429
|
+
**Since:** 8.43.12
|
|
1430
|
+
|
|
1431
|
+
--------------------
|
|
1432
|
+
|
|
1433
|
+
|
|
1411
1434
|
#### addListener('setNext', ...)
|
|
1412
1435
|
|
|
1413
1436
|
```typescript
|
|
@@ -1474,7 +1497,9 @@ Listen for reload event in the App, let you know when reload has happened
|
|
|
1474
1497
|
addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise<PluginListenerHandle>
|
|
1475
1498
|
```
|
|
1476
1499
|
|
|
1477
|
-
Listen for app ready event in the App, let you know when app is ready to use
|
|
1500
|
+
Listen for app ready event in the App, let you know when app is ready to use.
|
|
1501
|
+
This event is retained natively until JavaScript consumes it, so it can still be delivered after
|
|
1502
|
+
a reload even if the listener is attached later in app startup.
|
|
1478
1503
|
|
|
1479
1504
|
| Param | Type |
|
|
1480
1505
|
| ------------------ | --------------------------------------------------------------------------- |
|
|
@@ -2228,6 +2253,13 @@ If you don't use backend, you need to provide the URL and version of the bundle.
|
|
|
2228
2253
|
| **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emit when a update failed to install. | 4.0.0 |
|
|
2229
2254
|
|
|
2230
2255
|
|
|
2256
|
+
##### SetEvent
|
|
2257
|
+
|
|
2258
|
+
| Prop | Type | Description | Since |
|
|
2259
|
+
| ------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------- |
|
|
2260
|
+
| **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emit when a bundle has been applied successfully. This event uses native `retainUntilConsumed` behavior. | 8.43.12 |
|
|
2261
|
+
|
|
2262
|
+
|
|
2231
2263
|
##### SetNextEvent
|
|
2232
2264
|
|
|
2233
2265
|
| Prop | Type | Description | Since |
|
|
@@ -2244,10 +2276,10 @@ If you don't use backend, you need to provide the URL and version of the bundle.
|
|
|
2244
2276
|
|
|
2245
2277
|
##### AppReadyEvent
|
|
2246
2278
|
|
|
2247
|
-
| Prop | Type | Description
|
|
2248
|
-
| ------------ | ------------------------------------------------- |
|
|
2249
|
-
| **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emitted when the app is ready to use. | 5.2.0 |
|
|
2250
|
-
| **`status`** | <code>string</code> |
|
|
2279
|
+
| Prop | Type | Description | Since |
|
|
2280
|
+
| ------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----- |
|
|
2281
|
+
| **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emitted when the app is ready to use. This event uses native `retainUntilConsumed` behavior. | 5.2.0 |
|
|
2282
|
+
| **`status`** | <code>string</code> | | |
|
|
2251
2283
|
|
|
2252
2284
|
|
|
2253
2285
|
##### ChannelPrivateEvent
|
|
@@ -22,6 +22,7 @@ import android.view.View;
|
|
|
22
22
|
import android.view.ViewGroup;
|
|
23
23
|
import android.widget.FrameLayout;
|
|
24
24
|
import android.widget.ProgressBar;
|
|
25
|
+
import com.getcapacitor.Bridge;
|
|
25
26
|
import com.getcapacitor.CapConfig;
|
|
26
27
|
import com.getcapacitor.JSArray;
|
|
27
28
|
import com.getcapacitor.JSObject;
|
|
@@ -29,6 +30,7 @@ import com.getcapacitor.Plugin;
|
|
|
29
30
|
import com.getcapacitor.PluginCall;
|
|
30
31
|
import com.getcapacitor.PluginHandle;
|
|
31
32
|
import com.getcapacitor.PluginMethod;
|
|
33
|
+
import com.getcapacitor.PluginResult;
|
|
32
34
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
33
35
|
import com.getcapacitor.plugin.WebView;
|
|
34
36
|
import com.google.android.gms.tasks.Task;
|
|
@@ -56,7 +58,6 @@ import java.util.Objects;
|
|
|
56
58
|
import java.util.Set;
|
|
57
59
|
import java.util.Timer;
|
|
58
60
|
import java.util.TimerTask;
|
|
59
|
-
import java.util.UUID;
|
|
60
61
|
import java.util.concurrent.Phaser;
|
|
61
62
|
import java.util.concurrent.Semaphore;
|
|
62
63
|
import java.util.concurrent.TimeUnit;
|
|
@@ -83,8 +84,11 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
83
84
|
private static final String DEFAULT_CHANNEL_PREF_KEY = "CapacitorUpdater.defaultChannel";
|
|
84
85
|
private static final String[] BREAKING_EVENT_NAMES = { "breakingAvailable", "majorAvailable" };
|
|
85
86
|
private static final String LAST_FAILED_BUNDLE_PREF_KEY = "CapacitorUpdater.lastFailedBundle";
|
|
87
|
+
private static final String SPLASH_SCREEN_PLUGIN_ID = "SplashScreen";
|
|
88
|
+
private static final int SPLASH_SCREEN_RETRY_DELAY_MS = 100;
|
|
89
|
+
private static final int SPLASH_SCREEN_MAX_RETRIES = 20;
|
|
86
90
|
|
|
87
|
-
private final String pluginVersion = "8.
|
|
91
|
+
private final String pluginVersion = "8.45.1";
|
|
88
92
|
private static final String DELAY_CONDITION_PREFERENCES = "";
|
|
89
93
|
|
|
90
94
|
private SharedPreferences.Editor editor;
|
|
@@ -108,9 +112,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
108
112
|
private Boolean autoSplashscreenLoader = false;
|
|
109
113
|
private Integer autoSplashscreenTimeout = 10000;
|
|
110
114
|
private Boolean autoSplashscreenTimedOut = false;
|
|
115
|
+
private int splashscreenInvocationToken = 0;
|
|
111
116
|
private String directUpdateMode = "false";
|
|
112
117
|
private Boolean wasRecentlyInstalledOrUpdated = false;
|
|
113
|
-
private
|
|
118
|
+
private volatile boolean onLaunchDirectUpdateUsed = false;
|
|
114
119
|
Boolean shakeMenuEnabled = false;
|
|
115
120
|
Boolean shakeChannelSelectorEnabled = false;
|
|
116
121
|
private Boolean allowManualBundleError = false;
|
|
@@ -145,6 +150,28 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
145
150
|
private FrameLayout splashscreenLoaderOverlay;
|
|
146
151
|
private Runnable splashscreenTimeoutRunnable;
|
|
147
152
|
|
|
153
|
+
private static final class FireAndForgetPluginCall extends PluginCall {
|
|
154
|
+
|
|
155
|
+
FireAndForgetPluginCall(final String methodName, final JSObject data) {
|
|
156
|
+
super(null, SPLASH_SCREEN_PLUGIN_ID, PluginCall.CALLBACK_ID_DANGLING, methodName, data);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@Override
|
|
160
|
+
public void successCallback(final PluginResult successResult) {}
|
|
161
|
+
|
|
162
|
+
@Override
|
|
163
|
+
public void resolve(final JSObject data) {}
|
|
164
|
+
|
|
165
|
+
@Override
|
|
166
|
+
public void resolve() {}
|
|
167
|
+
|
|
168
|
+
@Override
|
|
169
|
+
public void errorCallback(final String msg) {}
|
|
170
|
+
|
|
171
|
+
@Override
|
|
172
|
+
public void reject(final String msg, final String code, final Exception ex, final JSObject data) {}
|
|
173
|
+
}
|
|
174
|
+
|
|
148
175
|
// App lifecycle observer using ProcessLifecycleOwner for reliable foreground/background detection
|
|
149
176
|
private AppLifecycleObserver appLifecycleObserver;
|
|
150
177
|
|
|
@@ -521,6 +548,15 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
521
548
|
sendReadyToJs(current, msg, false);
|
|
522
549
|
}
|
|
523
550
|
|
|
551
|
+
private void notifyBundleSet(final BundleInfo bundle) {
|
|
552
|
+
if (bundle == null) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
final JSObject ret = new JSObject();
|
|
556
|
+
ret.put("bundle", InternalUtils.mapToJSObject(bundle.toJSONMap()));
|
|
557
|
+
this.notifyListeners("set", ret, true);
|
|
558
|
+
}
|
|
559
|
+
|
|
524
560
|
private void sendReadyToJs(final BundleInfo current, final String msg, final boolean isDirectUpdate) {
|
|
525
561
|
logger.info("sendReadyToJs: " + msg);
|
|
526
562
|
final JSObject ret = new JSObject();
|
|
@@ -548,47 +584,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
548
584
|
private void hideSplashscreenInternal() {
|
|
549
585
|
cancelSplashscreenTimeout();
|
|
550
586
|
removeSplashscreenLoader();
|
|
551
|
-
|
|
552
|
-
try {
|
|
553
|
-
if (getBridge() == null) {
|
|
554
|
-
logger.warn("Bridge not ready for hiding splashscreen with autoSplashscreen");
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// Try to call the SplashScreen plugin directly through the bridge
|
|
559
|
-
PluginHandle splashScreenPlugin = getBridge().getPlugin("SplashScreen");
|
|
560
|
-
if (splashScreenPlugin != null) {
|
|
561
|
-
try {
|
|
562
|
-
// Create a plugin call for the hide method using reflection to access private msgHandler
|
|
563
|
-
JSObject options = new JSObject();
|
|
564
|
-
java.lang.reflect.Field msgHandlerField = getBridge().getClass().getDeclaredField("msgHandler");
|
|
565
|
-
msgHandlerField.setAccessible(true);
|
|
566
|
-
Object msgHandler = msgHandlerField.get(getBridge());
|
|
567
|
-
|
|
568
|
-
PluginCall call = new PluginCall(
|
|
569
|
-
(com.getcapacitor.MessageHandler) msgHandler,
|
|
570
|
-
"SplashScreen",
|
|
571
|
-
"FAKE_CALLBACK_ID_HIDE",
|
|
572
|
-
"hide",
|
|
573
|
-
options
|
|
574
|
-
);
|
|
575
|
-
|
|
576
|
-
// Call the hide method directly
|
|
577
|
-
splashScreenPlugin.invoke("hide", call);
|
|
578
|
-
logger.info("Splashscreen hidden automatically via direct plugin call");
|
|
579
|
-
} catch (Exception e) {
|
|
580
|
-
logger.error("Failed to call SplashScreen hide method: " + e.getMessage());
|
|
581
|
-
}
|
|
582
|
-
} else {
|
|
583
|
-
logger.warn("autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin.");
|
|
584
|
-
}
|
|
585
|
-
} catch (Exception e) {
|
|
586
|
-
logger.error(
|
|
587
|
-
"Error hiding splashscreen with autoSplashscreen: " +
|
|
588
|
-
e.getMessage() +
|
|
589
|
-
". Make sure @capacitor/splash-screen plugin is installed and configured."
|
|
590
|
-
);
|
|
591
|
-
}
|
|
587
|
+
invokeSplashScreenPluginMethod("hide", new JSObject(), SPLASH_SCREEN_MAX_RETRIES, ++this.splashscreenInvocationToken);
|
|
592
588
|
}
|
|
593
589
|
|
|
594
590
|
private void showSplashscreen() {
|
|
@@ -603,37 +599,87 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
603
599
|
cancelSplashscreenTimeout();
|
|
604
600
|
this.autoSplashscreenTimedOut = false;
|
|
605
601
|
|
|
602
|
+
final JSObject options = new JSObject();
|
|
603
|
+
options.put("autoHide", false);
|
|
604
|
+
invokeSplashScreenPluginMethod("show", options, SPLASH_SCREEN_MAX_RETRIES, ++this.splashscreenInvocationToken);
|
|
605
|
+
|
|
606
|
+
addSplashscreenLoaderIfNeeded();
|
|
607
|
+
scheduleSplashscreenTimeout();
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
private void invokeSplashScreenPluginMethod(
|
|
611
|
+
final String methodName,
|
|
612
|
+
final JSObject options,
|
|
613
|
+
final int retriesRemaining,
|
|
614
|
+
final int requestToken
|
|
615
|
+
) {
|
|
616
|
+
if (requestToken != this.splashscreenInvocationToken) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
|
|
606
620
|
try {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
(com.getcapacitor.MessageHandler) msgHandler,
|
|
619
|
-
"SplashScreen",
|
|
620
|
-
"FAKE_CALLBACK_ID_SHOW",
|
|
621
|
-
"show",
|
|
622
|
-
options
|
|
623
|
-
);
|
|
621
|
+
final Bridge bridge = getBridge();
|
|
622
|
+
if (bridge == null) {
|
|
623
|
+
retrySplashScreenInvocation(
|
|
624
|
+
methodName,
|
|
625
|
+
options,
|
|
626
|
+
retriesRemaining,
|
|
627
|
+
requestToken,
|
|
628
|
+
"Bridge not ready for " + ("show".equals(methodName) ? "showing" : "hiding") + " splashscreen"
|
|
629
|
+
);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
624
632
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
633
|
+
final PluginHandle splashScreenPlugin = bridge.getPlugin(SPLASH_SCREEN_PLUGIN_ID);
|
|
634
|
+
if (splashScreenPlugin == null) {
|
|
635
|
+
retrySplashScreenInvocation(
|
|
636
|
+
methodName,
|
|
637
|
+
options,
|
|
638
|
+
retriesRemaining,
|
|
639
|
+
requestToken,
|
|
640
|
+
"autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin."
|
|
641
|
+
);
|
|
642
|
+
return;
|
|
630
643
|
}
|
|
631
|
-
|
|
632
|
-
|
|
644
|
+
|
|
645
|
+
splashScreenPlugin.invoke(methodName, new FireAndForgetPluginCall(methodName, options));
|
|
646
|
+
logger.info("Splashscreen " + methodName + " invoked automatically");
|
|
647
|
+
} catch (final Exception e) {
|
|
648
|
+
retrySplashScreenInvocation(
|
|
649
|
+
methodName,
|
|
650
|
+
options,
|
|
651
|
+
retriesRemaining,
|
|
652
|
+
requestToken,
|
|
653
|
+
"Failed to call SplashScreen " + methodName + " method: " + e.getMessage()
|
|
654
|
+
);
|
|
633
655
|
}
|
|
656
|
+
}
|
|
634
657
|
|
|
635
|
-
|
|
636
|
-
|
|
658
|
+
private void retrySplashScreenInvocation(
|
|
659
|
+
final String methodName,
|
|
660
|
+
final JSObject options,
|
|
661
|
+
final int retriesRemaining,
|
|
662
|
+
final int requestToken,
|
|
663
|
+
final String message
|
|
664
|
+
) {
|
|
665
|
+
if (retriesRemaining > 0) {
|
|
666
|
+
logger.info(message + ". Retrying.");
|
|
667
|
+
this.mainHandler.postDelayed(
|
|
668
|
+
() -> invokeSplashScreenPluginMethod(methodName, options, retriesRemaining - 1, requestToken),
|
|
669
|
+
SPLASH_SCREEN_RETRY_DELAY_MS
|
|
670
|
+
);
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
if ("show".equals(methodName)) {
|
|
675
|
+
logger.warn(message);
|
|
676
|
+
} else {
|
|
677
|
+
logger.error(message);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
boolean isCurrentSplashscreenInvocationTokenForTesting(final int requestToken) {
|
|
682
|
+
return requestToken == this.splashscreenInvocationToken;
|
|
637
683
|
}
|
|
638
684
|
|
|
639
685
|
private void addSplashscreenLoaderIfNeeded() {
|
|
@@ -774,14 +820,58 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
774
820
|
return plannedDirectUpdate && !Boolean.TRUE.equals(this.autoSplashscreenTimedOut);
|
|
775
821
|
}
|
|
776
822
|
|
|
823
|
+
static boolean shouldConsumeOnLaunchDirectUpdate(final String directUpdateMode, final boolean plannedDirectUpdate) {
|
|
824
|
+
return plannedDirectUpdate && "onLaunch".equals(directUpdateMode);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
private void consumeOnLaunchDirectUpdateAttempt(final boolean plannedDirectUpdate) {
|
|
828
|
+
if (!shouldConsumeOnLaunchDirectUpdate(this.directUpdateMode, plannedDirectUpdate)) {
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
this.onLaunchDirectUpdateUsed = true;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
void configureDirectUpdateModeForTesting(final String directUpdateMode, final boolean onLaunchDirectUpdateUsed) {
|
|
836
|
+
this.directUpdateMode = directUpdateMode;
|
|
837
|
+
this.onLaunchDirectUpdateUsed = onLaunchDirectUpdateUsed;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
boolean shouldUseDirectUpdateForTesting() {
|
|
841
|
+
return this.shouldUseDirectUpdate();
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
boolean hasConsumedOnLaunchDirectUpdateForTesting() {
|
|
845
|
+
return this.onLaunchDirectUpdateUsed;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
boolean isVersionDownloadInProgress(final String version) {
|
|
849
|
+
return (
|
|
850
|
+
version != null &&
|
|
851
|
+
!version.isEmpty() &&
|
|
852
|
+
this.implementation != null &&
|
|
853
|
+
this.implementation.activity != null &&
|
|
854
|
+
DownloadWorkerManager.isVersionDownloading(this.implementation.activity, version)
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
void setLoggerForTesting(final Logger logger) {
|
|
859
|
+
this.logger = logger;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
void completeBackgroundTaskForTesting(final BundleInfo current, final boolean plannedDirectUpdate) {
|
|
863
|
+
this.endBackGroundTaskWithNotif("test", current.getVersionName(), current, false, plannedDirectUpdate);
|
|
864
|
+
}
|
|
865
|
+
|
|
777
866
|
private void directUpdateFinish(final BundleInfo latest) {
|
|
778
867
|
if ("onLaunch".equals(this.directUpdateMode)) {
|
|
779
868
|
this.onLaunchDirectUpdateUsed = true;
|
|
780
869
|
this.implementation.directUpdate = false;
|
|
781
870
|
}
|
|
782
|
-
CapacitorUpdaterPlugin.this.implementation.set(latest)
|
|
783
|
-
|
|
784
|
-
|
|
871
|
+
if (CapacitorUpdaterPlugin.this.implementation.set(latest) && CapacitorUpdaterPlugin.this._reload()) {
|
|
872
|
+
this.notifyBundleSet(latest);
|
|
873
|
+
sendReadyToJs(latest, "update installed", true);
|
|
874
|
+
}
|
|
785
875
|
}
|
|
786
876
|
|
|
787
877
|
private void cleanupObsoleteVersions() {
|
|
@@ -1401,9 +1491,13 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1401
1491
|
if (!this.implementation.set(id)) {
|
|
1402
1492
|
logger.info("No such bundle " + id);
|
|
1403
1493
|
call.reject("Update failed, id " + id + " does not exist.");
|
|
1494
|
+
} else if (!this._reload()) {
|
|
1495
|
+
logger.error("Reload failed after setting bundle " + id);
|
|
1496
|
+
call.reject("Reload failed after setting bundle " + id);
|
|
1404
1497
|
} else {
|
|
1405
1498
|
logger.info("Bundle successfully set to " + id);
|
|
1406
|
-
this.
|
|
1499
|
+
this.notifyBundleSet(this.implementation.getBundleInfo(id));
|
|
1500
|
+
call.resolve();
|
|
1407
1501
|
}
|
|
1408
1502
|
} catch (final Exception e) {
|
|
1409
1503
|
logger.error("Could not set id " + id + " " + e.getMessage());
|
|
@@ -1517,7 +1611,11 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1517
1611
|
|
|
1518
1612
|
if (toLastSuccessful && !fallback.isBuiltin()) {
|
|
1519
1613
|
logger.info("Resetting to: " + fallback);
|
|
1520
|
-
|
|
1614
|
+
if (this.implementation.set(fallback) && this._reload()) {
|
|
1615
|
+
this.notifyBundleSet(fallback);
|
|
1616
|
+
return true;
|
|
1617
|
+
}
|
|
1618
|
+
return false;
|
|
1521
1619
|
}
|
|
1522
1620
|
|
|
1523
1621
|
logger.info("Resetting to native.");
|
|
@@ -1786,11 +1884,12 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1786
1884
|
String latestVersionName,
|
|
1787
1885
|
BundleInfo current,
|
|
1788
1886
|
Boolean error,
|
|
1789
|
-
Boolean
|
|
1887
|
+
Boolean plannedDirectUpdate,
|
|
1790
1888
|
String failureAction,
|
|
1791
1889
|
String failureEvent,
|
|
1792
1890
|
boolean shouldSendStats
|
|
1793
1891
|
) {
|
|
1892
|
+
this.consumeOnLaunchDirectUpdateAttempt(Boolean.TRUE.equals(plannedDirectUpdate));
|
|
1794
1893
|
if (error) {
|
|
1795
1894
|
logger.info(
|
|
1796
1895
|
"endBackGroundTaskWithNotif error: " +
|
|
@@ -1810,7 +1909,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1810
1909
|
final JSObject ret = new JSObject();
|
|
1811
1910
|
ret.put("bundle", InternalUtils.mapToJSObject(current.toJSONMap()));
|
|
1812
1911
|
this.notifyListeners("noNeedUpdate", ret);
|
|
1813
|
-
this.sendReadyToJs(current, msg,
|
|
1912
|
+
this.sendReadyToJs(current, msg, plannedDirectUpdate);
|
|
1814
1913
|
this.backgroundDownloadTask = null;
|
|
1815
1914
|
this.downloadStartTimeMs = 0;
|
|
1816
1915
|
logger.info("endBackGroundTaskWithNotif " + msg);
|
|
@@ -1844,7 +1943,6 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1844
1943
|
private Thread backgroundDownload() {
|
|
1845
1944
|
final boolean plannedDirectUpdate = this.shouldUseDirectUpdate();
|
|
1846
1945
|
final boolean initialDirectUpdateAllowed = this.isDirectUpdateCurrentlyAllowed(plannedDirectUpdate);
|
|
1847
|
-
this.implementation.directUpdate = initialDirectUpdateAllowed;
|
|
1848
1946
|
final String messageUpdate = initialDirectUpdateAllowed
|
|
1849
1947
|
? "Update will occur now."
|
|
1850
1948
|
: "Update will occur next time app moves to background.";
|
|
@@ -1912,7 +2010,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1912
2010
|
"Next update will be to builtin version",
|
|
1913
2011
|
latestVersionName,
|
|
1914
2012
|
current,
|
|
1915
|
-
false
|
|
2013
|
+
false,
|
|
2014
|
+
plannedDirectUpdate
|
|
1916
2015
|
);
|
|
1917
2016
|
}
|
|
1918
2017
|
return;
|
|
@@ -1948,7 +2047,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1948
2047
|
);
|
|
1949
2048
|
return;
|
|
1950
2049
|
}
|
|
1951
|
-
if (latest.isDownloaded()) {
|
|
2050
|
+
if (latest.isDownloaded() && BundleStatus.DOWNLOADING != latest.getStatus()) {
|
|
1952
2051
|
logger.info("Latest bundle already exists and download is NOT required. " + messageUpdate);
|
|
1953
2052
|
final boolean directUpdateAllowedNow = CapacitorUpdaterPlugin.this.isDirectUpdateCurrentlyAllowed(
|
|
1954
2053
|
plannedDirectUpdate
|
|
@@ -1969,15 +2068,26 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1969
2068
|
);
|
|
1970
2069
|
return;
|
|
1971
2070
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2071
|
+
if (
|
|
2072
|
+
CapacitorUpdaterPlugin.this.implementation.set(latest) && CapacitorUpdaterPlugin.this._reload()
|
|
2073
|
+
) {
|
|
2074
|
+
CapacitorUpdaterPlugin.this.notifyBundleSet(latest);
|
|
2075
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
2076
|
+
"Update installed",
|
|
2077
|
+
latestVersionName,
|
|
2078
|
+
latest,
|
|
2079
|
+
false,
|
|
2080
|
+
true
|
|
2081
|
+
);
|
|
2082
|
+
} else {
|
|
2083
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
2084
|
+
"Update install failed",
|
|
2085
|
+
latestVersionName,
|
|
2086
|
+
latest,
|
|
2087
|
+
true,
|
|
2088
|
+
true
|
|
2089
|
+
);
|
|
2090
|
+
}
|
|
1981
2091
|
} else {
|
|
1982
2092
|
if (plannedDirectUpdate && !directUpdateAllowedNow) {
|
|
1983
2093
|
logger.info(
|
|
@@ -1990,7 +2100,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1990
2100
|
"update downloaded, will install next background",
|
|
1991
2101
|
latestVersionName,
|
|
1992
2102
|
latest,
|
|
1993
|
-
false
|
|
2103
|
+
false,
|
|
2104
|
+
plannedDirectUpdate
|
|
1994
2105
|
);
|
|
1995
2106
|
}
|
|
1996
2107
|
return;
|
|
@@ -2007,6 +2118,14 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2007
2118
|
}
|
|
2008
2119
|
}
|
|
2009
2120
|
}
|
|
2121
|
+
final boolean retryingInFlightDownload =
|
|
2122
|
+
latest != null &&
|
|
2123
|
+
BundleStatus.DOWNLOADING == latest.getStatus() &&
|
|
2124
|
+
CapacitorUpdaterPlugin.this.isVersionDownloadInProgress(latest.getVersionName());
|
|
2125
|
+
CapacitorUpdaterPlugin.this.consumeOnLaunchDirectUpdateAttempt(plannedDirectUpdate);
|
|
2126
|
+
CapacitorUpdaterPlugin.this.implementation.directUpdate = retryingInFlightDownload
|
|
2127
|
+
? Boolean.TRUE.equals(CapacitorUpdaterPlugin.this.implementation.directUpdate) || initialDirectUpdateAllowed
|
|
2128
|
+
: initialDirectUpdateAllowed;
|
|
2010
2129
|
startNewThread(() -> {
|
|
2011
2130
|
try {
|
|
2012
2131
|
logger.info(
|
|
@@ -2055,7 +2174,13 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2055
2174
|
});
|
|
2056
2175
|
} else {
|
|
2057
2176
|
logger.info("No need to update, " + current.getId() + " is the latest bundle.");
|
|
2058
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
2177
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
2178
|
+
"No need to update",
|
|
2179
|
+
latestVersionName,
|
|
2180
|
+
current,
|
|
2181
|
+
false,
|
|
2182
|
+
plannedDirectUpdate
|
|
2183
|
+
);
|
|
2059
2184
|
}
|
|
2060
2185
|
} catch (final Exception e) {
|
|
2061
2186
|
logger.error("error in update check " + e.getMessage());
|
|
@@ -2101,6 +2226,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2101
2226
|
logger.debug("Next bundle is: " + next.getVersionName());
|
|
2102
2227
|
if (this.implementation.set(next) && this._reload()) {
|
|
2103
2228
|
logger.info("Updated to bundle: " + next.getVersionName());
|
|
2229
|
+
this.notifyBundleSet(next);
|
|
2104
2230
|
this.implementation.setNextBundle(null);
|
|
2105
2231
|
} else {
|
|
2106
2232
|
logger.error("Update to bundle: " + next.getVersionName() + " Failed!");
|
package/dist/docs.json
CHANGED
|
@@ -976,6 +976,35 @@
|
|
|
976
976
|
],
|
|
977
977
|
"slug": "addlistenerupdatefailed-"
|
|
978
978
|
},
|
|
979
|
+
{
|
|
980
|
+
"name": "addListener",
|
|
981
|
+
"signature": "(eventName: 'set', listenerFunc: (state: SetEvent) => void) => Promise<PluginListenerHandle>",
|
|
982
|
+
"parameters": [
|
|
983
|
+
{
|
|
984
|
+
"name": "eventName",
|
|
985
|
+
"docs": "",
|
|
986
|
+
"type": "'set'"
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
"name": "listenerFunc",
|
|
990
|
+
"docs": "",
|
|
991
|
+
"type": "(state: SetEvent) => void"
|
|
992
|
+
}
|
|
993
|
+
],
|
|
994
|
+
"returns": "Promise<PluginListenerHandle>",
|
|
995
|
+
"tags": [
|
|
996
|
+
{
|
|
997
|
+
"name": "since",
|
|
998
|
+
"text": "8.43.12"
|
|
999
|
+
}
|
|
1000
|
+
],
|
|
1001
|
+
"docs": "Listen for set event in the App, let you know when a bundle has been applied successfully.\nThis event is retained natively until JavaScript consumes it, so if the app reloads before your\nlistener is attached, the last pending `set` event is delivered once the listener subscribes.",
|
|
1002
|
+
"complexTypes": [
|
|
1003
|
+
"PluginListenerHandle",
|
|
1004
|
+
"SetEvent"
|
|
1005
|
+
],
|
|
1006
|
+
"slug": "addlistenerset-"
|
|
1007
|
+
},
|
|
979
1008
|
{
|
|
980
1009
|
"name": "addListener",
|
|
981
1010
|
"signature": "(eventName: 'setNext', listenerFunc: (state: SetNextEvent) => void) => Promise<PluginListenerHandle>",
|
|
@@ -1084,7 +1113,7 @@
|
|
|
1084
1113
|
"text": "5.1.0"
|
|
1085
1114
|
}
|
|
1086
1115
|
],
|
|
1087
|
-
"docs": "Listen for app ready event in the App, let you know when app is ready to use,
|
|
1116
|
+
"docs": "Listen for app ready event in the App, let you know when app is ready to use.\nThis event is retained natively until JavaScript consumes it, so it can still be delivered after\na reload even if the listener is attached later in app startup.",
|
|
1088
1117
|
"complexTypes": [
|
|
1089
1118
|
"PluginListenerHandle",
|
|
1090
1119
|
"AppReadyEvent"
|
|
@@ -2528,6 +2557,29 @@
|
|
|
2528
2557
|
}
|
|
2529
2558
|
]
|
|
2530
2559
|
},
|
|
2560
|
+
{
|
|
2561
|
+
"name": "SetEvent",
|
|
2562
|
+
"slug": "setevent",
|
|
2563
|
+
"docs": "",
|
|
2564
|
+
"tags": [],
|
|
2565
|
+
"methods": [],
|
|
2566
|
+
"properties": [
|
|
2567
|
+
{
|
|
2568
|
+
"name": "bundle",
|
|
2569
|
+
"tags": [
|
|
2570
|
+
{
|
|
2571
|
+
"text": "8.43.12",
|
|
2572
|
+
"name": "since"
|
|
2573
|
+
}
|
|
2574
|
+
],
|
|
2575
|
+
"docs": "Emit when a bundle has been applied successfully.\nThis event uses native `retainUntilConsumed` behavior.",
|
|
2576
|
+
"complexTypes": [
|
|
2577
|
+
"BundleInfo"
|
|
2578
|
+
],
|
|
2579
|
+
"type": "BundleInfo"
|
|
2580
|
+
}
|
|
2581
|
+
]
|
|
2582
|
+
},
|
|
2531
2583
|
{
|
|
2532
2584
|
"name": "SetNextEvent",
|
|
2533
2585
|
"slug": "setnextevent",
|
|
@@ -2587,7 +2639,7 @@
|
|
|
2587
2639
|
"name": "since"
|
|
2588
2640
|
}
|
|
2589
2641
|
],
|
|
2590
|
-
"docs": "Emitted when the app is ready to use.",
|
|
2642
|
+
"docs": "Emitted when the app is ready to use.\nThis event uses native `retainUntilConsumed` behavior.",
|
|
2591
2643
|
"complexTypes": [
|
|
2592
2644
|
"BundleInfo"
|
|
2593
2645
|
],
|