@capgo/capacitor-updater 6.14.0 → 6.14.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 +11 -11
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +134 -194
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +23 -23
- package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +1 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +960 -1165
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1259 -1629
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +161 -197
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipherV2.java +202 -256
- package/android/src/main/java/ee/forgr/capacitor_updater/DataManager.java +16 -16
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +44 -48
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUntilNext.java +4 -4
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +378 -467
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +71 -83
- package/android/src/main/java/ee/forgr/capacitor_updater/InternalUtils.java +19 -28
- package/dist/docs.json +17 -17
- package/dist/esm/definitions.d.ts +13 -13
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +2 -2
- package/dist/esm/web.js +43 -43
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +43 -43
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +43 -43
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/CapacitorUpdater.swift +8 -8
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +1 -1
- package/package.json +5 -7
|
@@ -53,1732 +53,1362 @@ import org.json.JSONException;
|
|
|
53
53
|
@CapacitorPlugin(name = "CapacitorUpdater")
|
|
54
54
|
public class CapacitorUpdaterPlugin extends Plugin {
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
"https://plugin.capgo.app/
|
|
58
|
-
|
|
59
|
-
"https://plugin.capgo.app/stats";
|
|
60
|
-
private static final String channelUrlDefault =
|
|
61
|
-
"https://plugin.capgo.app/channel_self";
|
|
62
|
-
|
|
63
|
-
private final String PLUGIN_VERSION = "6.14.0";
|
|
64
|
-
private static final String DELAY_CONDITION_PREFERENCES = "";
|
|
65
|
-
|
|
66
|
-
private SharedPreferences.Editor editor;
|
|
67
|
-
private SharedPreferences prefs;
|
|
68
|
-
protected CapacitorUpdater implementation;
|
|
69
|
-
|
|
70
|
-
private Integer appReadyTimeout = 10000;
|
|
71
|
-
private Integer counterActivityCreate = 0;
|
|
72
|
-
private Integer periodCheckDelay = 0;
|
|
73
|
-
private Boolean autoDeleteFailed = true;
|
|
74
|
-
private Boolean autoDeletePrevious = true;
|
|
75
|
-
private Boolean autoUpdate = false;
|
|
76
|
-
private String updateUrl = "";
|
|
77
|
-
private Version currentVersionNative;
|
|
78
|
-
private Thread backgroundTask;
|
|
79
|
-
private Boolean taskRunning = false;
|
|
80
|
-
private Boolean keepUrlPathAfterReload = false;
|
|
81
|
-
|
|
82
|
-
private Boolean isPreviousMainActivity = true;
|
|
83
|
-
|
|
84
|
-
private volatile Thread backgroundDownloadTask;
|
|
85
|
-
private volatile Thread appReadyCheck;
|
|
86
|
-
|
|
87
|
-
// private static final CountDownLatch semaphoreReady = new CountDownLatch(1);
|
|
88
|
-
private static final Phaser semaphoreReady = new Phaser(1);
|
|
89
|
-
|
|
90
|
-
private int lastNotifiedStatPercent = 0;
|
|
91
|
-
|
|
92
|
-
public Thread startNewThread(final Runnable function, Number waitTime) {
|
|
93
|
-
Thread bgTask = new Thread(() -> {
|
|
94
|
-
try {
|
|
95
|
-
if (waitTime.longValue() > 0) {
|
|
96
|
-
Thread.sleep(waitTime.longValue());
|
|
97
|
-
}
|
|
98
|
-
function.run();
|
|
99
|
-
} catch (Exception e) {
|
|
100
|
-
e.printStackTrace();
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
bgTask.start();
|
|
104
|
-
return bgTask;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
public Thread startNewThread(final Runnable function) {
|
|
108
|
-
return startNewThread(function, 0);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
@Override
|
|
112
|
-
public void load() {
|
|
113
|
-
super.load();
|
|
114
|
-
this.counterActivityCreate++;
|
|
115
|
-
this.prefs = this.getContext()
|
|
116
|
-
.getSharedPreferences(WebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
117
|
-
this.editor = this.prefs.edit();
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
this.implementation = new CapacitorUpdater() {
|
|
121
|
-
@Override
|
|
122
|
-
public void notifyDownload(final String id, final int percent) {
|
|
123
|
-
CapacitorUpdaterPlugin.this.notifyDownload(id, percent);
|
|
124
|
-
}
|
|
56
|
+
private static final String updateUrlDefault = "https://plugin.capgo.app/updates";
|
|
57
|
+
private static final String statsUrlDefault = "https://plugin.capgo.app/stats";
|
|
58
|
+
private static final String channelUrlDefault = "https://plugin.capgo.app/channel_self";
|
|
125
59
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
60
|
+
private final String PLUGIN_VERSION = "6.14.3";
|
|
61
|
+
private static final String DELAY_CONDITION_PREFERENCES = "";
|
|
62
|
+
|
|
63
|
+
private SharedPreferences.Editor editor;
|
|
64
|
+
private SharedPreferences prefs;
|
|
65
|
+
protected CapacitorUpdater implementation;
|
|
66
|
+
|
|
67
|
+
private Integer appReadyTimeout = 10000;
|
|
68
|
+
private Integer counterActivityCreate = 0;
|
|
69
|
+
private Integer periodCheckDelay = 0;
|
|
70
|
+
private Boolean autoDeleteFailed = true;
|
|
71
|
+
private Boolean autoDeletePrevious = true;
|
|
72
|
+
private Boolean autoUpdate = false;
|
|
73
|
+
private String updateUrl = "";
|
|
74
|
+
private Version currentVersionNative;
|
|
75
|
+
private Thread backgroundTask;
|
|
76
|
+
private Boolean taskRunning = false;
|
|
77
|
+
private Boolean keepUrlPathAfterReload = false;
|
|
78
|
+
|
|
79
|
+
private Boolean isPreviousMainActivity = true;
|
|
80
|
+
|
|
81
|
+
private volatile Thread backgroundDownloadTask;
|
|
82
|
+
private volatile Thread appReadyCheck;
|
|
83
|
+
|
|
84
|
+
// private static final CountDownLatch semaphoreReady = new CountDownLatch(1);
|
|
85
|
+
private static final Phaser semaphoreReady = new Phaser(1);
|
|
86
|
+
|
|
87
|
+
private int lastNotifiedStatPercent = 0;
|
|
88
|
+
|
|
89
|
+
public Thread startNewThread(final Runnable function, Number waitTime) {
|
|
90
|
+
Thread bgTask = new Thread(() -> {
|
|
91
|
+
try {
|
|
92
|
+
if (waitTime.longValue() > 0) {
|
|
93
|
+
Thread.sleep(waitTime.longValue());
|
|
94
|
+
}
|
|
95
|
+
function.run();
|
|
96
|
+
} catch (Exception e) {
|
|
97
|
+
e.printStackTrace();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
bgTask.start();
|
|
101
|
+
return bgTask;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public Thread startNewThread(final Runnable function) {
|
|
105
|
+
return startNewThread(function, 0);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@Override
|
|
109
|
+
public void load() {
|
|
110
|
+
super.load();
|
|
111
|
+
this.counterActivityCreate++;
|
|
112
|
+
this.prefs = this.getContext().getSharedPreferences(WebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
113
|
+
this.editor = this.prefs.edit();
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
this.implementation = new CapacitorUpdater() {
|
|
117
|
+
@Override
|
|
118
|
+
public void notifyDownload(final String id, final int percent) {
|
|
119
|
+
CapacitorUpdaterPlugin.this.notifyDownload(id, percent);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@Override
|
|
123
|
+
public void directUpdateFinish(final BundleInfo latest) {
|
|
124
|
+
CapacitorUpdaterPlugin.this.directUpdateFinish(latest);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@Override
|
|
128
|
+
public void notifyListeners(final String id, final JSObject res) {
|
|
129
|
+
CapacitorUpdaterPlugin.this.notifyListeners(id, res);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
final PackageInfo pInfo = this.getContext().getPackageManager().getPackageInfo(this.getContext().getPackageName(), 0);
|
|
133
|
+
this.implementation.activity = this.getActivity();
|
|
134
|
+
this.implementation.versionBuild = this.getConfig().getString("version", pInfo.versionName);
|
|
135
|
+
this.implementation.PLUGIN_VERSION = this.PLUGIN_VERSION;
|
|
136
|
+
this.implementation.versionCode = Integer.toString(pInfo.versionCode);
|
|
137
|
+
this.implementation.client = new OkHttpClient.Builder()
|
|
138
|
+
.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1))
|
|
139
|
+
.connectTimeout(this.implementation.timeout, TimeUnit.MILLISECONDS)
|
|
140
|
+
.readTimeout(this.implementation.timeout, TimeUnit.MILLISECONDS)
|
|
141
|
+
.writeTimeout(this.implementation.timeout, TimeUnit.MILLISECONDS)
|
|
142
|
+
.build();
|
|
143
|
+
|
|
144
|
+
this.implementation.directUpdate = this.getConfig().getBoolean("directUpdate", false);
|
|
145
|
+
this.currentVersionNative = new Version(this.getConfig().getString("version", pInfo.versionName));
|
|
146
|
+
} catch (final PackageManager.NameNotFoundException e) {
|
|
147
|
+
Log.e(CapacitorUpdater.TAG, "Error instantiating implementation", e);
|
|
148
|
+
return;
|
|
149
|
+
} catch (final Exception e) {
|
|
150
|
+
Log.e(CapacitorUpdater.TAG, "Error getting current native app version", e);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
final CapConfig config = CapConfig.loadDefault(this.getActivity());
|
|
154
|
+
this.implementation.appId = InternalUtils.getPackageName(getContext().getPackageManager(), getContext().getPackageName());
|
|
155
|
+
this.implementation.appId = config.getString("appId", this.implementation.appId);
|
|
156
|
+
this.implementation.appId = this.getConfig().getString("appId", this.implementation.appId);
|
|
157
|
+
if (this.implementation.appId == null || this.implementation.appId.isEmpty()) {
|
|
158
|
+
// crash the app
|
|
159
|
+
throw new RuntimeException(
|
|
160
|
+
"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"
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
Log.i(CapacitorUpdater.TAG, "appId: " + implementation.appId);
|
|
164
|
+
this.implementation.publicKey = this.getConfig().getString("publicKey", "");
|
|
165
|
+
this.implementation.privateKey = this.getConfig().getString("privateKey", "");
|
|
166
|
+
if (this.implementation.privateKey != null && !this.implementation.privateKey.isEmpty()) {
|
|
167
|
+
this.implementation.hasOldPrivateKeyPropertyInConfig = true;
|
|
168
|
+
}
|
|
169
|
+
this.implementation.statsUrl = this.getConfig().getString("statsUrl", statsUrlDefault);
|
|
170
|
+
this.implementation.channelUrl = this.getConfig().getString("channelUrl", channelUrlDefault);
|
|
171
|
+
int userValue = this.getConfig().getInt("periodCheckDelay", 0);
|
|
172
|
+
this.implementation.defaultChannel = this.getConfig().getString("defaultChannel", "");
|
|
173
|
+
|
|
174
|
+
if (userValue >= 0 && userValue <= 600) {
|
|
175
|
+
this.periodCheckDelay = 600 * 1000;
|
|
176
|
+
} else if (userValue > 600) {
|
|
177
|
+
this.periodCheckDelay = userValue * 1000;
|
|
129
178
|
}
|
|
130
179
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
this.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
.getString("
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
.
|
|
147
|
-
.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
.
|
|
154
|
-
this.currentVersionNative = new Version(
|
|
155
|
-
this.getConfig().getString("version", pInfo.versionName)
|
|
156
|
-
);
|
|
157
|
-
} catch (final PackageManager.NameNotFoundException e) {
|
|
158
|
-
Log.e(CapacitorUpdater.TAG, "Error instantiating implementation", e);
|
|
159
|
-
return;
|
|
160
|
-
} catch (final Exception e) {
|
|
161
|
-
Log.e(
|
|
162
|
-
CapacitorUpdater.TAG,
|
|
163
|
-
"Error getting current native app version",
|
|
164
|
-
e
|
|
165
|
-
);
|
|
166
|
-
return;
|
|
180
|
+
this.implementation.documentsDir = this.getContext().getFilesDir();
|
|
181
|
+
this.implementation.prefs = this.prefs;
|
|
182
|
+
this.implementation.editor = this.editor;
|
|
183
|
+
this.implementation.versionOs = Build.VERSION.RELEASE;
|
|
184
|
+
this.implementation.deviceID = this.prefs.getString("appUUID", UUID.randomUUID().toString()).toLowerCase();
|
|
185
|
+
this.editor.putString("appUUID", this.implementation.deviceID);
|
|
186
|
+
this.editor.commit();
|
|
187
|
+
Log.i(CapacitorUpdater.TAG, "init for device " + this.implementation.deviceID);
|
|
188
|
+
Log.i(CapacitorUpdater.TAG, "version native " + this.currentVersionNative.getOriginalString());
|
|
189
|
+
this.autoDeleteFailed = this.getConfig().getBoolean("autoDeleteFailed", true);
|
|
190
|
+
this.autoDeletePrevious = this.getConfig().getBoolean("autoDeletePrevious", true);
|
|
191
|
+
this.updateUrl = this.getConfig().getString("updateUrl", updateUrlDefault);
|
|
192
|
+
this.autoUpdate = this.getConfig().getBoolean("autoUpdate", true);
|
|
193
|
+
this.appReadyTimeout = this.getConfig().getInt("appReadyTimeout", 10000);
|
|
194
|
+
this.keepUrlPathAfterReload = this.getConfig().getBoolean("keepUrlPathAfterReload", false);
|
|
195
|
+
this.implementation.timeout = this.getConfig().getInt("responseTimeout", 20) * 1000;
|
|
196
|
+
boolean resetWhenUpdate = this.getConfig().getBoolean("resetWhenUpdate", true);
|
|
197
|
+
|
|
198
|
+
this.implementation.autoReset();
|
|
199
|
+
if (resetWhenUpdate) {
|
|
200
|
+
this.cleanupObsoleteVersions();
|
|
201
|
+
}
|
|
202
|
+
this.checkForUpdateAfterDelay();
|
|
167
203
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// crash the app
|
|
183
|
-
throw new RuntimeException(
|
|
184
|
-
"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"
|
|
185
|
-
);
|
|
204
|
+
|
|
205
|
+
private void semaphoreWait(Number waitTime) {
|
|
206
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreWait " + waitTime);
|
|
207
|
+
try {
|
|
208
|
+
// Log.i(CapacitorUpdater.TAG, "semaphoreReady count " + CapacitorUpdaterPlugin.this.semaphoreReady.getCount());
|
|
209
|
+
semaphoreReady.awaitAdvanceInterruptibly(semaphoreReady.getPhase(), waitTime.longValue(), TimeUnit.SECONDS);
|
|
210
|
+
// Log.i(CapacitorUpdater.TAG, "semaphoreReady await " + res);
|
|
211
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreReady count " + semaphoreReady.getPhase());
|
|
212
|
+
} catch (InterruptedException e) {
|
|
213
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreWait InterruptedException");
|
|
214
|
+
e.printStackTrace();
|
|
215
|
+
} catch (TimeoutException e) {
|
|
216
|
+
throw new RuntimeException(e);
|
|
217
|
+
}
|
|
186
218
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (
|
|
192
|
-
this.implementation.privateKey != null &&
|
|
193
|
-
!this.implementation.privateKey.isEmpty()
|
|
194
|
-
) {
|
|
195
|
-
this.implementation.hasOldPrivateKeyPropertyInConfig = true;
|
|
219
|
+
|
|
220
|
+
private void semaphoreUp() {
|
|
221
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreUp");
|
|
222
|
+
semaphoreReady.register();
|
|
196
223
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
this.implementation.defaultChannel = this.getConfig()
|
|
203
|
-
.getString("defaultChannel", "");
|
|
204
|
-
|
|
205
|
-
if (userValue >= 0 && userValue <= 600) {
|
|
206
|
-
this.periodCheckDelay = 600 * 1000;
|
|
207
|
-
} else if (userValue > 600) {
|
|
208
|
-
this.periodCheckDelay = userValue * 1000;
|
|
224
|
+
|
|
225
|
+
private void semaphoreDown() {
|
|
226
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreDown");
|
|
227
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreDown count " + semaphoreReady.getPhase());
|
|
228
|
+
semaphoreReady.arriveAndDeregister();
|
|
209
229
|
}
|
|
210
230
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
CapacitorUpdater.TAG,
|
|
223
|
-
"init for device " + this.implementation.deviceID
|
|
224
|
-
);
|
|
225
|
-
Log.i(
|
|
226
|
-
CapacitorUpdater.TAG,
|
|
227
|
-
"version native " + this.currentVersionNative.getOriginalString()
|
|
228
|
-
);
|
|
229
|
-
this.autoDeleteFailed = this.getConfig()
|
|
230
|
-
.getBoolean("autoDeleteFailed", true);
|
|
231
|
-
this.autoDeletePrevious = this.getConfig()
|
|
232
|
-
.getBoolean("autoDeletePrevious", true);
|
|
233
|
-
this.updateUrl = this.getConfig().getString("updateUrl", updateUrlDefault);
|
|
234
|
-
this.autoUpdate = this.getConfig().getBoolean("autoUpdate", true);
|
|
235
|
-
this.appReadyTimeout = this.getConfig().getInt("appReadyTimeout", 10000);
|
|
236
|
-
this.keepUrlPathAfterReload = this.getConfig()
|
|
237
|
-
.getBoolean("keepUrlPathAfterReload", false);
|
|
238
|
-
this.implementation.timeout =
|
|
239
|
-
this.getConfig().getInt("responseTimeout", 20) * 1000;
|
|
240
|
-
boolean resetWhenUpdate =
|
|
241
|
-
this.getConfig().getBoolean("resetWhenUpdate", true);
|
|
242
|
-
|
|
243
|
-
this.implementation.autoReset();
|
|
244
|
-
if (resetWhenUpdate) {
|
|
245
|
-
this.cleanupObsoleteVersions();
|
|
231
|
+
private void sendReadyToJs(final BundleInfo current, final String msg) {
|
|
232
|
+
Log.i(CapacitorUpdater.TAG, "sendReadyToJs");
|
|
233
|
+
final JSObject ret = new JSObject();
|
|
234
|
+
ret.put("bundle", current.toJSON());
|
|
235
|
+
ret.put("status", msg);
|
|
236
|
+
startNewThread(() -> {
|
|
237
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreReady sendReadyToJs");
|
|
238
|
+
semaphoreWait(CapacitorUpdaterPlugin.this.appReadyTimeout);
|
|
239
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreReady sendReadyToJs done");
|
|
240
|
+
CapacitorUpdaterPlugin.this.notifyListeners("appReady", ret);
|
|
241
|
+
});
|
|
246
242
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
try {
|
|
253
|
-
// Log.i(CapacitorUpdater.TAG, "semaphoreReady count " + CapacitorUpdaterPlugin.this.semaphoreReady.getCount());
|
|
254
|
-
semaphoreReady.awaitAdvanceInterruptibly(
|
|
255
|
-
semaphoreReady.getPhase(),
|
|
256
|
-
waitTime.longValue(),
|
|
257
|
-
TimeUnit.SECONDS
|
|
258
|
-
);
|
|
259
|
-
// Log.i(CapacitorUpdater.TAG, "semaphoreReady await " + res);
|
|
260
|
-
Log.i(
|
|
261
|
-
CapacitorUpdater.TAG,
|
|
262
|
-
"semaphoreReady count " + semaphoreReady.getPhase()
|
|
263
|
-
);
|
|
264
|
-
} catch (InterruptedException e) {
|
|
265
|
-
Log.i(CapacitorUpdater.TAG, "semaphoreWait InterruptedException");
|
|
266
|
-
e.printStackTrace();
|
|
267
|
-
} catch (TimeoutException e) {
|
|
268
|
-
throw new RuntimeException(e);
|
|
243
|
+
|
|
244
|
+
private void directUpdateFinish(final BundleInfo latest) {
|
|
245
|
+
CapacitorUpdaterPlugin.this.implementation.set(latest);
|
|
246
|
+
CapacitorUpdaterPlugin.this._reload();
|
|
247
|
+
sendReadyToJs(latest, "update installed");
|
|
269
248
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
semaphoreReady.register();
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
private void semaphoreDown() {
|
|
278
|
-
Log.i(CapacitorUpdater.TAG, "semaphoreDown");
|
|
279
|
-
Log.i(
|
|
280
|
-
CapacitorUpdater.TAG,
|
|
281
|
-
"semaphoreDown count " + semaphoreReady.getPhase()
|
|
282
|
-
);
|
|
283
|
-
semaphoreReady.arriveAndDeregister();
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
private void sendReadyToJs(final BundleInfo current, final String msg) {
|
|
287
|
-
Log.i(CapacitorUpdater.TAG, "sendReadyToJs");
|
|
288
|
-
final JSObject ret = new JSObject();
|
|
289
|
-
ret.put("bundle", current.toJSON());
|
|
290
|
-
ret.put("status", msg);
|
|
291
|
-
startNewThread(() -> {
|
|
292
|
-
Log.i(CapacitorUpdater.TAG, "semaphoreReady sendReadyToJs");
|
|
293
|
-
semaphoreWait(CapacitorUpdaterPlugin.this.appReadyTimeout);
|
|
294
|
-
Log.i(CapacitorUpdater.TAG, "semaphoreReady sendReadyToJs done");
|
|
295
|
-
CapacitorUpdaterPlugin.this.notifyListeners("appReady", ret);
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
private void directUpdateFinish(final BundleInfo latest) {
|
|
300
|
-
CapacitorUpdaterPlugin.this.implementation.set(latest);
|
|
301
|
-
CapacitorUpdaterPlugin.this._reload();
|
|
302
|
-
sendReadyToJs(latest, "update installed");
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
private void cleanupObsoleteVersions() {
|
|
306
|
-
try {
|
|
307
|
-
final Version previous = new Version(
|
|
308
|
-
this.prefs.getString("LatestVersionNative", "")
|
|
309
|
-
);
|
|
310
|
-
try {
|
|
311
|
-
if (
|
|
312
|
-
!"".equals(previous.getOriginalString()) &&
|
|
313
|
-
!Objects.equals(
|
|
314
|
-
this.currentVersionNative.getOriginalString(),
|
|
315
|
-
previous.getOriginalString()
|
|
316
|
-
)
|
|
317
|
-
) {
|
|
318
|
-
Log.i(
|
|
319
|
-
CapacitorUpdater.TAG,
|
|
320
|
-
"New native version detected: " + this.currentVersionNative
|
|
321
|
-
);
|
|
322
|
-
this.implementation.reset(true);
|
|
323
|
-
final List<BundleInfo> installed = this.implementation.list(false);
|
|
324
|
-
for (final BundleInfo bundle : installed) {
|
|
249
|
+
|
|
250
|
+
private void cleanupObsoleteVersions() {
|
|
251
|
+
try {
|
|
252
|
+
final Version previous = new Version(this.prefs.getString("LatestVersionNative", ""));
|
|
325
253
|
try {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
254
|
+
if (
|
|
255
|
+
!"".equals(previous.getOriginalString()) &&
|
|
256
|
+
!Objects.equals(this.currentVersionNative.getOriginalString(), previous.getOriginalString())
|
|
257
|
+
) {
|
|
258
|
+
Log.i(CapacitorUpdater.TAG, "New native version detected: " + this.currentVersionNative);
|
|
259
|
+
this.implementation.reset(true);
|
|
260
|
+
final List<BundleInfo> installed = this.implementation.list(false);
|
|
261
|
+
for (final BundleInfo bundle : installed) {
|
|
262
|
+
try {
|
|
263
|
+
Log.i(CapacitorUpdater.TAG, "Deleting obsolete bundle: " + bundle.getId());
|
|
264
|
+
this.implementation.delete(bundle.getId());
|
|
265
|
+
} catch (final Exception e) {
|
|
266
|
+
Log.e(CapacitorUpdater.TAG, "Failed to delete: " + bundle.getId(), e);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
331
270
|
} catch (final Exception e) {
|
|
332
|
-
|
|
333
|
-
CapacitorUpdater.TAG,
|
|
334
|
-
"Failed to delete: " + bundle.getId(),
|
|
335
|
-
e
|
|
336
|
-
);
|
|
271
|
+
Log.e(CapacitorUpdater.TAG, "Could not determine the current version", e);
|
|
337
272
|
}
|
|
338
|
-
|
|
273
|
+
} catch (final Exception e) {
|
|
274
|
+
Log.e(CapacitorUpdater.TAG, "Error calculating previous native version", e);
|
|
339
275
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
CapacitorUpdater.TAG,
|
|
343
|
-
"Could not determine the current version",
|
|
344
|
-
e
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
} catch (final Exception e) {
|
|
348
|
-
Log.e(
|
|
349
|
-
CapacitorUpdater.TAG,
|
|
350
|
-
"Error calculating previous native version",
|
|
351
|
-
e
|
|
352
|
-
);
|
|
276
|
+
this.editor.putString("LatestVersionNative", this.currentVersionNative.toString());
|
|
277
|
+
this.editor.commit();
|
|
353
278
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
"
|
|
377
|
-
bundleInfo.getVersionName()
|
|
378
|
-
);
|
|
379
|
-
lastNotifiedStatPercent = 100;
|
|
380
|
-
} else {
|
|
381
|
-
int currentStatPercent = (percent / 10) * 10; // Round down to nearest 10
|
|
382
|
-
if (currentStatPercent > lastNotifiedStatPercent) {
|
|
383
|
-
this.implementation.sendStats(
|
|
384
|
-
"download_" + currentStatPercent,
|
|
385
|
-
bundleInfo.getVersionName()
|
|
386
|
-
);
|
|
387
|
-
lastNotifiedStatPercent = currentStatPercent;
|
|
279
|
+
|
|
280
|
+
public void notifyDownload(final String id, final int percent) {
|
|
281
|
+
try {
|
|
282
|
+
final JSObject ret = new JSObject();
|
|
283
|
+
ret.put("percent", percent);
|
|
284
|
+
final BundleInfo bundleInfo = this.implementation.getBundleInfo(id);
|
|
285
|
+
ret.put("bundle", bundleInfo.toJSON());
|
|
286
|
+
this.notifyListeners("download", ret);
|
|
287
|
+
|
|
288
|
+
if (percent == 100) {
|
|
289
|
+
final JSObject retDownloadComplete = new JSObject(ret, new String[] { "bundle" });
|
|
290
|
+
this.notifyListeners("downloadComplete", retDownloadComplete);
|
|
291
|
+
this.implementation.sendStats("download_complete", bundleInfo.getVersionName());
|
|
292
|
+
lastNotifiedStatPercent = 100;
|
|
293
|
+
} else {
|
|
294
|
+
int currentStatPercent = (percent / 10) * 10; // Round down to nearest 10
|
|
295
|
+
if (currentStatPercent > lastNotifiedStatPercent) {
|
|
296
|
+
this.implementation.sendStats("download_" + currentStatPercent, bundleInfo.getVersionName());
|
|
297
|
+
lastNotifiedStatPercent = currentStatPercent;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
} catch (final Exception e) {
|
|
301
|
+
Log.e(CapacitorUpdater.TAG, "Could not notify listeners", e);
|
|
388
302
|
}
|
|
389
|
-
}
|
|
390
|
-
} catch (final Exception e) {
|
|
391
|
-
Log.e(CapacitorUpdater.TAG, "Could not notify listeners", e);
|
|
392
303
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
304
|
+
|
|
305
|
+
@PluginMethod
|
|
306
|
+
public void setUpdateUrl(final PluginCall call) {
|
|
307
|
+
if (!this.getConfig().getBoolean("allowModifyUrl", false)) {
|
|
308
|
+
Log.e(CapacitorUpdater.TAG, "setUpdateUrl not allowed set allowModifyUrl in your config to true to allow it");
|
|
309
|
+
call.reject("setUpdateUrl not allowed");
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
final String url = call.getString("url");
|
|
313
|
+
if (url == null) {
|
|
314
|
+
Log.e(CapacitorUpdater.TAG, "setUpdateUrl called without url");
|
|
315
|
+
call.reject("setUpdateUrl called without url");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
this.updateUrl = url;
|
|
319
|
+
call.resolve();
|
|
404
320
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
321
|
+
|
|
322
|
+
@PluginMethod
|
|
323
|
+
public void setStatsUrl(final PluginCall call) {
|
|
324
|
+
if (!this.getConfig().getBoolean("allowModifyUrl", false)) {
|
|
325
|
+
Log.e(CapacitorUpdater.TAG, "setStatsUrl not allowed set allowModifyUrl in your config to true to allow it");
|
|
326
|
+
call.reject("setStatsUrl not allowed");
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
final String url = call.getString("url");
|
|
330
|
+
if (url == null) {
|
|
331
|
+
Log.e(CapacitorUpdater.TAG, "setStatsUrl called without url");
|
|
332
|
+
call.reject("setStatsUrl called without url");
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
this.implementation.statsUrl = url;
|
|
336
|
+
call.resolve();
|
|
410
337
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
338
|
+
|
|
339
|
+
@PluginMethod
|
|
340
|
+
public void setChannelUrl(final PluginCall call) {
|
|
341
|
+
if (!this.getConfig().getBoolean("allowModifyUrl", false)) {
|
|
342
|
+
Log.e(CapacitorUpdater.TAG, "setChannelUrl not allowed set allowModifyUrl in your config to true to allow it");
|
|
343
|
+
call.reject("setChannelUrl not allowed");
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
final String url = call.getString("url");
|
|
347
|
+
if (url == null) {
|
|
348
|
+
Log.e(CapacitorUpdater.TAG, "setChannelUrl called without url");
|
|
349
|
+
call.reject("setChannelUrl called without url");
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
this.implementation.channelUrl = url;
|
|
353
|
+
call.resolve();
|
|
424
354
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
355
|
+
|
|
356
|
+
@PluginMethod
|
|
357
|
+
public void getBuiltinVersion(final PluginCall call) {
|
|
358
|
+
try {
|
|
359
|
+
final JSObject ret = new JSObject();
|
|
360
|
+
ret.put("version", this.implementation.versionBuild);
|
|
361
|
+
call.resolve(ret);
|
|
362
|
+
} catch (final Exception e) {
|
|
363
|
+
Log.e(CapacitorUpdater.TAG, "Could not get version", e);
|
|
364
|
+
call.reject("Could not get version", e);
|
|
365
|
+
}
|
|
430
366
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
call.reject("setChannelUrl not allowed");
|
|
443
|
-
return;
|
|
367
|
+
|
|
368
|
+
@PluginMethod
|
|
369
|
+
public void getDeviceId(final PluginCall call) {
|
|
370
|
+
try {
|
|
371
|
+
final JSObject ret = new JSObject();
|
|
372
|
+
ret.put("deviceId", this.implementation.deviceID);
|
|
373
|
+
call.resolve(ret);
|
|
374
|
+
} catch (final Exception e) {
|
|
375
|
+
Log.e(CapacitorUpdater.TAG, "Could not get device id", e);
|
|
376
|
+
call.reject("Could not get device id", e);
|
|
377
|
+
}
|
|
444
378
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
379
|
+
|
|
380
|
+
@PluginMethod
|
|
381
|
+
public void setCustomId(final PluginCall call) {
|
|
382
|
+
final String customId = call.getString("customId");
|
|
383
|
+
if (customId == null) {
|
|
384
|
+
Log.e(CapacitorUpdater.TAG, "setCustomId called without customId");
|
|
385
|
+
call.reject("setCustomId called without customId");
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
this.implementation.customId = customId;
|
|
450
389
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
Log.e(CapacitorUpdater.TAG, "Could not get version", e);
|
|
463
|
-
call.reject("Could not get version", e);
|
|
390
|
+
|
|
391
|
+
@PluginMethod
|
|
392
|
+
public void getPluginVersion(final PluginCall call) {
|
|
393
|
+
try {
|
|
394
|
+
final JSObject ret = new JSObject();
|
|
395
|
+
ret.put("version", this.PLUGIN_VERSION);
|
|
396
|
+
call.resolve(ret);
|
|
397
|
+
} catch (final Exception e) {
|
|
398
|
+
Log.e(CapacitorUpdater.TAG, "Could not get plugin version", e);
|
|
399
|
+
call.reject("Could not get plugin version", e);
|
|
400
|
+
}
|
|
464
401
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
402
|
+
|
|
403
|
+
@PluginMethod
|
|
404
|
+
public void unsetChannel(final PluginCall call) {
|
|
405
|
+
final Boolean triggerAutoUpdate = call.getBoolean("triggerAutoUpdate", false);
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
Log.i(CapacitorUpdater.TAG, "unsetChannel triggerAutoUpdate: " + triggerAutoUpdate);
|
|
409
|
+
startNewThread(() ->
|
|
410
|
+
CapacitorUpdaterPlugin.this.implementation.unsetChannel(res -> {
|
|
411
|
+
if (res.has("error")) {
|
|
412
|
+
call.reject(res.getString("error"));
|
|
413
|
+
} else {
|
|
414
|
+
if (CapacitorUpdaterPlugin.this._isAutoUpdateEnabled() && Boolean.TRUE.equals(triggerAutoUpdate)) {
|
|
415
|
+
Log.i(CapacitorUpdater.TAG, "Calling autoupdater after channel change!");
|
|
416
|
+
backgroundDownload();
|
|
417
|
+
}
|
|
418
|
+
call.resolve(res);
|
|
419
|
+
}
|
|
420
|
+
})
|
|
421
|
+
);
|
|
422
|
+
} catch (final Exception e) {
|
|
423
|
+
Log.e(CapacitorUpdater.TAG, "Failed to unsetChannel: ", e);
|
|
424
|
+
call.reject("Failed to unsetChannel: ", e);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
@PluginMethod
|
|
429
|
+
public void setChannel(final PluginCall call) {
|
|
430
|
+
final String channel = call.getString("channel");
|
|
431
|
+
final Boolean triggerAutoUpdate = call.getBoolean("triggerAutoUpdate", false);
|
|
432
|
+
|
|
433
|
+
if (channel == null) {
|
|
434
|
+
Log.e(CapacitorUpdater.TAG, "setChannel called without channel");
|
|
435
|
+
call.reject("setChannel called without channel");
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
try {
|
|
439
|
+
Log.i(CapacitorUpdater.TAG, "setChannel " + channel + " triggerAutoUpdate: " + triggerAutoUpdate);
|
|
440
|
+
startNewThread(() ->
|
|
441
|
+
CapacitorUpdaterPlugin.this.implementation.setChannel(channel, res -> {
|
|
442
|
+
if (res.has("error")) {
|
|
443
|
+
call.reject(res.getString("error"));
|
|
444
|
+
} else {
|
|
445
|
+
if (CapacitorUpdaterPlugin.this._isAutoUpdateEnabled() && Boolean.TRUE.equals(triggerAutoUpdate)) {
|
|
446
|
+
Log.i(CapacitorUpdater.TAG, "Calling autoupdater after channel change!");
|
|
447
|
+
backgroundDownload();
|
|
448
|
+
}
|
|
449
|
+
call.resolve(res);
|
|
450
|
+
}
|
|
451
|
+
})
|
|
452
|
+
);
|
|
453
|
+
} catch (final Exception e) {
|
|
454
|
+
Log.e(CapacitorUpdater.TAG, "Failed to setChannel: " + channel, e);
|
|
455
|
+
call.reject("Failed to setChannel: " + channel, e);
|
|
456
|
+
}
|
|
476
457
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
458
|
+
|
|
459
|
+
@PluginMethod
|
|
460
|
+
public void getChannel(final PluginCall call) {
|
|
461
|
+
try {
|
|
462
|
+
Log.i(CapacitorUpdater.TAG, "getChannel");
|
|
463
|
+
startNewThread(() ->
|
|
464
|
+
CapacitorUpdaterPlugin.this.implementation.getChannel(res -> {
|
|
465
|
+
if (res.has("error")) {
|
|
466
|
+
call.reject(res.getString("error"));
|
|
467
|
+
} else {
|
|
468
|
+
call.resolve(res);
|
|
469
|
+
}
|
|
470
|
+
})
|
|
471
|
+
);
|
|
472
|
+
} catch (final Exception e) {
|
|
473
|
+
Log.e(CapacitorUpdater.TAG, "Failed to getChannel", e);
|
|
474
|
+
call.reject("Failed to getChannel", e);
|
|
475
|
+
}
|
|
486
476
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
477
|
+
|
|
478
|
+
@PluginMethod
|
|
479
|
+
public void download(final PluginCall call) {
|
|
480
|
+
final String url = call.getString("url");
|
|
481
|
+
final String version = call.getString("version");
|
|
482
|
+
final String sessionKey = call.getString("sessionKey", "");
|
|
483
|
+
final String checksum = call.getString("checksum", "");
|
|
484
|
+
if (url == null) {
|
|
485
|
+
Log.e(CapacitorUpdater.TAG, "Download called without url");
|
|
486
|
+
call.reject("Download called without url");
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (version == null) {
|
|
490
|
+
Log.e(CapacitorUpdater.TAG, "Download called without version");
|
|
491
|
+
call.reject("Download called without version");
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
Log.i(CapacitorUpdater.TAG, "Downloading " + url);
|
|
496
|
+
startNewThread(() -> {
|
|
497
|
+
try {
|
|
498
|
+
final BundleInfo downloaded = CapacitorUpdaterPlugin.this.implementation.download(url, version, sessionKey, checksum);
|
|
499
|
+
if (downloaded.isErrorStatus()) {
|
|
500
|
+
throw new RuntimeException("Download failed: " + downloaded.getStatus());
|
|
501
|
+
} else {
|
|
502
|
+
call.resolve(downloaded.toJSON());
|
|
503
|
+
}
|
|
504
|
+
} catch (final Exception e) {
|
|
505
|
+
Log.e(CapacitorUpdater.TAG, "Failed to download from: " + url, e);
|
|
506
|
+
call.reject("Failed to download from: " + url, e);
|
|
507
|
+
final JSObject ret = new JSObject();
|
|
508
|
+
ret.put("version", version);
|
|
509
|
+
CapacitorUpdaterPlugin.this.notifyListeners("downloadFailed", ret);
|
|
510
|
+
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
511
|
+
CapacitorUpdaterPlugin.this.implementation.sendStats("download_fail", current.getVersionName());
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
} catch (final Exception e) {
|
|
515
|
+
Log.e(CapacitorUpdater.TAG, "Failed to download from: " + url, e);
|
|
516
|
+
call.reject("Failed to download from: " + url, e);
|
|
517
|
+
final JSObject ret = new JSObject();
|
|
518
|
+
ret.put("version", version);
|
|
519
|
+
CapacitorUpdaterPlugin.this.notifyListeners("downloadFailed", ret);
|
|
520
|
+
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
521
|
+
CapacitorUpdaterPlugin.this.implementation.sendStats("download_fail", current.getVersionName());
|
|
522
|
+
}
|
|
499
523
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
524
|
+
|
|
525
|
+
protected boolean _reload() {
|
|
526
|
+
final String path = this.implementation.getCurrentBundlePath();
|
|
527
|
+
this.semaphoreUp();
|
|
528
|
+
Log.i(CapacitorUpdater.TAG, "Reloading: " + path);
|
|
529
|
+
|
|
530
|
+
AtomicReference<URL> url = new AtomicReference<>();
|
|
531
|
+
if (this.keepUrlPathAfterReload) {
|
|
532
|
+
try {
|
|
533
|
+
if (Looper.myLooper() != Looper.getMainLooper()) {
|
|
534
|
+
Semaphore mainThreadSemaphore = new Semaphore(0);
|
|
535
|
+
this.bridge.executeOnMainThread(() -> {
|
|
536
|
+
try {
|
|
537
|
+
url.set(new URL(this.bridge.getWebView().getUrl()));
|
|
538
|
+
} catch (Exception e) {
|
|
539
|
+
Log.e(CapacitorUpdater.TAG, "Error executing on main thread", e);
|
|
540
|
+
}
|
|
541
|
+
mainThreadSemaphore.release();
|
|
542
|
+
});
|
|
543
|
+
mainThreadSemaphore.acquire();
|
|
544
|
+
} else {
|
|
545
|
+
try {
|
|
546
|
+
url.set(new URL(this.bridge.getWebView().getUrl()));
|
|
547
|
+
} catch (Exception e) {
|
|
548
|
+
Log.e(CapacitorUpdater.TAG, "Error executing on main thread", e);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
} catch (InterruptedException e) {
|
|
552
|
+
Log.e(CapacitorUpdater.TAG, "Error waiting for main thread or getting the current URL from webview", e);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (url.get() != null) {
|
|
557
|
+
if (this.implementation.isUsingBuiltin()) {
|
|
558
|
+
this.bridge.getLocalServer().hostAssets(path);
|
|
518
559
|
} else {
|
|
519
|
-
|
|
520
|
-
CapacitorUpdaterPlugin.this._isAutoUpdateEnabled() &&
|
|
521
|
-
Boolean.TRUE.equals(triggerAutoUpdate)
|
|
522
|
-
) {
|
|
523
|
-
Log.i(
|
|
524
|
-
CapacitorUpdater.TAG,
|
|
525
|
-
"Calling autoupdater after channel change!"
|
|
526
|
-
);
|
|
527
|
-
backgroundDownload();
|
|
528
|
-
}
|
|
529
|
-
call.resolve(res);
|
|
560
|
+
this.bridge.getLocalServer().hostFiles(path);
|
|
530
561
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
CapacitorUpdater.TAG,
|
|
555
|
-
"setChannel " + channel + " triggerAutoUpdate: " + triggerAutoUpdate
|
|
556
|
-
);
|
|
557
|
-
startNewThread(() ->
|
|
558
|
-
CapacitorUpdaterPlugin.this.implementation.setChannel(channel, res -> {
|
|
559
|
-
if (res.has("error")) {
|
|
560
|
-
call.reject(res.getString("error"));
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
URL finalUrl = null;
|
|
565
|
+
finalUrl = new URL(this.bridge.getAppUrl());
|
|
566
|
+
finalUrl = new URL(finalUrl.getProtocol(), finalUrl.getHost(), finalUrl.getPort(), url.get().getPath());
|
|
567
|
+
URL finalUrl1 = finalUrl;
|
|
568
|
+
this.bridge.getWebView()
|
|
569
|
+
.post(() -> {
|
|
570
|
+
this.bridge.getWebView().loadUrl(finalUrl1.toString());
|
|
571
|
+
this.bridge.getWebView().clearHistory();
|
|
572
|
+
});
|
|
573
|
+
} catch (MalformedURLException e) {
|
|
574
|
+
Log.e(CapacitorUpdater.TAG, "Cannot get finalUrl from capacitor bridge", e);
|
|
575
|
+
|
|
576
|
+
if (this.implementation.isUsingBuiltin()) {
|
|
577
|
+
this.bridge.setServerAssetPath(path);
|
|
578
|
+
} else {
|
|
579
|
+
this.bridge.setServerBasePath(path);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
} else {
|
|
583
|
+
if (this.implementation.isUsingBuiltin()) {
|
|
584
|
+
this.bridge.setServerAssetPath(path);
|
|
561
585
|
} else {
|
|
562
|
-
|
|
563
|
-
CapacitorUpdaterPlugin.this._isAutoUpdateEnabled() &&
|
|
564
|
-
Boolean.TRUE.equals(triggerAutoUpdate)
|
|
565
|
-
) {
|
|
566
|
-
Log.i(
|
|
567
|
-
CapacitorUpdater.TAG,
|
|
568
|
-
"Calling autoupdater after channel change!"
|
|
569
|
-
);
|
|
570
|
-
backgroundDownload();
|
|
571
|
-
}
|
|
572
|
-
call.resolve(res);
|
|
586
|
+
this.bridge.setServerBasePath(path);
|
|
573
587
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
this.checkAppReady();
|
|
591
|
+
this.notifyListeners("appReloaded", new JSObject());
|
|
592
|
+
return true;
|
|
579
593
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
startNewThread(() ->
|
|
587
|
-
CapacitorUpdaterPlugin.this.implementation.getChannel(res -> {
|
|
588
|
-
if (res.has("error")) {
|
|
589
|
-
call.reject(res.getString("error"));
|
|
594
|
+
|
|
595
|
+
@PluginMethod
|
|
596
|
+
public void reload(final PluginCall call) {
|
|
597
|
+
try {
|
|
598
|
+
if (this._reload()) {
|
|
599
|
+
call.resolve();
|
|
590
600
|
} else {
|
|
591
|
-
|
|
601
|
+
Log.e(CapacitorUpdater.TAG, "Reload failed");
|
|
602
|
+
call.reject("Reload failed");
|
|
592
603
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
call.reject("Failed to getChannel", e);
|
|
604
|
+
} catch (final Exception e) {
|
|
605
|
+
Log.e(CapacitorUpdater.TAG, "Could not reload", e);
|
|
606
|
+
call.reject("Could not reload", e);
|
|
607
|
+
}
|
|
598
608
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
609
|
+
|
|
610
|
+
@PluginMethod
|
|
611
|
+
public void next(final PluginCall call) {
|
|
612
|
+
final String id = call.getString("id");
|
|
613
|
+
if (id == null) {
|
|
614
|
+
Log.e(CapacitorUpdater.TAG, "Next called without id");
|
|
615
|
+
call.reject("Next called without id");
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
try {
|
|
619
|
+
Log.i(CapacitorUpdater.TAG, "Setting next active id " + id);
|
|
620
|
+
if (!this.implementation.setNextBundle(id)) {
|
|
621
|
+
Log.e(CapacitorUpdater.TAG, "Set next id failed. Bundle " + id + " does not exist.");
|
|
622
|
+
call.reject("Set next id failed. Bundle " + id + " does not exist.");
|
|
623
|
+
} else {
|
|
624
|
+
call.resolve(this.implementation.getBundleInfo(id).toJSON());
|
|
625
|
+
}
|
|
626
|
+
} catch (final Exception e) {
|
|
627
|
+
Log.e(CapacitorUpdater.TAG, "Could not set next id " + id, e);
|
|
628
|
+
call.reject("Could not set next id: " + id, e);
|
|
629
|
+
}
|
|
611
630
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
631
|
+
|
|
632
|
+
@PluginMethod
|
|
633
|
+
public void set(final PluginCall call) {
|
|
634
|
+
final String id = call.getString("id");
|
|
635
|
+
if (id == null) {
|
|
636
|
+
Log.e(CapacitorUpdater.TAG, "Set called without id");
|
|
637
|
+
call.reject("Set called without id");
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
try {
|
|
641
|
+
Log.i(CapacitorUpdater.TAG, "Setting active bundle " + id);
|
|
642
|
+
if (!this.implementation.set(id)) {
|
|
643
|
+
Log.i(CapacitorUpdater.TAG, "No such bundle " + id);
|
|
644
|
+
call.reject("Update failed, id " + id + " does not exist.");
|
|
645
|
+
} else {
|
|
646
|
+
Log.i(CapacitorUpdater.TAG, "Bundle successfully set to " + id);
|
|
647
|
+
this.reload(call);
|
|
648
|
+
}
|
|
649
|
+
} catch (final Exception e) {
|
|
650
|
+
Log.e(CapacitorUpdater.TAG, "Could not set id " + id, e);
|
|
651
|
+
call.reject("Could not set id " + id, e);
|
|
652
|
+
}
|
|
616
653
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
654
|
+
|
|
655
|
+
@PluginMethod
|
|
656
|
+
public void delete(final PluginCall call) {
|
|
657
|
+
final String id = call.getString("id");
|
|
658
|
+
if (id == null) {
|
|
659
|
+
Log.e(CapacitorUpdater.TAG, "missing id");
|
|
660
|
+
call.reject("missing id");
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
Log.i(CapacitorUpdater.TAG, "Deleting id " + id);
|
|
620
664
|
try {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
if (downloaded.isErrorStatus()) {
|
|
629
|
-
throw new RuntimeException(
|
|
630
|
-
"Download failed: " + downloaded.getStatus()
|
|
631
|
-
);
|
|
632
|
-
} else {
|
|
633
|
-
call.resolve(downloaded.toJSON());
|
|
634
|
-
}
|
|
665
|
+
final Boolean res = this.implementation.delete(id);
|
|
666
|
+
if (res) {
|
|
667
|
+
call.resolve();
|
|
668
|
+
} else {
|
|
669
|
+
Log.e(CapacitorUpdater.TAG, "Delete failed, id " + id + " does not exist");
|
|
670
|
+
call.reject("Delete failed, id " + id + " does not exist or it cannot be deleted (perhaps it is the 'next' bundle)");
|
|
671
|
+
}
|
|
635
672
|
} catch (final Exception e) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
final JSObject ret = new JSObject();
|
|
639
|
-
ret.put("version", version);
|
|
640
|
-
CapacitorUpdaterPlugin.this.notifyListeners("downloadFailed", ret);
|
|
641
|
-
final BundleInfo current =
|
|
642
|
-
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
643
|
-
CapacitorUpdaterPlugin.this.implementation.sendStats(
|
|
644
|
-
"download_fail",
|
|
645
|
-
current.getVersionName()
|
|
646
|
-
);
|
|
673
|
+
Log.e(CapacitorUpdater.TAG, "Could not delete id " + id, e);
|
|
674
|
+
call.reject("Could not delete id " + id, e);
|
|
647
675
|
}
|
|
648
|
-
});
|
|
649
|
-
} catch (final Exception e) {
|
|
650
|
-
Log.e(CapacitorUpdater.TAG, "Failed to download from: " + url, e);
|
|
651
|
-
call.reject("Failed to download from: " + url, e);
|
|
652
|
-
final JSObject ret = new JSObject();
|
|
653
|
-
ret.put("version", version);
|
|
654
|
-
CapacitorUpdaterPlugin.this.notifyListeners("downloadFailed", ret);
|
|
655
|
-
final BundleInfo current =
|
|
656
|
-
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
657
|
-
CapacitorUpdaterPlugin.this.implementation.sendStats(
|
|
658
|
-
"download_fail",
|
|
659
|
-
current.getVersionName()
|
|
660
|
-
);
|
|
661
676
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
Log.e(
|
|
679
|
-
CapacitorUpdater.TAG,
|
|
680
|
-
"Error executing on main thread",
|
|
681
|
-
e
|
|
682
|
-
);
|
|
683
|
-
}
|
|
684
|
-
mainThreadSemaphore.release();
|
|
685
|
-
});
|
|
686
|
-
mainThreadSemaphore.acquire();
|
|
687
|
-
} else {
|
|
688
|
-
try {
|
|
689
|
-
url.set(new URL(this.bridge.getWebView().getUrl()));
|
|
690
|
-
} catch (Exception e) {
|
|
691
|
-
Log.e(CapacitorUpdater.TAG, "Error executing on main thread", e);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
} catch (InterruptedException e) {
|
|
695
|
-
Log.e(
|
|
696
|
-
CapacitorUpdater.TAG,
|
|
697
|
-
"Error waiting for main thread or getting the current URL from webview",
|
|
698
|
-
e
|
|
699
|
-
);
|
|
700
|
-
}
|
|
677
|
+
|
|
678
|
+
@PluginMethod
|
|
679
|
+
public void list(final PluginCall call) {
|
|
680
|
+
try {
|
|
681
|
+
final List<BundleInfo> res = this.implementation.list(call.getBoolean("raw", false));
|
|
682
|
+
final JSObject ret = new JSObject();
|
|
683
|
+
final JSArray values = new JSArray();
|
|
684
|
+
for (final BundleInfo bundle : res) {
|
|
685
|
+
values.put(bundle.toJSON());
|
|
686
|
+
}
|
|
687
|
+
ret.put("bundles", values);
|
|
688
|
+
call.resolve(ret);
|
|
689
|
+
} catch (final Exception e) {
|
|
690
|
+
Log.e(CapacitorUpdater.TAG, "Could not list bundles", e);
|
|
691
|
+
call.reject("Could not list bundles", e);
|
|
692
|
+
}
|
|
701
693
|
}
|
|
702
694
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
695
|
+
@PluginMethod
|
|
696
|
+
public void getLatest(final PluginCall call) {
|
|
697
|
+
final String channel = call.getString("channel");
|
|
698
|
+
startNewThread(() ->
|
|
699
|
+
CapacitorUpdaterPlugin.this.implementation.getLatest(CapacitorUpdaterPlugin.this.updateUrl, channel, res -> {
|
|
700
|
+
if (res.has("error")) {
|
|
701
|
+
call.reject(res.getString("error"));
|
|
702
|
+
return;
|
|
703
|
+
} else if (res.has("message")) {
|
|
704
|
+
call.reject(res.getString("message"));
|
|
705
|
+
return;
|
|
706
|
+
} else {
|
|
707
|
+
call.resolve(res);
|
|
708
|
+
}
|
|
709
|
+
final JSObject ret = new JSObject();
|
|
710
|
+
Iterator<String> keys = res.keys();
|
|
711
|
+
while (keys.hasNext()) {
|
|
712
|
+
String key = keys.next();
|
|
713
|
+
if (res.has(key)) {
|
|
714
|
+
try {
|
|
715
|
+
ret.put(key, res.get(key));
|
|
716
|
+
} catch (JSONException e) {
|
|
717
|
+
e.printStackTrace();
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
call.resolve(ret);
|
|
722
|
+
})
|
|
730
723
|
);
|
|
731
|
-
|
|
732
|
-
if (this.implementation.isUsingBuiltin()) {
|
|
733
|
-
this.bridge.setServerAssetPath(path);
|
|
734
|
-
} else {
|
|
735
|
-
this.bridge.setServerBasePath(path);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
} else {
|
|
739
|
-
if (this.implementation.isUsingBuiltin()) {
|
|
740
|
-
this.bridge.setServerAssetPath(path);
|
|
741
|
-
} else {
|
|
742
|
-
this.bridge.setServerBasePath(path);
|
|
743
|
-
}
|
|
744
724
|
}
|
|
745
725
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
}
|
|
726
|
+
private boolean _reset(final Boolean toLastSuccessful) {
|
|
727
|
+
final BundleInfo fallback = this.implementation.getFallbackBundle();
|
|
728
|
+
this.implementation.reset();
|
|
750
729
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
call.reject("Reload failed");
|
|
759
|
-
}
|
|
760
|
-
} catch (final Exception e) {
|
|
761
|
-
Log.e(CapacitorUpdater.TAG, "Could not reload", e);
|
|
762
|
-
call.reject("Could not reload", e);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
@PluginMethod
|
|
767
|
-
public void next(final PluginCall call) {
|
|
768
|
-
final String id = call.getString("id");
|
|
769
|
-
if (id == null) {
|
|
770
|
-
Log.e(CapacitorUpdater.TAG, "Next called without id");
|
|
771
|
-
call.reject("Next called without id");
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
try {
|
|
775
|
-
Log.i(CapacitorUpdater.TAG, "Setting next active id " + id);
|
|
776
|
-
if (!this.implementation.setNextBundle(id)) {
|
|
777
|
-
Log.e(
|
|
778
|
-
CapacitorUpdater.TAG,
|
|
779
|
-
"Set next id failed. Bundle " + id + " does not exist."
|
|
780
|
-
);
|
|
781
|
-
call.reject("Set next id failed. Bundle " + id + " does not exist.");
|
|
782
|
-
} else {
|
|
783
|
-
call.resolve(this.implementation.getBundleInfo(id).toJSON());
|
|
784
|
-
}
|
|
785
|
-
} catch (final Exception e) {
|
|
786
|
-
Log.e(CapacitorUpdater.TAG, "Could not set next id " + id, e);
|
|
787
|
-
call.reject("Could not set next id: " + id, e);
|
|
730
|
+
if (toLastSuccessful && !fallback.isBuiltin()) {
|
|
731
|
+
Log.i(CapacitorUpdater.TAG, "Resetting to: " + fallback);
|
|
732
|
+
return this.implementation.set(fallback) && this._reload();
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
Log.i(CapacitorUpdater.TAG, "Resetting to native.");
|
|
736
|
+
return this._reload();
|
|
788
737
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
738
|
+
|
|
739
|
+
@PluginMethod
|
|
740
|
+
public void reset(final PluginCall call) {
|
|
741
|
+
try {
|
|
742
|
+
final Boolean toLastSuccessful = call.getBoolean("toLastSuccessful", false);
|
|
743
|
+
if (this._reset(toLastSuccessful)) {
|
|
744
|
+
call.resolve();
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
Log.e(CapacitorUpdater.TAG, "Reset failed");
|
|
748
|
+
call.reject("Reset failed");
|
|
749
|
+
} catch (final Exception e) {
|
|
750
|
+
Log.e(CapacitorUpdater.TAG, "Reset failed", e);
|
|
751
|
+
call.reject("Reset failed", e);
|
|
752
|
+
}
|
|
798
753
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
754
|
+
|
|
755
|
+
@PluginMethod
|
|
756
|
+
public void current(final PluginCall call) {
|
|
757
|
+
try {
|
|
758
|
+
final JSObject ret = new JSObject();
|
|
759
|
+
final BundleInfo bundle = this.implementation.getCurrentBundle();
|
|
760
|
+
ret.put("bundle", bundle.toJSON());
|
|
761
|
+
ret.put("native", this.currentVersionNative);
|
|
762
|
+
call.resolve(ret);
|
|
763
|
+
} catch (final Exception e) {
|
|
764
|
+
Log.e(CapacitorUpdater.TAG, "Could not get current bundle", e);
|
|
765
|
+
call.reject("Could not get current bundle", e);
|
|
766
|
+
}
|
|
811
767
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
768
|
+
|
|
769
|
+
@PluginMethod
|
|
770
|
+
public void getNextBundle(final PluginCall call) {
|
|
771
|
+
try {
|
|
772
|
+
final BundleInfo bundle = this.implementation.getNextBundle();
|
|
773
|
+
if (bundle == null) {
|
|
774
|
+
call.resolve(null);
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
call.resolve(bundle.toJSON());
|
|
779
|
+
} catch (final Exception e) {
|
|
780
|
+
Log.e(CapacitorUpdater.TAG, "Could not get next bundle", e);
|
|
781
|
+
call.reject("Could not get next bundle", e);
|
|
782
|
+
}
|
|
821
783
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
784
|
+
|
|
785
|
+
public void checkForUpdateAfterDelay() {
|
|
786
|
+
if (this.periodCheckDelay == 0 || !this._isAutoUpdateEnabled()) {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
final Timer timer = new Timer();
|
|
790
|
+
timer.schedule(
|
|
791
|
+
new TimerTask() {
|
|
792
|
+
@Override
|
|
793
|
+
public void run() {
|
|
794
|
+
try {
|
|
795
|
+
CapacitorUpdaterPlugin.this.implementation.getLatest(CapacitorUpdaterPlugin.this.updateUrl, null, res -> {
|
|
796
|
+
if (res.has("error")) {
|
|
797
|
+
Log.e(CapacitorUpdater.TAG, Objects.requireNonNull(res.getString("error")));
|
|
798
|
+
} else if (res.has("version")) {
|
|
799
|
+
String newVersion = res.getString("version");
|
|
800
|
+
String currentVersion = String.valueOf(CapacitorUpdaterPlugin.this.implementation.getCurrentBundle());
|
|
801
|
+
if (!Objects.equals(newVersion, currentVersion)) {
|
|
802
|
+
Log.i(CapacitorUpdater.TAG, "New version found: " + newVersion);
|
|
803
|
+
CapacitorUpdaterPlugin.this.backgroundDownload();
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
} catch (final Exception e) {
|
|
808
|
+
Log.e(CapacitorUpdater.TAG, "Failed to check for update", e);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
this.periodCheckDelay,
|
|
813
|
+
this.periodCheckDelay
|
|
836
814
|
);
|
|
837
|
-
}
|
|
838
|
-
} catch (final Exception e) {
|
|
839
|
-
Log.e(CapacitorUpdater.TAG, "Could not delete id " + id, e);
|
|
840
|
-
call.reject("Could not delete id " + id, e);
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
@PluginMethod
|
|
845
|
-
public void list(final PluginCall call) {
|
|
846
|
-
try {
|
|
847
|
-
final List<BundleInfo> res =
|
|
848
|
-
this.implementation.list(call.getBoolean("raw", false));
|
|
849
|
-
final JSObject ret = new JSObject();
|
|
850
|
-
final JSArray values = new JSArray();
|
|
851
|
-
for (final BundleInfo bundle : res) {
|
|
852
|
-
values.put(bundle.toJSON());
|
|
853
|
-
}
|
|
854
|
-
ret.put("bundles", values);
|
|
855
|
-
call.resolve(ret);
|
|
856
|
-
} catch (final Exception e) {
|
|
857
|
-
Log.e(CapacitorUpdater.TAG, "Could not list bundles", e);
|
|
858
|
-
call.reject("Could not list bundles", e);
|
|
859
815
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
if (res.has("error")) {
|
|
871
|
-
call.reject(res.getString("error"));
|
|
872
|
-
return;
|
|
873
|
-
} else if (res.has("message")) {
|
|
874
|
-
call.reject(res.getString("message"));
|
|
875
|
-
return;
|
|
876
|
-
} else {
|
|
877
|
-
call.resolve(res);
|
|
878
|
-
}
|
|
816
|
+
|
|
817
|
+
@PluginMethod
|
|
818
|
+
public void notifyAppReady(final PluginCall call) {
|
|
819
|
+
try {
|
|
820
|
+
final BundleInfo bundle = this.implementation.getCurrentBundle();
|
|
821
|
+
this.implementation.setSuccess(bundle, this.autoDeletePrevious);
|
|
822
|
+
Log.i(CapacitorUpdater.TAG, "Current bundle loaded successfully. ['notifyAppReady()' was called] " + bundle);
|
|
823
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreReady countDown");
|
|
824
|
+
this.semaphoreDown();
|
|
825
|
+
Log.i(CapacitorUpdater.TAG, "semaphoreReady countDown done");
|
|
879
826
|
final JSObject ret = new JSObject();
|
|
880
|
-
|
|
881
|
-
while (keys.hasNext()) {
|
|
882
|
-
String key = keys.next();
|
|
883
|
-
if (res.has(key)) {
|
|
884
|
-
try {
|
|
885
|
-
ret.put(key, res.get(key));
|
|
886
|
-
} catch (JSONException e) {
|
|
887
|
-
e.printStackTrace();
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
}
|
|
827
|
+
ret.put("bundle", bundle.toJSON());
|
|
891
828
|
call.resolve(ret);
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
private boolean _reset(final Boolean toLastSuccessful) {
|
|
898
|
-
final BundleInfo fallback = this.implementation.getFallbackBundle();
|
|
899
|
-
this.implementation.reset();
|
|
900
|
-
|
|
901
|
-
if (toLastSuccessful && !fallback.isBuiltin()) {
|
|
902
|
-
Log.i(CapacitorUpdater.TAG, "Resetting to: " + fallback);
|
|
903
|
-
return this.implementation.set(fallback) && this._reload();
|
|
829
|
+
} catch (final Exception e) {
|
|
830
|
+
Log.e(CapacitorUpdater.TAG, "Failed to notify app ready state. [Error calling 'notifyAppReady()']", e);
|
|
831
|
+
call.reject("Failed to commit app ready state.", e);
|
|
832
|
+
}
|
|
904
833
|
}
|
|
905
834
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
Log.e(CapacitorUpdater.TAG, "Reset failed", e);
|
|
925
|
-
call.reject("Reset failed", e);
|
|
835
|
+
@PluginMethod
|
|
836
|
+
public void setMultiDelay(final PluginCall call) {
|
|
837
|
+
try {
|
|
838
|
+
final Object delayConditions = call.getData().opt("delayConditions");
|
|
839
|
+
if (delayConditions == null) {
|
|
840
|
+
Log.e(CapacitorUpdater.TAG, "setMultiDelay called without delayCondition");
|
|
841
|
+
call.reject("setMultiDelay called without delayCondition");
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (_setMultiDelay(delayConditions.toString())) {
|
|
845
|
+
call.resolve();
|
|
846
|
+
} else {
|
|
847
|
+
call.reject("Failed to delay update");
|
|
848
|
+
}
|
|
849
|
+
} catch (final Exception e) {
|
|
850
|
+
Log.e(CapacitorUpdater.TAG, "Failed to delay update, [Error calling 'setMultiDelay()']", e);
|
|
851
|
+
call.reject("Failed to delay update", e);
|
|
852
|
+
}
|
|
926
853
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
Log.e(CapacitorUpdater.TAG, "Could not get current bundle", e);
|
|
939
|
-
call.reject("Could not get current bundle", e);
|
|
854
|
+
|
|
855
|
+
private Boolean _setMultiDelay(String delayConditions) {
|
|
856
|
+
try {
|
|
857
|
+
this.editor.putString(DELAY_CONDITION_PREFERENCES, delayConditions);
|
|
858
|
+
this.editor.commit();
|
|
859
|
+
Log.i(CapacitorUpdater.TAG, "Delay update saved");
|
|
860
|
+
return true;
|
|
861
|
+
} catch (final Exception e) {
|
|
862
|
+
Log.e(CapacitorUpdater.TAG, "Failed to delay update, [Error calling '_setMultiDelay()']", e);
|
|
863
|
+
return false;
|
|
864
|
+
}
|
|
940
865
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
call.resolve(bundle.toJSON());
|
|
953
|
-
} catch (final Exception e) {
|
|
954
|
-
Log.e(CapacitorUpdater.TAG, "Could not get next bundle", e);
|
|
955
|
-
call.reject("Could not get next bundle", e);
|
|
866
|
+
|
|
867
|
+
private boolean _cancelDelay(String source) {
|
|
868
|
+
try {
|
|
869
|
+
this.editor.remove(DELAY_CONDITION_PREFERENCES);
|
|
870
|
+
this.editor.commit();
|
|
871
|
+
Log.i(CapacitorUpdater.TAG, "All delays canceled from " + source);
|
|
872
|
+
return true;
|
|
873
|
+
} catch (final Exception e) {
|
|
874
|
+
Log.e(CapacitorUpdater.TAG, "Failed to cancel update delay", e);
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
956
877
|
}
|
|
957
|
-
}
|
|
958
878
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
879
|
+
@PluginMethod
|
|
880
|
+
public void cancelDelay(final PluginCall call) {
|
|
881
|
+
if (this._cancelDelay("JS")) {
|
|
882
|
+
call.resolve();
|
|
883
|
+
} else {
|
|
884
|
+
call.reject("Failed to cancel delay");
|
|
885
|
+
}
|
|
962
886
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
887
|
+
|
|
888
|
+
private void _checkCancelDelay(Boolean killed) {
|
|
889
|
+
Gson gson = new Gson();
|
|
890
|
+
String delayUpdatePreferences = prefs.getString(DELAY_CONDITION_PREFERENCES, "[]");
|
|
891
|
+
Type type = new TypeToken<ArrayList<DelayCondition>>() {}.getType();
|
|
892
|
+
ArrayList<DelayCondition> delayConditionList = gson.fromJson(delayUpdatePreferences, type);
|
|
893
|
+
for (DelayCondition condition : delayConditionList) {
|
|
894
|
+
String kind = condition.getKind().toString();
|
|
895
|
+
String value = condition.getValue();
|
|
896
|
+
if (!kind.isEmpty()) {
|
|
897
|
+
switch (kind) {
|
|
898
|
+
case "background":
|
|
899
|
+
if (!killed) {
|
|
900
|
+
this._cancelDelay("background check");
|
|
901
|
+
}
|
|
902
|
+
break;
|
|
903
|
+
case "kill":
|
|
904
|
+
if (killed) {
|
|
905
|
+
this._cancelDelay("kill check");
|
|
906
|
+
this.installNext();
|
|
907
|
+
}
|
|
908
|
+
break;
|
|
909
|
+
case "date":
|
|
910
|
+
if (!"".equals(value)) {
|
|
911
|
+
try {
|
|
912
|
+
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
|
913
|
+
Date date = sdf.parse(value);
|
|
914
|
+
assert date != null;
|
|
915
|
+
if (new Date().compareTo(date) > 0) {
|
|
916
|
+
this._cancelDelay("date expired");
|
|
917
|
+
}
|
|
918
|
+
} catch (final Exception e) {
|
|
919
|
+
this._cancelDelay("date parsing issue");
|
|
920
|
+
}
|
|
921
|
+
} else {
|
|
922
|
+
this._cancelDelay("delayVal absent");
|
|
923
|
+
}
|
|
924
|
+
break;
|
|
925
|
+
case "nativeVersion":
|
|
926
|
+
if (!"".equals(value)) {
|
|
927
|
+
try {
|
|
928
|
+
final Version versionLimit = new Version(value);
|
|
929
|
+
if (this.currentVersionNative.isAtLeast(versionLimit)) {
|
|
930
|
+
this._cancelDelay("nativeVersion above limit");
|
|
931
|
+
}
|
|
932
|
+
} catch (final Exception e) {
|
|
933
|
+
this._cancelDelay("nativeVersion parsing issue");
|
|
934
|
+
}
|
|
935
|
+
} else {
|
|
936
|
+
this._cancelDelay("delayVal absent");
|
|
937
|
+
}
|
|
938
|
+
break;
|
|
991
939
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
Log.e(CapacitorUpdater.TAG, "Failed to check for update", e);
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
},
|
|
998
|
-
this.periodCheckDelay,
|
|
999
|
-
this.periodCheckDelay
|
|
1000
|
-
);
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
@PluginMethod
|
|
1004
|
-
public void notifyAppReady(final PluginCall call) {
|
|
1005
|
-
try {
|
|
1006
|
-
final BundleInfo bundle = this.implementation.getCurrentBundle();
|
|
1007
|
-
this.implementation.setSuccess(bundle, this.autoDeletePrevious);
|
|
1008
|
-
Log.i(
|
|
1009
|
-
CapacitorUpdater.TAG,
|
|
1010
|
-
"Current bundle loaded successfully. ['notifyAppReady()' was called] " +
|
|
1011
|
-
bundle
|
|
1012
|
-
);
|
|
1013
|
-
Log.i(CapacitorUpdater.TAG, "semaphoreReady countDown");
|
|
1014
|
-
this.semaphoreDown();
|
|
1015
|
-
Log.i(CapacitorUpdater.TAG, "semaphoreReady countDown done");
|
|
1016
|
-
final JSObject ret = new JSObject();
|
|
1017
|
-
ret.put("bundle", bundle.toJSON());
|
|
1018
|
-
call.resolve(ret);
|
|
1019
|
-
} catch (final Exception e) {
|
|
1020
|
-
Log.e(
|
|
1021
|
-
CapacitorUpdater.TAG,
|
|
1022
|
-
"Failed to notify app ready state. [Error calling 'notifyAppReady()']",
|
|
1023
|
-
e
|
|
1024
|
-
);
|
|
1025
|
-
call.reject("Failed to commit app ready state.", e);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
1026
942
|
}
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
943
|
+
|
|
944
|
+
private Boolean _isAutoUpdateEnabled() {
|
|
945
|
+
final CapConfig config = CapConfig.loadDefault(this.getActivity());
|
|
946
|
+
String serverUrl = config.getServerUrl();
|
|
947
|
+
if (serverUrl != null && !serverUrl.isEmpty()) {
|
|
948
|
+
// log warning autoupdate disabled when serverUrl is set
|
|
949
|
+
Log.w(CapacitorUpdater.TAG, "AutoUpdate is automatic disabled when serverUrl is set.");
|
|
950
|
+
}
|
|
951
|
+
return (
|
|
952
|
+
CapacitorUpdaterPlugin.this.autoUpdate &&
|
|
953
|
+
!"".equals(CapacitorUpdaterPlugin.this.updateUrl) &&
|
|
954
|
+
(serverUrl == null || serverUrl.isEmpty())
|
|
1037
955
|
);
|
|
1038
|
-
call.reject("setMultiDelay called without delayCondition");
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
if (_setMultiDelay(delayConditions.toString())) {
|
|
1042
|
-
call.resolve();
|
|
1043
|
-
} else {
|
|
1044
|
-
call.reject("Failed to delay update");
|
|
1045
|
-
}
|
|
1046
|
-
} catch (final Exception e) {
|
|
1047
|
-
Log.e(
|
|
1048
|
-
CapacitorUpdater.TAG,
|
|
1049
|
-
"Failed to delay update, [Error calling 'setMultiDelay()']",
|
|
1050
|
-
e
|
|
1051
|
-
);
|
|
1052
|
-
call.reject("Failed to delay update", e);
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
private Boolean _setMultiDelay(String delayConditions) {
|
|
1057
|
-
try {
|
|
1058
|
-
this.editor.putString(DELAY_CONDITION_PREFERENCES, delayConditions);
|
|
1059
|
-
this.editor.commit();
|
|
1060
|
-
Log.i(CapacitorUpdater.TAG, "Delay update saved");
|
|
1061
|
-
return true;
|
|
1062
|
-
} catch (final Exception e) {
|
|
1063
|
-
Log.e(
|
|
1064
|
-
CapacitorUpdater.TAG,
|
|
1065
|
-
"Failed to delay update, [Error calling '_setMultiDelay()']",
|
|
1066
|
-
e
|
|
1067
|
-
);
|
|
1068
|
-
return false;
|
|
1069
956
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
957
|
+
|
|
958
|
+
@PluginMethod
|
|
959
|
+
public void isAutoUpdateEnabled(final PluginCall call) {
|
|
960
|
+
try {
|
|
961
|
+
final JSObject ret = new JSObject();
|
|
962
|
+
ret.put("enabled", this._isAutoUpdateEnabled());
|
|
963
|
+
call.resolve(ret);
|
|
964
|
+
} catch (final Exception e) {
|
|
965
|
+
Log.e(CapacitorUpdater.TAG, "Could not get autoUpdate status", e);
|
|
966
|
+
call.reject("Could not get autoUpdate status", e);
|
|
967
|
+
}
|
|
1081
968
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
969
|
+
|
|
970
|
+
@PluginMethod
|
|
971
|
+
public void isAutoUpdateAvailable(final PluginCall call) {
|
|
972
|
+
try {
|
|
973
|
+
final CapConfig config = CapConfig.loadDefault(this.getActivity());
|
|
974
|
+
String serverUrl = config.getServerUrl();
|
|
975
|
+
final JSObject ret = new JSObject();
|
|
976
|
+
ret.put("available", serverUrl == null || serverUrl.isEmpty());
|
|
977
|
+
call.resolve(ret);
|
|
978
|
+
} catch (final Exception e) {
|
|
979
|
+
Log.e(CapacitorUpdater.TAG, "Could not get autoUpdate availability", e);
|
|
980
|
+
call.reject("Could not get autoUpdate availability", e);
|
|
981
|
+
}
|
|
1090
982
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
DELAY_CONDITION_PREFERENCES,
|
|
1097
|
-
"[]"
|
|
1098
|
-
);
|
|
1099
|
-
Type type = new TypeToken<ArrayList<DelayCondition>>() {}.getType();
|
|
1100
|
-
ArrayList<DelayCondition> delayConditionList = gson.fromJson(
|
|
1101
|
-
delayUpdatePreferences,
|
|
1102
|
-
type
|
|
1103
|
-
);
|
|
1104
|
-
for (DelayCondition condition : delayConditionList) {
|
|
1105
|
-
String kind = condition.getKind().toString();
|
|
1106
|
-
String value = condition.getValue();
|
|
1107
|
-
if (!kind.isEmpty()) {
|
|
1108
|
-
switch (kind) {
|
|
1109
|
-
case "background":
|
|
1110
|
-
if (!killed) {
|
|
1111
|
-
this._cancelDelay("background check");
|
|
983
|
+
|
|
984
|
+
private void checkAppReady() {
|
|
985
|
+
try {
|
|
986
|
+
if (this.appReadyCheck != null) {
|
|
987
|
+
this.appReadyCheck.interrupt();
|
|
1112
988
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
989
|
+
this.appReadyCheck = startNewThread(new DeferredNotifyAppReadyCheck());
|
|
990
|
+
} catch (final Exception e) {
|
|
991
|
+
Log.e(CapacitorUpdater.TAG, "Failed to start " + DeferredNotifyAppReadyCheck.class.getName(), e);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
private boolean isValidURL(String urlStr) {
|
|
996
|
+
try {
|
|
997
|
+
new URL(urlStr);
|
|
998
|
+
return true;
|
|
999
|
+
} catch (MalformedURLException e) {
|
|
1000
|
+
return false;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
private void endBackGroundTaskWithNotif(String msg, String latestVersionName, BundleInfo current, Boolean error) {
|
|
1005
|
+
if (error) {
|
|
1006
|
+
Log.i(
|
|
1007
|
+
CapacitorUpdater.TAG,
|
|
1008
|
+
"endBackGroundTaskWithNotif error: " +
|
|
1009
|
+
error +
|
|
1010
|
+
" current: " +
|
|
1011
|
+
current.getVersionName() +
|
|
1012
|
+
"latestVersionName: " +
|
|
1013
|
+
latestVersionName
|
|
1014
|
+
);
|
|
1015
|
+
this.implementation.sendStats("download_fail", current.getVersionName());
|
|
1016
|
+
final JSObject ret = new JSObject();
|
|
1017
|
+
ret.put("version", latestVersionName);
|
|
1018
|
+
this.notifyListeners("downloadFailed", ret);
|
|
1019
|
+
}
|
|
1020
|
+
final JSObject ret = new JSObject();
|
|
1021
|
+
ret.put("bundle", current.toJSON());
|
|
1022
|
+
this.notifyListeners("noNeedUpdate", ret);
|
|
1023
|
+
this.sendReadyToJs(current, msg);
|
|
1024
|
+
this.backgroundDownloadTask = null;
|
|
1025
|
+
Log.i(CapacitorUpdater.TAG, "endBackGroundTaskWithNotif " + msg);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
private Thread backgroundDownload() {
|
|
1029
|
+
String messageUpdate = this.implementation.directUpdate
|
|
1030
|
+
? "Update will occur now."
|
|
1031
|
+
: "Update will occur next time app moves to background.";
|
|
1032
|
+
return startNewThread(() -> {
|
|
1033
|
+
Log.i(CapacitorUpdater.TAG, "Check for update via: " + CapacitorUpdaterPlugin.this.updateUrl);
|
|
1034
|
+
CapacitorUpdaterPlugin.this.implementation.getLatest(CapacitorUpdaterPlugin.this.updateUrl, null, res -> {
|
|
1035
|
+
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
1036
|
+
try {
|
|
1037
|
+
if (res.has("message")) {
|
|
1038
|
+
Log.i(CapacitorUpdater.TAG, "API message: " + res.get("message"));
|
|
1039
|
+
if (res.has("major") && res.getBoolean("major") && res.has("version")) {
|
|
1040
|
+
final JSObject majorAvailable = new JSObject();
|
|
1041
|
+
majorAvailable.put("version", res.getString("version"));
|
|
1042
|
+
CapacitorUpdaterPlugin.this.notifyListeners("majorAvailable", majorAvailable);
|
|
1043
|
+
}
|
|
1044
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1045
|
+
res.getString("message"),
|
|
1046
|
+
current.getVersionName(),
|
|
1047
|
+
current,
|
|
1048
|
+
true
|
|
1049
|
+
);
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
final String latestVersionName = res.getString("version");
|
|
1054
|
+
|
|
1055
|
+
if ("builtin".equals(latestVersionName)) {
|
|
1056
|
+
Log.i(CapacitorUpdater.TAG, "Latest version is builtin");
|
|
1057
|
+
if (CapacitorUpdaterPlugin.this.implementation.directUpdate) {
|
|
1058
|
+
Log.i(CapacitorUpdater.TAG, "Direct update to builtin version");
|
|
1059
|
+
this._reset(false);
|
|
1060
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1061
|
+
"Updated to builtin version",
|
|
1062
|
+
latestVersionName,
|
|
1063
|
+
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle(),
|
|
1064
|
+
false
|
|
1065
|
+
);
|
|
1066
|
+
} else {
|
|
1067
|
+
Log.i(CapacitorUpdater.TAG, "Setting next bundle to builtin");
|
|
1068
|
+
CapacitorUpdaterPlugin.this.implementation.setNextBundle(BundleInfo.ID_BUILTIN);
|
|
1069
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1070
|
+
"Next update will be to builtin version",
|
|
1071
|
+
latestVersionName,
|
|
1072
|
+
current,
|
|
1073
|
+
false
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
if (!res.has("url") || !CapacitorUpdaterPlugin.this.isValidURL(res.getString("url"))) {
|
|
1080
|
+
Log.e(CapacitorUpdater.TAG, "Error no url or wrong format");
|
|
1081
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1082
|
+
"Error no url or wrong format",
|
|
1083
|
+
current.getVersionName(),
|
|
1084
|
+
current,
|
|
1085
|
+
true
|
|
1086
|
+
);
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
if (
|
|
1091
|
+
latestVersionName != null && !latestVersionName.isEmpty() && !current.getVersionName().equals(latestVersionName)
|
|
1092
|
+
) {
|
|
1093
|
+
final BundleInfo latest = CapacitorUpdaterPlugin.this.implementation.getBundleInfoByName(latestVersionName);
|
|
1094
|
+
if (latest != null) {
|
|
1095
|
+
final JSObject ret = new JSObject();
|
|
1096
|
+
ret.put("bundle", latest.toJSON());
|
|
1097
|
+
if (latest.isErrorStatus()) {
|
|
1098
|
+
Log.e(CapacitorUpdater.TAG, "Latest bundle already exists, and is in error state. Aborting update.");
|
|
1099
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1100
|
+
"Latest bundle already exists, and is in error state. Aborting update.",
|
|
1101
|
+
latestVersionName,
|
|
1102
|
+
current,
|
|
1103
|
+
true
|
|
1104
|
+
);
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
if (latest.isDownloaded()) {
|
|
1108
|
+
Log.i(
|
|
1109
|
+
CapacitorUpdater.TAG,
|
|
1110
|
+
"Latest bundle already exists and download is NOT required. " + messageUpdate
|
|
1111
|
+
);
|
|
1112
|
+
if (CapacitorUpdaterPlugin.this.implementation.directUpdate) {
|
|
1113
|
+
CapacitorUpdaterPlugin.this.implementation.set(latest);
|
|
1114
|
+
CapacitorUpdaterPlugin.this._reload();
|
|
1115
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1116
|
+
"Update installed",
|
|
1117
|
+
latestVersionName,
|
|
1118
|
+
latest,
|
|
1119
|
+
false
|
|
1120
|
+
);
|
|
1121
|
+
} else {
|
|
1122
|
+
CapacitorUpdaterPlugin.this.notifyListeners("updateAvailable", ret);
|
|
1123
|
+
CapacitorUpdaterPlugin.this.implementation.setNextBundle(latest.getId());
|
|
1124
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1125
|
+
"update downloaded, will install next background",
|
|
1126
|
+
latestVersionName,
|
|
1127
|
+
latest,
|
|
1128
|
+
false
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
if (latest.isDeleted()) {
|
|
1134
|
+
Log.i(
|
|
1135
|
+
CapacitorUpdater.TAG,
|
|
1136
|
+
"Latest bundle already exists and will be deleted, download will overwrite it."
|
|
1137
|
+
);
|
|
1138
|
+
try {
|
|
1139
|
+
final Boolean deleted = CapacitorUpdaterPlugin.this.implementation.delete(latest.getId(), true);
|
|
1140
|
+
if (deleted) {
|
|
1141
|
+
Log.i(CapacitorUpdater.TAG, "Failed bundle deleted: " + latest.getVersionName());
|
|
1142
|
+
}
|
|
1143
|
+
} catch (final IOException e) {
|
|
1144
|
+
Log.e(CapacitorUpdater.TAG, "Failed to delete failed bundle: " + latest.getVersionName(), e);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
startNewThread(() -> {
|
|
1149
|
+
try {
|
|
1150
|
+
Log.i(
|
|
1151
|
+
CapacitorUpdater.TAG,
|
|
1152
|
+
"New bundle: " +
|
|
1153
|
+
latestVersionName +
|
|
1154
|
+
" found. Current is: " +
|
|
1155
|
+
current.getVersionName() +
|
|
1156
|
+
". " +
|
|
1157
|
+
messageUpdate
|
|
1158
|
+
);
|
|
1159
|
+
|
|
1160
|
+
final String url = res.getString("url");
|
|
1161
|
+
final String sessionKey = res.has("sessionKey") ? res.getString("sessionKey") : "";
|
|
1162
|
+
final String checksum = res.has("checksum") ? res.getString("checksum") : "";
|
|
1163
|
+
|
|
1164
|
+
if (res.has("manifest")) {
|
|
1165
|
+
// Handle manifest-based download
|
|
1166
|
+
JSONArray manifest = res.getJSONArray("manifest");
|
|
1167
|
+
CapacitorUpdaterPlugin.this.implementation.downloadBackground(
|
|
1168
|
+
url,
|
|
1169
|
+
latestVersionName,
|
|
1170
|
+
sessionKey,
|
|
1171
|
+
checksum,
|
|
1172
|
+
manifest
|
|
1173
|
+
);
|
|
1174
|
+
} else {
|
|
1175
|
+
// Handle single file download (existing code)
|
|
1176
|
+
CapacitorUpdaterPlugin.this.implementation.downloadBackground(
|
|
1177
|
+
url,
|
|
1178
|
+
latestVersionName,
|
|
1179
|
+
sessionKey,
|
|
1180
|
+
checksum,
|
|
1181
|
+
null
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
} catch (final Exception e) {
|
|
1185
|
+
Log.e(CapacitorUpdater.TAG, "error downloading file", e);
|
|
1186
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1187
|
+
"Error downloading file",
|
|
1188
|
+
latestVersionName,
|
|
1189
|
+
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle(),
|
|
1190
|
+
true
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
} else {
|
|
1195
|
+
Log.i(CapacitorUpdater.TAG, "No need to update, " + current.getId() + " is the latest bundle.");
|
|
1196
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif("No need to update", latestVersionName, current, false);
|
|
1197
|
+
}
|
|
1198
|
+
} catch (final JSONException e) {
|
|
1199
|
+
Log.e(CapacitorUpdater.TAG, "error parsing JSON", e);
|
|
1200
|
+
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1201
|
+
"Error parsing JSON",
|
|
1202
|
+
current.getVersionName(),
|
|
1203
|
+
current,
|
|
1204
|
+
true
|
|
1205
|
+
);
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
private void installNext() {
|
|
1212
|
+
try {
|
|
1213
|
+
Gson gson = new Gson();
|
|
1214
|
+
String delayUpdatePreferences = prefs.getString(DELAY_CONDITION_PREFERENCES, "[]");
|
|
1215
|
+
Type type = new TypeToken<ArrayList<DelayCondition>>() {}.getType();
|
|
1216
|
+
ArrayList<DelayCondition> delayConditionList = gson.fromJson(delayUpdatePreferences, type);
|
|
1217
|
+
if (delayConditionList != null && !delayConditionList.isEmpty()) {
|
|
1218
|
+
Log.i(CapacitorUpdater.TAG, "Update delayed until delay conditions met");
|
|
1219
|
+
return;
|
|
1118
1220
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
)
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1221
|
+
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
1222
|
+
final BundleInfo next = this.implementation.getNextBundle();
|
|
1223
|
+
|
|
1224
|
+
if (next != null && !next.isErrorStatus() && !next.getId().equals(current.getId())) {
|
|
1225
|
+
// There is a next bundle waiting for activation
|
|
1226
|
+
Log.d(CapacitorUpdater.TAG, "Next bundle is: " + next.getVersionName());
|
|
1227
|
+
if (this.implementation.set(next) && this._reload()) {
|
|
1228
|
+
Log.i(CapacitorUpdater.TAG, "Updated to bundle: " + next.getVersionName());
|
|
1229
|
+
this.implementation.setNextBundle(null);
|
|
1230
|
+
} else {
|
|
1231
|
+
Log.e(CapacitorUpdater.TAG, "Update to bundle: " + next.getVersionName() + " Failed!");
|
|
1130
1232
|
}
|
|
1131
|
-
} catch (final Exception e) {
|
|
1132
|
-
this._cancelDelay("date parsing issue");
|
|
1133
|
-
}
|
|
1134
|
-
} else {
|
|
1135
|
-
this._cancelDelay("delayVal absent");
|
|
1136
1233
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1234
|
+
} catch (final Exception e) {
|
|
1235
|
+
Log.e(CapacitorUpdater.TAG, "Error during onActivityStopped", e);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
private void checkRevert() {
|
|
1240
|
+
// Automatically roll back to fallback version if notifyAppReady has not been called yet
|
|
1241
|
+
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
1242
|
+
|
|
1243
|
+
if (current.isBuiltin()) {
|
|
1244
|
+
Log.i(CapacitorUpdater.TAG, "Built-in bundle is active. We skip the check for notifyAppReady.");
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
Log.d(CapacitorUpdater.TAG, "Current bundle is: " + current);
|
|
1248
|
+
|
|
1249
|
+
if (BundleStatus.SUCCESS != current.getStatus()) {
|
|
1250
|
+
Log.e(CapacitorUpdater.TAG, "notifyAppReady was not called, roll back current bundle: " + current.getId());
|
|
1251
|
+
Log.i(CapacitorUpdater.TAG, "Did you forget to call 'notifyAppReady()' in your Capacitor App code?");
|
|
1252
|
+
final JSObject ret = new JSObject();
|
|
1253
|
+
ret.put("bundle", current.toJSON());
|
|
1254
|
+
this.notifyListeners("updateFailed", ret);
|
|
1255
|
+
this.implementation.sendStats("update_fail", current.getVersionName());
|
|
1256
|
+
this.implementation.setError(current);
|
|
1257
|
+
this._reset(true);
|
|
1258
|
+
if (CapacitorUpdaterPlugin.this.autoDeleteFailed && !current.isBuiltin()) {
|
|
1259
|
+
Log.i(CapacitorUpdater.TAG, "Deleting failing bundle: " + current.getVersionName());
|
|
1260
|
+
try {
|
|
1261
|
+
final Boolean res = this.implementation.delete(current.getId(), false);
|
|
1262
|
+
if (res) {
|
|
1263
|
+
Log.i(CapacitorUpdater.TAG, "Failed bundle deleted: " + current.getVersionName());
|
|
1264
|
+
}
|
|
1265
|
+
} catch (final IOException e) {
|
|
1266
|
+
Log.e(CapacitorUpdater.TAG, "Failed to delete failed bundle: " + current.getVersionName(), e);
|
|
1144
1267
|
}
|
|
1145
|
-
} catch (final Exception e) {
|
|
1146
|
-
this._cancelDelay("nativeVersion parsing issue");
|
|
1147
|
-
}
|
|
1148
|
-
} else {
|
|
1149
|
-
this._cancelDelay("delayVal absent");
|
|
1150
1268
|
}
|
|
1151
|
-
|
|
1269
|
+
} else {
|
|
1270
|
+
Log.i(CapacitorUpdater.TAG, "notifyAppReady was called. This is fine: " + current.getId());
|
|
1152
1271
|
}
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
private Boolean _isAutoUpdateEnabled() {
|
|
1158
|
-
final CapConfig config = CapConfig.loadDefault(this.getActivity());
|
|
1159
|
-
String serverUrl = config.getServerUrl();
|
|
1160
|
-
if (serverUrl != null && !serverUrl.isEmpty()) {
|
|
1161
|
-
// log warning autoupdate disabled when serverUrl is set
|
|
1162
|
-
Log.w(
|
|
1163
|
-
CapacitorUpdater.TAG,
|
|
1164
|
-
"AutoUpdate is automatic disabled when serverUrl is set."
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
1167
|
-
return (
|
|
1168
|
-
CapacitorUpdaterPlugin.this.autoUpdate &&
|
|
1169
|
-
!"".equals(CapacitorUpdaterPlugin.this.updateUrl) &&
|
|
1170
|
-
(serverUrl == null || serverUrl.isEmpty())
|
|
1171
|
-
);
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
@PluginMethod
|
|
1175
|
-
public void isAutoUpdateEnabled(final PluginCall call) {
|
|
1176
|
-
try {
|
|
1177
|
-
final JSObject ret = new JSObject();
|
|
1178
|
-
ret.put("enabled", this._isAutoUpdateEnabled());
|
|
1179
|
-
call.resolve(ret);
|
|
1180
|
-
} catch (final Exception e) {
|
|
1181
|
-
Log.e(CapacitorUpdater.TAG, "Could not get autoUpdate status", e);
|
|
1182
|
-
call.reject("Could not get autoUpdate status", e);
|
|
1183
1272
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
final CapConfig config = CapConfig.loadDefault(this.getActivity());
|
|
1190
|
-
String serverUrl = config.getServerUrl();
|
|
1191
|
-
final JSObject ret = new JSObject();
|
|
1192
|
-
ret.put("available", serverUrl == null || serverUrl.isEmpty());
|
|
1193
|
-
call.resolve(ret);
|
|
1194
|
-
} catch (final Exception e) {
|
|
1195
|
-
Log.e(CapacitorUpdater.TAG, "Could not get autoUpdate availability", e);
|
|
1196
|
-
call.reject("Could not get autoUpdate availability", e);
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
private void checkAppReady() {
|
|
1201
|
-
try {
|
|
1202
|
-
if (this.appReadyCheck != null) {
|
|
1203
|
-
this.appReadyCheck.interrupt();
|
|
1204
|
-
}
|
|
1205
|
-
this.appReadyCheck = startNewThread(new DeferredNotifyAppReadyCheck());
|
|
1206
|
-
} catch (final Exception e) {
|
|
1207
|
-
Log.e(
|
|
1208
|
-
CapacitorUpdater.TAG,
|
|
1209
|
-
"Failed to start " + DeferredNotifyAppReadyCheck.class.getName(),
|
|
1210
|
-
e
|
|
1211
|
-
);
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
private boolean isValidURL(String urlStr) {
|
|
1216
|
-
try {
|
|
1217
|
-
new URL(urlStr);
|
|
1218
|
-
return true;
|
|
1219
|
-
} catch (MalformedURLException e) {
|
|
1220
|
-
return false;
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
private void endBackGroundTaskWithNotif(
|
|
1225
|
-
String msg,
|
|
1226
|
-
String latestVersionName,
|
|
1227
|
-
BundleInfo current,
|
|
1228
|
-
Boolean error
|
|
1229
|
-
) {
|
|
1230
|
-
if (error) {
|
|
1231
|
-
Log.i(
|
|
1232
|
-
CapacitorUpdater.TAG,
|
|
1233
|
-
"endBackGroundTaskWithNotif error: " +
|
|
1234
|
-
error +
|
|
1235
|
-
" current: " +
|
|
1236
|
-
current.getVersionName() +
|
|
1237
|
-
"latestVersionName: " +
|
|
1238
|
-
latestVersionName
|
|
1239
|
-
);
|
|
1240
|
-
this.implementation.sendStats("download_fail", current.getVersionName());
|
|
1241
|
-
final JSObject ret = new JSObject();
|
|
1242
|
-
ret.put("version", latestVersionName);
|
|
1243
|
-
this.notifyListeners("downloadFailed", ret);
|
|
1244
|
-
}
|
|
1245
|
-
final JSObject ret = new JSObject();
|
|
1246
|
-
ret.put("bundle", current.toJSON());
|
|
1247
|
-
this.notifyListeners("noNeedUpdate", ret);
|
|
1248
|
-
this.sendReadyToJs(current, msg);
|
|
1249
|
-
this.backgroundDownloadTask = null;
|
|
1250
|
-
Log.i(CapacitorUpdater.TAG, "endBackGroundTaskWithNotif " + msg);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
private Thread backgroundDownload() {
|
|
1254
|
-
String messageUpdate = this.implementation.directUpdate
|
|
1255
|
-
? "Update will occur now."
|
|
1256
|
-
: "Update will occur next time app moves to background.";
|
|
1257
|
-
return startNewThread(() -> {
|
|
1258
|
-
Log.i(
|
|
1259
|
-
CapacitorUpdater.TAG,
|
|
1260
|
-
"Check for update via: " + CapacitorUpdaterPlugin.this.updateUrl
|
|
1261
|
-
);
|
|
1262
|
-
CapacitorUpdaterPlugin.this.implementation.getLatest(
|
|
1263
|
-
CapacitorUpdaterPlugin.this.updateUrl,
|
|
1264
|
-
null,
|
|
1265
|
-
res -> {
|
|
1266
|
-
final BundleInfo current =
|
|
1267
|
-
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
1273
|
+
|
|
1274
|
+
private class DeferredNotifyAppReadyCheck implements Runnable {
|
|
1275
|
+
|
|
1276
|
+
@Override
|
|
1277
|
+
public void run() {
|
|
1268
1278
|
try {
|
|
1269
|
-
if (res.has("message")) {
|
|
1270
1279
|
Log.i(
|
|
1271
|
-
|
|
1272
|
-
|
|
1280
|
+
CapacitorUpdater.TAG,
|
|
1281
|
+
"Wait for " + CapacitorUpdaterPlugin.this.appReadyTimeout + "ms, then check for notifyAppReady"
|
|
1273
1282
|
);
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
)
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
"majorAvailable",
|
|
1283
|
-
majorAvailable
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1287
|
-
res.getString("message"),
|
|
1288
|
-
current.getVersionName(),
|
|
1289
|
-
current,
|
|
1290
|
-
true
|
|
1291
|
-
);
|
|
1292
|
-
return;
|
|
1293
|
-
}
|
|
1283
|
+
Thread.sleep(CapacitorUpdaterPlugin.this.appReadyTimeout);
|
|
1284
|
+
CapacitorUpdaterPlugin.this.checkRevert();
|
|
1285
|
+
CapacitorUpdaterPlugin.this.appReadyCheck = null;
|
|
1286
|
+
} catch (final InterruptedException e) {
|
|
1287
|
+
Log.i(CapacitorUpdater.TAG, DeferredNotifyAppReadyCheck.class.getName() + " was interrupted.");
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1294
1291
|
|
|
1295
|
-
|
|
1292
|
+
public void appMovedToForeground() {
|
|
1293
|
+
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
1294
|
+
CapacitorUpdaterPlugin.this.implementation.sendStats("app_moved_to_foreground", current.getVersionName());
|
|
1295
|
+
this._checkCancelDelay(false);
|
|
1296
|
+
if (
|
|
1297
|
+
CapacitorUpdaterPlugin.this._isAutoUpdateEnabled() &&
|
|
1298
|
+
(this.backgroundDownloadTask == null || !this.backgroundDownloadTask.isAlive())
|
|
1299
|
+
) {
|
|
1300
|
+
this.backgroundDownloadTask = this.backgroundDownload();
|
|
1301
|
+
} else {
|
|
1302
|
+
Log.i(CapacitorUpdater.TAG, "Auto update is disabled");
|
|
1303
|
+
this.sendReadyToJs(current, "disabled");
|
|
1304
|
+
}
|
|
1305
|
+
this.checkAppReady();
|
|
1306
|
+
}
|
|
1296
1307
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
);
|
|
1311
|
-
} else {
|
|
1312
|
-
Log.i(CapacitorUpdater.TAG, "Setting next bundle to builtin");
|
|
1313
|
-
CapacitorUpdaterPlugin.this.implementation.setNextBundle(
|
|
1314
|
-
BundleInfo.ID_BUILTIN
|
|
1315
|
-
);
|
|
1316
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1317
|
-
"Next update will be to builtin version",
|
|
1318
|
-
latestVersionName,
|
|
1319
|
-
current,
|
|
1320
|
-
false
|
|
1321
|
-
);
|
|
1308
|
+
public void appMovedToBackground() {
|
|
1309
|
+
final BundleInfo current = CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
1310
|
+
CapacitorUpdaterPlugin.this.implementation.sendStats("app_moved_to_background", current.getVersionName());
|
|
1311
|
+
Log.i(CapacitorUpdater.TAG, "Checking for pending update");
|
|
1312
|
+
try {
|
|
1313
|
+
Gson gson = new Gson();
|
|
1314
|
+
String delayUpdatePreferences = prefs.getString(DELAY_CONDITION_PREFERENCES, "[]");
|
|
1315
|
+
Type type = new TypeToken<ArrayList<DelayCondition>>() {}.getType();
|
|
1316
|
+
ArrayList<DelayCondition> delayConditionList = gson.fromJson(delayUpdatePreferences, type);
|
|
1317
|
+
String backgroundValue = null;
|
|
1318
|
+
for (DelayCondition delayCondition : delayConditionList) {
|
|
1319
|
+
if (delayCondition.getKind().toString().equals("background")) {
|
|
1320
|
+
String value = delayCondition.getValue();
|
|
1321
|
+
backgroundValue = (value != null && !value.isEmpty()) ? value : "0";
|
|
1322
1322
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
) {
|
|
1330
|
-
Log.e(CapacitorUpdater.TAG, "Error no url or wrong format");
|
|
1331
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1332
|
-
"Error no url or wrong format",
|
|
1333
|
-
current.getVersionName(),
|
|
1334
|
-
current,
|
|
1335
|
-
true
|
|
1336
|
-
);
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
if (
|
|
1341
|
-
latestVersionName != null &&
|
|
1342
|
-
!latestVersionName.isEmpty() &&
|
|
1343
|
-
!current.getVersionName().equals(latestVersionName)
|
|
1344
|
-
) {
|
|
1345
|
-
final BundleInfo latest =
|
|
1346
|
-
CapacitorUpdaterPlugin.this.implementation.getBundleInfoByName(
|
|
1347
|
-
latestVersionName
|
|
1348
|
-
);
|
|
1349
|
-
if (latest != null) {
|
|
1350
|
-
final JSObject ret = new JSObject();
|
|
1351
|
-
ret.put("bundle", latest.toJSON());
|
|
1352
|
-
if (latest.isErrorStatus()) {
|
|
1353
|
-
Log.e(
|
|
1354
|
-
CapacitorUpdater.TAG,
|
|
1355
|
-
"Latest bundle already exists, and is in error state. Aborting update."
|
|
1356
|
-
);
|
|
1357
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1358
|
-
"Latest bundle already exists, and is in error state. Aborting update.",
|
|
1359
|
-
latestVersionName,
|
|
1360
|
-
current,
|
|
1361
|
-
true
|
|
1362
|
-
);
|
|
1363
|
-
return;
|
|
1364
|
-
}
|
|
1365
|
-
if (latest.isDownloaded()) {
|
|
1366
|
-
Log.i(
|
|
1367
|
-
CapacitorUpdater.TAG,
|
|
1368
|
-
"Latest bundle already exists and download is NOT required. " +
|
|
1369
|
-
messageUpdate
|
|
1370
|
-
);
|
|
1371
|
-
if (
|
|
1372
|
-
CapacitorUpdaterPlugin.this.implementation.directUpdate
|
|
1373
|
-
) {
|
|
1374
|
-
CapacitorUpdaterPlugin.this.implementation.set(latest);
|
|
1375
|
-
CapacitorUpdaterPlugin.this._reload();
|
|
1376
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1377
|
-
"Update installed",
|
|
1378
|
-
latestVersionName,
|
|
1379
|
-
latest,
|
|
1380
|
-
false
|
|
1381
|
-
);
|
|
1382
|
-
} else {
|
|
1383
|
-
CapacitorUpdaterPlugin.this.notifyListeners(
|
|
1384
|
-
"updateAvailable",
|
|
1385
|
-
ret
|
|
1386
|
-
);
|
|
1387
|
-
CapacitorUpdaterPlugin.this.implementation.setNextBundle(
|
|
1388
|
-
latest.getId()
|
|
1389
|
-
);
|
|
1390
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1391
|
-
"update downloaded, will install next background",
|
|
1392
|
-
latestVersionName,
|
|
1393
|
-
latest,
|
|
1394
|
-
false
|
|
1395
|
-
);
|
|
1396
|
-
}
|
|
1397
|
-
return;
|
|
1398
|
-
}
|
|
1399
|
-
if (latest.isDeleted()) {
|
|
1400
|
-
Log.i(
|
|
1401
|
-
CapacitorUpdater.TAG,
|
|
1402
|
-
"Latest bundle already exists and will be deleted, download will overwrite it."
|
|
1403
|
-
);
|
|
1404
|
-
try {
|
|
1405
|
-
final Boolean deleted =
|
|
1406
|
-
CapacitorUpdaterPlugin.this.implementation.delete(
|
|
1407
|
-
latest.getId(),
|
|
1408
|
-
true
|
|
1409
|
-
);
|
|
1410
|
-
if (deleted) {
|
|
1411
|
-
Log.i(
|
|
1412
|
-
CapacitorUpdater.TAG,
|
|
1413
|
-
"Failed bundle deleted: " + latest.getVersionName()
|
|
1414
|
-
);
|
|
1415
|
-
}
|
|
1416
|
-
} catch (final IOException e) {
|
|
1417
|
-
Log.e(
|
|
1418
|
-
CapacitorUpdater.TAG,
|
|
1419
|
-
"Failed to delete failed bundle: " +
|
|
1420
|
-
latest.getVersionName(),
|
|
1421
|
-
e
|
|
1422
|
-
);
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1323
|
+
}
|
|
1324
|
+
if (backgroundValue != null) {
|
|
1325
|
+
taskRunning = true;
|
|
1326
|
+
final Long timeout = Long.parseLong(backgroundValue);
|
|
1327
|
+
if (backgroundTask != null) {
|
|
1328
|
+
backgroundTask.interrupt();
|
|
1425
1329
|
}
|
|
1426
|
-
startNewThread(
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
current.getVersionName() +
|
|
1434
|
-
". " +
|
|
1435
|
-
messageUpdate
|
|
1436
|
-
);
|
|
1437
|
-
|
|
1438
|
-
final String url = res.getString("url");
|
|
1439
|
-
final String sessionKey = res.has("sessionKey")
|
|
1440
|
-
? res.getString("sessionKey")
|
|
1441
|
-
: "";
|
|
1442
|
-
final String checksum = res.has("checksum")
|
|
1443
|
-
? res.getString("checksum")
|
|
1444
|
-
: "";
|
|
1445
|
-
|
|
1446
|
-
if (res.has("manifest")) {
|
|
1447
|
-
// Handle manifest-based download
|
|
1448
|
-
JSONArray manifest = res.getJSONArray("manifest");
|
|
1449
|
-
CapacitorUpdaterPlugin.this.implementation.downloadBackground(
|
|
1450
|
-
url,
|
|
1451
|
-
latestVersionName,
|
|
1452
|
-
sessionKey,
|
|
1453
|
-
checksum,
|
|
1454
|
-
manifest
|
|
1455
|
-
);
|
|
1456
|
-
} else {
|
|
1457
|
-
// Handle single file download (existing code)
|
|
1458
|
-
CapacitorUpdaterPlugin.this.implementation.downloadBackground(
|
|
1459
|
-
url,
|
|
1460
|
-
latestVersionName,
|
|
1461
|
-
sessionKey,
|
|
1462
|
-
checksum,
|
|
1463
|
-
null
|
|
1464
|
-
);
|
|
1465
|
-
}
|
|
1466
|
-
} catch (final Exception e) {
|
|
1467
|
-
Log.e(CapacitorUpdater.TAG, "error downloading file", e);
|
|
1468
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1469
|
-
"Error downloading file",
|
|
1470
|
-
latestVersionName,
|
|
1471
|
-
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle(),
|
|
1472
|
-
true
|
|
1473
|
-
);
|
|
1474
|
-
}
|
|
1475
|
-
});
|
|
1476
|
-
} else {
|
|
1477
|
-
Log.i(
|
|
1478
|
-
CapacitorUpdater.TAG,
|
|
1479
|
-
"No need to update, " +
|
|
1480
|
-
current.getId() +
|
|
1481
|
-
" is the latest bundle."
|
|
1482
|
-
);
|
|
1483
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1484
|
-
"No need to update",
|
|
1485
|
-
latestVersionName,
|
|
1486
|
-
current,
|
|
1487
|
-
false
|
|
1488
|
-
);
|
|
1489
|
-
}
|
|
1490
|
-
} catch (final JSONException e) {
|
|
1491
|
-
Log.e(CapacitorUpdater.TAG, "error parsing JSON", e);
|
|
1492
|
-
CapacitorUpdaterPlugin.this.endBackGroundTaskWithNotif(
|
|
1493
|
-
"Error parsing JSON",
|
|
1494
|
-
current.getVersionName(),
|
|
1495
|
-
current,
|
|
1496
|
-
true
|
|
1330
|
+
backgroundTask = startNewThread(
|
|
1331
|
+
() -> {
|
|
1332
|
+
taskRunning = false;
|
|
1333
|
+
_checkCancelDelay(false);
|
|
1334
|
+
installNext();
|
|
1335
|
+
},
|
|
1336
|
+
timeout
|
|
1497
1337
|
);
|
|
1338
|
+
} else {
|
|
1339
|
+
this._checkCancelDelay(false);
|
|
1340
|
+
this.installNext();
|
|
1498
1341
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
private void installNext() {
|
|
1505
|
-
try {
|
|
1506
|
-
Gson gson = new Gson();
|
|
1507
|
-
String delayUpdatePreferences = prefs.getString(
|
|
1508
|
-
DELAY_CONDITION_PREFERENCES,
|
|
1509
|
-
"[]"
|
|
1510
|
-
);
|
|
1511
|
-
Type type = new TypeToken<ArrayList<DelayCondition>>() {}.getType();
|
|
1512
|
-
ArrayList<DelayCondition> delayConditionList = gson.fromJson(
|
|
1513
|
-
delayUpdatePreferences,
|
|
1514
|
-
type
|
|
1515
|
-
);
|
|
1516
|
-
if (delayConditionList != null && !delayConditionList.isEmpty()) {
|
|
1517
|
-
Log.i(
|
|
1518
|
-
CapacitorUpdater.TAG,
|
|
1519
|
-
"Update delayed until delay conditions met"
|
|
1520
|
-
);
|
|
1521
|
-
return;
|
|
1522
|
-
}
|
|
1523
|
-
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
1524
|
-
final BundleInfo next = this.implementation.getNextBundle();
|
|
1525
|
-
|
|
1526
|
-
if (
|
|
1527
|
-
next != null &&
|
|
1528
|
-
!next.isErrorStatus() &&
|
|
1529
|
-
!next.getId().equals(current.getId())
|
|
1530
|
-
) {
|
|
1531
|
-
// There is a next bundle waiting for activation
|
|
1532
|
-
Log.d(CapacitorUpdater.TAG, "Next bundle is: " + next.getVersionName());
|
|
1533
|
-
if (this.implementation.set(next) && this._reload()) {
|
|
1534
|
-
Log.i(
|
|
1535
|
-
CapacitorUpdater.TAG,
|
|
1536
|
-
"Updated to bundle: " + next.getVersionName()
|
|
1537
|
-
);
|
|
1538
|
-
this.implementation.setNextBundle(null);
|
|
1539
|
-
} else {
|
|
1540
|
-
Log.e(
|
|
1541
|
-
CapacitorUpdater.TAG,
|
|
1542
|
-
"Update to bundle: " + next.getVersionName() + " Failed!"
|
|
1543
|
-
);
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
} catch (final Exception e) {
|
|
1547
|
-
Log.e(CapacitorUpdater.TAG, "Error during onActivityStopped", e);
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
private void checkRevert() {
|
|
1552
|
-
// Automatically roll back to fallback version if notifyAppReady has not been called yet
|
|
1553
|
-
final BundleInfo current = this.implementation.getCurrentBundle();
|
|
1554
|
-
|
|
1555
|
-
if (current.isBuiltin()) {
|
|
1556
|
-
Log.i(
|
|
1557
|
-
CapacitorUpdater.TAG,
|
|
1558
|
-
"Built-in bundle is active. We skip the check for notifyAppReady."
|
|
1559
|
-
);
|
|
1560
|
-
return;
|
|
1342
|
+
} catch (final Exception e) {
|
|
1343
|
+
Log.e(CapacitorUpdater.TAG, "Error during onActivityStopped", e);
|
|
1344
|
+
}
|
|
1561
1345
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
"notifyAppReady was not called, roll back current bundle: " +
|
|
1568
|
-
current.getId()
|
|
1569
|
-
);
|
|
1570
|
-
Log.i(
|
|
1571
|
-
CapacitorUpdater.TAG,
|
|
1572
|
-
"Did you forget to call 'notifyAppReady()' in your Capacitor App code?"
|
|
1573
|
-
);
|
|
1574
|
-
final JSObject ret = new JSObject();
|
|
1575
|
-
ret.put("bundle", current.toJSON());
|
|
1576
|
-
this.notifyListeners("updateFailed", ret);
|
|
1577
|
-
this.implementation.sendStats("update_fail", current.getVersionName());
|
|
1578
|
-
this.implementation.setError(current);
|
|
1579
|
-
this._reset(true);
|
|
1580
|
-
if (
|
|
1581
|
-
CapacitorUpdaterPlugin.this.autoDeleteFailed && !current.isBuiltin()
|
|
1582
|
-
) {
|
|
1583
|
-
Log.i(
|
|
1584
|
-
CapacitorUpdater.TAG,
|
|
1585
|
-
"Deleting failing bundle: " + current.getVersionName()
|
|
1586
|
-
);
|
|
1346
|
+
|
|
1347
|
+
private boolean isMainActivity() {
|
|
1348
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
1349
|
+
return false;
|
|
1350
|
+
}
|
|
1587
1351
|
try {
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
);
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
} else {
|
|
1605
|
-
Log.i(
|
|
1606
|
-
CapacitorUpdater.TAG,
|
|
1607
|
-
"notifyAppReady was called. This is fine: " + current.getId()
|
|
1608
|
-
);
|
|
1352
|
+
Context mContext = this.getContext();
|
|
1353
|
+
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
|
1354
|
+
List<ActivityManager.AppTask> runningTasks = activityManager.getAppTasks();
|
|
1355
|
+
if (runningTasks.isEmpty()) {
|
|
1356
|
+
return false;
|
|
1357
|
+
}
|
|
1358
|
+
ActivityManager.RecentTaskInfo runningTask = runningTasks.get(0).getTaskInfo();
|
|
1359
|
+
String className = Objects.requireNonNull(runningTask.baseIntent.getComponent()).getClassName();
|
|
1360
|
+
if (runningTask.topActivity == null) {
|
|
1361
|
+
return false;
|
|
1362
|
+
}
|
|
1363
|
+
String runningActivity = runningTask.topActivity.getClassName();
|
|
1364
|
+
return className.equals(runningActivity);
|
|
1365
|
+
} catch (NullPointerException e) {
|
|
1366
|
+
return false;
|
|
1367
|
+
}
|
|
1609
1368
|
}
|
|
1610
|
-
}
|
|
1611
1369
|
|
|
1612
|
-
|
|
1370
|
+
private void appKilled() {
|
|
1371
|
+
Log.d(CapacitorUpdater.TAG, "onActivityDestroyed: all activity destroyed");
|
|
1372
|
+
this._checkCancelDelay(true);
|
|
1373
|
+
}
|
|
1613
1374
|
|
|
1614
1375
|
@Override
|
|
1615
|
-
public void
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
"ms, then check for notifyAppReady"
|
|
1622
|
-
);
|
|
1623
|
-
Thread.sleep(CapacitorUpdaterPlugin.this.appReadyTimeout);
|
|
1624
|
-
CapacitorUpdaterPlugin.this.checkRevert();
|
|
1625
|
-
CapacitorUpdaterPlugin.this.appReadyCheck = null;
|
|
1626
|
-
} catch (final InterruptedException e) {
|
|
1627
|
-
Log.i(
|
|
1628
|
-
CapacitorUpdater.TAG,
|
|
1629
|
-
DeferredNotifyAppReadyCheck.class.getName() + " was interrupted."
|
|
1630
|
-
);
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
public void appMovedToForeground() {
|
|
1636
|
-
final BundleInfo current =
|
|
1637
|
-
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
1638
|
-
CapacitorUpdaterPlugin.this.implementation.sendStats(
|
|
1639
|
-
"app_moved_to_foreground",
|
|
1640
|
-
current.getVersionName()
|
|
1641
|
-
);
|
|
1642
|
-
this._checkCancelDelay(false);
|
|
1643
|
-
if (
|
|
1644
|
-
CapacitorUpdaterPlugin.this._isAutoUpdateEnabled() &&
|
|
1645
|
-
(this.backgroundDownloadTask == null ||
|
|
1646
|
-
!this.backgroundDownloadTask.isAlive())
|
|
1647
|
-
) {
|
|
1648
|
-
this.backgroundDownloadTask = this.backgroundDownload();
|
|
1649
|
-
} else {
|
|
1650
|
-
Log.i(CapacitorUpdater.TAG, "Auto update is disabled");
|
|
1651
|
-
this.sendReadyToJs(current, "disabled");
|
|
1652
|
-
}
|
|
1653
|
-
this.checkAppReady();
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
public void appMovedToBackground() {
|
|
1657
|
-
final BundleInfo current =
|
|
1658
|
-
CapacitorUpdaterPlugin.this.implementation.getCurrentBundle();
|
|
1659
|
-
CapacitorUpdaterPlugin.this.implementation.sendStats(
|
|
1660
|
-
"app_moved_to_background",
|
|
1661
|
-
current.getVersionName()
|
|
1662
|
-
);
|
|
1663
|
-
Log.i(CapacitorUpdater.TAG, "Checking for pending update");
|
|
1664
|
-
try {
|
|
1665
|
-
Gson gson = new Gson();
|
|
1666
|
-
String delayUpdatePreferences = prefs.getString(
|
|
1667
|
-
DELAY_CONDITION_PREFERENCES,
|
|
1668
|
-
"[]"
|
|
1669
|
-
);
|
|
1670
|
-
Type type = new TypeToken<ArrayList<DelayCondition>>() {}.getType();
|
|
1671
|
-
ArrayList<DelayCondition> delayConditionList = gson.fromJson(
|
|
1672
|
-
delayUpdatePreferences,
|
|
1673
|
-
type
|
|
1674
|
-
);
|
|
1675
|
-
String backgroundValue = null;
|
|
1676
|
-
for (DelayCondition delayCondition : delayConditionList) {
|
|
1677
|
-
if (delayCondition.getKind().toString().equals("background")) {
|
|
1678
|
-
String value = delayCondition.getValue();
|
|
1679
|
-
backgroundValue = (value != null && !value.isEmpty()) ? value : "0";
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
if (backgroundValue != null) {
|
|
1683
|
-
taskRunning = true;
|
|
1684
|
-
final Long timeout = Long.parseLong(backgroundValue);
|
|
1685
|
-
if (backgroundTask != null) {
|
|
1686
|
-
backgroundTask.interrupt();
|
|
1687
|
-
}
|
|
1688
|
-
backgroundTask = startNewThread(
|
|
1689
|
-
() -> {
|
|
1690
|
-
taskRunning = false;
|
|
1691
|
-
_checkCancelDelay(false);
|
|
1692
|
-
installNext();
|
|
1693
|
-
},
|
|
1694
|
-
timeout
|
|
1695
|
-
);
|
|
1696
|
-
} else {
|
|
1697
|
-
this._checkCancelDelay(false);
|
|
1698
|
-
this.installNext();
|
|
1699
|
-
}
|
|
1700
|
-
} catch (final Exception e) {
|
|
1701
|
-
Log.e(CapacitorUpdater.TAG, "Error during onActivityStopped", e);
|
|
1376
|
+
public void handleOnStart() {
|
|
1377
|
+
if (isPreviousMainActivity) {
|
|
1378
|
+
this.appMovedToForeground();
|
|
1379
|
+
}
|
|
1380
|
+
Log.i(CapacitorUpdater.TAG, "onActivityStarted " + getActivity().getClass().getName());
|
|
1381
|
+
isPreviousMainActivity = true;
|
|
1702
1382
|
}
|
|
1703
|
-
}
|
|
1704
1383
|
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
ActivityManager activityManager =
|
|
1712
|
-
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
|
1713
|
-
List<ActivityManager.AppTask> runningTasks =
|
|
1714
|
-
activityManager.getAppTasks();
|
|
1715
|
-
if (runningTasks.isEmpty()) {
|
|
1716
|
-
return false;
|
|
1717
|
-
}
|
|
1718
|
-
ActivityManager.RecentTaskInfo runningTask = runningTasks
|
|
1719
|
-
.get(0)
|
|
1720
|
-
.getTaskInfo();
|
|
1721
|
-
String className = Objects.requireNonNull(
|
|
1722
|
-
runningTask.baseIntent.getComponent()
|
|
1723
|
-
).getClassName();
|
|
1724
|
-
if (runningTask.topActivity == null) {
|
|
1725
|
-
return false;
|
|
1726
|
-
}
|
|
1727
|
-
String runningActivity = runningTask.topActivity.getClassName();
|
|
1728
|
-
return className.equals(runningActivity);
|
|
1729
|
-
} catch (NullPointerException e) {
|
|
1730
|
-
return false;
|
|
1384
|
+
@Override
|
|
1385
|
+
public void handleOnStop() {
|
|
1386
|
+
isPreviousMainActivity = isMainActivity();
|
|
1387
|
+
if (isPreviousMainActivity) {
|
|
1388
|
+
this.appMovedToBackground();
|
|
1389
|
+
}
|
|
1731
1390
|
}
|
|
1732
|
-
}
|
|
1733
1391
|
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
public void handleOnStart() {
|
|
1741
|
-
if (isPreviousMainActivity) {
|
|
1742
|
-
this.appMovedToForeground();
|
|
1743
|
-
}
|
|
1744
|
-
Log.i(
|
|
1745
|
-
CapacitorUpdater.TAG,
|
|
1746
|
-
"onActivityStarted " + getActivity().getClass().getName()
|
|
1747
|
-
);
|
|
1748
|
-
isPreviousMainActivity = true;
|
|
1749
|
-
}
|
|
1750
|
-
|
|
1751
|
-
@Override
|
|
1752
|
-
public void handleOnStop() {
|
|
1753
|
-
isPreviousMainActivity = isMainActivity();
|
|
1754
|
-
if (isPreviousMainActivity) {
|
|
1755
|
-
this.appMovedToBackground();
|
|
1392
|
+
@Override
|
|
1393
|
+
public void handleOnResume() {
|
|
1394
|
+
if (backgroundTask != null && taskRunning) {
|
|
1395
|
+
backgroundTask.interrupt();
|
|
1396
|
+
}
|
|
1397
|
+
this.implementation.activity = getActivity();
|
|
1756
1398
|
}
|
|
1757
|
-
}
|
|
1758
1399
|
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
backgroundTask.interrupt();
|
|
1400
|
+
@Override
|
|
1401
|
+
public void handleOnPause() {
|
|
1402
|
+
this.implementation.activity = getActivity();
|
|
1763
1403
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
public void handleOnDestroy() {
|
|
1774
|
-
Log.i(
|
|
1775
|
-
CapacitorUpdater.TAG,
|
|
1776
|
-
"onActivityDestroyed " + getActivity().getClass().getName()
|
|
1777
|
-
);
|
|
1778
|
-
this.implementation.activity = getActivity();
|
|
1779
|
-
counterActivityCreate--;
|
|
1780
|
-
if (counterActivityCreate == 0) {
|
|
1781
|
-
this.appKilled();
|
|
1404
|
+
|
|
1405
|
+
@Override
|
|
1406
|
+
public void handleOnDestroy() {
|
|
1407
|
+
Log.i(CapacitorUpdater.TAG, "onActivityDestroyed " + getActivity().getClass().getName());
|
|
1408
|
+
this.implementation.activity = getActivity();
|
|
1409
|
+
counterActivityCreate--;
|
|
1410
|
+
if (counterActivityCreate == 0) {
|
|
1411
|
+
this.appKilled();
|
|
1412
|
+
}
|
|
1782
1413
|
}
|
|
1783
|
-
}
|
|
1784
1414
|
}
|