@capgo/capacitor-updater 8.46.1 → 8.47.0
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 +178 -19
- package/android/src/main/java/ee/forgr/capacitor_updater/AndroidAppExitReporter.java +92 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +504 -115
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +239 -22
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +95 -3
- package/dist/docs.json +473 -0
- package/dist/esm/definitions.d.ts +241 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +4 -1
- package/dist/esm/web.js +30 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +30 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +30 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +376 -17
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +194 -8
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +2 -0
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +47 -3
- package/package.json +1 -1
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
package ee.forgr.capacitor_updater;
|
|
8
8
|
|
|
9
9
|
import android.app.Activity;
|
|
10
|
-
import android.app.
|
|
11
|
-
import android.app.ApplicationExitInfo;
|
|
10
|
+
import android.app.AlertDialog;
|
|
12
11
|
import android.content.Context;
|
|
13
12
|
import android.content.Intent;
|
|
14
13
|
import android.content.SharedPreferences;
|
|
@@ -87,6 +86,12 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
87
86
|
private static final String STATS_URL_PREF_KEY = "CapacitorUpdater.statsUrl";
|
|
88
87
|
private static final String CHANNEL_URL_PREF_KEY = "CapacitorUpdater.channelUrl";
|
|
89
88
|
private static final String DEFAULT_CHANNEL_PREF_KEY = "CapacitorUpdater.defaultChannel";
|
|
89
|
+
private static final String PREVIEW_SESSION_PREF_KEY = "CapacitorUpdater.previewSession";
|
|
90
|
+
private static final String PREVIEW_PREVIOUS_SHAKE_MENU_PREF_KEY = "CapacitorUpdater.previewPreviousShakeMenu";
|
|
91
|
+
private static final String PREVIEW_PREVIOUS_SHAKE_CHANNEL_SELECTOR_PREF_KEY = "CapacitorUpdater.previewPreviousShakeChannelSelector";
|
|
92
|
+
private static final String PREVIEW_PREVIOUS_NEXT_BUNDLE_PREF_KEY = "CapacitorUpdater.previewPreviousNextBundle";
|
|
93
|
+
private static final String PREVIEW_PREVIOUS_APP_ID_PREF_KEY = "CapacitorUpdater.previewPreviousAppId";
|
|
94
|
+
private static final String PREVIEW_APP_ID_PREF_KEY = "CapacitorUpdater.previewAppId";
|
|
90
95
|
private static final String[] BREAKING_EVENT_NAMES = { "breakingAvailable", "majorAvailable" };
|
|
91
96
|
private static final String LAST_FAILED_BUNDLE_PREF_KEY = "CapacitorUpdater.lastFailedBundle";
|
|
92
97
|
private static final String LAST_REPORTED_APP_EXIT_TIMESTAMP_PREF_KEY = "CapacitorUpdater.lastReportedAppExitTimestamp";
|
|
@@ -95,8 +100,20 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
95
100
|
private static final int SPLASH_SCREEN_RETRY_DELAY_MS = 100;
|
|
96
101
|
private static final int SPLASH_SCREEN_MAX_RETRIES = 20;
|
|
97
102
|
private static final long PENDING_BUNDLE_APP_READY_MIN_TIMEOUT_MS = 30000L;
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
static final int APPLICATION_EXIT_REASON_UNKNOWN = 0;
|
|
104
|
+
static final int APPLICATION_EXIT_REASON_EXIT_SELF = 1;
|
|
105
|
+
static final int APPLICATION_EXIT_REASON_SIGNALED = 2;
|
|
106
|
+
static final int APPLICATION_EXIT_REASON_LOW_MEMORY = 3;
|
|
107
|
+
static final int APPLICATION_EXIT_REASON_CRASH = 4;
|
|
108
|
+
static final int APPLICATION_EXIT_REASON_CRASH_NATIVE = 5;
|
|
109
|
+
static final int APPLICATION_EXIT_REASON_ANR = 6;
|
|
110
|
+
static final int APPLICATION_EXIT_REASON_INITIALIZATION_FAILURE = 7;
|
|
111
|
+
static final int APPLICATION_EXIT_REASON_PERMISSION_CHANGE = 8;
|
|
112
|
+
static final int APPLICATION_EXIT_REASON_EXCESSIVE_RESOURCE_USAGE = 9;
|
|
113
|
+
static final int APPLICATION_EXIT_REASON_USER_REQUESTED = 10;
|
|
114
|
+
static final int APPLICATION_EXIT_REASON_DEPENDENCY_DIED = 12;
|
|
115
|
+
|
|
116
|
+
private final String pluginVersion = "8.47.0";
|
|
100
117
|
private static final String DELAY_CONDITION_PREFERENCES = "";
|
|
101
118
|
|
|
102
119
|
private SharedPreferences.Editor editor;
|
|
@@ -126,7 +143,10 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
126
143
|
private volatile boolean onLaunchDirectUpdateUsed = false;
|
|
127
144
|
Boolean shakeMenuEnabled = false;
|
|
128
145
|
Boolean shakeChannelSelectorEnabled = false;
|
|
146
|
+
Boolean previewSessionEnabled = false;
|
|
147
|
+
private Boolean previewSessionAlertPending = false;
|
|
129
148
|
private Boolean allowManualBundleError = false;
|
|
149
|
+
private Boolean allowPreview = false;
|
|
130
150
|
Boolean allowSetDefaultChannel = true;
|
|
131
151
|
|
|
132
152
|
String getUpdateUrl() {
|
|
@@ -411,6 +431,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
411
431
|
"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"
|
|
412
432
|
);
|
|
413
433
|
}
|
|
434
|
+
this.allowPreview = this.getConfig().getBoolean("allowPreview", false);
|
|
414
435
|
logger.info("appId: " + implementation.appId);
|
|
415
436
|
|
|
416
437
|
this.persistCustomId = this.getConfig().getBoolean("persistCustomId", false);
|
|
@@ -499,12 +520,30 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
499
520
|
this.implementation.timeout = this.getConfig().getInt("responseTimeout", 20) * 1000;
|
|
500
521
|
this.shakeMenuEnabled = this.getConfig().getBoolean("shakeMenu", false);
|
|
501
522
|
this.shakeChannelSelectorEnabled = this.getConfig().getBoolean("allowShakeChannelSelector", false);
|
|
523
|
+
this.previewSessionEnabled = Boolean.TRUE.equals(this.allowPreview) && this.prefs.getBoolean(PREVIEW_SESSION_PREF_KEY, false);
|
|
524
|
+
if (!Boolean.TRUE.equals(this.allowPreview) && this.prefs.getBoolean(PREVIEW_SESSION_PREF_KEY, false)) {
|
|
525
|
+
this.clearPreviewSessionBecauseDisabled();
|
|
526
|
+
}
|
|
527
|
+
this.implementation.previewSession = Boolean.TRUE.equals(this.previewSessionEnabled);
|
|
528
|
+
if (Boolean.TRUE.equals(this.previewSessionEnabled)) {
|
|
529
|
+
final String previewAppId = this.prefs.getString(PREVIEW_APP_ID_PREF_KEY, "");
|
|
530
|
+
if (previewAppId != null && !previewAppId.isEmpty()) {
|
|
531
|
+
this.setActiveAppId(previewAppId);
|
|
532
|
+
logger.info("Using preview appId " + previewAppId);
|
|
533
|
+
}
|
|
534
|
+
this.shakeMenuEnabled = true;
|
|
535
|
+
this.shakeChannelSelectorEnabled = false;
|
|
536
|
+
}
|
|
502
537
|
boolean resetWhenUpdate = this.getConfig().getBoolean("resetWhenUpdate", true);
|
|
503
538
|
|
|
504
539
|
// Check if app was recently installed/updated BEFORE cleanupObsoleteVersions updates LatestVersionNative
|
|
505
540
|
this.wasRecentlyInstalledOrUpdated = this.checkIfRecentlyInstalledOrUpdated();
|
|
541
|
+
final boolean nativeBuildVersionChanged = this.hasNativeBuildVersionChanged();
|
|
506
542
|
|
|
507
543
|
this.implementation.autoReset(this.currentBuildVersion, resetWhenUpdate);
|
|
544
|
+
if (nativeBuildVersionChanged) {
|
|
545
|
+
this.clearPreviewSessionForNativeBuildChange();
|
|
546
|
+
}
|
|
508
547
|
this.reportPreviousAppExitReasons();
|
|
509
548
|
this.reportPreviousWebViewRenderProcessGone();
|
|
510
549
|
this.installWebViewStatsReporter();
|
|
@@ -850,66 +889,38 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
850
889
|
return false;
|
|
851
890
|
}
|
|
852
891
|
|
|
892
|
+
private boolean hasNativeBuildVersionChanged() {
|
|
893
|
+
final String lastKnownVersion = this.getStoredNativeBuildVersion();
|
|
894
|
+
return !lastKnownVersion.isEmpty() && !lastKnownVersion.equals(this.currentBuildVersion);
|
|
895
|
+
}
|
|
896
|
+
|
|
853
897
|
private void reportPreviousAppExitReasons() {
|
|
854
898
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || this.implementation == null || this.implementation.statsUrl.isEmpty()) {
|
|
855
899
|
return;
|
|
856
900
|
}
|
|
857
901
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
this.getContext().getPackageName(),
|
|
866
|
-
0,
|
|
867
|
-
8
|
|
868
|
-
);
|
|
869
|
-
if (exitReasons == null || exitReasons.isEmpty()) {
|
|
870
|
-
return;
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
final long lastReportedTimestamp = this.prefs.getLong(LAST_REPORTED_APP_EXIT_TIMESTAMP_PREF_KEY, 0L);
|
|
874
|
-
long newestReportedTimestamp = lastReportedTimestamp;
|
|
875
|
-
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
876
|
-
final String versionName = current == null ? "" : current.getVersionName();
|
|
877
|
-
|
|
878
|
-
for (final ApplicationExitInfo exitInfo : exitReasons) {
|
|
879
|
-
if (exitInfo == null || exitInfo.getTimestamp() <= lastReportedTimestamp) {
|
|
880
|
-
continue;
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
final String action = statsActionForApplicationExitReason(exitInfo.getReason());
|
|
884
|
-
if (action == null) {
|
|
885
|
-
continue;
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
this.implementation.sendStats(action, versionName, "", buildApplicationExitMetadata(exitInfo));
|
|
889
|
-
newestReportedTimestamp = Math.max(newestReportedTimestamp, exitInfo.getTimestamp());
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (newestReportedTimestamp > lastReportedTimestamp) {
|
|
893
|
-
this.prefs.edit().putLong(LAST_REPORTED_APP_EXIT_TIMESTAMP_PREF_KEY, newestReportedTimestamp).apply();
|
|
894
|
-
}
|
|
895
|
-
} catch (final Exception e) {
|
|
896
|
-
logger.warn("Unable to report previous app exit reason: " + e.getMessage());
|
|
897
|
-
}
|
|
902
|
+
AndroidAppExitReporter.reportPreviousAppExitReasons(
|
|
903
|
+
this.getContext(),
|
|
904
|
+
this.prefs,
|
|
905
|
+
this.implementation,
|
|
906
|
+
this.logger,
|
|
907
|
+
LAST_REPORTED_APP_EXIT_TIMESTAMP_PREF_KEY
|
|
908
|
+
);
|
|
898
909
|
}
|
|
899
910
|
|
|
900
911
|
static String statsActionForApplicationExitReason(final int reason) {
|
|
901
912
|
switch (reason) {
|
|
902
|
-
case
|
|
913
|
+
case APPLICATION_EXIT_REASON_CRASH:
|
|
903
914
|
return "app_crash";
|
|
904
|
-
case
|
|
915
|
+
case APPLICATION_EXIT_REASON_CRASH_NATIVE:
|
|
905
916
|
return "app_crash_native";
|
|
906
|
-
case
|
|
917
|
+
case APPLICATION_EXIT_REASON_ANR:
|
|
907
918
|
return "app_anr";
|
|
908
|
-
case
|
|
919
|
+
case APPLICATION_EXIT_REASON_LOW_MEMORY:
|
|
909
920
|
return "app_killed_low_memory";
|
|
910
|
-
case
|
|
921
|
+
case APPLICATION_EXIT_REASON_EXCESSIVE_RESOURCE_USAGE:
|
|
911
922
|
return "app_killed_excessive_resource_usage";
|
|
912
|
-
case
|
|
923
|
+
case APPLICATION_EXIT_REASON_INITIALIZATION_FAILURE:
|
|
913
924
|
return "app_initialization_failure";
|
|
914
925
|
default:
|
|
915
926
|
return null;
|
|
@@ -918,58 +929,34 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
918
929
|
|
|
919
930
|
static String applicationExitReasonName(final int reason) {
|
|
920
931
|
switch (reason) {
|
|
921
|
-
case
|
|
932
|
+
case APPLICATION_EXIT_REASON_EXIT_SELF:
|
|
922
933
|
return "exit_self";
|
|
923
|
-
case
|
|
934
|
+
case APPLICATION_EXIT_REASON_SIGNALED:
|
|
924
935
|
return "signaled";
|
|
925
|
-
case
|
|
936
|
+
case APPLICATION_EXIT_REASON_LOW_MEMORY:
|
|
926
937
|
return "low_memory";
|
|
927
|
-
case
|
|
938
|
+
case APPLICATION_EXIT_REASON_CRASH:
|
|
928
939
|
return "crash";
|
|
929
|
-
case
|
|
940
|
+
case APPLICATION_EXIT_REASON_CRASH_NATIVE:
|
|
930
941
|
return "crash_native";
|
|
931
|
-
case
|
|
942
|
+
case APPLICATION_EXIT_REASON_ANR:
|
|
932
943
|
return "anr";
|
|
933
|
-
case
|
|
944
|
+
case APPLICATION_EXIT_REASON_INITIALIZATION_FAILURE:
|
|
934
945
|
return "initialization_failure";
|
|
935
|
-
case
|
|
946
|
+
case APPLICATION_EXIT_REASON_PERMISSION_CHANGE:
|
|
936
947
|
return "permission_change";
|
|
937
|
-
case
|
|
948
|
+
case APPLICATION_EXIT_REASON_EXCESSIVE_RESOURCE_USAGE:
|
|
938
949
|
return "excessive_resource_usage";
|
|
939
|
-
case
|
|
950
|
+
case APPLICATION_EXIT_REASON_USER_REQUESTED:
|
|
940
951
|
return "user_requested";
|
|
941
|
-
case
|
|
952
|
+
case APPLICATION_EXIT_REASON_DEPENDENCY_DIED:
|
|
942
953
|
return "dependency_died";
|
|
943
954
|
default:
|
|
944
955
|
return "unknown";
|
|
945
956
|
}
|
|
946
957
|
}
|
|
947
958
|
|
|
948
|
-
|
|
949
|
-
final Map<String, String> metadata = new HashMap<>();
|
|
950
|
-
metadata.put("exit_reason", applicationExitReasonName(exitInfo.getReason()));
|
|
951
|
-
metadata.put("exit_reason_code", Integer.toString(exitInfo.getReason()));
|
|
952
|
-
metadata.put("exit_status", Integer.toString(exitInfo.getStatus()));
|
|
953
|
-
metadata.put("exit_importance", Integer.toString(exitInfo.getImportance()));
|
|
954
|
-
metadata.put("exit_timestamp", Long.toString(exitInfo.getTimestamp()));
|
|
955
|
-
metadata.put("pid", Integer.toString(exitInfo.getPid()));
|
|
956
|
-
metadata.put("pss_kb", Long.toString(exitInfo.getPss()));
|
|
957
|
-
metadata.put("rss_kb", Long.toString(exitInfo.getRss()));
|
|
958
|
-
|
|
959
|
-
final String processName = exitInfo.getProcessName();
|
|
960
|
-
if (processName != null && !processName.isEmpty()) {
|
|
961
|
-
metadata.put("process_name", truncateStatsMetadataValue(processName, 128));
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
final String description = exitInfo.getDescription();
|
|
965
|
-
if (description != null && !description.isEmpty()) {
|
|
966
|
-
metadata.put("exit_description", truncateStatsMetadataValue(description, 512));
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
return metadata;
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
private static String truncateStatsMetadataValue(final String value, final int maxLength) {
|
|
959
|
+
static String truncateStatsMetadataValue(final String value, final int maxLength) {
|
|
973
960
|
return value.length() <= maxLength ? value : value.substring(0, maxLength);
|
|
974
961
|
}
|
|
975
962
|
|
|
@@ -1104,6 +1091,19 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
1104
1091
|
return map;
|
|
1105
1092
|
}
|
|
1106
1093
|
|
|
1094
|
+
private static JSObject jsonObjectToJSObject(final JSONObject json) throws JSONException {
|
|
1095
|
+
final JSObject ret = new JSObject();
|
|
1096
|
+
final JSONArray names = json.names();
|
|
1097
|
+
if (names == null) {
|
|
1098
|
+
return ret;
|
|
1099
|
+
}
|
|
1100
|
+
for (int i = 0; i < names.length(); i++) {
|
|
1101
|
+
final String key = names.getString(i);
|
|
1102
|
+
ret.put(key, json.get(key));
|
|
1103
|
+
}
|
|
1104
|
+
return ret;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
1107
|
@PluginMethod
|
|
1108
1108
|
public void reportWebViewError(final PluginCall call) {
|
|
1109
1109
|
final JSObject data = call.getData();
|
|
@@ -2051,6 +2051,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2051
2051
|
}
|
|
2052
2052
|
this.notifyBundleSet(next);
|
|
2053
2053
|
this.implementation.setNextBundle(null);
|
|
2054
|
+
this.showPreviewSessionNoticeIfNeeded();
|
|
2054
2055
|
call.resolve();
|
|
2055
2056
|
return;
|
|
2056
2057
|
}
|
|
@@ -2062,6 +2063,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2062
2063
|
}
|
|
2063
2064
|
|
|
2064
2065
|
if (this._reload()) {
|
|
2066
|
+
this.showPreviewSessionNoticeIfNeeded();
|
|
2065
2067
|
call.resolve();
|
|
2066
2068
|
} else {
|
|
2067
2069
|
logger.error("Reload failed");
|
|
@@ -2116,6 +2118,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2116
2118
|
} else {
|
|
2117
2119
|
logger.info("Bundle successfully set to " + id);
|
|
2118
2120
|
this.notifyBundleSet(this.implementation.getBundleInfo(id));
|
|
2121
|
+
this.showPreviewSessionNoticeIfNeeded();
|
|
2119
2122
|
call.resolve();
|
|
2120
2123
|
}
|
|
2121
2124
|
} catch (final Exception e) {
|
|
@@ -2125,6 +2128,308 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2125
2128
|
});
|
|
2126
2129
|
}
|
|
2127
2130
|
|
|
2131
|
+
@PluginMethod
|
|
2132
|
+
public void startPreviewSession(final PluginCall call) {
|
|
2133
|
+
if (!Boolean.TRUE.equals(this.allowPreview)) {
|
|
2134
|
+
logger.error("startPreviewSession not allowed set allowPreview in your config to true to enable it");
|
|
2135
|
+
call.reject("startPreviewSession not allowed");
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
final String previewAppId = this.normalizePreviewAppId(call.getString("appId"));
|
|
2139
|
+
startNewThread(() -> {
|
|
2140
|
+
try {
|
|
2141
|
+
if (!Boolean.TRUE.equals(this.previewSessionEnabled)) {
|
|
2142
|
+
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
2143
|
+
if (!this.implementation.setPreviewFallbackBundle(current.getId())) {
|
|
2144
|
+
logger.error("Could not save current bundle as preview fallback");
|
|
2145
|
+
call.reject("Could not save current bundle as preview fallback");
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
final BundleInfo previousNext = this.implementation.getNextBundle();
|
|
2150
|
+
if (previousNext == null || previousNext.isDeleted() || previousNext.isErrorStatus()) {
|
|
2151
|
+
this.editor.remove(PREVIEW_PREVIOUS_NEXT_BUNDLE_PREF_KEY);
|
|
2152
|
+
} else {
|
|
2153
|
+
this.editor.putString(PREVIEW_PREVIOUS_NEXT_BUNDLE_PREF_KEY, previousNext.getId());
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
this.editor.putString(PREVIEW_PREVIOUS_APP_ID_PREF_KEY, this.implementation.appId);
|
|
2157
|
+
this.editor.putBoolean(PREVIEW_PREVIOUS_SHAKE_MENU_PREF_KEY, Boolean.TRUE.equals(this.shakeMenuEnabled));
|
|
2158
|
+
this.editor.putBoolean(
|
|
2159
|
+
PREVIEW_PREVIOUS_SHAKE_CHANNEL_SELECTOR_PREF_KEY,
|
|
2160
|
+
Boolean.TRUE.equals(this.shakeChannelSelectorEnabled)
|
|
2161
|
+
);
|
|
2162
|
+
logger.info("Preview session started with fallback bundle: " + current);
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
if (previewAppId != null) {
|
|
2166
|
+
this.setActiveAppId(previewAppId);
|
|
2167
|
+
this.editor.putString(PREVIEW_APP_ID_PREF_KEY, previewAppId);
|
|
2168
|
+
logger.info("Preview session using appId: " + previewAppId);
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
this.previewSessionEnabled = true;
|
|
2172
|
+
this.previewSessionAlertPending = true;
|
|
2173
|
+
this.implementation.previewSession = true;
|
|
2174
|
+
this.shakeMenuEnabled = true;
|
|
2175
|
+
this.shakeChannelSelectorEnabled = false;
|
|
2176
|
+
this.editor.putBoolean(PREVIEW_SESSION_PREF_KEY, true);
|
|
2177
|
+
this.editor.apply();
|
|
2178
|
+
this.ensureShakeMenuStarted();
|
|
2179
|
+
call.resolve();
|
|
2180
|
+
} catch (final Exception e) {
|
|
2181
|
+
logger.error("Could not start preview session " + e.getMessage());
|
|
2182
|
+
call.reject("Could not start preview session", e);
|
|
2183
|
+
}
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
public boolean leavePreviewSessionFromShakeMenu() {
|
|
2188
|
+
final BundleInfo previewBundle = this.implementation.getCurrentBundle();
|
|
2189
|
+
|
|
2190
|
+
final boolean didReset = this.resetToPreviewFallbackBundle();
|
|
2191
|
+
if (!didReset) {
|
|
2192
|
+
return false;
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
if (!this.clearPreviewChannelOverride()) {
|
|
2196
|
+
return false;
|
|
2197
|
+
}
|
|
2198
|
+
final BundleInfo previewFallbackBundle = this.implementation.getPreviewFallbackBundle();
|
|
2199
|
+
this.endPreviewSession();
|
|
2200
|
+
final BundleInfo restoredNextBundle = this.implementation.getNextBundle();
|
|
2201
|
+
if (
|
|
2202
|
+
!previewBundle.isBuiltin() &&
|
|
2203
|
+
(previewFallbackBundle == null || !previewBundle.getId().equals(previewFallbackBundle.getId())) &&
|
|
2204
|
+
(restoredNextBundle == null || !previewBundle.getId().equals(restoredNextBundle.getId()))
|
|
2205
|
+
) {
|
|
2206
|
+
try {
|
|
2207
|
+
this.implementation.delete(previewBundle.getId(), false);
|
|
2208
|
+
} catch (final Exception err) {
|
|
2209
|
+
logger.warn("Cannot delete preview bundle " + previewBundle.getId() + ": " + err.getMessage());
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
return true;
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
public boolean reloadPreviewSessionFromShakeMenu() {
|
|
2216
|
+
return this._reload();
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
public boolean hasActivePreviewSession() {
|
|
2220
|
+
return Boolean.TRUE.equals(this.previewSessionEnabled);
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
private boolean resetToPreviewFallbackBundle() {
|
|
2224
|
+
final BundleInfo fallback = this.implementation.getPreviewFallbackBundle();
|
|
2225
|
+
if (fallback == null || fallback.isErrorStatus()) {
|
|
2226
|
+
logger.error("No preview fallback bundle available");
|
|
2227
|
+
return false;
|
|
2228
|
+
}
|
|
2229
|
+
if (!this.implementation.canSet(fallback)) {
|
|
2230
|
+
logger.error("Preview fallback bundle is not installable");
|
|
2231
|
+
return false;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
final CapgoUpdater.ResetState previousState = this.implementation.captureResetState();
|
|
2235
|
+
final String previousBundleName = this.implementation.getCurrentBundle().getVersionName();
|
|
2236
|
+
logger.info("Resetting to preview fallback bundle: " + fallback.getVersionName());
|
|
2237
|
+
if (this.implementation.stagePreviewFallbackReload(fallback) && this._reload()) {
|
|
2238
|
+
this.implementation.finalizeResetTransition(previousBundleName, false);
|
|
2239
|
+
this.notifyBundleSet(fallback);
|
|
2240
|
+
return true;
|
|
2241
|
+
}
|
|
2242
|
+
this.implementation.restoreResetState(previousState);
|
|
2243
|
+
this.restoreLiveBundleStateAfterFailedReload();
|
|
2244
|
+
return false;
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
private void endPreviewSession() {
|
|
2248
|
+
final boolean previousShakeMenuEnabled = this.prefs.getBoolean(
|
|
2249
|
+
PREVIEW_PREVIOUS_SHAKE_MENU_PREF_KEY,
|
|
2250
|
+
this.getConfig().getBoolean("shakeMenu", false)
|
|
2251
|
+
);
|
|
2252
|
+
final boolean previousShakeChannelSelectorEnabled = this.prefs.getBoolean(
|
|
2253
|
+
PREVIEW_PREVIOUS_SHAKE_CHANNEL_SELECTOR_PREF_KEY,
|
|
2254
|
+
this.getConfig().getBoolean("allowShakeChannelSelector", false)
|
|
2255
|
+
);
|
|
2256
|
+
this.restorePreviewPreviousNextBundle();
|
|
2257
|
+
this.restorePreviewPreviousAppId();
|
|
2258
|
+
|
|
2259
|
+
this.previewSessionEnabled = false;
|
|
2260
|
+
this.previewSessionAlertPending = false;
|
|
2261
|
+
this.implementation.previewSession = false;
|
|
2262
|
+
this.shakeMenuEnabled = previousShakeMenuEnabled;
|
|
2263
|
+
this.shakeChannelSelectorEnabled = previousShakeChannelSelectorEnabled;
|
|
2264
|
+
this.implementation.setPreviewFallbackBundle(null);
|
|
2265
|
+
this.clearPreviewSessionPreferences();
|
|
2266
|
+
logger.info("Preview session ended");
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
private void clearPreviewSessionBecauseDisabled() {
|
|
2270
|
+
logger.info("Preview session disabled by config; restoring preview fallback");
|
|
2271
|
+
final BundleInfo fallback = this.implementation.getPreviewFallbackBundle();
|
|
2272
|
+
final BundleInfo bundleToRestore = fallback == null || fallback.isErrorStatus()
|
|
2273
|
+
? this.implementation.getBundleInfo(BundleInfo.ID_BUILTIN)
|
|
2274
|
+
: fallback;
|
|
2275
|
+
|
|
2276
|
+
if (this.implementation.canSet(bundleToRestore)) {
|
|
2277
|
+
this.implementation.stagePreviewFallbackReload(bundleToRestore);
|
|
2278
|
+
} else {
|
|
2279
|
+
logger.warn("Could not restore preview fallback while disabling preview");
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
this.restorePreviewPreviousNextBundle();
|
|
2283
|
+
this.restorePreviewPreviousAppId();
|
|
2284
|
+
this.previewSessionEnabled = false;
|
|
2285
|
+
this.previewSessionAlertPending = false;
|
|
2286
|
+
this.implementation.previewSession = false;
|
|
2287
|
+
this.shakeMenuEnabled = this.getConfig().getBoolean("shakeMenu", false);
|
|
2288
|
+
this.shakeChannelSelectorEnabled = this.getConfig().getBoolean("allowShakeChannelSelector", false);
|
|
2289
|
+
this.clearPreviewSessionPreferences();
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
private void clearPreviewSessionPreferences() {
|
|
2293
|
+
if (this.implementation != null) {
|
|
2294
|
+
this.implementation.setPreviewFallbackBundle(null);
|
|
2295
|
+
}
|
|
2296
|
+
this.editor.remove(PREVIEW_SESSION_PREF_KEY);
|
|
2297
|
+
this.editor.remove(PREVIEW_PREVIOUS_SHAKE_MENU_PREF_KEY);
|
|
2298
|
+
this.editor.remove(PREVIEW_PREVIOUS_SHAKE_CHANNEL_SELECTOR_PREF_KEY);
|
|
2299
|
+
this.editor.remove(PREVIEW_PREVIOUS_NEXT_BUNDLE_PREF_KEY);
|
|
2300
|
+
this.editor.remove(PREVIEW_PREVIOUS_APP_ID_PREF_KEY);
|
|
2301
|
+
this.editor.remove(PREVIEW_APP_ID_PREF_KEY);
|
|
2302
|
+
this.editor.apply();
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
private void setActiveAppId(final String appId) {
|
|
2306
|
+
this.implementation.appId = appId;
|
|
2307
|
+
if (this.implementation.versionOs != null) {
|
|
2308
|
+
DownloadService.updateUserAgent(this.implementation.appId, this.pluginVersion, this.implementation.versionOs);
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
private void restorePreviewPreviousAppId() {
|
|
2313
|
+
final String previousAppId = this.prefs.getString(PREVIEW_PREVIOUS_APP_ID_PREF_KEY, "");
|
|
2314
|
+
if (previousAppId == null || previousAppId.isEmpty()) {
|
|
2315
|
+
return;
|
|
2316
|
+
}
|
|
2317
|
+
this.setActiveAppId(previousAppId);
|
|
2318
|
+
logger.info("Restored appId after preview: " + previousAppId);
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
private String normalizePreviewAppId(final String rawAppId) {
|
|
2322
|
+
if (rawAppId == null) {
|
|
2323
|
+
return null;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
final String appId = rawAppId.trim();
|
|
2327
|
+
if (appId.isEmpty()) {
|
|
2328
|
+
return null;
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
final String lowercasedAppId = appId.toLowerCase(java.util.Locale.ROOT);
|
|
2332
|
+
if ("undefined".equals(lowercasedAppId) || "null".equals(lowercasedAppId)) {
|
|
2333
|
+
return null;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
return appId;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
private void clearPreviewSessionForNativeBuildChange() {
|
|
2340
|
+
if (!Boolean.TRUE.equals(this.previewSessionEnabled) && this.implementation.getPreviewFallbackBundle() == null) {
|
|
2341
|
+
return;
|
|
2342
|
+
}
|
|
2343
|
+
logger.info("Native build changed; clearing preview session state");
|
|
2344
|
+
this.previewSessionEnabled = false;
|
|
2345
|
+
this.previewSessionAlertPending = false;
|
|
2346
|
+
this.implementation.previewSession = false;
|
|
2347
|
+
this.shakeMenuEnabled = this.getConfig().getBoolean("shakeMenu", false);
|
|
2348
|
+
this.shakeChannelSelectorEnabled = this.getConfig().getBoolean("allowShakeChannelSelector", false);
|
|
2349
|
+
this.restorePreviewPreviousAppId();
|
|
2350
|
+
this.implementation.setPreviewFallbackBundle(null);
|
|
2351
|
+
this.implementation.setNextBundle(null);
|
|
2352
|
+
this.clearPreviewChannelOverride();
|
|
2353
|
+
this.clearPreviewSessionPreferences();
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
private boolean clearPreviewChannelOverride() {
|
|
2357
|
+
final String configDefaultChannel = this.getConfig().getString("defaultChannel", "");
|
|
2358
|
+
final AtomicReference<Map<String, Object>> unsetChannelResult = new AtomicReference<>();
|
|
2359
|
+
try {
|
|
2360
|
+
this.implementation.unsetChannel(this.editor, DEFAULT_CHANNEL_PREF_KEY, configDefaultChannel, unsetChannelResult::set);
|
|
2361
|
+
} catch (final Exception err) {
|
|
2362
|
+
logger.error("Could not clear preview channel override: " + err.getMessage());
|
|
2363
|
+
return false;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
final Map<String, Object> result = unsetChannelResult.get();
|
|
2367
|
+
if (result == null) {
|
|
2368
|
+
logger.error("Could not clear preview channel override: no result");
|
|
2369
|
+
return false;
|
|
2370
|
+
}
|
|
2371
|
+
if (result.containsKey("error")) {
|
|
2372
|
+
final Object message = result.getOrDefault("message", result.get("error"));
|
|
2373
|
+
logger.error("Could not clear preview channel override: " + message);
|
|
2374
|
+
return false;
|
|
2375
|
+
}
|
|
2376
|
+
return true;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
private void restorePreviewPreviousNextBundle() {
|
|
2380
|
+
final String previousNextBundleId = this.prefs.getString(PREVIEW_PREVIOUS_NEXT_BUNDLE_PREF_KEY, null);
|
|
2381
|
+
if (previousNextBundleId == null || previousNextBundleId.isEmpty()) {
|
|
2382
|
+
this.implementation.setNextBundle(null);
|
|
2383
|
+
return;
|
|
2384
|
+
}
|
|
2385
|
+
if (!this.implementation.setNextBundle(previousNextBundleId)) {
|
|
2386
|
+
logger.warn("Could not restore pre-preview next bundle: " + previousNextBundleId);
|
|
2387
|
+
this.implementation.setNextBundle(null);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
private void ensureShakeMenuStarted() {
|
|
2392
|
+
if (getActivity() instanceof com.getcapacitor.BridgeActivity && shakeMenu == null) {
|
|
2393
|
+
try {
|
|
2394
|
+
shakeMenu = new ShakeMenu(this, (com.getcapacitor.BridgeActivity) getActivity(), logger);
|
|
2395
|
+
logger.info("Shake menu initialized");
|
|
2396
|
+
} catch (Exception e) {
|
|
2397
|
+
logger.error("Failed to initialize shake menu: " + e.getMessage());
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
private void showPreviewSessionNoticeIfNeeded() {
|
|
2403
|
+
if (!Boolean.TRUE.equals(this.previewSessionEnabled) || !Boolean.TRUE.equals(this.previewSessionAlertPending)) {
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
this.previewSessionAlertPending = false;
|
|
2407
|
+
|
|
2408
|
+
new Handler(Looper.getMainLooper()).postDelayed(
|
|
2409
|
+
() -> {
|
|
2410
|
+
try {
|
|
2411
|
+
if (!Boolean.TRUE.equals(this.previewSessionEnabled)) {
|
|
2412
|
+
return;
|
|
2413
|
+
}
|
|
2414
|
+
if (getActivity() == null || getActivity().isFinishing()) {
|
|
2415
|
+
this.previewSessionAlertPending = true;
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
new AlertDialog.Builder(getActivity())
|
|
2420
|
+
.setTitle("Preview started")
|
|
2421
|
+
.setMessage("Shake your device anytime to reload or leave the test app.")
|
|
2422
|
+
.setPositiveButton("Got it", (dialog, which) -> dialog.dismiss())
|
|
2423
|
+
.show();
|
|
2424
|
+
} catch (final Exception e) {
|
|
2425
|
+
this.previewSessionAlertPending = true;
|
|
2426
|
+
logger.warn("Could not show preview session notice: " + e.getMessage());
|
|
2427
|
+
}
|
|
2428
|
+
},
|
|
2429
|
+
600
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2128
2433
|
@PluginMethod
|
|
2129
2434
|
public void delete(final PluginCall call) {
|
|
2130
2435
|
final String id = call.getString("id");
|
|
@@ -2206,37 +2511,121 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
2206
2511
|
@PluginMethod
|
|
2207
2512
|
public void getLatest(final PluginCall call) {
|
|
2208
2513
|
final String channel = call.getString("channel");
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
} else if (jsRes.has("message")) {
|
|
2231
|
-
String latestVersion = jsRes.has("version") ? jsRes.getString("version") : "";
|
|
2232
|
-
CapacitorUpdaterPlugin.this.notifyBreakingEventsIfNeeded(jsRes, latestVersion);
|
|
2233
|
-
call.reject(jsRes.getString("message"));
|
|
2234
|
-
return;
|
|
2514
|
+
final boolean includeBundleSize = call.getBoolean("includeBundleSize", false);
|
|
2515
|
+
final String previewAppId = this.normalizePreviewAppId(call.getString("appId"));
|
|
2516
|
+
final boolean hasPreviewAppId = previewAppId != null;
|
|
2517
|
+
if (hasPreviewAppId && !Boolean.TRUE.equals(this.allowPreview)) {
|
|
2518
|
+
logger.error("getLatest preview override not allowed set allowPreview in your config to true to enable it");
|
|
2519
|
+
call.reject("getLatest preview override not allowed");
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
final Callback latestCallback = (res) -> {
|
|
2524
|
+
JSObject jsRes = InternalUtils.mapToJSObject(res);
|
|
2525
|
+
if (jsRes.has("error") || jsRes.has("kind")) {
|
|
2526
|
+
String error = jsRes.has("error") ? jsRes.getString("error") : "";
|
|
2527
|
+
String errorMessage = jsRes.has("message") ? jsRes.getString("message") : "server did not provide a message";
|
|
2528
|
+
String kind = CapacitorUpdaterPlugin.this.getUpdateResponseKind(jsRes.has("kind") ? jsRes.getString("kind") : null);
|
|
2529
|
+
String latestVersion = jsRes.has("version") ? jsRes.getString("version") : "";
|
|
2530
|
+
jsRes.put("kind", kind);
|
|
2531
|
+
CapacitorUpdaterPlugin.this.notifyBreakingEventsIfNeeded(jsRes, latestVersion);
|
|
2532
|
+
if ("failed".equals(kind)) {
|
|
2533
|
+
logger.error("getLatest failed with error: " + error + ", message: " + errorMessage);
|
|
2534
|
+
call.reject(error.isEmpty() ? errorMessage : error);
|
|
2235
2535
|
} else {
|
|
2536
|
+
if (!jsRes.has("version") || jsRes.getString("version").isEmpty()) {
|
|
2537
|
+
jsRes.put("version", CapacitorUpdaterPlugin.this.implementation.getCurrentBundle().getVersionName());
|
|
2538
|
+
}
|
|
2539
|
+
logger.info("getLatest returned " + kind + ": " + errorMessage);
|
|
2236
2540
|
call.resolve(jsRes);
|
|
2237
2541
|
}
|
|
2238
|
-
|
|
2239
|
-
|
|
2542
|
+
return;
|
|
2543
|
+
} else if (jsRes.has("message")) {
|
|
2544
|
+
String latestVersion = jsRes.has("version") ? jsRes.getString("version") : "";
|
|
2545
|
+
CapacitorUpdaterPlugin.this.notifyBreakingEventsIfNeeded(jsRes, latestVersion);
|
|
2546
|
+
call.reject(jsRes.getString("message"));
|
|
2547
|
+
return;
|
|
2548
|
+
} else {
|
|
2549
|
+
if (includeBundleSize) {
|
|
2550
|
+
CapacitorUpdaterPlugin.this.attachBundleSize(jsRes);
|
|
2551
|
+
}
|
|
2552
|
+
call.resolve(jsRes);
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
|
|
2556
|
+
startNewThread(() -> {
|
|
2557
|
+
if (hasPreviewAppId) {
|
|
2558
|
+
CapacitorUpdaterPlugin.this.implementation.getLatest(
|
|
2559
|
+
CapacitorUpdaterPlugin.this.updateUrl,
|
|
2560
|
+
channel,
|
|
2561
|
+
previewAppId,
|
|
2562
|
+
latestCallback
|
|
2563
|
+
);
|
|
2564
|
+
return;
|
|
2565
|
+
}
|
|
2566
|
+
CapacitorUpdaterPlugin.this.implementation.getLatest(CapacitorUpdaterPlugin.this.updateUrl, channel, latestCallback);
|
|
2567
|
+
});
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
private void attachBundleSize(final JSObject latest) {
|
|
2571
|
+
try {
|
|
2572
|
+
final JSONArray manifest = latest.optJSONArray("manifest");
|
|
2573
|
+
if (manifest == null || manifest.length() == 0) {
|
|
2574
|
+
return;
|
|
2575
|
+
}
|
|
2576
|
+
final String sessionKey = latest.optString("sessionKey", "");
|
|
2577
|
+
final JSONObject missing = this.implementation.missingBundleFilesResult(manifest, sessionKey);
|
|
2578
|
+
final JSONArray missingManifest = missing.getJSONArray("missing");
|
|
2579
|
+
final JSONObject size = this.implementation.getBundleDownloadSize(
|
|
2580
|
+
this.updateUrl,
|
|
2581
|
+
latest.optString("version", ""),
|
|
2582
|
+
missingManifest
|
|
2583
|
+
);
|
|
2584
|
+
latest.put("missing", missing);
|
|
2585
|
+
latest.put("downloadSize", size);
|
|
2586
|
+
} catch (Exception e) {
|
|
2587
|
+
logger.error("Failed to attach bundle size to getLatest result");
|
|
2588
|
+
logger.debug("Error: " + e.getMessage());
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
@PluginMethod
|
|
2593
|
+
public void getMissingBundleFiles(final PluginCall call) {
|
|
2594
|
+
final JSONArray manifest = call.getData().optJSONArray("manifest");
|
|
2595
|
+
if (manifest == null) {
|
|
2596
|
+
call.reject("getMissingBundleFiles called without manifest");
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
2599
|
+
String sessionKey = call.getString("sessionKey");
|
|
2600
|
+
if (sessionKey == null) {
|
|
2601
|
+
sessionKey = "";
|
|
2602
|
+
}
|
|
2603
|
+
final String finalSessionKey = sessionKey;
|
|
2604
|
+
startNewThread(() -> {
|
|
2605
|
+
try {
|
|
2606
|
+
call.resolve(jsonObjectToJSObject(this.implementation.missingBundleFilesResult(manifest, finalSessionKey)));
|
|
2607
|
+
} catch (Exception e) {
|
|
2608
|
+
call.reject("Could not get missing bundle files", e);
|
|
2609
|
+
}
|
|
2610
|
+
});
|
|
2611
|
+
}
|
|
2612
|
+
|
|
2613
|
+
@PluginMethod
|
|
2614
|
+
public void getBundleDownloadSize(final PluginCall call) {
|
|
2615
|
+
final JSONArray manifest = call.getData().optJSONArray("manifest");
|
|
2616
|
+
if (manifest == null) {
|
|
2617
|
+
call.reject("getBundleDownloadSize called without manifest");
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
final String version = call.getData().optString("version", "");
|
|
2621
|
+
startNewThread(() -> {
|
|
2622
|
+
try {
|
|
2623
|
+
final JSONObject size = this.implementation.getBundleDownloadSize(this.updateUrl, version, manifest);
|
|
2624
|
+
call.resolve(jsonObjectToJSObject(size));
|
|
2625
|
+
} catch (Exception e) {
|
|
2626
|
+
call.reject("Could not get bundle download size", e);
|
|
2627
|
+
}
|
|
2628
|
+
});
|
|
2240
2629
|
}
|
|
2241
2630
|
|
|
2242
2631
|
public String triggerBackgroundUpdateCheck() {
|
|
@@ -3377,7 +3766,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
3377
3766
|
call.reject("setAppId called without appId");
|
|
3378
3767
|
return;
|
|
3379
3768
|
}
|
|
3380
|
-
this.
|
|
3769
|
+
this.setActiveAppId(appId);
|
|
3381
3770
|
call.resolve();
|
|
3382
3771
|
}
|
|
3383
3772
|
|