@capgo/capacitor-updater 3.0.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/CHANGELOG.md +326 -0
- package/CapacitorUpdater.podspec +20 -0
- package/LICENCE +661 -0
- package/README.md +456 -0
- package/android/build.gradle +60 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +402 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +404 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +523 -0
- package/dist/esm/definitions.d.ts +132 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +36 -0
- package/dist/esm/web.js +49 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +65 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +68 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/CapacitorUpdater.swift +266 -0
- package/ios/Plugin/CapacitorUpdaterPlugin.h +10 -0
- package/ios/Plugin/CapacitorUpdaterPlugin.m +18 -0
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +307 -0
- package/ios/Plugin/Info.plist +28 -0
- package/package.json +85 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
package ee.forgr.capacitor_updater;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.app.Application;
|
|
5
|
+
import android.content.SharedPreferences;
|
|
6
|
+
import android.content.pm.PackageInfo;
|
|
7
|
+
import android.content.pm.PackageManager;
|
|
8
|
+
import android.os.Build;
|
|
9
|
+
import android.os.Bundle;
|
|
10
|
+
import android.util.Log;
|
|
11
|
+
|
|
12
|
+
import androidx.annotation.NonNull;
|
|
13
|
+
import androidx.annotation.Nullable;
|
|
14
|
+
import androidx.annotation.RequiresApi;
|
|
15
|
+
|
|
16
|
+
import com.getcapacitor.CapConfig;
|
|
17
|
+
import com.getcapacitor.JSArray;
|
|
18
|
+
import com.getcapacitor.JSObject;
|
|
19
|
+
import com.getcapacitor.Plugin;
|
|
20
|
+
import com.getcapacitor.PluginCall;
|
|
21
|
+
import com.getcapacitor.PluginMethod;
|
|
22
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
23
|
+
import io.github.g00fy2.versioncompare.Version;
|
|
24
|
+
|
|
25
|
+
import org.json.JSONException;
|
|
26
|
+
|
|
27
|
+
import java.io.IOException;
|
|
28
|
+
import java.util.ArrayList;
|
|
29
|
+
|
|
30
|
+
@CapacitorPlugin(name = "CapacitorUpdater")
|
|
31
|
+
public class CapacitorUpdaterPlugin extends Plugin implements Application.ActivityLifecycleCallbacks {
|
|
32
|
+
private String TAG = "Capacitor-updater";
|
|
33
|
+
private CapacitorUpdater implementation;
|
|
34
|
+
private SharedPreferences prefs;
|
|
35
|
+
private SharedPreferences.Editor editor;
|
|
36
|
+
private static final String autoUpdateUrlDefault = "https://capgo.app/api/auto_update";
|
|
37
|
+
private static final String statsUrlDefault = "https://capgo.app/api/stats";
|
|
38
|
+
private String autoUpdateUrl = "";
|
|
39
|
+
private Version currentVersionNative;
|
|
40
|
+
private Boolean autoUpdate = false;
|
|
41
|
+
private Boolean resetWhenUpdate = true;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@Override
|
|
45
|
+
public void load() {
|
|
46
|
+
super.load();
|
|
47
|
+
this.prefs = this.getContext().getSharedPreferences("CapWebViewSettings", Activity.MODE_PRIVATE);
|
|
48
|
+
this.editor = prefs.edit();
|
|
49
|
+
try {
|
|
50
|
+
implementation = new CapacitorUpdater(this.getContext(), this);
|
|
51
|
+
PackageInfo pInfo = this.getContext().getPackageManager().getPackageInfo(this.getContext().getPackageName(), 0);
|
|
52
|
+
currentVersionNative = new Version(pInfo.versionName);
|
|
53
|
+
} catch (PackageManager.NameNotFoundException e) {
|
|
54
|
+
e.printStackTrace();
|
|
55
|
+
return;
|
|
56
|
+
} catch (Exception ex) {
|
|
57
|
+
Log.e(TAG, "Error get currentVersionNative", ex);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
CapConfig config = CapConfig.loadDefault(getActivity());
|
|
61
|
+
implementation.appId = config.getString("appId", "");
|
|
62
|
+
implementation.statsUrl = getConfig().getString("statsUrl", statsUrlDefault);
|
|
63
|
+
this.autoUpdateUrl = getConfig().getString("autoUpdateUrl", autoUpdateUrlDefault);
|
|
64
|
+
this.autoUpdate = getConfig().getBoolean("autoUpdate", false);
|
|
65
|
+
resetWhenUpdate = getConfig().getBoolean("resetWhenUpdate", true);
|
|
66
|
+
if (resetWhenUpdate) {
|
|
67
|
+
Version LatestVersionNative = new Version(prefs.getString("LatestVersionNative", ""));
|
|
68
|
+
try {
|
|
69
|
+
if (!LatestVersionNative.equals("") && currentVersionNative.getMajor() > LatestVersionNative.getMajor()) {
|
|
70
|
+
this._reset(false);
|
|
71
|
+
editor.putString("LatestVersionAutoUpdate", "");
|
|
72
|
+
editor.putString("LatestVersionNameAutoUpdate", "");
|
|
73
|
+
ArrayList<String> res = implementation.list();
|
|
74
|
+
for (int i = 0; i < res.size(); i++) {
|
|
75
|
+
try {
|
|
76
|
+
implementation.delete(res.get(i), "");
|
|
77
|
+
} catch (IOException e) {
|
|
78
|
+
e.printStackTrace();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
editor.putString("LatestVersionNative", currentVersionNative.toString());
|
|
83
|
+
editor.commit();
|
|
84
|
+
} catch (Exception ex) {
|
|
85
|
+
Log.e("CapacitorUpdater", "Cannot get the current version" + ex.getMessage());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!autoUpdate || this.autoUpdateUrl.equals("")) return;
|
|
89
|
+
Application application = (Application) this.getContext().getApplicationContext();
|
|
90
|
+
application.registerActivityLifecycleCallbacks(this);
|
|
91
|
+
onActivityStarted(getActivity());
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public void notifyDownload(int percent) {
|
|
95
|
+
JSObject ret = new JSObject();
|
|
96
|
+
ret.put("percent", percent);
|
|
97
|
+
notifyListeners("download", ret);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@PluginMethod
|
|
101
|
+
public void getId(PluginCall call) {
|
|
102
|
+
JSObject ret = new JSObject();
|
|
103
|
+
ret.put("id", implementation.deviceID);
|
|
104
|
+
call.resolve(ret);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@PluginMethod
|
|
108
|
+
public void download(PluginCall call) {
|
|
109
|
+
new Thread(new Runnable(){
|
|
110
|
+
@Override
|
|
111
|
+
public void run() {
|
|
112
|
+
String url = call.getString("url");
|
|
113
|
+
String res = implementation.download(url);
|
|
114
|
+
if (!res.equals("")) {
|
|
115
|
+
JSObject ret = new JSObject();
|
|
116
|
+
ret.put("version", res);
|
|
117
|
+
call.resolve(ret);
|
|
118
|
+
} else {
|
|
119
|
+
call.reject("download failed");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}).start();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private boolean _reload() {
|
|
126
|
+
String pathHot = implementation.getLastPathHot();
|
|
127
|
+
this.bridge.setServerBasePath(pathHot);
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@PluginMethod
|
|
132
|
+
public void reload(PluginCall call) {
|
|
133
|
+
if (this._reload()) {
|
|
134
|
+
call.resolve();
|
|
135
|
+
} else {
|
|
136
|
+
call.reject("reload failed");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@PluginMethod
|
|
141
|
+
public void set(PluginCall call) {
|
|
142
|
+
String version = call.getString("version");
|
|
143
|
+
String versionName = call.getString("versionName", version);
|
|
144
|
+
Boolean res = implementation.set(version, versionName);
|
|
145
|
+
|
|
146
|
+
if (!res) {
|
|
147
|
+
call.reject("Update failed, version " + version + " doesn't exist");
|
|
148
|
+
} else {
|
|
149
|
+
this.reload(call);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@PluginMethod
|
|
154
|
+
public void delete(PluginCall call) {
|
|
155
|
+
String version = call.getString("version");
|
|
156
|
+
try {
|
|
157
|
+
Boolean res = implementation.delete(version, "");
|
|
158
|
+
if (res) {
|
|
159
|
+
call.resolve();
|
|
160
|
+
} else {
|
|
161
|
+
call.reject("Delete failed, version " + version + " doesn't exist");
|
|
162
|
+
}
|
|
163
|
+
} catch(IOException ex) {
|
|
164
|
+
Log.e("CapacitorUpdater", "An unexpected error occurred during deletion of folder. Message: " + ex.getMessage());
|
|
165
|
+
call.reject("An unexpected error occurred during deletion of folder.");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@PluginMethod
|
|
170
|
+
public void list(PluginCall call) {
|
|
171
|
+
ArrayList<String> res = implementation.list();
|
|
172
|
+
JSObject ret = new JSObject();
|
|
173
|
+
ret.put("versions", new JSArray(res));
|
|
174
|
+
call.resolve(ret);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private boolean _reset(Boolean toAutoUpdate) {
|
|
178
|
+
String version = prefs.getString("LatestVersionAutoUpdate", "");
|
|
179
|
+
String versionName = prefs.getString("LatestVersionNameAutoUpdate", "");
|
|
180
|
+
if (toAutoUpdate && !version.equals("") && !versionName.equals("")) {
|
|
181
|
+
Boolean res = implementation.set(version, versionName);
|
|
182
|
+
return res && this._reload();
|
|
183
|
+
}
|
|
184
|
+
implementation.reset();
|
|
185
|
+
String pathHot = implementation.getLastPathHot();
|
|
186
|
+
this.bridge.setServerAssetPath(pathHot);
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@PluginMethod
|
|
191
|
+
public void reset(PluginCall call) {
|
|
192
|
+
Boolean toAutoUpdate = call.getBoolean("toAutoUpdate");
|
|
193
|
+
if (this._reset(toAutoUpdate)) {
|
|
194
|
+
call.resolve();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
call.reject("✨ Capacitor-updater: Reset failed");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@PluginMethod
|
|
201
|
+
public void versionName(PluginCall call) {
|
|
202
|
+
String name = implementation.getVersionName();
|
|
203
|
+
JSObject ret = new JSObject();
|
|
204
|
+
ret.put("versionName", name);
|
|
205
|
+
call.resolve(ret);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
@PluginMethod
|
|
209
|
+
public void current(PluginCall call) {
|
|
210
|
+
String pathHot = implementation.getLastPathHot();
|
|
211
|
+
JSObject ret = new JSObject();
|
|
212
|
+
String current = pathHot.length() >= 10 ? pathHot.substring(pathHot.length() - 10) : "builtin";
|
|
213
|
+
ret.put("current", current);
|
|
214
|
+
ret.put("currentNative", currentVersionNative);
|
|
215
|
+
call.resolve(ret);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@PluginMethod
|
|
219
|
+
public void notifyAppReady(PluginCall call) {
|
|
220
|
+
editor.putBoolean("notifyAppReady", true);
|
|
221
|
+
editor.commit();
|
|
222
|
+
call.resolve();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
@PluginMethod
|
|
226
|
+
public void delayUpdate(PluginCall call) {
|
|
227
|
+
editor.putBoolean("delayUpdate", true);
|
|
228
|
+
editor.commit();
|
|
229
|
+
call.resolve();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@PluginMethod
|
|
233
|
+
public void cancelDelay(PluginCall call) {
|
|
234
|
+
editor.putBoolean("delayUpdate", false);
|
|
235
|
+
editor.commit();
|
|
236
|
+
call.resolve();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@Override
|
|
240
|
+
public void onActivityStarted(@NonNull Activity activity) {
|
|
241
|
+
// disableRevert disableBreaking
|
|
242
|
+
String currentVersionNative = "";
|
|
243
|
+
try {
|
|
244
|
+
PackageInfo pInfo = this.getContext().getPackageManager().getPackageInfo(this.getContext().getPackageName(), 0);
|
|
245
|
+
currentVersionNative = pInfo.versionName;
|
|
246
|
+
} catch (Exception ex) {
|
|
247
|
+
Log.e(TAG, "Error get stats", ex);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
Log.i(TAG, "Check for update in the server");
|
|
251
|
+
if (autoUpdateUrl.equals("")) return;
|
|
252
|
+
String finalCurrentVersionNative = currentVersionNative;
|
|
253
|
+
new Thread(new Runnable(){
|
|
254
|
+
@Override
|
|
255
|
+
public void run() {
|
|
256
|
+
implementation.getLatest(autoUpdateUrl, (res) -> {
|
|
257
|
+
try {
|
|
258
|
+
String currentVersion = implementation.getVersionName();
|
|
259
|
+
String newVersion = (String) res.get("version");
|
|
260
|
+
JSObject ret = new JSObject();
|
|
261
|
+
ret.put("newVersion", newVersion);
|
|
262
|
+
if (res.has("message")) {
|
|
263
|
+
Log.i(TAG, "Capacitor-updater: " + res.get("message"));
|
|
264
|
+
if (res.getBoolean("major")) {
|
|
265
|
+
notifyListeners("majorAvailable", ret);
|
|
266
|
+
}
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
String failingVersion = prefs.getString("failingVersion", "");
|
|
270
|
+
if (!newVersion.equals("") && !newVersion.equals(failingVersion)) {
|
|
271
|
+
new Thread(new Runnable(){
|
|
272
|
+
@Override
|
|
273
|
+
public void run() {
|
|
274
|
+
try {
|
|
275
|
+
String dl = implementation.download((String) res.get("url"));
|
|
276
|
+
if (dl.equals("")) {
|
|
277
|
+
Log.i(TAG, "Download version: " + newVersion + " failed");
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
Log.i(TAG, "New version: " + newVersion + " found. Current is " + (currentVersion.equals("") ? "builtin" : currentVersion) + ", next backgrounding will trigger update");
|
|
281
|
+
editor.putString("nextVersion", dl);
|
|
282
|
+
editor.putString("nextVersionName", (String) res.get("version"));
|
|
283
|
+
editor.commit();
|
|
284
|
+
notifyListeners("updateAvailable", ret);
|
|
285
|
+
} catch (JSONException e) {
|
|
286
|
+
e.printStackTrace();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}).start();
|
|
290
|
+
} else {
|
|
291
|
+
Log.i(TAG, "No need to update, " + currentVersion + " is the latest");
|
|
292
|
+
}
|
|
293
|
+
} catch (JSONException e) {
|
|
294
|
+
e.printStackTrace();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}).start();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@Override
|
|
302
|
+
public void onActivityStopped(@NonNull Activity activity) {
|
|
303
|
+
String pathHot = implementation.getLastPathHot();
|
|
304
|
+
Log.i(TAG, "Check for waiting update");
|
|
305
|
+
String nextVersion = prefs.getString("nextVersion", "");
|
|
306
|
+
Boolean delayUpdate = prefs.getBoolean("delayUpdate", false);
|
|
307
|
+
editor.putBoolean("delayUpdate", false);
|
|
308
|
+
editor.commit();
|
|
309
|
+
if (delayUpdate) {
|
|
310
|
+
Log.i(TAG, "Update delayed to next backgrounding");
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
String nextVersionName = prefs.getString("nextVersionName", "");
|
|
314
|
+
String pastVersion = prefs.getString("pastVersion", "");
|
|
315
|
+
String pastVersionName = prefs.getString("pastVersionName", "");
|
|
316
|
+
Boolean notifyAppReady = prefs.getBoolean("notifyAppReady", false);
|
|
317
|
+
String tmpCurVersion = implementation.getLastPathHot();
|
|
318
|
+
String curVersion = tmpCurVersion.substring(tmpCurVersion.lastIndexOf('/') +1);
|
|
319
|
+
String curVersionName = implementation.getVersionName();
|
|
320
|
+
if (!nextVersion.equals("") && !nextVersionName.equals("")) {
|
|
321
|
+
Boolean res = implementation.set(nextVersion, nextVersionName);
|
|
322
|
+
if (res && this._reload()) {
|
|
323
|
+
Log.i(TAG, "Auto update to version: " + nextVersionName);
|
|
324
|
+
editor.putString("LatestVersionAutoUpdate", nextVersion);
|
|
325
|
+
editor.putString("LatestVersionNameAutoUpdate", nextVersionName);
|
|
326
|
+
editor.putString("nextVersion", "");
|
|
327
|
+
editor.putString("nextVersionName", "");
|
|
328
|
+
editor.putString("pastVersion", curVersion);
|
|
329
|
+
editor.putString("pastVersionName", curVersionName);
|
|
330
|
+
editor.putBoolean("notifyAppReady", false);
|
|
331
|
+
editor.commit();
|
|
332
|
+
} else {
|
|
333
|
+
Log.i(TAG, "Auto update to version: " + nextVersionName + "Failed");
|
|
334
|
+
}
|
|
335
|
+
} else if (!notifyAppReady && !pathHot.equals("public")) {
|
|
336
|
+
Log.i(TAG, "notifyAppReady never trigger");
|
|
337
|
+
Log.i(TAG, "Version: " + curVersionName + ", is considered broken");
|
|
338
|
+
Log.i(TAG, "Will downgraded to version: " + (pastVersionName.equals("") ? "builtin" : pastVersionName) + " for next start");
|
|
339
|
+
Log.i(TAG, "Don't forget to trigger 'notifyAppReady()' in js code to validate a version.");
|
|
340
|
+
if (!pastVersion.equals("") && !pastVersionName.equals("")) {
|
|
341
|
+
Boolean res = implementation.set(pastVersion, pastVersionName);
|
|
342
|
+
if (res && this._reload()) {
|
|
343
|
+
Log.i(TAG, "Revert to version: " + (pastVersionName.equals("") ? "builtin" : pastVersionName));
|
|
344
|
+
editor.putString("LatestVersionAutoUpdate", pastVersion);
|
|
345
|
+
editor.putString("LatestVersionNameAutoUpdate", pastVersionName);
|
|
346
|
+
editor.putString("pastVersion", "");
|
|
347
|
+
editor.putString("pastVersionName", "");
|
|
348
|
+
editor.commit();
|
|
349
|
+
} else {
|
|
350
|
+
Log.i(TAG, "Revert to version: " + (pastVersionName.equals("") ? "builtin" : pastVersionName) + "Failed");
|
|
351
|
+
}
|
|
352
|
+
} else {
|
|
353
|
+
if (this._reset(false)) {
|
|
354
|
+
editor.putString("LatestVersionAutoUpdate", "");
|
|
355
|
+
editor.putString("LatestVersionNameAutoUpdate", "");
|
|
356
|
+
Log.i(TAG, "Auto reset done");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
editor.putString("failingVersion", curVersionName);
|
|
360
|
+
editor.commit();
|
|
361
|
+
try {
|
|
362
|
+
Boolean res = implementation.delete(curVersion, curVersionName);
|
|
363
|
+
if (res) {
|
|
364
|
+
Log.i(TAG, "Delete failing version: " + curVersionName);
|
|
365
|
+
}
|
|
366
|
+
} catch (IOException e) {
|
|
367
|
+
e.printStackTrace();
|
|
368
|
+
}
|
|
369
|
+
} else if (!pastVersion.equals("")) {
|
|
370
|
+
Log.i(TAG, "Validated version: " + curVersionName);
|
|
371
|
+
try {
|
|
372
|
+
Boolean res = implementation.delete(pastVersion, pastVersionName);
|
|
373
|
+
if (res) {
|
|
374
|
+
Log.i(TAG, "Delete past version: " + pastVersionName);
|
|
375
|
+
}
|
|
376
|
+
} catch (IOException e) {
|
|
377
|
+
e.printStackTrace();
|
|
378
|
+
}
|
|
379
|
+
editor.putString("pastVersion", "");
|
|
380
|
+
editor.putString("pastVersionName", "");
|
|
381
|
+
editor.commit();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// not use but necessary here to remove warnings
|
|
386
|
+
@Override
|
|
387
|
+
public void onActivityResumed(@NonNull Activity activity) {
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
@Override
|
|
391
|
+
public void onActivityPaused(@NonNull Activity activity) {
|
|
392
|
+
}
|
|
393
|
+
@Override
|
|
394
|
+
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
@Override
|
|
398
|
+
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
@Override
|
|
402
|
+
public void onActivityDestroyed(@NonNull Activity activity) {
|
|
403
|
+
}
|
|
404
|
+
}
|
|
File without changes
|