@capgo/capacitor-updater 8.45.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.
|
@@ -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.45.
|
|
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
|
|
|
@@ -557,47 +584,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
557
584
|
private void hideSplashscreenInternal() {
|
|
558
585
|
cancelSplashscreenTimeout();
|
|
559
586
|
removeSplashscreenLoader();
|
|
560
|
-
|
|
561
|
-
try {
|
|
562
|
-
if (getBridge() == null) {
|
|
563
|
-
logger.warn("Bridge not ready for hiding splashscreen with autoSplashscreen");
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
// Try to call the SplashScreen plugin directly through the bridge
|
|
568
|
-
PluginHandle splashScreenPlugin = getBridge().getPlugin("SplashScreen");
|
|
569
|
-
if (splashScreenPlugin != null) {
|
|
570
|
-
try {
|
|
571
|
-
// Create a plugin call for the hide method using reflection to access private msgHandler
|
|
572
|
-
JSObject options = new JSObject();
|
|
573
|
-
java.lang.reflect.Field msgHandlerField = getBridge().getClass().getDeclaredField("msgHandler");
|
|
574
|
-
msgHandlerField.setAccessible(true);
|
|
575
|
-
Object msgHandler = msgHandlerField.get(getBridge());
|
|
576
|
-
|
|
577
|
-
PluginCall call = new PluginCall(
|
|
578
|
-
(com.getcapacitor.MessageHandler) msgHandler,
|
|
579
|
-
"SplashScreen",
|
|
580
|
-
"FAKE_CALLBACK_ID_HIDE",
|
|
581
|
-
"hide",
|
|
582
|
-
options
|
|
583
|
-
);
|
|
584
|
-
|
|
585
|
-
// Call the hide method directly
|
|
586
|
-
splashScreenPlugin.invoke("hide", call);
|
|
587
|
-
logger.info("Splashscreen hidden automatically via direct plugin call");
|
|
588
|
-
} catch (Exception e) {
|
|
589
|
-
logger.error("Failed to call SplashScreen hide method: " + e.getMessage());
|
|
590
|
-
}
|
|
591
|
-
} else {
|
|
592
|
-
logger.warn("autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin.");
|
|
593
|
-
}
|
|
594
|
-
} catch (Exception e) {
|
|
595
|
-
logger.error(
|
|
596
|
-
"Error hiding splashscreen with autoSplashscreen: " +
|
|
597
|
-
e.getMessage() +
|
|
598
|
-
". Make sure @capacitor/splash-screen plugin is installed and configured."
|
|
599
|
-
);
|
|
600
|
-
}
|
|
587
|
+
invokeSplashScreenPluginMethod("hide", new JSObject(), SPLASH_SCREEN_MAX_RETRIES, ++this.splashscreenInvocationToken);
|
|
601
588
|
}
|
|
602
589
|
|
|
603
590
|
private void showSplashscreen() {
|
|
@@ -612,37 +599,87 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
612
599
|
cancelSplashscreenTimeout();
|
|
613
600
|
this.autoSplashscreenTimedOut = false;
|
|
614
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
|
+
|
|
615
620
|
try {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
(com.getcapacitor.MessageHandler) msgHandler,
|
|
628
|
-
"SplashScreen",
|
|
629
|
-
"FAKE_CALLBACK_ID_SHOW",
|
|
630
|
-
"show",
|
|
631
|
-
options
|
|
632
|
-
);
|
|
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
|
+
}
|
|
633
632
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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;
|
|
639
643
|
}
|
|
640
|
-
|
|
641
|
-
|
|
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
|
+
);
|
|
642
655
|
}
|
|
656
|
+
}
|
|
643
657
|
|
|
644
|
-
|
|
645
|
-
|
|
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;
|
|
646
683
|
}
|
|
647
684
|
|
|
648
685
|
private void addSplashscreenLoaderIfNeeded() {
|
|
@@ -783,6 +820,49 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
783
820
|
return plannedDirectUpdate && !Boolean.TRUE.equals(this.autoSplashscreenTimedOut);
|
|
784
821
|
}
|
|
785
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
|
+
|
|
786
866
|
private void directUpdateFinish(final BundleInfo latest) {
|
|
787
867
|
if ("onLaunch".equals(this.directUpdateMode)) {
|
|
788
868
|
this.onLaunchDirectUpdateUsed = true;
|
|
@@ -1804,11 +1884,12 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1804
1884
|
String latestVersionName,
|
|
1805
1885
|
BundleInfo current,
|
|
1806
1886
|
Boolean error,
|
|
1807
|
-
Boolean
|
|
1887
|
+
Boolean plannedDirectUpdate,
|
|
1808
1888
|
String failureAction,
|
|
1809
1889
|
String failureEvent,
|
|
1810
1890
|
boolean shouldSendStats
|
|
1811
1891
|
) {
|
|
1892
|
+
this.consumeOnLaunchDirectUpdateAttempt(Boolean.TRUE.equals(plannedDirectUpdate));
|
|
1812
1893
|
if (error) {
|
|
1813
1894
|
logger.info(
|
|
1814
1895
|
"endBackGroundTaskWithNotif error: " +
|
|
@@ -1828,7 +1909,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1828
1909
|
final JSObject ret = new JSObject();
|
|
1829
1910
|
ret.put("bundle", InternalUtils.mapToJSObject(current.toJSONMap()));
|
|
1830
1911
|
this.notifyListeners("noNeedUpdate", ret);
|
|
1831
|
-
this.sendReadyToJs(current, msg,
|
|
1912
|
+
this.sendReadyToJs(current, msg, plannedDirectUpdate);
|
|
1832
1913
|
this.backgroundDownloadTask = null;
|
|
1833
1914
|
this.downloadStartTimeMs = 0;
|
|
1834
1915
|
logger.info("endBackGroundTaskWithNotif " + msg);
|
|
@@ -1862,7 +1943,6 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1862
1943
|
private Thread backgroundDownload() {
|
|
1863
1944
|
final boolean plannedDirectUpdate = this.shouldUseDirectUpdate();
|
|
1864
1945
|
final boolean initialDirectUpdateAllowed = this.isDirectUpdateCurrentlyAllowed(plannedDirectUpdate);
|
|
1865
|
-
this.implementation.directUpdate = initialDirectUpdateAllowed;
|
|
1866
1946
|
final String messageUpdate = initialDirectUpdateAllowed
|
|
1867
1947
|
? "Update will occur now."
|
|
1868
1948
|
: "Update will occur next time app moves to background.";
|
|
@@ -1930,7 +2010,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1930
2010
|
"Next update will be to builtin version",
|
|
1931
2011
|
latestVersionName,
|
|
1932
2012
|
current,
|
|
1933
|
-
false
|
|
2013
|
+
false,
|
|
2014
|
+
plannedDirectUpdate
|
|
1934
2015
|
);
|
|
1935
2016
|
}
|
|
1936
2017
|
return;
|
|
@@ -1966,7 +2047,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1966
2047
|
);
|
|
1967
2048
|
return;
|
|
1968
2049
|
}
|
|
1969
|
-
if (latest.isDownloaded()) {
|
|
2050
|
+
if (latest.isDownloaded() && BundleStatus.DOWNLOADING != latest.getStatus()) {
|
|
1970
2051
|
logger.info("Latest bundle already exists and download is NOT required. " + messageUpdate);
|
|
1971
2052
|
final boolean directUpdateAllowedNow = CapacitorUpdaterPlugin.this.isDirectUpdateCurrentlyAllowed(
|
|
1972
2053
|
plannedDirectUpdate
|
|
@@ -2019,7 +2100,8 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2019
2100
|
"update downloaded, will install next background",
|
|
2020
2101
|
latestVersionName,
|
|
2021
2102
|
latest,
|
|
2022
|
-
false
|
|
2103
|
+
false,
|
|
2104
|
+
plannedDirectUpdate
|
|
2023
2105
|
);
|
|
2024
2106
|
}
|
|
2025
2107
|
return;
|
|
@@ -2036,6 +2118,14 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2036
2118
|
}
|
|
2037
2119
|
}
|
|
2038
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;
|
|
2039
2129
|
startNewThread(() -> {
|
|
2040
2130
|
try {
|
|
2041
2131
|
logger.info(
|
|
@@ -2084,7 +2174,13 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2084
2174
|
});
|
|
2085
2175
|
} else {
|
|
2086
2176
|
logger.info("No need to update, " + current.getId() + " is the latest bundle.");
|
|
2087
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
2177
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
2178
|
+
"No need to update",
|
|
2179
|
+
latestVersionName,
|
|
2180
|
+
current,
|
|
2181
|
+
false,
|
|
2182
|
+
plannedDirectUpdate
|
|
2183
|
+
);
|
|
2088
2184
|
}
|
|
2089
2185
|
} catch (final Exception e) {
|
|
2090
2186
|
logger.error("error in update check " + e.getMessage());
|
|
@@ -72,7 +72,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
72
72
|
CAPPluginMethod(name: "completeFlexibleUpdate", returnType: CAPPluginReturnPromise)
|
|
73
73
|
]
|
|
74
74
|
public var implementation = CapgoUpdater()
|
|
75
|
-
private let pluginVersion: String = "8.45.
|
|
75
|
+
private let pluginVersion: String = "8.45.1"
|
|
76
76
|
static let updateUrlDefault = "https://plugin.capgo.app/updates"
|
|
77
77
|
static let statsUrlDefault = "https://plugin.capgo.app/stats"
|
|
78
78
|
static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
|
|
@@ -102,7 +102,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
102
102
|
private var autoSplashscreenTimeoutWorkItem: DispatchWorkItem?
|
|
103
103
|
private var splashscreenLoaderView: UIActivityIndicatorView?
|
|
104
104
|
private var splashscreenLoaderContainer: UIView?
|
|
105
|
+
private let splashscreenPluginName = "SplashScreen"
|
|
106
|
+
private let splashscreenRetryDelayMilliseconds = 100
|
|
107
|
+
private let splashscreenMaxRetries = 20
|
|
105
108
|
private var autoSplashscreenTimedOut = false
|
|
109
|
+
private var splashscreenInvocationToken = 0
|
|
106
110
|
private var autoDeleteFailed = false
|
|
107
111
|
private var autoDeletePrevious = false
|
|
108
112
|
var allowSetDefaultChannel = true
|
|
@@ -111,6 +115,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
111
115
|
private var taskRunning = false
|
|
112
116
|
private var periodCheckDelay = 0
|
|
113
117
|
private let downloadLock = NSLock()
|
|
118
|
+
private let onLaunchDirectUpdateStateLock = NSLock()
|
|
114
119
|
private var downloadInProgress = false
|
|
115
120
|
private var downloadStartTime: Date?
|
|
116
121
|
private let downloadTimeout: TimeInterval = 3600 // 1 hour timeout
|
|
@@ -1135,32 +1140,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1135
1140
|
private func performHideSplashscreen() {
|
|
1136
1141
|
self.cancelSplashscreenTimeout()
|
|
1137
1142
|
self.removeSplashscreenLoader()
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
self.logger.info("Splashscreen hidden automatically")
|
|
1147
|
-
}, error: { (_) in
|
|
1148
|
-
self.logger.error("Failed to auto-hide splashscreen")
|
|
1149
|
-
})
|
|
1150
|
-
|
|
1151
|
-
// Try to call the SplashScreen hide method directly through the bridge
|
|
1152
|
-
if let splashScreenPlugin = bridge.plugin(withName: "SplashScreen") {
|
|
1153
|
-
// Use runtime method invocation to call hide method
|
|
1154
|
-
let selector = NSSelectorFromString("hide:")
|
|
1155
|
-
if splashScreenPlugin.responds(to: selector) {
|
|
1156
|
-
_ = splashScreenPlugin.perform(selector, with: call)
|
|
1157
|
-
self.logger.info("Called SplashScreen hide method")
|
|
1158
|
-
} else {
|
|
1159
|
-
self.logger.warn("autoSplashscreen: SplashScreen plugin does not respond to hide: method. Make sure @capacitor/splash-screen plugin is properly installed.")
|
|
1160
|
-
}
|
|
1161
|
-
} else {
|
|
1162
|
-
self.logger.warn("autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin.")
|
|
1163
|
-
}
|
|
1143
|
+
self.splashscreenInvocationToken += 1
|
|
1144
|
+
self.invokeSplashscreenMethod(
|
|
1145
|
+
methodName: "hide",
|
|
1146
|
+
callbackId: "autoHideSplashscreen",
|
|
1147
|
+
options: self.splashscreenOptions(methodName: "hide"),
|
|
1148
|
+
retriesRemaining: self.splashscreenMaxRetries,
|
|
1149
|
+
requestToken: self.splashscreenInvocationToken
|
|
1150
|
+
)
|
|
1164
1151
|
}
|
|
1165
1152
|
|
|
1166
1153
|
private func showSplashscreen() {
|
|
@@ -1176,35 +1163,132 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1176
1163
|
private func performShowSplashscreen() {
|
|
1177
1164
|
self.cancelSplashscreenTimeout()
|
|
1178
1165
|
self.autoSplashscreenTimedOut = false
|
|
1166
|
+
self.splashscreenInvocationToken += 1
|
|
1167
|
+
self.invokeSplashscreenMethod(
|
|
1168
|
+
methodName: "show",
|
|
1169
|
+
callbackId: "autoShowSplashscreen",
|
|
1170
|
+
options: self.splashscreenOptions(methodName: "show"),
|
|
1171
|
+
retriesRemaining: self.splashscreenMaxRetries,
|
|
1172
|
+
requestToken: self.splashscreenInvocationToken
|
|
1173
|
+
)
|
|
1174
|
+
|
|
1175
|
+
self.addSplashscreenLoaderIfNeeded()
|
|
1176
|
+
self.scheduleSplashscreenTimeout()
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
private func splashscreenOptions(methodName: String) -> [String: Any] {
|
|
1180
|
+
methodName == "show" ? ["autoHide": false] : [:]
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
private func splashscreenCompletedMessage(methodName: String) -> String {
|
|
1184
|
+
methodName == "show" ? "Splashscreen shown automatically" : "Splashscreen hidden automatically"
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
func splashscreenOptionsForTesting(methodName: String) -> [String: Any] {
|
|
1188
|
+
self.splashscreenOptions(methodName: methodName)
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
func isCurrentSplashscreenInvocationTokenForTesting(_ requestToken: Int) -> Bool {
|
|
1192
|
+
requestToken == self.splashscreenInvocationToken
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
func advanceSplashscreenInvocationTokenForTesting() {
|
|
1196
|
+
self.splashscreenInvocationToken += 1
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
private func makeSplashscreenCall(callbackId: String, options: [String: Any], methodName: String) -> CAPPluginCall {
|
|
1200
|
+
CAPPluginCall(callbackId: callbackId, options: options, success: { [weak self] (_, _) in
|
|
1201
|
+
guard let self = self else { return }
|
|
1202
|
+
self.logger.info(self.splashscreenCompletedMessage(methodName: methodName))
|
|
1203
|
+
}, error: { [weak self] (_) in
|
|
1204
|
+
guard let self = self else { return }
|
|
1205
|
+
self.logger.error("Failed to auto-\(methodName) splashscreen")
|
|
1206
|
+
})
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
private func invokeSplashscreenMethod(
|
|
1210
|
+
methodName: String,
|
|
1211
|
+
callbackId: String,
|
|
1212
|
+
options: [String: Any],
|
|
1213
|
+
retriesRemaining: Int,
|
|
1214
|
+
requestToken: Int
|
|
1215
|
+
) {
|
|
1216
|
+
guard requestToken == self.splashscreenInvocationToken else {
|
|
1217
|
+
return
|
|
1218
|
+
}
|
|
1179
1219
|
|
|
1180
1220
|
guard let bridge = self.bridge else {
|
|
1181
|
-
self.
|
|
1221
|
+
self.retrySplashscreenMethod(
|
|
1222
|
+
methodName: methodName,
|
|
1223
|
+
callbackId: callbackId,
|
|
1224
|
+
options: options,
|
|
1225
|
+
retriesRemaining: retriesRemaining,
|
|
1226
|
+
requestToken: requestToken,
|
|
1227
|
+
message: "Bridge not available for \(methodName == "show" ? "showing" : "hiding") splashscreen with autoSplashscreen"
|
|
1228
|
+
)
|
|
1182
1229
|
return
|
|
1183
1230
|
}
|
|
1184
1231
|
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1232
|
+
guard let splashScreenPlugin = bridge.plugin(withName: self.splashscreenPluginName) else {
|
|
1233
|
+
self.retrySplashscreenMethod(
|
|
1234
|
+
methodName: methodName,
|
|
1235
|
+
callbackId: callbackId,
|
|
1236
|
+
options: options,
|
|
1237
|
+
retriesRemaining: retriesRemaining,
|
|
1238
|
+
requestToken: requestToken,
|
|
1239
|
+
message: "autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin."
|
|
1240
|
+
)
|
|
1241
|
+
return
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
let selector = NSSelectorFromString("\(methodName):")
|
|
1245
|
+
guard splashScreenPlugin.responds(to: selector) else {
|
|
1246
|
+
self.retrySplashscreenMethod(
|
|
1247
|
+
methodName: methodName,
|
|
1248
|
+
callbackId: callbackId,
|
|
1249
|
+
options: options,
|
|
1250
|
+
retriesRemaining: retriesRemaining,
|
|
1251
|
+
requestToken: requestToken,
|
|
1252
|
+
message: "autoSplashscreen: SplashScreen plugin does not respond to \(methodName): method. Make sure @capacitor/splash-screen plugin is properly installed."
|
|
1253
|
+
)
|
|
1254
|
+
return
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
let call = self.makeSplashscreenCall(callbackId: callbackId, options: options, methodName: methodName)
|
|
1258
|
+
_ = splashScreenPlugin.perform(selector, with: call)
|
|
1259
|
+
self.logger.info("Called SplashScreen \(methodName) method")
|
|
1260
|
+
}
|
|
1191
1261
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1262
|
+
private func retrySplashscreenMethod(
|
|
1263
|
+
methodName: String,
|
|
1264
|
+
callbackId: String,
|
|
1265
|
+
options: [String: Any],
|
|
1266
|
+
retriesRemaining: Int,
|
|
1267
|
+
requestToken: Int,
|
|
1268
|
+
message: String
|
|
1269
|
+
) {
|
|
1270
|
+
guard retriesRemaining > 0 else {
|
|
1271
|
+
if methodName == "show" {
|
|
1272
|
+
self.logger.warn(message)
|
|
1199
1273
|
} else {
|
|
1200
|
-
self.logger.
|
|
1274
|
+
self.logger.error(message)
|
|
1201
1275
|
}
|
|
1202
|
-
|
|
1203
|
-
self.logger.warn("autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin.")
|
|
1276
|
+
return
|
|
1204
1277
|
}
|
|
1205
1278
|
|
|
1206
|
-
self.
|
|
1207
|
-
|
|
1279
|
+
self.logger.info("\(message). Retrying.")
|
|
1280
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(self.splashscreenRetryDelayMilliseconds)) { [weak self] in
|
|
1281
|
+
guard let self = self, requestToken == self.splashscreenInvocationToken else {
|
|
1282
|
+
return
|
|
1283
|
+
}
|
|
1284
|
+
self.invokeSplashscreenMethod(
|
|
1285
|
+
methodName: methodName,
|
|
1286
|
+
callbackId: callbackId,
|
|
1287
|
+
options: options,
|
|
1288
|
+
retriesRemaining: retriesRemaining - 1,
|
|
1289
|
+
requestToken: requestToken
|
|
1290
|
+
)
|
|
1291
|
+
}
|
|
1208
1292
|
}
|
|
1209
1293
|
|
|
1210
1294
|
private func addSplashscreenLoaderIfNeeded() {
|
|
@@ -1358,7 +1442,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1358
1442
|
}
|
|
1359
1443
|
return false
|
|
1360
1444
|
case "onLaunch":
|
|
1361
|
-
if !self.
|
|
1445
|
+
if !self.getOnLaunchDirectUpdateUsed() {
|
|
1362
1446
|
return true
|
|
1363
1447
|
}
|
|
1364
1448
|
return false
|
|
@@ -1368,6 +1452,47 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1368
1452
|
}
|
|
1369
1453
|
}
|
|
1370
1454
|
|
|
1455
|
+
static func shouldConsumeOnLaunchDirectUpdate(directUpdateMode: String, plannedDirectUpdate: Bool) -> Bool {
|
|
1456
|
+
plannedDirectUpdate && directUpdateMode == "onLaunch"
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
private func getOnLaunchDirectUpdateUsed() -> Bool {
|
|
1460
|
+
self.onLaunchDirectUpdateStateLock.lock()
|
|
1461
|
+
defer { self.onLaunchDirectUpdateStateLock.unlock() }
|
|
1462
|
+
return self.onLaunchDirectUpdateUsed
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
private func setOnLaunchDirectUpdateUsed(_ used: Bool) {
|
|
1466
|
+
self.onLaunchDirectUpdateStateLock.lock()
|
|
1467
|
+
self.onLaunchDirectUpdateUsed = used
|
|
1468
|
+
self.onLaunchDirectUpdateStateLock.unlock()
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
private func consumeOnLaunchDirectUpdateAttempt(plannedDirectUpdate: Bool) {
|
|
1472
|
+
guard Self.shouldConsumeOnLaunchDirectUpdate(directUpdateMode: self.directUpdateMode, plannedDirectUpdate: plannedDirectUpdate) else {
|
|
1473
|
+
return
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
self.setOnLaunchDirectUpdateUsed(true)
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
func configureDirectUpdateModeForTesting(_ directUpdateMode: String, onLaunchDirectUpdateUsed: Bool = false) {
|
|
1480
|
+
self.directUpdateMode = directUpdateMode
|
|
1481
|
+
self.setOnLaunchDirectUpdateUsed(onLaunchDirectUpdateUsed)
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
func setUpdateUrlForTesting(_ updateUrl: String) {
|
|
1485
|
+
self.updateUrl = updateUrl
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
func shouldUseDirectUpdateForTesting() -> Bool {
|
|
1489
|
+
self.shouldUseDirectUpdate()
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
var hasConsumedOnLaunchDirectUpdateForTesting: Bool {
|
|
1493
|
+
self.getOnLaunchDirectUpdateUsed()
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1371
1496
|
private func notifyBreakingEvents(version: String) {
|
|
1372
1497
|
guard !version.isEmpty else {
|
|
1373
1498
|
return
|
|
@@ -1382,6 +1507,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1382
1507
|
latestVersionName: String,
|
|
1383
1508
|
current: BundleInfo,
|
|
1384
1509
|
error: Bool = true,
|
|
1510
|
+
plannedDirectUpdate: Bool = false,
|
|
1385
1511
|
failureAction: String = "download_fail",
|
|
1386
1512
|
failureEvent: String = "downloadFailed",
|
|
1387
1513
|
sendStats: Bool = true
|
|
@@ -1393,6 +1519,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1393
1519
|
downloadInProgress = false
|
|
1394
1520
|
downloadStartTime = nil
|
|
1395
1521
|
|
|
1522
|
+
self.consumeOnLaunchDirectUpdateAttempt(plannedDirectUpdate: plannedDirectUpdate)
|
|
1523
|
+
|
|
1396
1524
|
if error {
|
|
1397
1525
|
if sendStats {
|
|
1398
1526
|
self.implementation.sendStats(action: failureAction, versionName: current.getVersionName())
|
|
@@ -1427,6 +1555,10 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1427
1555
|
return true
|
|
1428
1556
|
}
|
|
1429
1557
|
|
|
1558
|
+
func runBackgroundDownloadWork(_ work: @escaping () -> Void) {
|
|
1559
|
+
DispatchQueue.global(qos: .background).async(execute: work)
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1430
1562
|
func backgroundDownload() {
|
|
1431
1563
|
// Set download in progress flag (thread-safe)
|
|
1432
1564
|
downloadLock.lock()
|
|
@@ -1446,7 +1578,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1446
1578
|
return
|
|
1447
1579
|
}
|
|
1448
1580
|
|
|
1449
|
-
|
|
1581
|
+
self.runBackgroundDownloadWork {
|
|
1450
1582
|
// Wait for cleanup to complete before starting download
|
|
1451
1583
|
self.waitForCleanupIfNeeded()
|
|
1452
1584
|
self.backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "Finish Download Tasks") {
|
|
@@ -1467,6 +1599,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1467
1599
|
latestVersionName: res.version,
|
|
1468
1600
|
current: current,
|
|
1469
1601
|
error: true,
|
|
1602
|
+
plannedDirectUpdate: plannedDirectUpdate,
|
|
1470
1603
|
sendStats: !responseIsOk
|
|
1471
1604
|
)
|
|
1472
1605
|
return
|
|
@@ -1476,26 +1609,39 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1476
1609
|
let directUpdateAllowed = plannedDirectUpdate && !self.autoSplashscreenTimedOut
|
|
1477
1610
|
if directUpdateAllowed {
|
|
1478
1611
|
self.logger.info("Direct update to builtin version")
|
|
1479
|
-
if self.directUpdateMode == "onLaunch" {
|
|
1480
|
-
self.onLaunchDirectUpdateUsed = true
|
|
1481
|
-
self.directUpdate = false
|
|
1482
|
-
}
|
|
1483
1612
|
_ = self._reset(toLastSuccessful: false)
|
|
1484
|
-
self.endBackGroundTaskWithNotif(
|
|
1613
|
+
self.endBackGroundTaskWithNotif(
|
|
1614
|
+
msg: "Updated to builtin version",
|
|
1615
|
+
latestVersionName: res.version,
|
|
1616
|
+
current: self.implementation.getCurrentBundle(),
|
|
1617
|
+
error: false,
|
|
1618
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1619
|
+
)
|
|
1485
1620
|
} else {
|
|
1486
1621
|
if plannedDirectUpdate && !directUpdateAllowed {
|
|
1487
1622
|
self.logger.info("Direct update skipped because splashscreen timeout occurred. Update will apply later.")
|
|
1488
1623
|
}
|
|
1489
1624
|
self.logger.info("Setting next bundle to builtin")
|
|
1490
1625
|
_ = self.implementation.setNextBundle(next: BundleInfo.ID_BUILTIN)
|
|
1491
|
-
self.endBackGroundTaskWithNotif(
|
|
1626
|
+
self.endBackGroundTaskWithNotif(
|
|
1627
|
+
msg: "Next update will be to builtin version",
|
|
1628
|
+
latestVersionName: res.version,
|
|
1629
|
+
current: current,
|
|
1630
|
+
error: false,
|
|
1631
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1632
|
+
)
|
|
1492
1633
|
}
|
|
1493
1634
|
return
|
|
1494
1635
|
}
|
|
1495
1636
|
let sessionKey = res.sessionKey ?? ""
|
|
1496
1637
|
guard let downloadUrl = URL(string: res.url) else {
|
|
1497
1638
|
self.logger.error("Error no url or wrong format")
|
|
1498
|
-
self.endBackGroundTaskWithNotif(
|
|
1639
|
+
self.endBackGroundTaskWithNotif(
|
|
1640
|
+
msg: "Error no url or wrong format",
|
|
1641
|
+
latestVersionName: res.version,
|
|
1642
|
+
current: current,
|
|
1643
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1644
|
+
)
|
|
1499
1645
|
return
|
|
1500
1646
|
}
|
|
1501
1647
|
let latestVersionName = res.version
|
|
@@ -1513,6 +1659,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1513
1659
|
self.logger.error("Failed to delete failed bundle: \(nextImpl!.toString())")
|
|
1514
1660
|
}
|
|
1515
1661
|
}
|
|
1662
|
+
self.consumeOnLaunchDirectUpdateAttempt(plannedDirectUpdate: plannedDirectUpdate)
|
|
1516
1663
|
if res.manifest != nil {
|
|
1517
1664
|
nextImpl = try self.implementation.downloadManifest(manifest: res.manifest!, version: latestVersionName, sessionKey: sessionKey, link: res.link, comment: res.comment)
|
|
1518
1665
|
} else {
|
|
@@ -1521,12 +1668,22 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1521
1668
|
}
|
|
1522
1669
|
guard let next = nextImpl else {
|
|
1523
1670
|
self.logger.error("Error downloading file")
|
|
1524
|
-
self.endBackGroundTaskWithNotif(
|
|
1671
|
+
self.endBackGroundTaskWithNotif(
|
|
1672
|
+
msg: "Error downloading file",
|
|
1673
|
+
latestVersionName: latestVersionName,
|
|
1674
|
+
current: current,
|
|
1675
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1676
|
+
)
|
|
1525
1677
|
return
|
|
1526
1678
|
}
|
|
1527
1679
|
if next.isErrorStatus() {
|
|
1528
1680
|
self.logger.error("Latest bundle already exists and is in error state. Aborting update.")
|
|
1529
|
-
self.endBackGroundTaskWithNotif(
|
|
1681
|
+
self.endBackGroundTaskWithNotif(
|
|
1682
|
+
msg: "Latest version is in error state. Aborting update.",
|
|
1683
|
+
latestVersionName: latestVersionName,
|
|
1684
|
+
current: current,
|
|
1685
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1686
|
+
)
|
|
1530
1687
|
return
|
|
1531
1688
|
}
|
|
1532
1689
|
res.checksum = try CryptoCipher.decryptChecksum(checksum: res.checksum, publicKey: self.implementation.publicKey)
|
|
@@ -1540,7 +1697,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1540
1697
|
if !resDel {
|
|
1541
1698
|
self.logger.error("Delete failed, id \(id) doesn't exist")
|
|
1542
1699
|
}
|
|
1543
|
-
self.endBackGroundTaskWithNotif(
|
|
1700
|
+
self.endBackGroundTaskWithNotif(
|
|
1701
|
+
msg: "Error checksum",
|
|
1702
|
+
latestVersionName: latestVersionName,
|
|
1703
|
+
current: current,
|
|
1704
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1705
|
+
)
|
|
1544
1706
|
return
|
|
1545
1707
|
}
|
|
1546
1708
|
let directUpdateAllowed = plannedDirectUpdate && !self.autoSplashscreenTimedOut
|
|
@@ -1553,18 +1715,31 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1553
1715
|
}
|
|
1554
1716
|
if !delayConditionList.isEmpty {
|
|
1555
1717
|
self.logger.info("Update delayed until delay conditions met")
|
|
1556
|
-
self.endBackGroundTaskWithNotif(
|
|
1718
|
+
self.endBackGroundTaskWithNotif(
|
|
1719
|
+
msg: "Update delayed until delay conditions met",
|
|
1720
|
+
latestVersionName: latestVersionName,
|
|
1721
|
+
current: next,
|
|
1722
|
+
error: false,
|
|
1723
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1724
|
+
)
|
|
1557
1725
|
return
|
|
1558
1726
|
}
|
|
1559
|
-
if self.directUpdateMode == "onLaunch" {
|
|
1560
|
-
self.onLaunchDirectUpdateUsed = true
|
|
1561
|
-
self.directUpdate = false
|
|
1562
|
-
}
|
|
1563
1727
|
if self.implementation.set(bundle: next) && self._reload() {
|
|
1564
1728
|
self.notifyBundleSet(next)
|
|
1565
|
-
self.endBackGroundTaskWithNotif(
|
|
1729
|
+
self.endBackGroundTaskWithNotif(
|
|
1730
|
+
msg: "update installed",
|
|
1731
|
+
latestVersionName: latestVersionName,
|
|
1732
|
+
current: next,
|
|
1733
|
+
error: false,
|
|
1734
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1735
|
+
)
|
|
1566
1736
|
} else {
|
|
1567
|
-
self.endBackGroundTaskWithNotif(
|
|
1737
|
+
self.endBackGroundTaskWithNotif(
|
|
1738
|
+
msg: "Update install failed",
|
|
1739
|
+
latestVersionName: latestVersionName,
|
|
1740
|
+
current: next,
|
|
1741
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1742
|
+
)
|
|
1568
1743
|
}
|
|
1569
1744
|
} else {
|
|
1570
1745
|
if plannedDirectUpdate && !directUpdateAllowed {
|
|
@@ -1572,18 +1747,35 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1572
1747
|
}
|
|
1573
1748
|
self.notifyListeners("updateAvailable", data: ["bundle": next.toJSON()])
|
|
1574
1749
|
_ = self.implementation.setNextBundle(next: next.getId())
|
|
1575
|
-
self.endBackGroundTaskWithNotif(
|
|
1750
|
+
self.endBackGroundTaskWithNotif(
|
|
1751
|
+
msg: "update downloaded, will install next background",
|
|
1752
|
+
latestVersionName: latestVersionName,
|
|
1753
|
+
current: current,
|
|
1754
|
+
error: false,
|
|
1755
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1756
|
+
)
|
|
1576
1757
|
}
|
|
1577
1758
|
return
|
|
1578
1759
|
} catch {
|
|
1579
1760
|
self.logger.error("Error downloading file \(error.localizedDescription)")
|
|
1580
1761
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
1581
|
-
self.endBackGroundTaskWithNotif(
|
|
1762
|
+
self.endBackGroundTaskWithNotif(
|
|
1763
|
+
msg: "Error downloading file",
|
|
1764
|
+
latestVersionName: latestVersionName,
|
|
1765
|
+
current: current,
|
|
1766
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1767
|
+
)
|
|
1582
1768
|
return
|
|
1583
1769
|
}
|
|
1584
1770
|
} else {
|
|
1585
1771
|
self.logger.info("No need to update, \(current.getId()) is the latest bundle.")
|
|
1586
|
-
self.endBackGroundTaskWithNotif(
|
|
1772
|
+
self.endBackGroundTaskWithNotif(
|
|
1773
|
+
msg: "No need to update, \(current.getId()) is the latest bundle.",
|
|
1774
|
+
latestVersionName: latestVersionName,
|
|
1775
|
+
current: current,
|
|
1776
|
+
error: false,
|
|
1777
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1778
|
+
)
|
|
1587
1779
|
return
|
|
1588
1780
|
}
|
|
1589
1781
|
}
|