@capgo/capacitor-updater 7.2.20 → 7.3.3
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 +6 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +48 -26
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +152 -141
- package/android/src/main/java/ee/forgr/capacitor_updater/{CapacitorUpdater.java → CapgoUpdater.java} +93 -59
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipherV2.java +13 -8
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +43 -43
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +24 -20
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +8 -4
- package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +338 -0
- package/dist/docs.json +16 -0
- package/dist/esm/definitions.d.ts +7 -0
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Plugin/AES.swift +5 -3
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +108 -94
- package/ios/Plugin/{CapacitorUpdater.swift → CapgoUpdater.swift} +71 -69
- package/ios/Plugin/CryptoCipherV2.swift +31 -26
- package/ios/Plugin/DelayUpdateUtils.swift +26 -24
- package/ios/Plugin/Logger.swift +289 -0
- package/ios/Plugin/UserDefaultsExtension.swift +0 -2
- package/package.json +1 -1
|
@@ -14,6 +14,8 @@ import Version
|
|
|
14
14
|
*/
|
|
15
15
|
@objc(CapacitorUpdaterPlugin)
|
|
16
16
|
public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
17
|
+
private let logger = Logger(withTag: "✨ CapgoUpdater")
|
|
18
|
+
|
|
17
19
|
public let identifier = "CapacitorUpdaterPlugin"
|
|
18
20
|
public let jsName = "CapacitorUpdater"
|
|
19
21
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
@@ -44,8 +46,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
44
46
|
CAPPluginMethod(name: "isAutoUpdateAvailable", returnType: CAPPluginReturnPromise),
|
|
45
47
|
CAPPluginMethod(name: "getNextBundle", returnType: CAPPluginReturnPromise)
|
|
46
48
|
]
|
|
47
|
-
public var implementation =
|
|
48
|
-
private let PLUGIN_VERSION: String = "7.
|
|
49
|
+
public var implementation = CapgoUpdater()
|
|
50
|
+
private let PLUGIN_VERSION: String = "7.3.3"
|
|
49
51
|
static let updateUrlDefault = "https://plugin.capgo.app/updates"
|
|
50
52
|
static let statsUrlDefault = "https://plugin.capgo.app/stats"
|
|
51
53
|
static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
|
|
@@ -70,27 +72,35 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
70
72
|
private var delayUpdateUtils: DelayUpdateUtils!
|
|
71
73
|
|
|
72
74
|
override public func load() {
|
|
75
|
+
let disableJSLogging = getConfig().getBoolean("disableJSLogging", false)
|
|
76
|
+
// Set webView for logging to JavaScript console
|
|
77
|
+
if ((self.bridge?.webView) != nil) && !disableJSLogging {
|
|
78
|
+
logger.setWebView(webView: (self.bridge?.webView)!)
|
|
79
|
+
logger.info("WebView set successfully for logging")
|
|
80
|
+
} else {
|
|
81
|
+
logger.error("Failed to get webView for logging")
|
|
82
|
+
}
|
|
73
83
|
#if targetEnvironment(simulator)
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
logger.info("::::: SIMULATOR :::::")
|
|
85
|
+
logger.info("Application directory: \(NSHomeDirectory())")
|
|
76
86
|
#endif
|
|
77
87
|
|
|
78
88
|
self.semaphoreUp()
|
|
79
89
|
self.implementation.deviceID = (UserDefaults.standard.string(forKey: "appUUID") ?? UUID().uuidString).lowercased()
|
|
80
90
|
UserDefaults.standard.set( self.implementation.deviceID, forKey: "appUUID")
|
|
81
91
|
UserDefaults.standard.synchronize()
|
|
82
|
-
|
|
92
|
+
logger.info("init for device \(self.implementation.deviceID)")
|
|
83
93
|
guard let versionName = getConfig().getString("version", Bundle.main.versionName) else {
|
|
84
|
-
|
|
94
|
+
logger.error("Cannot get version name")
|
|
85
95
|
// crash the app
|
|
86
96
|
fatalError("Cannot get version name")
|
|
87
97
|
}
|
|
88
98
|
do {
|
|
89
99
|
currentVersionNative = try Version(versionName)
|
|
90
100
|
} catch {
|
|
91
|
-
|
|
101
|
+
logger.error("Cannot parse versionName \(versionName)")
|
|
92
102
|
}
|
|
93
|
-
|
|
103
|
+
logger.info("version native \(self.currentVersionNative.description)")
|
|
94
104
|
implementation.versionBuild = getConfig().getString("version", Bundle.main.versionName)!
|
|
95
105
|
autoDeleteFailed = getConfig().getBoolean("autoDeleteFailed", true)
|
|
96
106
|
autoDeletePrevious = getConfig().getBoolean("autoDeletePrevious", true)
|
|
@@ -112,10 +122,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
112
122
|
implementation.notifyDownloadRaw = notifyDownload
|
|
113
123
|
implementation.PLUGIN_VERSION = self.PLUGIN_VERSION
|
|
114
124
|
|
|
125
|
+
// Set logger for shared classes
|
|
126
|
+
implementation.setLogger(logger)
|
|
127
|
+
CryptoCipherV2.setLogger(logger)
|
|
128
|
+
|
|
115
129
|
// Initialize DelayUpdateUtils
|
|
116
130
|
self.delayUpdateUtils = DelayUpdateUtils(currentVersionNative: currentVersionNative, installNext: { [weak self] in
|
|
117
131
|
self?.installNext()
|
|
118
|
-
})
|
|
132
|
+
}, logger: logger)
|
|
119
133
|
let config = (self.bridge?.viewController as? CAPBridgeViewController)?.instanceDescriptor().legacyConfig
|
|
120
134
|
implementation.appId = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String ?? ""
|
|
121
135
|
implementation.appId = config?["appId"] as? String ?? implementation.appId
|
|
@@ -123,7 +137,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
123
137
|
if implementation.appId == "" {
|
|
124
138
|
fatalError("appId is missing in capacitor.config.json or plugin config, and cannot be retrieved from the native app, please add it globally or in the plugin config")
|
|
125
139
|
}
|
|
126
|
-
|
|
140
|
+
logger.info("appId \(implementation.appId)")
|
|
127
141
|
implementation.statsUrl = getConfig().getString("statsUrl", CapacitorUpdaterPlugin.statsUrlDefault)!
|
|
128
142
|
implementation.channelUrl = getConfig().getString("channelUrl", CapacitorUpdaterPlugin.channelUrlDefault)!
|
|
129
143
|
implementation.defaultChannel = getConfig().getString("defaultChannel", "")!
|
|
@@ -141,7 +155,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
141
155
|
// According to martin it is not possible to use serverBasePath on ios in a way that allows us to store the bundle once
|
|
142
156
|
|
|
143
157
|
if !self.initialLoad() {
|
|
144
|
-
|
|
158
|
+
logger.error("unable to force reload, the plugin might fallback to the builtin version")
|
|
145
159
|
}
|
|
146
160
|
|
|
147
161
|
let nc = NotificationCenter.default
|
|
@@ -164,18 +178,18 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
164
178
|
}
|
|
165
179
|
|
|
166
180
|
if !FileManager.default.fileExists(atPath: dest.path) {
|
|
167
|
-
|
|
181
|
+
logger.error("Initial load fail - file at path \(dest.path) doesn't exist. Defaulting to buildin!! \(id)")
|
|
168
182
|
dest = Bundle.main.resourceURL!.appendingPathComponent("public")
|
|
169
183
|
}
|
|
170
184
|
|
|
171
|
-
|
|
185
|
+
logger.info("Initial load \(id)")
|
|
172
186
|
// We don't use the viewcontroller here as it does not work during the initial load state
|
|
173
187
|
bridge.setServerBasePath(dest.path)
|
|
174
188
|
return true
|
|
175
189
|
}
|
|
176
190
|
|
|
177
191
|
private func semaphoreWait(waitTime: Int) {
|
|
178
|
-
// print("\(
|
|
192
|
+
// print("\(CapgoUpdater.TAG) semaphoreWait \(waitTime)")
|
|
179
193
|
_ = semaphoreReady.wait(timeout: .now() + .milliseconds(waitTime))
|
|
180
194
|
}
|
|
181
195
|
|
|
@@ -194,16 +208,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
194
208
|
do {
|
|
195
209
|
LatestVersionNative = try Version(UserDefaults.standard.string(forKey: "LatestVersionNative") ?? "0.0.0")
|
|
196
210
|
} catch {
|
|
197
|
-
|
|
211
|
+
logger.error("Cannot get version native \(currentVersionNative)")
|
|
198
212
|
}
|
|
199
213
|
if LatestVersionNative != "0.0.0" && self.currentVersionNative.description != LatestVersionNative.description {
|
|
200
214
|
_ = self._reset(toLastSuccessful: false)
|
|
201
215
|
let res = implementation.list()
|
|
202
216
|
res.forEach { version in
|
|
203
|
-
|
|
217
|
+
logger.info("Deleting obsolete bundle: \(version.getId())")
|
|
204
218
|
let res = implementation.delete(id: version.getId())
|
|
205
219
|
if !res {
|
|
206
|
-
|
|
220
|
+
logger.error("Delete failed, id \(version.getId()) doesn't exist")
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
223
|
}
|
|
@@ -224,12 +238,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
224
238
|
|
|
225
239
|
@objc func setUpdateUrl(_ call: CAPPluginCall) {
|
|
226
240
|
if !getConfig().getBoolean("allowModifyUrl", false) {
|
|
227
|
-
|
|
241
|
+
logger.error("setUpdateUrl called without allowModifyUrl")
|
|
228
242
|
call.reject("setUpdateUrl called without allowModifyUrl set allowModifyUrl in your config to true to allow it")
|
|
229
243
|
return
|
|
230
244
|
}
|
|
231
245
|
guard let url = call.getString("url") else {
|
|
232
|
-
|
|
246
|
+
logger.error("setUpdateUrl called without url")
|
|
233
247
|
call.reject("setUpdateUrl called without url")
|
|
234
248
|
return
|
|
235
249
|
}
|
|
@@ -239,12 +253,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
239
253
|
|
|
240
254
|
@objc func setStatsUrl(_ call: CAPPluginCall) {
|
|
241
255
|
if !getConfig().getBoolean("allowModifyUrl", false) {
|
|
242
|
-
|
|
256
|
+
logger.error("setStatsUrl called without allowModifyUrl")
|
|
243
257
|
call.reject("setStatsUrl called without allowModifyUrl set allowModifyUrl in your config to true to allow it")
|
|
244
258
|
return
|
|
245
259
|
}
|
|
246
260
|
guard let url = call.getString("url") else {
|
|
247
|
-
|
|
261
|
+
logger.error("setStatsUrl called without url")
|
|
248
262
|
call.reject("setStatsUrl called without url")
|
|
249
263
|
return
|
|
250
264
|
}
|
|
@@ -254,12 +268,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
254
268
|
|
|
255
269
|
@objc func setChannelUrl(_ call: CAPPluginCall) {
|
|
256
270
|
if !getConfig().getBoolean("allowModifyUrl", false) {
|
|
257
|
-
|
|
271
|
+
logger.error("setChannelUrl called without allowModifyUrl")
|
|
258
272
|
call.reject("setChannelUrl called without allowModifyUrl set allowModifyUrl in your config to true to allow it")
|
|
259
273
|
return
|
|
260
274
|
}
|
|
261
275
|
guard let url = call.getString("url") else {
|
|
262
|
-
|
|
276
|
+
logger.error("setChannelUrl called without url")
|
|
263
277
|
call.reject("setChannelUrl called without url")
|
|
264
278
|
return
|
|
265
279
|
}
|
|
@@ -281,12 +295,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
281
295
|
|
|
282
296
|
@objc func download(_ call: CAPPluginCall) {
|
|
283
297
|
guard let urlString = call.getString("url") else {
|
|
284
|
-
|
|
298
|
+
logger.error("Download called without url")
|
|
285
299
|
call.reject("Download called without url")
|
|
286
300
|
return
|
|
287
301
|
}
|
|
288
302
|
guard let version = call.getString("version") else {
|
|
289
|
-
|
|
303
|
+
logger.error("Download called without version")
|
|
290
304
|
call.reject("Download called without version")
|
|
291
305
|
return
|
|
292
306
|
}
|
|
@@ -294,39 +308,39 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
294
308
|
let sessionKey = call.getString("sessionKey", "")
|
|
295
309
|
var checksum = call.getString("checksum", "")
|
|
296
310
|
let url = URL(string: urlString)
|
|
297
|
-
|
|
311
|
+
logger.info("Downloading \(String(describing: url))")
|
|
298
312
|
DispatchQueue.global(qos: .background).async {
|
|
299
313
|
do {
|
|
300
314
|
let next = try self.implementation.download(url: url!, version: version, sessionKey: sessionKey)
|
|
301
315
|
// If public key is present but no checksum provided, refuse installation
|
|
302
316
|
if self.implementation.publicKey != "" && checksum == "" {
|
|
303
|
-
|
|
317
|
+
self.logger.error("Public key present but no checksum provided")
|
|
304
318
|
self.implementation.sendStats(action: "checksum_required", versionName: next.getVersionName())
|
|
305
319
|
let id = next.getId()
|
|
306
320
|
let resDel = self.implementation.delete(id: id)
|
|
307
321
|
if !resDel {
|
|
308
|
-
|
|
322
|
+
self.logger.error("Delete failed, id \(id) doesn't exist")
|
|
309
323
|
}
|
|
310
324
|
throw ObjectSavableError.checksum
|
|
311
325
|
}
|
|
312
326
|
|
|
313
327
|
checksum = try CryptoCipherV2.decryptChecksum(checksum: checksum, publicKey: self.implementation.publicKey)
|
|
314
328
|
if (checksum != "" || self.implementation.publicKey != "") && next.getChecksum() != checksum {
|
|
315
|
-
|
|
329
|
+
self.logger.error("Error checksum \(next.getChecksum()) \(checksum)")
|
|
316
330
|
self.implementation.sendStats(action: "checksum_fail", versionName: next.getVersionName())
|
|
317
331
|
let id = next.getId()
|
|
318
332
|
let resDel = self.implementation.delete(id: id)
|
|
319
333
|
if !resDel {
|
|
320
|
-
|
|
334
|
+
self.logger.error("Delete failed, id \(id) doesn't exist")
|
|
321
335
|
}
|
|
322
336
|
throw ObjectSavableError.checksum
|
|
323
337
|
} else {
|
|
324
|
-
|
|
338
|
+
self.logger.info("Good checksum \(next.getChecksum()) \(checksum)")
|
|
325
339
|
}
|
|
326
340
|
self.notifyListeners("updateAvailable", data: ["bundle": next.toJSON()])
|
|
327
341
|
call.resolve(next.toJSON())
|
|
328
342
|
} catch {
|
|
329
|
-
|
|
343
|
+
self.logger.error("Failed to download from: \(String(describing: url)) \(error.localizedDescription)")
|
|
330
344
|
self.notifyListeners("downloadFailed", data: ["version": version])
|
|
331
345
|
self.implementation.sendStats(action: "download_fail")
|
|
332
346
|
call.reject("Failed to download from: \(url!)", error.localizedDescription)
|
|
@@ -344,16 +358,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
344
358
|
} else {
|
|
345
359
|
dest = self.implementation.getBundleDirectory(id: id)
|
|
346
360
|
}
|
|
347
|
-
|
|
361
|
+
logger.info("Reloading \(id)")
|
|
348
362
|
if let vc = bridge.viewController as? CAPBridgeViewController {
|
|
349
363
|
guard let capBridge = vc.bridge else {
|
|
350
|
-
|
|
364
|
+
logger.error("Cannot get capBridge")
|
|
351
365
|
return false
|
|
352
366
|
}
|
|
353
367
|
if keepUrlPathAfterReload {
|
|
354
368
|
DispatchQueue.main.async {
|
|
355
369
|
guard let url = vc.webView?.url else {
|
|
356
|
-
|
|
370
|
+
self.logger.error("vc.webView?.url is null?")
|
|
357
371
|
return
|
|
358
372
|
}
|
|
359
373
|
capBridge.setServerBasePath(dest.path)
|
|
@@ -379,20 +393,20 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
379
393
|
if self._reload() {
|
|
380
394
|
call.resolve()
|
|
381
395
|
} else {
|
|
382
|
-
|
|
396
|
+
logger.error("Reload failed")
|
|
383
397
|
call.reject("Reload failed")
|
|
384
398
|
}
|
|
385
399
|
}
|
|
386
400
|
|
|
387
401
|
@objc func next(_ call: CAPPluginCall) {
|
|
388
402
|
guard let id = call.getString("id") else {
|
|
389
|
-
|
|
403
|
+
logger.error("Next called without id")
|
|
390
404
|
call.reject("Next called without id")
|
|
391
405
|
return
|
|
392
406
|
}
|
|
393
|
-
|
|
407
|
+
logger.info("Setting next active id \(id)")
|
|
394
408
|
if !self.implementation.setNextBundle(next: id) {
|
|
395
|
-
|
|
409
|
+
logger.error("Set next version failed. id \(id) does not exist.")
|
|
396
410
|
call.reject("Set next version failed. id \(id) does not exist.")
|
|
397
411
|
} else {
|
|
398
412
|
call.resolve(self.implementation.getBundleInfo(id: id).toJSON())
|
|
@@ -401,14 +415,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
401
415
|
|
|
402
416
|
@objc func set(_ call: CAPPluginCall) {
|
|
403
417
|
guard let id = call.getString("id") else {
|
|
404
|
-
|
|
418
|
+
logger.error("Set called without id")
|
|
405
419
|
call.reject("Set called without id")
|
|
406
420
|
return
|
|
407
421
|
}
|
|
408
422
|
let res = implementation.set(id: id)
|
|
409
|
-
|
|
423
|
+
logger.info("Set active bundle: \(id)")
|
|
410
424
|
if !res {
|
|
411
|
-
|
|
425
|
+
logger.info("Bundle successfully set to: \(id) ")
|
|
412
426
|
call.reject("Update failed, id \(id) doesn't exist")
|
|
413
427
|
} else {
|
|
414
428
|
self.reload(call)
|
|
@@ -417,7 +431,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
417
431
|
|
|
418
432
|
@objc func delete(_ call: CAPPluginCall) {
|
|
419
433
|
guard let id = call.getString("id") else {
|
|
420
|
-
|
|
434
|
+
logger.error("Delete called without version")
|
|
421
435
|
call.reject("Delete called without id")
|
|
422
436
|
return
|
|
423
437
|
}
|
|
@@ -425,7 +439,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
425
439
|
if res {
|
|
426
440
|
call.resolve()
|
|
427
441
|
} else {
|
|
428
|
-
|
|
442
|
+
logger.error("Delete failed, id \(id) doesn't exist or it cannot be deleted (perhaps it is the 'next' bundle)")
|
|
429
443
|
call.reject("Delete failed, id \(id) does not exist or it cannot be deleted (perhaps it is the 'next' bundle)")
|
|
430
444
|
}
|
|
431
445
|
}
|
|
@@ -464,7 +478,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
464
478
|
call.reject(res.error)
|
|
465
479
|
} else {
|
|
466
480
|
if self._isAutoUpdateEnabled() && triggerAutoUpdate {
|
|
467
|
-
|
|
481
|
+
self.logger.info("Calling autoupdater after channel change!")
|
|
468
482
|
self.backgroundDownload()
|
|
469
483
|
}
|
|
470
484
|
call.resolve(res.toDict())
|
|
@@ -474,7 +488,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
474
488
|
|
|
475
489
|
@objc func setChannel(_ call: CAPPluginCall) {
|
|
476
490
|
guard let channel = call.getString("channel") else {
|
|
477
|
-
|
|
491
|
+
logger.error("setChannel called without channel")
|
|
478
492
|
call.reject("setChannel called without channel")
|
|
479
493
|
return
|
|
480
494
|
}
|
|
@@ -485,7 +499,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
485
499
|
call.reject(res.error)
|
|
486
500
|
} else {
|
|
487
501
|
if self._isAutoUpdateEnabled() && triggerAutoUpdate {
|
|
488
|
-
|
|
502
|
+
self.logger.info("Calling autoupdater after channel change!")
|
|
489
503
|
self.backgroundDownload()
|
|
490
504
|
}
|
|
491
505
|
call.resolve(res.toDict())
|
|
@@ -505,7 +519,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
505
519
|
}
|
|
506
520
|
@objc func setCustomId(_ call: CAPPluginCall) {
|
|
507
521
|
guard let customId = call.getString("customId") else {
|
|
508
|
-
|
|
522
|
+
logger.error("setCustomId called without customId")
|
|
509
523
|
call.reject("setCustomId called without customId")
|
|
510
524
|
return
|
|
511
525
|
}
|
|
@@ -521,11 +535,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
521
535
|
// If developer wants to reset to the last successful bundle, and that bundle is not
|
|
522
536
|
// the built-in bundle, set it as the bundle to use and reload.
|
|
523
537
|
if toLastSuccessful && !fallback.isBuiltin() {
|
|
524
|
-
|
|
538
|
+
logger.info("Resetting to: \(fallback.toString())")
|
|
525
539
|
return self.implementation.set(bundle: fallback) && self._reload()
|
|
526
540
|
}
|
|
527
541
|
|
|
528
|
-
|
|
542
|
+
logger.info("Resetting to builtin version")
|
|
529
543
|
|
|
530
544
|
// Otherwise, reset back to the built-in bundle and reload.
|
|
531
545
|
self.implementation.reset()
|
|
@@ -540,8 +554,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
540
554
|
if self._reset(toLastSuccessful: toLastSuccessful) {
|
|
541
555
|
call.resolve()
|
|
542
556
|
} else {
|
|
543
|
-
|
|
544
|
-
call.reject("
|
|
557
|
+
logger.error("Reset failed")
|
|
558
|
+
call.reject("Reset failed")
|
|
545
559
|
}
|
|
546
560
|
}
|
|
547
561
|
|
|
@@ -557,13 +571,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
557
571
|
self.semaphoreDown()
|
|
558
572
|
let bundle = self.implementation.getCurrentBundle()
|
|
559
573
|
self.implementation.setSuccess(bundle: bundle, autoDeletePrevious: self.autoDeletePrevious)
|
|
560
|
-
|
|
574
|
+
logger.info("Current bundle loaded successfully. ['notifyAppReady()' was called] \(bundle.toString())")
|
|
561
575
|
call.resolve(["bundle": bundle.toJSON()])
|
|
562
576
|
}
|
|
563
577
|
|
|
564
578
|
@objc func setMultiDelay(_ call: CAPPluginCall) {
|
|
565
579
|
guard let delayConditionList = call.getValue("delayConditions") else {
|
|
566
|
-
|
|
580
|
+
logger.error("setMultiDelay called without delayCondition")
|
|
567
581
|
call.reject("setMultiDelay called without delayCondition")
|
|
568
582
|
return
|
|
569
583
|
}
|
|
@@ -609,7 +623,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
609
623
|
private func _isAutoUpdateEnabled() -> Bool {
|
|
610
624
|
let instanceDescriptor = (self.bridge?.viewController as? CAPBridgeViewController)?.instanceDescriptor()
|
|
611
625
|
if instanceDescriptor?.serverURL != nil {
|
|
612
|
-
|
|
626
|
+
logger.warn("AutoUpdate is automatic disabled when serverUrl is set.")
|
|
613
627
|
}
|
|
614
628
|
return self.autoUpdate && self.updateUrl != "" && instanceDescriptor?.serverURL == nil
|
|
615
629
|
}
|
|
@@ -633,7 +647,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
633
647
|
self.appReadyCheck = DispatchWorkItem(block: {
|
|
634
648
|
self.DeferredNotifyAppReadyCheck()
|
|
635
649
|
})
|
|
636
|
-
|
|
650
|
+
logger.info("Wait for \(self.appReadyTimeout) ms, then check for notifyAppReady")
|
|
637
651
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(self.appReadyTimeout), execute: self.appReadyCheck!)
|
|
638
652
|
}
|
|
639
653
|
|
|
@@ -641,15 +655,15 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
641
655
|
// Automatically roll back to fallback version if notifyAppReady has not been called yet
|
|
642
656
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
643
657
|
if current.isBuiltin() {
|
|
644
|
-
|
|
658
|
+
logger.info("Built-in bundle is active. We skip the check for notifyAppReady.")
|
|
645
659
|
return
|
|
646
660
|
}
|
|
647
661
|
|
|
648
|
-
|
|
662
|
+
logger.info("Current bundle is: \(current.toString())")
|
|
649
663
|
|
|
650
664
|
if BundleStatus.SUCCESS.localizedString != current.getStatus() {
|
|
651
|
-
|
|
652
|
-
|
|
665
|
+
logger.error("notifyAppReady was not called, roll back current bundle: \(current.toString())")
|
|
666
|
+
logger.error("Did you forget to call 'notifyAppReady()' in your Capacitor App code?")
|
|
653
667
|
self.notifyListeners("updateFailed", data: [
|
|
654
668
|
"bundle": current.toJSON()
|
|
655
669
|
])
|
|
@@ -657,16 +671,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
657
671
|
self.implementation.setError(bundle: current)
|
|
658
672
|
_ = self._reset(toLastSuccessful: true)
|
|
659
673
|
if self.autoDeleteFailed && !current.isBuiltin() {
|
|
660
|
-
|
|
674
|
+
logger.info("Deleting failing bundle: \(current.toString())")
|
|
661
675
|
let res = self.implementation.delete(id: current.getId(), removeInfo: false)
|
|
662
676
|
if !res {
|
|
663
|
-
|
|
677
|
+
logger.info("Delete version deleted: \(current.toString())")
|
|
664
678
|
} else {
|
|
665
|
-
|
|
679
|
+
logger.error("Failed to delete failed bundle: \(current.toString())")
|
|
666
680
|
}
|
|
667
681
|
}
|
|
668
682
|
} else {
|
|
669
|
-
|
|
683
|
+
logger.info("notifyAppReady was called. This is fine: \(current.toString())")
|
|
670
684
|
}
|
|
671
685
|
}
|
|
672
686
|
|
|
@@ -681,7 +695,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
681
695
|
}
|
|
682
696
|
|
|
683
697
|
func sendReadyToJs(current: BundleInfo, msg: String) {
|
|
684
|
-
|
|
698
|
+
logger.info("sendReadyToJs")
|
|
685
699
|
DispatchQueue.global().async {
|
|
686
700
|
self.semaphoreWait(waitTime: self.appReadyTimeout)
|
|
687
701
|
self.notifyListeners("appReady", data: ["bundle": current.toJSON(), "status": msg])
|
|
@@ -695,14 +709,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
695
709
|
}
|
|
696
710
|
self.notifyListeners("noNeedUpdate", data: ["bundle": current.toJSON()])
|
|
697
711
|
self.sendReadyToJs(current: current, msg: msg)
|
|
698
|
-
|
|
712
|
+
logger.info("endBackGroundTaskWithNotif \(msg) current: \(current.getVersionName()) latestVersionName: \(latestVersionName)")
|
|
699
713
|
self.endBackGroundTask()
|
|
700
714
|
}
|
|
701
715
|
|
|
702
716
|
func backgroundDownload() {
|
|
703
717
|
let messageUpdate = self.directUpdate ? "Update will occur now." : "Update will occur next time app moves to background."
|
|
704
718
|
guard let url = URL(string: self.updateUrl) else {
|
|
705
|
-
|
|
719
|
+
logger.error("Error no url or wrong format")
|
|
706
720
|
return
|
|
707
721
|
}
|
|
708
722
|
DispatchQueue.global(qos: .background).async {
|
|
@@ -710,12 +724,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
710
724
|
// End the task if time expires.
|
|
711
725
|
self.endBackGroundTask()
|
|
712
726
|
}
|
|
713
|
-
|
|
727
|
+
self.logger.info("Check for update via \(self.updateUrl)")
|
|
714
728
|
let res = self.implementation.getLatest(url: url, channel: nil)
|
|
715
729
|
let current = self.implementation.getCurrentBundle()
|
|
716
730
|
|
|
717
731
|
if (res.message) != nil {
|
|
718
|
-
|
|
732
|
+
self.logger.info("API message: \(res.message ?? "")")
|
|
719
733
|
if res.major == true {
|
|
720
734
|
self.notifyListeners("majorAvailable", data: ["version": res.version])
|
|
721
735
|
}
|
|
@@ -723,13 +737,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
723
737
|
return
|
|
724
738
|
}
|
|
725
739
|
if res.version == "builtin" {
|
|
726
|
-
|
|
740
|
+
self.logger.info("Latest version is builtin")
|
|
727
741
|
if self.directUpdate {
|
|
728
|
-
|
|
742
|
+
self.logger.info("Direct update to builtin version")
|
|
729
743
|
_ = self._reset(toLastSuccessful: false)
|
|
730
744
|
self.endBackGroundTaskWithNotif(msg: "Updated to builtin version", latestVersionName: res.version, current: self.implementation.getCurrentBundle(), error: false)
|
|
731
745
|
} else {
|
|
732
|
-
|
|
746
|
+
self.logger.info("Setting next bundle to builtin")
|
|
733
747
|
_ = self.implementation.setNextBundle(next: BundleInfo.ID_BUILTIN)
|
|
734
748
|
self.endBackGroundTaskWithNotif(msg: "Next update will be to builtin version", latestVersionName: res.version, current: current, error: false)
|
|
735
749
|
}
|
|
@@ -737,23 +751,23 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
737
751
|
}
|
|
738
752
|
let sessionKey = res.sessionKey ?? ""
|
|
739
753
|
guard let downloadUrl = URL(string: res.url) else {
|
|
740
|
-
|
|
754
|
+
self.logger.error("Error no url or wrong format")
|
|
741
755
|
self.endBackGroundTaskWithNotif(msg: "Error no url or wrong format", latestVersionName: res.version, current: current)
|
|
742
756
|
return
|
|
743
757
|
}
|
|
744
758
|
let latestVersionName = res.version
|
|
745
759
|
if latestVersionName != "" && current.getVersionName() != latestVersionName {
|
|
746
760
|
do {
|
|
747
|
-
|
|
761
|
+
self.logger.info("New bundle: \(latestVersionName) found. Current is: \(current.getVersionName()). \(messageUpdate)")
|
|
748
762
|
var nextImpl = self.implementation.getBundleInfoByVersionName(version: latestVersionName)
|
|
749
763
|
if nextImpl == nil || nextImpl?.isDeleted() == true {
|
|
750
764
|
if nextImpl?.isDeleted() == true {
|
|
751
|
-
|
|
765
|
+
self.logger.info("Latest bundle already exists and will be deleted, download will overwrite it.")
|
|
752
766
|
let res = self.implementation.delete(id: nextImpl!.getId(), removeInfo: true)
|
|
753
767
|
if res {
|
|
754
|
-
|
|
768
|
+
self.logger.info("Failed bundle deleted: \(nextImpl!.toString())")
|
|
755
769
|
} else {
|
|
756
|
-
|
|
770
|
+
self.logger.error("Failed to delete failed bundle: \(nextImpl!.toString())")
|
|
757
771
|
}
|
|
758
772
|
}
|
|
759
773
|
if res.manifest != nil {
|
|
@@ -763,23 +777,23 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
763
777
|
}
|
|
764
778
|
}
|
|
765
779
|
guard let next = nextImpl else {
|
|
766
|
-
|
|
780
|
+
self.logger.error("Error downloading file")
|
|
767
781
|
self.endBackGroundTaskWithNotif(msg: "Error downloading file", latestVersionName: latestVersionName, current: current)
|
|
768
782
|
return
|
|
769
783
|
}
|
|
770
784
|
if next.isErrorStatus() {
|
|
771
|
-
|
|
785
|
+
self.logger.error("Latest bundle already exists and is in error state. Aborting update.")
|
|
772
786
|
self.endBackGroundTaskWithNotif(msg: "Latest version is in error state. Aborting update.", latestVersionName: latestVersionName, current: current)
|
|
773
787
|
return
|
|
774
788
|
}
|
|
775
789
|
res.checksum = try CryptoCipherV2.decryptChecksum(checksum: res.checksum, publicKey: self.implementation.publicKey)
|
|
776
790
|
if res.checksum != "" && next.getChecksum() != res.checksum && res.manifest == nil {
|
|
777
|
-
|
|
791
|
+
self.logger.error("Error checksum \(next.getChecksum()) \(res.checksum)")
|
|
778
792
|
self.implementation.sendStats(action: "checksum_fail", versionName: next.getVersionName())
|
|
779
793
|
let id = next.getId()
|
|
780
794
|
let resDel = self.implementation.delete(id: id)
|
|
781
795
|
if !resDel {
|
|
782
|
-
|
|
796
|
+
self.logger.error("Delete failed, id \(id) doesn't exist")
|
|
783
797
|
}
|
|
784
798
|
self.endBackGroundTaskWithNotif(msg: "Error checksum", latestVersionName: latestVersionName, current: current)
|
|
785
799
|
return
|
|
@@ -792,7 +806,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
792
806
|
return DelayCondition(kind: kind, value: value)
|
|
793
807
|
}
|
|
794
808
|
if !delayConditionList.isEmpty {
|
|
795
|
-
|
|
809
|
+
self.logger.info("Update delayed until delay conditions met")
|
|
796
810
|
self.endBackGroundTaskWithNotif(msg: "Update delayed until delay conditions met", latestVersionName: latestVersionName, current: next, error: false)
|
|
797
811
|
return
|
|
798
812
|
}
|
|
@@ -806,13 +820,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
806
820
|
}
|
|
807
821
|
return
|
|
808
822
|
} catch {
|
|
809
|
-
|
|
823
|
+
self.logger.error("Error downloading file \(error.localizedDescription)")
|
|
810
824
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
811
825
|
self.endBackGroundTaskWithNotif(msg: "Error downloading file", latestVersionName: latestVersionName, current: current)
|
|
812
826
|
return
|
|
813
827
|
}
|
|
814
828
|
} else {
|
|
815
|
-
|
|
829
|
+
self.logger.info("No need to update, \(current.getId()) is the latest bundle.")
|
|
816
830
|
self.endBackGroundTaskWithNotif(msg: "No need to update, \(current.getId()) is the latest bundle.", latestVersionName: latestVersionName, current: current, error: false)
|
|
817
831
|
return
|
|
818
832
|
}
|
|
@@ -820,7 +834,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
820
834
|
}
|
|
821
835
|
|
|
822
836
|
@objc func appKilled() {
|
|
823
|
-
|
|
837
|
+
logger.info("onActivityDestroyed: all activity destroyed")
|
|
824
838
|
self.delayUpdateUtils.checkCancelDelay(source: .killed)
|
|
825
839
|
}
|
|
826
840
|
|
|
@@ -832,19 +846,19 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
832
846
|
return DelayCondition(kind: kind, value: value)
|
|
833
847
|
}
|
|
834
848
|
if !delayConditionList.isEmpty {
|
|
835
|
-
|
|
849
|
+
logger.info("Update delayed until delay conditions met")
|
|
836
850
|
return
|
|
837
851
|
}
|
|
838
852
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
839
853
|
let next: BundleInfo? = self.implementation.getNextBundle()
|
|
840
854
|
|
|
841
855
|
if next != nil && !next!.isErrorStatus() && next!.getVersionName() != current.getVersionName() {
|
|
842
|
-
|
|
856
|
+
logger.info("Next bundle is: \(next!.toString())")
|
|
843
857
|
if self.implementation.set(bundle: next!) && self._reload() {
|
|
844
|
-
|
|
858
|
+
logger.info("Updated to bundle: \(next!.toString())")
|
|
845
859
|
_ = self.implementation.setNextBundle(next: Optional<String>.none)
|
|
846
860
|
} else {
|
|
847
|
-
|
|
861
|
+
logger.error("Update to bundle: \(next!.toString()) Failed!")
|
|
848
862
|
}
|
|
849
863
|
}
|
|
850
864
|
}
|
|
@@ -874,12 +888,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
874
888
|
self.delayUpdateUtils.unsetBackgroundTimestamp()
|
|
875
889
|
if backgroundWork != nil && taskRunning {
|
|
876
890
|
backgroundWork!.cancel()
|
|
877
|
-
|
|
891
|
+
logger.info("Background Timer Task canceled, Activity resumed before timer completes")
|
|
878
892
|
}
|
|
879
893
|
if self._isAutoUpdateEnabled() {
|
|
880
894
|
self.backgroundDownload()
|
|
881
895
|
} else {
|
|
882
|
-
|
|
896
|
+
logger.info("Auto update is disabled")
|
|
883
897
|
self.sendReadyToJs(current: current, msg: "disabled")
|
|
884
898
|
}
|
|
885
899
|
self.checkAppReady()
|
|
@@ -890,7 +904,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
890
904
|
return
|
|
891
905
|
}
|
|
892
906
|
guard let url = URL(string: self.updateUrl) else {
|
|
893
|
-
|
|
907
|
+
logger.error("Error no url or wrong format")
|
|
894
908
|
return
|
|
895
909
|
}
|
|
896
910
|
let timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(periodCheckDelay), repeats: true) { _ in
|
|
@@ -899,7 +913,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
899
913
|
let current = self.implementation.getCurrentBundle()
|
|
900
914
|
|
|
901
915
|
if res.version != current.getVersionName() {
|
|
902
|
-
|
|
916
|
+
self.logger.info("New version found: \(res.version)")
|
|
903
917
|
self.backgroundDownload()
|
|
904
918
|
}
|
|
905
919
|
}
|
|
@@ -910,7 +924,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
910
924
|
@objc func appMovedToBackground() {
|
|
911
925
|
let current: BundleInfo = self.implementation.getCurrentBundle()
|
|
912
926
|
self.implementation.sendStats(action: "app_moved_to_background", versionName: current.getVersionName())
|
|
913
|
-
|
|
927
|
+
logger.info("Check for pending update")
|
|
914
928
|
|
|
915
929
|
// Set background timestamp
|
|
916
930
|
let backgroundTimestamp = Int64(Date().timeIntervalSince1970 * 1000) // Convert to milliseconds
|