@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
|
@@ -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.
|
|
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
|
|
@@ -742,8 +747,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
742
747
|
if !res {
|
|
743
748
|
logger.info("Bundle successfully set to: \(id) ")
|
|
744
749
|
call.reject("Update failed, id \(id) doesn't exist")
|
|
750
|
+
} else if !self._reload() {
|
|
751
|
+
call.reject("Reload failed after setting bundle \(id)")
|
|
745
752
|
} else {
|
|
746
|
-
self.
|
|
753
|
+
self.notifyBundleSet(self.implementation.getBundleInfo(id: id))
|
|
754
|
+
call.resolve()
|
|
747
755
|
}
|
|
748
756
|
}
|
|
749
757
|
|
|
@@ -938,7 +946,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
938
946
|
// the built-in bundle, set it as the bundle to use and reload.
|
|
939
947
|
if toLastSuccessful && !fallback.isBuiltin() {
|
|
940
948
|
logger.info("Resetting to: \(fallback.toString())")
|
|
941
|
-
|
|
949
|
+
if self.implementation.set(bundle: fallback) && self._reload() {
|
|
950
|
+
self.notifyBundleSet(fallback)
|
|
951
|
+
return true
|
|
952
|
+
}
|
|
953
|
+
return false
|
|
942
954
|
}
|
|
943
955
|
|
|
944
956
|
logger.info("Resetting to builtin version")
|
|
@@ -1097,6 +1109,10 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1097
1109
|
self.backgroundTaskID = UIBackgroundTaskIdentifier.invalid
|
|
1098
1110
|
}
|
|
1099
1111
|
|
|
1112
|
+
private func notifyBundleSet(_ bundle: BundleInfo) {
|
|
1113
|
+
self.notifyListeners("set", data: ["bundle": bundle.toJSON()], retainUntilConsumed: true)
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1100
1116
|
func sendReadyToJs(current: BundleInfo, msg: String) {
|
|
1101
1117
|
logger.info("sendReadyToJs")
|
|
1102
1118
|
DispatchQueue.global().async {
|
|
@@ -1124,32 +1140,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1124
1140
|
private func performHideSplashscreen() {
|
|
1125
1141
|
self.cancelSplashscreenTimeout()
|
|
1126
1142
|
self.removeSplashscreenLoader()
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
self.logger.info("Splashscreen hidden automatically")
|
|
1136
|
-
}, error: { (_) in
|
|
1137
|
-
self.logger.error("Failed to auto-hide splashscreen")
|
|
1138
|
-
})
|
|
1139
|
-
|
|
1140
|
-
// Try to call the SplashScreen hide method directly through the bridge
|
|
1141
|
-
if let splashScreenPlugin = bridge.plugin(withName: "SplashScreen") {
|
|
1142
|
-
// Use runtime method invocation to call hide method
|
|
1143
|
-
let selector = NSSelectorFromString("hide:")
|
|
1144
|
-
if splashScreenPlugin.responds(to: selector) {
|
|
1145
|
-
_ = splashScreenPlugin.perform(selector, with: call)
|
|
1146
|
-
self.logger.info("Called SplashScreen hide method")
|
|
1147
|
-
} else {
|
|
1148
|
-
self.logger.warn("autoSplashscreen: SplashScreen plugin does not respond to hide: method. Make sure @capacitor/splash-screen plugin is properly installed.")
|
|
1149
|
-
}
|
|
1150
|
-
} else {
|
|
1151
|
-
self.logger.warn("autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin.")
|
|
1152
|
-
}
|
|
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
|
+
)
|
|
1153
1151
|
}
|
|
1154
1152
|
|
|
1155
1153
|
private func showSplashscreen() {
|
|
@@ -1165,35 +1163,132 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1165
1163
|
private func performShowSplashscreen() {
|
|
1166
1164
|
self.cancelSplashscreenTimeout()
|
|
1167
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
|
+
}
|
|
1168
1219
|
|
|
1169
1220
|
guard let bridge = self.bridge else {
|
|
1170
|
-
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
|
+
)
|
|
1171
1229
|
return
|
|
1172
1230
|
}
|
|
1173
1231
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
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
|
+
}
|
|
1180
1261
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
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)
|
|
1188
1273
|
} else {
|
|
1189
|
-
self.logger.
|
|
1274
|
+
self.logger.error(message)
|
|
1190
1275
|
}
|
|
1191
|
-
|
|
1192
|
-
self.logger.warn("autoSplashscreen: SplashScreen plugin not found. Install @capacitor/splash-screen plugin.")
|
|
1276
|
+
return
|
|
1193
1277
|
}
|
|
1194
1278
|
|
|
1195
|
-
self.
|
|
1196
|
-
|
|
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
|
+
}
|
|
1197
1292
|
}
|
|
1198
1293
|
|
|
1199
1294
|
private func addSplashscreenLoaderIfNeeded() {
|
|
@@ -1347,7 +1442,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1347
1442
|
}
|
|
1348
1443
|
return false
|
|
1349
1444
|
case "onLaunch":
|
|
1350
|
-
if !self.
|
|
1445
|
+
if !self.getOnLaunchDirectUpdateUsed() {
|
|
1351
1446
|
return true
|
|
1352
1447
|
}
|
|
1353
1448
|
return false
|
|
@@ -1357,6 +1452,47 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1357
1452
|
}
|
|
1358
1453
|
}
|
|
1359
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
|
+
|
|
1360
1496
|
private func notifyBreakingEvents(version: String) {
|
|
1361
1497
|
guard !version.isEmpty else {
|
|
1362
1498
|
return
|
|
@@ -1371,6 +1507,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1371
1507
|
latestVersionName: String,
|
|
1372
1508
|
current: BundleInfo,
|
|
1373
1509
|
error: Bool = true,
|
|
1510
|
+
plannedDirectUpdate: Bool = false,
|
|
1374
1511
|
failureAction: String = "download_fail",
|
|
1375
1512
|
failureEvent: String = "downloadFailed",
|
|
1376
1513
|
sendStats: Bool = true
|
|
@@ -1382,6 +1519,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1382
1519
|
downloadInProgress = false
|
|
1383
1520
|
downloadStartTime = nil
|
|
1384
1521
|
|
|
1522
|
+
self.consumeOnLaunchDirectUpdateAttempt(plannedDirectUpdate: plannedDirectUpdate)
|
|
1523
|
+
|
|
1385
1524
|
if error {
|
|
1386
1525
|
if sendStats {
|
|
1387
1526
|
self.implementation.sendStats(action: failureAction, versionName: current.getVersionName())
|
|
@@ -1416,6 +1555,10 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1416
1555
|
return true
|
|
1417
1556
|
}
|
|
1418
1557
|
|
|
1558
|
+
func runBackgroundDownloadWork(_ work: @escaping () -> Void) {
|
|
1559
|
+
DispatchQueue.global(qos: .background).async(execute: work)
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1419
1562
|
func backgroundDownload() {
|
|
1420
1563
|
// Set download in progress flag (thread-safe)
|
|
1421
1564
|
downloadLock.lock()
|
|
@@ -1435,7 +1578,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1435
1578
|
return
|
|
1436
1579
|
}
|
|
1437
1580
|
|
|
1438
|
-
|
|
1581
|
+
self.runBackgroundDownloadWork {
|
|
1439
1582
|
// Wait for cleanup to complete before starting download
|
|
1440
1583
|
self.waitForCleanupIfNeeded()
|
|
1441
1584
|
self.backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "Finish Download Tasks") {
|
|
@@ -1456,6 +1599,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1456
1599
|
latestVersionName: res.version,
|
|
1457
1600
|
current: current,
|
|
1458
1601
|
error: true,
|
|
1602
|
+
plannedDirectUpdate: plannedDirectUpdate,
|
|
1459
1603
|
sendStats: !responseIsOk
|
|
1460
1604
|
)
|
|
1461
1605
|
return
|
|
@@ -1465,26 +1609,39 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1465
1609
|
let directUpdateAllowed = plannedDirectUpdate && !self.autoSplashscreenTimedOut
|
|
1466
1610
|
if directUpdateAllowed {
|
|
1467
1611
|
self.logger.info("Direct update to builtin version")
|
|
1468
|
-
if self.directUpdateMode == "onLaunch" {
|
|
1469
|
-
self.onLaunchDirectUpdateUsed = true
|
|
1470
|
-
self.directUpdate = false
|
|
1471
|
-
}
|
|
1472
1612
|
_ = self._reset(toLastSuccessful: false)
|
|
1473
|
-
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
|
+
)
|
|
1474
1620
|
} else {
|
|
1475
1621
|
if plannedDirectUpdate && !directUpdateAllowed {
|
|
1476
1622
|
self.logger.info("Direct update skipped because splashscreen timeout occurred. Update will apply later.")
|
|
1477
1623
|
}
|
|
1478
1624
|
self.logger.info("Setting next bundle to builtin")
|
|
1479
1625
|
_ = self.implementation.setNextBundle(next: BundleInfo.ID_BUILTIN)
|
|
1480
|
-
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
|
+
)
|
|
1481
1633
|
}
|
|
1482
1634
|
return
|
|
1483
1635
|
}
|
|
1484
1636
|
let sessionKey = res.sessionKey ?? ""
|
|
1485
1637
|
guard let downloadUrl = URL(string: res.url) else {
|
|
1486
1638
|
self.logger.error("Error no url or wrong format")
|
|
1487
|
-
self.endBackGroundTaskWithNotif(
|
|
1639
|
+
self.endBackGroundTaskWithNotif(
|
|
1640
|
+
msg: "Error no url or wrong format",
|
|
1641
|
+
latestVersionName: res.version,
|
|
1642
|
+
current: current,
|
|
1643
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1644
|
+
)
|
|
1488
1645
|
return
|
|
1489
1646
|
}
|
|
1490
1647
|
let latestVersionName = res.version
|
|
@@ -1502,6 +1659,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1502
1659
|
self.logger.error("Failed to delete failed bundle: \(nextImpl!.toString())")
|
|
1503
1660
|
}
|
|
1504
1661
|
}
|
|
1662
|
+
self.consumeOnLaunchDirectUpdateAttempt(plannedDirectUpdate: plannedDirectUpdate)
|
|
1505
1663
|
if res.manifest != nil {
|
|
1506
1664
|
nextImpl = try self.implementation.downloadManifest(manifest: res.manifest!, version: latestVersionName, sessionKey: sessionKey, link: res.link, comment: res.comment)
|
|
1507
1665
|
} else {
|
|
@@ -1510,12 +1668,22 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1510
1668
|
}
|
|
1511
1669
|
guard let next = nextImpl else {
|
|
1512
1670
|
self.logger.error("Error downloading file")
|
|
1513
|
-
self.endBackGroundTaskWithNotif(
|
|
1671
|
+
self.endBackGroundTaskWithNotif(
|
|
1672
|
+
msg: "Error downloading file",
|
|
1673
|
+
latestVersionName: latestVersionName,
|
|
1674
|
+
current: current,
|
|
1675
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1676
|
+
)
|
|
1514
1677
|
return
|
|
1515
1678
|
}
|
|
1516
1679
|
if next.isErrorStatus() {
|
|
1517
1680
|
self.logger.error("Latest bundle already exists and is in error state. Aborting update.")
|
|
1518
|
-
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
|
+
)
|
|
1519
1687
|
return
|
|
1520
1688
|
}
|
|
1521
1689
|
res.checksum = try CryptoCipher.decryptChecksum(checksum: res.checksum, publicKey: self.implementation.publicKey)
|
|
@@ -1529,7 +1697,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1529
1697
|
if !resDel {
|
|
1530
1698
|
self.logger.error("Delete failed, id \(id) doesn't exist")
|
|
1531
1699
|
}
|
|
1532
|
-
self.endBackGroundTaskWithNotif(
|
|
1700
|
+
self.endBackGroundTaskWithNotif(
|
|
1701
|
+
msg: "Error checksum",
|
|
1702
|
+
latestVersionName: latestVersionName,
|
|
1703
|
+
current: current,
|
|
1704
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1705
|
+
)
|
|
1533
1706
|
return
|
|
1534
1707
|
}
|
|
1535
1708
|
let directUpdateAllowed = plannedDirectUpdate && !self.autoSplashscreenTimedOut
|
|
@@ -1542,34 +1715,67 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1542
1715
|
}
|
|
1543
1716
|
if !delayConditionList.isEmpty {
|
|
1544
1717
|
self.logger.info("Update delayed until delay conditions met")
|
|
1545
|
-
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
|
+
)
|
|
1546
1725
|
return
|
|
1547
1726
|
}
|
|
1548
|
-
if self.
|
|
1549
|
-
self.
|
|
1550
|
-
self.
|
|
1727
|
+
if self.implementation.set(bundle: next) && self._reload() {
|
|
1728
|
+
self.notifyBundleSet(next)
|
|
1729
|
+
self.endBackGroundTaskWithNotif(
|
|
1730
|
+
msg: "update installed",
|
|
1731
|
+
latestVersionName: latestVersionName,
|
|
1732
|
+
current: next,
|
|
1733
|
+
error: false,
|
|
1734
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1735
|
+
)
|
|
1736
|
+
} else {
|
|
1737
|
+
self.endBackGroundTaskWithNotif(
|
|
1738
|
+
msg: "Update install failed",
|
|
1739
|
+
latestVersionName: latestVersionName,
|
|
1740
|
+
current: next,
|
|
1741
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1742
|
+
)
|
|
1551
1743
|
}
|
|
1552
|
-
_ = self.implementation.set(bundle: next)
|
|
1553
|
-
_ = self._reload()
|
|
1554
|
-
self.endBackGroundTaskWithNotif(msg: "update installed", latestVersionName: latestVersionName, current: next, error: false)
|
|
1555
1744
|
} else {
|
|
1556
1745
|
if plannedDirectUpdate && !directUpdateAllowed {
|
|
1557
1746
|
self.logger.info("Direct update skipped because splashscreen timeout occurred. Update will install on next app background.")
|
|
1558
1747
|
}
|
|
1559
1748
|
self.notifyListeners("updateAvailable", data: ["bundle": next.toJSON()])
|
|
1560
1749
|
_ = self.implementation.setNextBundle(next: next.getId())
|
|
1561
|
-
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
|
+
)
|
|
1562
1757
|
}
|
|
1563
1758
|
return
|
|
1564
1759
|
} catch {
|
|
1565
1760
|
self.logger.error("Error downloading file \(error.localizedDescription)")
|
|
1566
1761
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
1567
|
-
self.endBackGroundTaskWithNotif(
|
|
1762
|
+
self.endBackGroundTaskWithNotif(
|
|
1763
|
+
msg: "Error downloading file",
|
|
1764
|
+
latestVersionName: latestVersionName,
|
|
1765
|
+
current: current,
|
|
1766
|
+
plannedDirectUpdate: plannedDirectUpdate
|
|
1767
|
+
)
|
|
1568
1768
|
return
|
|
1569
1769
|
}
|
|
1570
1770
|
} else {
|
|
1571
1771
|
self.logger.info("No need to update, \(current.getId()) is the latest bundle.")
|
|
1572
|
-
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
|
+
)
|
|
1573
1779
|
return
|
|
1574
1780
|
}
|
|
1575
1781
|
}
|
|
@@ -1593,6 +1799,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1593
1799
|
logger.info("Next bundle is: \(next!.toString())")
|
|
1594
1800
|
if self.implementation.set(bundle: next!) && self._reload() {
|
|
1595
1801
|
logger.info("Updated to bundle: \(next!.toString())")
|
|
1802
|
+
self.notifyBundleSet(next!)
|
|
1596
1803
|
_ = self.implementation.setNextBundle(next: Optional<String>.none)
|
|
1597
1804
|
} else {
|
|
1598
1805
|
logger.error("Update to bundle: \(next!.toString()) Failed!")
|