@capgo/capacitor-updater 4.13.8 → 4.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,6 @@
1
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  package="ee.forgr.capacitor_updater">
3
+ <application>
4
+ <service android:name="ee.forgr.capacitor_updater.DownloadService" />
5
+ </application>
3
6
  </manifest>
@@ -1,7 +1,13 @@
1
1
  package ee.forgr.capacitor_updater;
2
2
 
3
+ import android.app.Activity;
4
+ import android.content.BroadcastReceiver;
5
+ import android.content.Context;
6
+ import android.content.Intent;
7
+ import android.content.IntentFilter;
3
8
  import android.content.SharedPreferences;
4
9
  import android.os.Build;
10
+ import android.os.Bundle;
5
11
  import android.util.Base64;
6
12
  import android.util.Log;
7
13
  import com.android.volley.BuildConfig;
@@ -54,7 +60,7 @@ public class CapacitorUpdater {
54
60
  private static final String bundleDirectory = "versions";
55
61
 
56
62
  public static final String TAG = "Capacitor-updater";
57
- public static final String pluginVersion = "4.13.8";
63
+ public static final String pluginVersion = "4.14.1";
58
64
 
59
65
  public SharedPreferences.Editor editor;
60
66
  public SharedPreferences prefs;
@@ -62,6 +68,7 @@ public class CapacitorUpdater {
62
68
  public RequestQueue requestQueue;
63
69
 
64
70
  public File documentsDir;
71
+ public Activity activity;
65
72
  public String versionBuild = "";
66
73
  public String versionCode = "";
67
74
  public String versionOs = "";
@@ -125,6 +132,10 @@ public class CapacitorUpdater {
125
132
  return;
126
133
  }
127
134
 
135
+ void notifyListeners(final String id, final JSObject res) {
136
+ return;
137
+ }
138
+
128
139
  private String randomString(final int len) {
129
140
  final StringBuilder sb = new StringBuilder(len);
130
141
  for (int i = 0; i < len; i++) sb.append(
@@ -224,6 +235,135 @@ public class CapacitorUpdater {
224
235
  sourceFile.delete();
225
236
  }
226
237
 
238
+ public void onResume() {
239
+ this.activity.registerReceiver(
240
+ receiver,
241
+ new IntentFilter(DownloadService.NOTIFICATION)
242
+ );
243
+ }
244
+
245
+ public void onPause() {
246
+ this.activity.unregisterReceiver(receiver);
247
+ }
248
+
249
+ private BroadcastReceiver receiver = new BroadcastReceiver() {
250
+ @Override
251
+ public void onReceive(Context context, Intent intent) {
252
+ String action = intent.getAction();
253
+ Bundle bundle = intent.getExtras();
254
+ if (bundle != null) {
255
+ if (action == DownloadService.PERCENTDOWNLOAD) {
256
+ String id = bundle.getString(DownloadService.ID);
257
+ int percent = bundle.getInt(DownloadService.PERCENT);
258
+ CapacitorUpdater.this.notifyDownload(id, percent);
259
+ } else if (action == DownloadService.NOTIFICATION) {
260
+ String id = bundle.getString(DownloadService.ID);
261
+ String dest = bundle.getString(DownloadService.FILEDEST);
262
+ String version = bundle.getString(DownloadService.VERSION);
263
+ String sessionKey = bundle.getString(DownloadService.SESSIONKEY);
264
+ String checksum = bundle.getString(DownloadService.CHECKSUM);
265
+ Log.i(
266
+ CapacitorUpdater.TAG,
267
+ "res " +
268
+ id +
269
+ " " +
270
+ dest +
271
+ " " +
272
+ version +
273
+ " " +
274
+ sessionKey +
275
+ " " +
276
+ checksum
277
+ );
278
+ CapacitorUpdater.this.finishBackground(
279
+ id,
280
+ dest,
281
+ version,
282
+ sessionKey,
283
+ checksum
284
+ );
285
+ } else {
286
+ Log.i(TAG, "Unknown action " + action);
287
+ }
288
+ }
289
+ }
290
+ };
291
+
292
+ public void finishBackground(
293
+ String id,
294
+ String dest,
295
+ String version,
296
+ String sessionKey,
297
+ String checksumRes
298
+ ) {
299
+ try {
300
+ final File downloaded = new File(this.documentsDir, dest);
301
+ this.decryptFile(downloaded, sessionKey);
302
+ final String checksum;
303
+ checksum = this.getChecksum(downloaded);
304
+
305
+ this.notifyDownload(id, 71);
306
+ final File unzipped = this.unzip(id, downloaded, this.randomString(10));
307
+ downloaded.delete();
308
+ this.notifyDownload(id, 91);
309
+ final String idName = bundleDirectory + "/" + id;
310
+ this.flattenAssets(unzipped, idName);
311
+ this.notifyDownload(id, 100);
312
+ this.saveBundleInfo(id, null);
313
+ BundleInfo info = new BundleInfo(
314
+ id,
315
+ version,
316
+ BundleStatus.PENDING,
317
+ new Date(System.currentTimeMillis()),
318
+ checksum
319
+ );
320
+ this.saveBundleInfo(id, info);
321
+ if (!checksumRes.equals("") && !checksumRes.equals(checksum)) {
322
+ Log.e(
323
+ CapacitorUpdater.TAG,
324
+ "Error checksum " + info.getChecksum() + " " + checksum
325
+ );
326
+ this.sendStats("checksum_fail", getCurrentBundle().getVersionName());
327
+ final Boolean res = this.delete(info.getId());
328
+ if (res) {
329
+ Log.i(
330
+ CapacitorUpdater.TAG,
331
+ "Failed bundle deleted: " + info.getVersionName()
332
+ );
333
+ }
334
+ return;
335
+ }
336
+ final JSObject ret = new JSObject();
337
+ ret.put("bundle", info.toJSON());
338
+ CapacitorUpdater.this.notifyListeners("updateAvailable", ret);
339
+ this.setNextBundle(info.getId());
340
+ } catch (IOException e) {
341
+ e.printStackTrace();
342
+ }
343
+ }
344
+
345
+ private void downloadFileBackground(
346
+ final String id,
347
+ final String url,
348
+ final String version,
349
+ final String sessionKey,
350
+ final String checksum,
351
+ final String dest
352
+ ) {
353
+ Intent intent = new Intent(this.activity, DownloadService.class);
354
+ intent.putExtra(DownloadService.URL, url);
355
+ intent.putExtra(DownloadService.FILEDEST, dest);
356
+ intent.putExtra(
357
+ DownloadService.DOCDIR,
358
+ this.documentsDir.getAbsolutePath()
359
+ );
360
+ intent.putExtra(DownloadService.ID, id);
361
+ intent.putExtra(DownloadService.VERSION, version);
362
+ intent.putExtra(DownloadService.SESSIONKEY, sessionKey);
363
+ intent.putExtra(DownloadService.CHECKSUM, checksum);
364
+ this.activity.startService(intent);
365
+ }
366
+
227
367
  private File downloadFile(
228
368
  final String id,
229
369
  final String url,
@@ -325,6 +465,35 @@ public class CapacitorUpdater {
325
465
  }
326
466
  }
327
467
 
468
+ public void downloadBackground(
469
+ final String url,
470
+ final String version,
471
+ final String sessionKey,
472
+ final String checksum
473
+ ) {
474
+ final String id = this.randomString(10);
475
+ this.saveBundleInfo(
476
+ id,
477
+ new BundleInfo(
478
+ id,
479
+ version,
480
+ BundleStatus.DOWNLOADING,
481
+ new Date(System.currentTimeMillis()),
482
+ ""
483
+ )
484
+ );
485
+ this.notifyDownload(id, 0);
486
+ this.notifyDownload(id, 5);
487
+ this.downloadFileBackground(
488
+ id,
489
+ url,
490
+ version,
491
+ sessionKey,
492
+ checksum,
493
+ this.randomString(10)
494
+ );
495
+ }
496
+
328
497
  public BundleInfo download(
329
498
  final String url,
330
499
  final String version,
@@ -81,11 +81,17 @@ public class CapacitorUpdaterPlugin
81
81
  public void notifyDownload(final String id, final int percent) {
82
82
  CapacitorUpdaterPlugin.this.notifyDownload(id, percent);
83
83
  }
84
+
85
+ @Override
86
+ public void notifyListeners(final String id, final JSObject res) {
87
+ CapacitorUpdaterPlugin.this.notifyListeners(id, res);
88
+ }
84
89
  };
85
90
  final PackageInfo pInfo =
86
91
  this.getContext()
87
92
  .getPackageManager()
88
93
  .getPackageInfo(this.getContext().getPackageName(), 0);
94
+ this.implementation.activity = this.getActivity();
89
95
  this.implementation.versionBuild = pInfo.versionName;
90
96
  this.implementation.versionCode = Integer.toString(pInfo.versionCode);
91
97
  this.implementation.requestQueue =
@@ -946,51 +952,11 @@ public class CapacitorUpdaterPlugin
946
952
  final String session_key = res.has("session_key")
947
953
  ? res.getString("session_key")
948
954
  : "";
949
- final BundleInfo next =
950
- CapacitorUpdaterPlugin.this.implementation.download(
951
- url,
952
- latestVersionName,
953
- session_key
954
- );
955
- final String checksum = res.has("checksum")
956
- ? res.getString("checksum")
957
- : "";
958
- if (
959
- !checksum.equals("") &&
960
- !next.getChecksum().equals(checksum)
961
- ) {
962
- Log.e(
963
- CapacitorUpdater.TAG,
964
- "Error checksum " +
965
- next.getChecksum() +
966
- " " +
967
- checksum
968
- );
969
- CapacitorUpdaterPlugin.this.implementation.sendStats(
970
- "checksum_fail",
971
- current.getVersionName()
972
- );
973
- final Boolean res =
974
- CapacitorUpdaterPlugin.this.implementation.delete(
975
- next.getId()
976
- );
977
- if (res) {
978
- Log.i(
979
- CapacitorUpdater.TAG,
980
- "Failed bundle deleted: " +
981
- next.getVersionName()
982
- );
983
- }
984
- return;
985
- }
986
- final JSObject ret = new JSObject();
987
- ret.put("bundle", next.toJSON());
988
- CapacitorUpdaterPlugin.this.notifyListeners(
989
- "updateAvailable",
990
- ret
991
- );
992
- CapacitorUpdaterPlugin.this.implementation.setNextBundle(
993
- next.getId()
955
+ CapacitorUpdaterPlugin.this.implementation.downloadBackground(
956
+ url,
957
+ latestVersionName,
958
+ session_key,
959
+ res.getString("checksum")
994
960
  );
995
961
  } catch (final Exception e) {
996
962
  Log.e(
@@ -1246,23 +1212,34 @@ public class CapacitorUpdaterPlugin
1246
1212
  if (backgroundTask != null && taskRunning) {
1247
1213
  backgroundTask.interrupt();
1248
1214
  }
1215
+ this.implementation.activity = activity;
1216
+ this.implementation.onResume();
1249
1217
  }
1250
1218
 
1251
1219
  @Override
1252
- public void onActivityPaused(@NonNull final Activity activity) {}
1220
+ public void onActivityPaused(@NonNull final Activity activity) {
1221
+ this.implementation.activity = activity;
1222
+ this.implementation.onPause();
1223
+ }
1253
1224
 
1254
1225
  @Override
1255
1226
  public void onActivityCreated(
1256
1227
  @NonNull final Activity activity,
1257
1228
  @Nullable final Bundle savedInstanceState
1258
- ) {}
1229
+ ) {
1230
+ this.implementation.activity = activity;
1231
+ }
1259
1232
 
1260
1233
  @Override
1261
1234
  public void onActivitySaveInstanceState(
1262
1235
  @NonNull final Activity activity,
1263
1236
  @NonNull final Bundle outState
1264
- ) {}
1237
+ ) {
1238
+ this.implementation.activity = activity;
1239
+ }
1265
1240
 
1266
1241
  @Override
1267
- public void onActivityDestroyed(@NonNull final Activity activity) {}
1242
+ public void onActivityDestroyed(@NonNull final Activity activity) {
1243
+ this.implementation.activity = activity;
1244
+ }
1268
1245
  }
@@ -0,0 +1,120 @@
1
+ package ee.forgr.capacitor_updater;
2
+
3
+ import android.app.IntentService;
4
+ import android.content.Intent;
5
+ import java.io.DataInputStream;
6
+ import java.io.File;
7
+ import java.io.FileOutputStream;
8
+ import java.io.InputStream;
9
+ import java.net.URL;
10
+ import java.net.URLConnection;
11
+
12
+ public class DownloadService extends IntentService {
13
+
14
+ public static final String URL = "URL";
15
+ public static final String ID = "id";
16
+ public static final String PERCENT = "percent";
17
+ public static final String FILEDEST = "filendest";
18
+ public static final String DOCDIR = "docdir";
19
+ public static final String ERROR = "error";
20
+ public static final String VERSION = "version";
21
+ public static final String SESSIONKEY = "sessionkey";
22
+ public static final String CHECKSUM = "checksum";
23
+ public static final String NOTIFICATION = "service receiver";
24
+ public static final String PERCENTDOWNLOAD = "percent receiver";
25
+
26
+ public DownloadService() {
27
+ super("Background DownloadService");
28
+ }
29
+
30
+ private int calcTotalPercent(
31
+ final int percent,
32
+ final int min,
33
+ final int max
34
+ ) {
35
+ return (percent * (max - min)) / 100 + min;
36
+ }
37
+
38
+ // Will be called asynchronously by OS.
39
+ @Override
40
+ protected void onHandleIntent(Intent intent) {
41
+ String url = intent.getStringExtra(URL);
42
+ String id = intent.getStringExtra(ID);
43
+ String documentsDir = intent.getStringExtra(DOCDIR);
44
+ String dest = intent.getStringExtra(FILEDEST);
45
+ String version = intent.getStringExtra(VERSION);
46
+ String sessionKey = intent.getStringExtra(SESSIONKEY);
47
+ String checksum = intent.getStringExtra(CHECKSUM);
48
+
49
+ try {
50
+ final URL u = new URL(url);
51
+ final URLConnection connection = u.openConnection();
52
+ final InputStream is = u.openStream();
53
+ final DataInputStream dis = new DataInputStream(is);
54
+
55
+ final File target = new File(documentsDir, dest);
56
+ target.getParentFile().mkdirs();
57
+ target.createNewFile();
58
+ final FileOutputStream fos = new FileOutputStream(target);
59
+
60
+ final long totalLength = connection.getContentLength();
61
+ final int bufferSize = 1024;
62
+ final byte[] buffer = new byte[bufferSize];
63
+ int length;
64
+
65
+ int bytesRead = bufferSize;
66
+ int percent = 0;
67
+ this.notifyDownload(id, 10);
68
+ while ((length = dis.read(buffer)) > 0) {
69
+ fos.write(buffer, 0, length);
70
+ final int newPercent = (int) ((bytesRead * 100) / totalLength);
71
+ if (totalLength > 1 && newPercent != percent) {
72
+ percent = newPercent;
73
+ this.notifyDownload(id, this.calcTotalPercent(percent, 10, 70));
74
+ }
75
+ bytesRead += length;
76
+ }
77
+ publishResults(dest, id, version, checksum, sessionKey, "");
78
+ } catch (Exception e) {
79
+ e.printStackTrace();
80
+ publishResults(
81
+ "",
82
+ id,
83
+ version,
84
+ checksum,
85
+ sessionKey,
86
+ e.getLocalizedMessage()
87
+ );
88
+ }
89
+ }
90
+
91
+ private void notifyDownload(String id, int percent) {
92
+ Intent intent = new Intent(PERCENTDOWNLOAD);
93
+ intent.putExtra(ID, id);
94
+ intent.putExtra(PERCENT, percent);
95
+ sendBroadcast(intent);
96
+ }
97
+
98
+ private void publishResults(
99
+ String dest,
100
+ String id,
101
+ String version,
102
+ String checksum,
103
+ String sessionKey,
104
+ String error
105
+ ) {
106
+ Intent intent = new Intent(NOTIFICATION);
107
+ if (!dest.equals("")) {
108
+ intent.putExtra(FILEDEST, dest);
109
+ }
110
+ if (!error.equals("")) {
111
+ intent.putExtra(ERROR, error);
112
+ }
113
+ intent.putExtra(ID, id);
114
+ intent.putExtra(VERSION, version);
115
+ intent.putExtra(SESSIONKEY, sessionKey);
116
+ intent.putExtra(CHECKSUM, checksum);
117
+ intent.putExtra(ERROR, error);
118
+ sendBroadcast(intent);
119
+ }
120
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "4.13.8",
3
+ "version": "4.14.1",
4
4
  "license": "LGPL-3.0-only",
5
5
  "description": "OTA update for capacitor apps",
6
6
  "main": "dist/plugin.cjs.js",