@capgo/capacitor-updater 8.52.0 → 8.52.1-beta.pr937.1951.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/CapgoCapacitorUpdater.podspec +2 -0
- package/Package.swift +5 -0
- package/README.md +2 -2
- package/android/build.gradle +89 -9
- package/android/consumer-rules.pro +15 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/AndroidAppExitReporter.java +32 -60
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1099 -5311
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoCore.java +67 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoCoreNative.java +97 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoDownloadWorker.java +188 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoEngine.java +114 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoEngineHolder.java +59 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoEngineHost.java +118 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +505 -3389
- package/android/src/main/java/ee/forgr/capacitor_updater/DeviceIdHelper.java +23 -6
- package/android/src/main/java/ee/forgr/capacitor_updater/EngineMethodLanes.java +168 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +6 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +217 -417
- package/android/src/main/java/ee/forgr/capacitor_updater/ThreeFingerPinchDetector.java +3 -1
- package/dist/docs.json +1 -1
- package/dist/esm/definitions.d.ts +3 -3
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin+AppStore.swift +171 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin+Methods.swift +168 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin+Overlays.swift +285 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin+WebView.swift +134 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +199 -5049
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoCore.swift +61 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoEngine.swift +319 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +367 -3734
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +63 -218
- package/ios/Sources/CapacitorUpdaterPlugin/WebViewStatsReporter.swift +5 -147
- package/package.json +22 -14
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +0 -246
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +0 -45
- package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +0 -13
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +0 -495
- package/android/src/main/java/ee/forgr/capacitor_updater/DataManager.java +0 -44
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +0 -56
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUntilNext.java +0 -14
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +0 -306
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +0 -1521
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +0 -258
- package/android/src/main/java/ee/forgr/capacitor_updater/InternalUtils.java +0 -45
- package/android/src/main/java/ee/forgr/capacitor_updater/Version.java +0 -306
- package/ios/Sources/CapacitorUpdaterPlugin/AES.swift +0 -210
- package/ios/Sources/CapacitorUpdaterPlugin/AppHealthTracker.swift +0 -82
- package/ios/Sources/CapacitorUpdaterPlugin/BundleInfo.swift +0 -185
- package/ios/Sources/CapacitorUpdaterPlugin/BundleStatus.swift +0 -127
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoRawRsa.swift +0 -36
- package/ios/Sources/CapacitorUpdaterPlugin/CryptoCipher.swift +0 -327
- package/ios/Sources/CapacitorUpdaterPlugin/DelayCondition.swift +0 -74
- package/ios/Sources/CapacitorUpdaterPlugin/DelayUntilNext.swift +0 -30
- package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +0 -231
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +0 -471
- package/ios/Sources/CapacitorUpdaterPlugin/RSA.swift +0 -96
- package/ios/Sources/CapacitorUpdaterPlugin/RedirectPolicyDelegate.swift +0 -53
- package/ios/Sources/CapacitorUpdaterPlugin/UserDefaultsExtension.swift +0 -46
- package/ios/Sources/CapacitorUpdaterPlugin/ZipArchiveReader.swift +0 -247
- package/ios/Sources/CapacitorUpdaterPlugin/ZipCentralDirectory.swift +0 -280
|
@@ -11,6 +11,8 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
13
|
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
# Shared Rust updater core (core/), built by scripts/build-core.sh ios.
|
|
15
|
+
s.vendored_frameworks = 'ios/Frameworks/CapgoUpdaterCore.xcframework'
|
|
14
16
|
s.ios.deployment_target = '15.0'
|
|
15
17
|
s.dependency 'Capacitor'
|
|
16
18
|
s.swift_version = '5.1'
|
package/Package.swift
CHANGED
|
@@ -13,9 +13,14 @@ let package = Package(
|
|
|
13
13
|
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
|
|
14
14
|
],
|
|
15
15
|
targets: [
|
|
16
|
+
// Shared Rust updater core (core/), built by scripts/build-core.sh ios.
|
|
17
|
+
.binaryTarget(
|
|
18
|
+
name: "CapgoUpdaterCore",
|
|
19
|
+
path: "ios/Frameworks/CapgoUpdaterCore.xcframework"),
|
|
16
20
|
.target(
|
|
17
21
|
name: "CapacitorUpdaterPlugin",
|
|
18
22
|
dependencies: [
|
|
23
|
+
"CapgoUpdaterCore",
|
|
19
24
|
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
20
25
|
.product(name: "Cordova", package: "capacitor-swift-pm")
|
|
21
26
|
],
|
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ First follow the migration guide of Capacitor:
|
|
|
86
86
|
|
|
87
87
|
The minimum iOS version is now **15.0** to match Capacitor 7/8 requirements.
|
|
88
88
|
|
|
89
|
-
The plugin has no third-party iOS dependencies besides Capacitor: ZIP extraction
|
|
89
|
+
The plugin has no third-party iOS dependencies besides Capacitor: the updater logic (downloads, ZIP extraction, decryption, checksums, bundle storage) runs in the shared Rust core, also used on Android, shipped prebuilt as `CapgoUpdaterCore.xcframework`. It has its own HTTPS client (rustls) that checks certificates against the system trust store.
|
|
90
90
|
|
|
91
91
|
## Compatibility
|
|
92
92
|
|
|
@@ -312,7 +312,7 @@ CapacitorUpdater can be configured with these options:
|
|
|
312
312
|
| Prop | Type | Description | Default | Since |
|
|
313
313
|
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------- |
|
|
314
314
|
| **`appReadyTimeout`** | <code>number</code> | Configure the number of milliseconds the native plugin should wait before considering an update 'failed'. Only available for Android and iOS. | <code>10000 // (10 seconds)</code> | |
|
|
315
|
-
| **`responseTimeout`** | <code>number</code> | Configure the number of seconds the native plugin should wait before considering an HTTP timeout. Applies to update checks and file downloads. On Android these are idle connect/read/write timeouts
|
|
315
|
+
| **`responseTimeout`** | <code>number</code> | Configure the number of seconds the native plugin should wait before considering an HTTP timeout. Applies to update checks, channel and statistics requests, and file downloads. On Android and iOS these are idle connect/read/write timeouts: they do not cap the total download time. Bundle and preview payload transfers always allow at least 60 seconds per read. Only available for Android and iOS. | <code>20 // (20 second)</code> | |
|
|
316
316
|
| **`autoDeleteFailed`** | <code>boolean</code> | Configure whether the plugin should use automatically delete failed bundles. Only available for Android and iOS. | <code>true</code> | |
|
|
317
317
|
| **`autoDeletePrevious`** | <code>boolean</code> | Configure whether the plugin should use automatically delete previous bundles after a successful update. Only available for Android and iOS. | <code>true</code> | |
|
|
318
318
|
| **`autoUpdate`** | <code>boolean \| 'always' \| 'off' \| 'atBackground' \| 'atInstall' \| 'onLaunch' \| 'onlyDownload'</code> | Configure how the plugin checks for, downloads, and applies live updates. The plugin checks for updates when the app moves to the foreground. When {@link periodCheckDelay} is greater than 0, it also checks on a repeating timer while the app stays open. Boolean values keep their existing behavior: - `true`: Same as `"atBackground"`. - `false`: Same as `"off"`. String values merge the previous Auto Update and Direct Update configuration: - `"off"`: Disable automatic update checks. - `"atBackground"`: Check and download automatically on each foreground check, then apply the update the next time the app moves to background. - `"atInstall"`: Apply immediately only after a fresh install or native app store update; otherwise use `"atBackground"` behavior. - `"onLaunch"`: Apply immediately only when the app is brought to the foreground from a killed state (cold start). After that first check, fall back to `"atBackground"` behavior. - `"always"`: Check on every foreground transition and apply immediately whenever an update is available. - `"onlyDownload"`: Check and download automatically, emit `updateAvailable`, and never set the next bundle or apply an update automatically. Instant apply modes (`"atInstall"`, `"onLaunch"`, `"always"`) apply while the user is waiting. Upload with `npx @capgo/cli@latest bundle upload --delta` so only changed files download. A full zip upload slows the user experience. These modes require `autoSplashscreen: true` and `@capacitor/splash-screen` installed with `launchAutoHide: false`. Only available for Android and iOS. | <code>true</code> | |
|
package/android/build.gradle
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
3
|
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
|
|
4
|
-
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
5
|
-
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
6
|
-
okhttpVersion = project.hasProperty('okhttpVersion') ? rootProject.ext.okhttpVersion : '4.12.0'
|
|
7
4
|
}
|
|
8
5
|
|
|
9
6
|
buildscript {
|
|
@@ -26,7 +23,7 @@ android {
|
|
|
26
23
|
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
|
|
27
24
|
versionCode 1
|
|
28
25
|
versionName "1.0"
|
|
29
|
-
|
|
26
|
+
consumerProguardFiles "consumer-rules.pro"
|
|
30
27
|
}
|
|
31
28
|
buildTypes {
|
|
32
29
|
release {
|
|
@@ -57,17 +54,100 @@ dependencies {
|
|
|
57
54
|
implementation "com.google.android.gms:play-services-tasks:18.4.1"
|
|
58
55
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
59
56
|
implementation project(':capacitor-android')
|
|
57
|
+
// BridgeActivity extends AppCompatActivity: the plugin needs AppCompat on its compile classpath.
|
|
60
58
|
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
61
59
|
// Play Core library for in-app updates
|
|
62
60
|
implementation 'com.google.android.play:app-update:2.1.0'
|
|
63
61
|
testImplementation "junit:junit:$junitVersion"
|
|
64
|
-
testImplementation
|
|
62
|
+
testImplementation "androidx.work:work-testing:$work_version"
|
|
63
|
+
testImplementation 'org.mockito:mockito-core:5.24.0'
|
|
65
64
|
testImplementation 'org.json:json:20250517'
|
|
66
65
|
testImplementation 'org.robolectric:robolectric:4.17'
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// JVM unit tests load the shared Rust core (../core) built for the host machine.
|
|
69
|
+
// The npm package does not ship core/, so app builds never run cargo; they use
|
|
70
|
+
// the prebuilt src/main/jniLibs from scripts/build-core.sh android.
|
|
71
|
+
def capgoCoreDir = file("../core")
|
|
72
|
+
|
|
73
|
+
// Some ld releases end the indirect symbol table of the host dylib on a 4-byte boundary and
|
|
74
|
+
// put the string table right after it; newer dyld refuses that ("mis-aligned LINKEDIT string
|
|
75
|
+
// pool"). Host test library only: move the string table to an 8-byte boundary and re-sign.
|
|
76
|
+
def alignMachOStringTable = { File dylib ->
|
|
77
|
+
def read = { java.nio.ByteBuffer.wrap(dylib.bytes).order(java.nio.ByteOrder.LITTLE_ENDIAN) }
|
|
78
|
+
def stringTableOffset = { java.nio.ByteBuffer buffer ->
|
|
79
|
+
int offset = 32
|
|
80
|
+
for (int index = 0; index < buffer.getInt(16); index++) {
|
|
81
|
+
if (buffer.getInt(offset) == 0x2) {
|
|
82
|
+
return offset
|
|
83
|
+
}
|
|
84
|
+
offset += buffer.getInt(offset + 4)
|
|
85
|
+
}
|
|
86
|
+
return -1
|
|
87
|
+
}
|
|
88
|
+
def buffer = read()
|
|
89
|
+
if (buffer.getInt(0) != (int) 0xfeedfacf) {
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
int symtab = stringTableOffset(buffer)
|
|
93
|
+
if (symtab < 0 || buffer.getInt(symtab + 16) % 8 == 0) {
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
def sign = { List<String> args ->
|
|
97
|
+
def process = (["codesign"] + args + [dylib.absolutePath]).execute()
|
|
98
|
+
process.waitForProcessOutput(System.out, System.err)
|
|
99
|
+
if (process.exitValue() != 0) {
|
|
100
|
+
throw new GradleException("codesign ${args} failed for ${dylib}")
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
sign(["--remove-signature"])
|
|
104
|
+
buffer = read()
|
|
105
|
+
int stroff = buffer.getInt(symtab + 16)
|
|
106
|
+
int pad = 8 - stroff % 8
|
|
107
|
+
byte[] original = buffer.array()
|
|
108
|
+
byte[] patched = new byte[original.length + pad]
|
|
109
|
+
System.arraycopy(original, 0, patched, 0, stroff)
|
|
110
|
+
System.arraycopy(original, stroff, patched, stroff + pad, original.length - stroff)
|
|
111
|
+
def out = java.nio.ByteBuffer.wrap(patched).order(java.nio.ByteOrder.LITTLE_ENDIAN)
|
|
112
|
+
out.putInt(symtab + 16, stroff + pad)
|
|
113
|
+
int offset = 32
|
|
114
|
+
for (int index = 0; index < out.getInt(16); index++) {
|
|
115
|
+
if (out.getInt(offset) == 0x19 && new String(patched, offset + 8, 10, "US-ASCII") == "__LINKEDIT") {
|
|
116
|
+
long filesize = out.getLong(offset + 48) + pad
|
|
117
|
+
out.putLong(offset + 48, filesize)
|
|
118
|
+
out.putLong(offset + 32, Math.max(out.getLong(offset + 32), (filesize + 0x3fff) & ~0x3fffL))
|
|
119
|
+
}
|
|
120
|
+
offset += out.getInt(offset + 4)
|
|
121
|
+
}
|
|
122
|
+
dylib.bytes = patched
|
|
123
|
+
sign(["-s", "-", "-f"])
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (capgoCoreDir.exists()) {
|
|
127
|
+
def capgoCoreHostLibDir = new File(capgoCoreDir, "target/host/release")
|
|
128
|
+
def buildCapgoCoreHost = tasks.register("buildCapgoCoreHost", Exec) {
|
|
129
|
+
description = "Builds the Capgo Rust core for the host JVM (unit tests)"
|
|
130
|
+
workingDir capgoCoreDir
|
|
131
|
+
def cargoHome = System.getenv("CARGO_HOME") ?: "${System.getProperty('user.home')}/.cargo"
|
|
132
|
+
def rustupCargo = new File(cargoHome, "bin/cargo")
|
|
133
|
+
executable rustupCargo.exists() ? rustupCargo.absolutePath : "cargo"
|
|
134
|
+
args "build", "--release", "--locked", "--features", "jni", "--target-dir", "target/host"
|
|
135
|
+
inputs.dir(new File(capgoCoreDir, "src"))
|
|
136
|
+
inputs.file(new File(capgoCoreDir, "Cargo.toml"))
|
|
137
|
+
inputs.file(new File(capgoCoreDir, "Cargo.lock"))
|
|
138
|
+
outputs.dir(capgoCoreHostLibDir)
|
|
139
|
+
doLast {
|
|
140
|
+
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
|
|
141
|
+
alignMachOStringTable(new File(capgoCoreHostLibDir, System.mapLibraryName("capgo_updater_core")))
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
tasks.withType(Test).configureEach {
|
|
146
|
+
dependsOn buildCapgoCoreHost
|
|
147
|
+
// Re-run the JVM tests whenever the core library changes.
|
|
148
|
+
inputs.files(buildCapgoCoreHost)
|
|
149
|
+
systemProperty "capgo.core.hostLibrary", new File(capgoCoreHostLibDir, System.mapLibraryName("capgo_updater_core")).absolutePath
|
|
150
|
+
}
|
|
71
151
|
}
|
|
72
152
|
|
|
73
153
|
tasks.withType(Test) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Applied to apps that use this plugin (consumerProguardFiles).
|
|
2
|
+
|
|
3
|
+
# The Rust core (JNI) binds its native methods by name and calls the host
|
|
4
|
+
# callbacks by name and signature. R8 cannot see those references.
|
|
5
|
+
-keepclasseswithmembernames,includedescriptorclasses class ee.forgr.capacitor_updater.CapgoCoreNative {
|
|
6
|
+
native <methods>;
|
|
7
|
+
}
|
|
8
|
+
-keep class ee.forgr.capacitor_updater.CapgoEngineHost { *; }
|
|
9
|
+
-keep class * extends ee.forgr.capacitor_updater.CapgoEngineHost { *; }
|
|
10
|
+
|
|
11
|
+
# WorkManager stores the worker class name with each queued download: keep it
|
|
12
|
+
# stable so jobs queued before an app update still run after it.
|
|
13
|
+
-keep class ee.forgr.capacitor_updater.CapgoDownloadWorker {
|
|
14
|
+
public <init>(android.content.Context, androidx.work.WorkerParameters);
|
|
15
|
+
}
|
|
@@ -10,83 +10,55 @@ import android.annotation.TargetApi;
|
|
|
10
10
|
import android.app.ActivityManager;
|
|
11
11
|
import android.app.ApplicationExitInfo;
|
|
12
12
|
import android.content.Context;
|
|
13
|
-
import android.content.SharedPreferences;
|
|
14
13
|
import android.os.Build;
|
|
15
|
-
import java.util.HashMap;
|
|
16
14
|
import java.util.List;
|
|
17
|
-
import
|
|
15
|
+
import org.json.JSONArray;
|
|
16
|
+
import org.json.JSONObject;
|
|
18
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Reads the previous process exits ({@link ApplicationExitInfo}, API 30+) for the engine, which reports the
|
|
20
|
+
* ones worth a statistic ({@code previousExits} of {@code pluginLoad}). Kept out of the plugin class so older
|
|
21
|
+
* Android versions never resolve {@link ApplicationExitInfo} while reflecting plugin methods.
|
|
22
|
+
*/
|
|
19
23
|
@TargetApi(Build.VERSION_CODES.R)
|
|
20
24
|
final class AndroidAppExitReporter {
|
|
21
25
|
|
|
26
|
+
private static final int MAX_EXITS = 8;
|
|
27
|
+
|
|
22
28
|
private AndroidAppExitReporter() {}
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
final
|
|
27
|
-
final CapgoUpdater implementation,
|
|
28
|
-
final Logger logger,
|
|
29
|
-
final String lastReportedAppExitTimestampPrefKey
|
|
30
|
-
) {
|
|
30
|
+
/** Newest first; empty when unavailable. */
|
|
31
|
+
static JSONArray previousExits(final Context context, final Logger logger) {
|
|
32
|
+
final JSONArray exits = new JSONArray();
|
|
31
33
|
try {
|
|
32
34
|
final ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
33
35
|
if (activityManager == null) {
|
|
34
|
-
return;
|
|
36
|
+
return exits;
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return;
|
|
38
|
+
final List<ApplicationExitInfo> infos = activityManager.getHistoricalProcessExitReasons(context.getPackageName(), 0, MAX_EXITS);
|
|
39
|
+
if (infos == null) {
|
|
40
|
+
return exits;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
long newestReportedTimestamp = lastReportedTimestamp;
|
|
44
|
-
final BundleInfo current = implementation.getCurrentBundle();
|
|
45
|
-
final String versionName = current == null ? "" : current.getVersionName();
|
|
46
|
-
|
|
47
|
-
for (final ApplicationExitInfo exitInfo : exitReasons) {
|
|
48
|
-
if (exitInfo == null || exitInfo.getTimestamp() <= lastReportedTimestamp) {
|
|
42
|
+
for (final ApplicationExitInfo info : infos) {
|
|
43
|
+
if (info == null) {
|
|
49
44
|
continue;
|
|
50
45
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
46
|
+
exits.put(
|
|
47
|
+
new JSONObject()
|
|
48
|
+
.put("reason", info.getReason())
|
|
49
|
+
.put("status", info.getStatus())
|
|
50
|
+
.put("importance", info.getImportance())
|
|
51
|
+
.put("timestamp", info.getTimestamp())
|
|
52
|
+
.put("pid", info.getPid())
|
|
53
|
+
.put("pss", info.getPss())
|
|
54
|
+
.put("rss", info.getRss())
|
|
55
|
+
.put("processName", info.getProcessName() == null ? "" : info.getProcessName())
|
|
56
|
+
.put("description", info.getDescription() == null ? "" : info.getDescription())
|
|
57
|
+
);
|
|
63
58
|
}
|
|
64
59
|
} catch (final Exception e) {
|
|
65
|
-
logger.warn("Unable to
|
|
60
|
+
logger.warn("Unable to read previous app exit reasons: " + e.getMessage());
|
|
66
61
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
private static Map<String, String> buildApplicationExitMetadata(final ApplicationExitInfo exitInfo) {
|
|
70
|
-
final Map<String, String> metadata = new HashMap<>();
|
|
71
|
-
metadata.put("exit_reason", CapacitorUpdaterPlugin.applicationExitReasonName(exitInfo.getReason()));
|
|
72
|
-
metadata.put("exit_reason_code", Integer.toString(exitInfo.getReason()));
|
|
73
|
-
metadata.put("exit_status", Integer.toString(exitInfo.getStatus()));
|
|
74
|
-
metadata.put("exit_importance", Integer.toString(exitInfo.getImportance()));
|
|
75
|
-
metadata.put("exit_timestamp", Long.toString(exitInfo.getTimestamp()));
|
|
76
|
-
metadata.put("pid", Integer.toString(exitInfo.getPid()));
|
|
77
|
-
metadata.put("pss_kb", Long.toString(exitInfo.getPss()));
|
|
78
|
-
metadata.put("rss_kb", Long.toString(exitInfo.getRss()));
|
|
79
|
-
|
|
80
|
-
final String processName = exitInfo.getProcessName();
|
|
81
|
-
if (processName != null && !processName.isEmpty()) {
|
|
82
|
-
metadata.put("process_name", CapacitorUpdaterPlugin.truncateStatsMetadataValue(processName, 128));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
final String description = exitInfo.getDescription();
|
|
86
|
-
if (description != null && !description.isEmpty()) {
|
|
87
|
-
metadata.put("exit_description", CapacitorUpdaterPlugin.truncateStatsMetadataValue(description, 512));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return metadata;
|
|
62
|
+
return exits;
|
|
91
63
|
}
|
|
92
64
|
}
|