@capgo/capacitor-updater 6.7.5 → 6.7.7-alpha.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,5 +1,9 @@
1
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
3
+
2
4
  <application>
3
- <service android:name="ee.forgr.capacitor_updater.DownloadService" />
5
+ <service
6
+ android:name="ee.forgr.capacitor_updater.DownloadService"
7
+ android:exported="false" />
4
8
  </application>
5
9
  </manifest>
@@ -482,11 +482,7 @@ public class CapacitorUpdater {
482
482
  intent.putExtra(DownloadService.IS_MANIFEST, true);
483
483
  }
484
484
 
485
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
486
- this.activity.startForegroundService(intent);
487
- } else {
488
- this.activity.startService(intent);
489
- }
485
+ this.activity.startService(intent);
490
486
  }
491
487
 
492
488
  private void downloadFile(
@@ -502,28 +498,27 @@ public class CapacitorUpdater {
502
498
  target.createNewFile();
503
499
 
504
500
  final long totalLength = connection.getContentLength();
505
- final int bufferSize = 1024;
506
- final byte[] buffer = new byte[bufferSize];
507
- int length;
508
-
509
- int bytesRead = bufferSize;
501
+ int bytesRead = 0;
510
502
  int percent = 0;
511
503
  this.notifyDownload(id, 10);
504
+
512
505
  try (
513
- final InputStream is = connection.getInputStream();
514
- final DataInputStream dis = new DataInputStream(is);
515
- final FileOutputStream fos = new FileOutputStream(target)
506
+ InputStream is = connection.getInputStream();
507
+ DataInputStream dis = new DataInputStream(is);
508
+ FileOutputStream fos = new FileOutputStream(target)
516
509
  ) {
510
+ byte[] buffer = new byte[8192];
511
+ int length;
517
512
  while ((length = dis.read(buffer)) > 0) {
518
513
  fos.write(buffer, 0, length);
514
+ bytesRead += length;
519
515
  final int newPercent = (int) ((bytesRead / (float) totalLength) * 100);
520
516
  if (totalLength > 1 && newPercent != percent) {
521
517
  percent = newPercent;
522
518
  this.notifyDownload(id, this.calcTotalPercent(percent, 10, 70));
523
519
  }
524
- bytesRead += length;
525
520
  }
526
- if (bytesRead == bufferSize) {
521
+ if (bytesRead == 0) {
527
522
  throw new IOException("Failed to download: No data read from URL");
528
523
  }
529
524
  } catch (OutOfMemoryError e) {
@@ -57,7 +57,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
57
57
  private static final String channelUrlDefault =
58
58
  "https://plugin.capgo.app/channel_self";
59
59
 
60
- private final String PLUGIN_VERSION = "6.7.5";
60
+ private final String PLUGIN_VERSION = "6.7.7-alpha.1";
61
61
  private static final String DELAY_CONDITION_PREFERENCES = "";
62
62
 
63
63
  private SharedPreferences.Editor editor;
@@ -6,13 +6,8 @@
6
6
  package ee.forgr.capacitor_updater;
7
7
 
8
8
  import android.app.IntentService;
9
- import android.app.Notification;
10
- import android.app.NotificationChannel;
11
- import android.app.NotificationManager;
12
9
  import android.content.Intent;
13
- import android.os.Build;
14
- import android.os.Handler;
15
- import android.os.Looper;
10
+ import android.os.PowerManager;
16
11
  import android.util.Log;
17
12
  import java.io.*;
18
13
  import java.io.FileInputStream;
@@ -23,7 +18,6 @@ import java.security.MessageDigest;
23
18
  import java.util.ArrayList;
24
19
  import java.util.Arrays;
25
20
  import java.util.List;
26
- import java.util.concurrent.CompletableFuture;
27
21
  import java.util.concurrent.ExecutorService;
28
22
  import java.util.concurrent.Executors;
29
23
  import java.util.concurrent.Future;
@@ -56,15 +50,11 @@ public class DownloadService extends IntentService {
56
50
  public static final String IS_MANIFEST = "is_manifest";
57
51
  public static final String MANIFEST = "manifest";
58
52
  private static final String UPDATE_FILE = "update.dat";
59
- private static final int NOTIFICATION_ID = 1;
60
- private static final long NOTIFICATION_DELAY_MS = 4000; // 4 seconds
61
53
 
62
54
  private final OkHttpClient client = new OkHttpClient.Builder()
63
55
  .protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1))
64
56
  .build();
65
- private Handler handler = new Handler(Looper.getMainLooper());
66
- private Runnable notificationRunnable;
67
- private boolean isNotificationShown = false;
57
+ private PowerManager.WakeLock wakeLock;
68
58
 
69
59
  public DownloadService() {
70
60
  super("Background DownloadService");
@@ -73,40 +63,20 @@ public class DownloadService extends IntentService {
73
63
  @Override
74
64
  public void onCreate() {
75
65
  super.onCreate();
76
- notificationRunnable = () -> startForeground();
77
- handler.postDelayed(notificationRunnable, NOTIFICATION_DELAY_MS);
66
+ PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
67
+ wakeLock = powerManager.newWakeLock(
68
+ PowerManager.PARTIAL_WAKE_LOCK,
69
+ "CapacitorUpdater::DownloadWakeLock"
70
+ );
78
71
  }
79
72
 
80
73
  @Override
81
74
  public void onDestroy() {
82
75
  super.onDestroy();
83
- handler.removeCallbacks(notificationRunnable);
84
- }
85
-
86
- private void startForeground() {
87
- isNotificationShown = true;
88
- String channelId = createNotificationChannel();
89
- Notification.Builder builder = new Notification.Builder(this, channelId)
90
- .setContentTitle("Downloading Update")
91
- .setContentText("Download in progress")
92
- .setSmallIcon(android.R.drawable.stat_sys_download)
93
- .setOngoing(true);
94
-
95
- startForeground(NOTIFICATION_ID, builder.build());
96
- }
97
-
98
- private String createNotificationChannel() {
99
- String channelId = "capacitor_updater_channel";
100
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
101
- NotificationChannel channel = new NotificationChannel(
102
- channelId,
103
- "Capacitor Updater Downloads",
104
- NotificationManager.IMPORTANCE_LOW
105
- );
106
- NotificationManager manager = getSystemService(NotificationManager.class);
107
- manager.createNotificationChannel(channel);
76
+ Log.w(TAG + " DownloadService", "DownloadService killed/destroyed");
77
+ if (wakeLock != null && wakeLock.isHeld()) {
78
+ wakeLock.release();
108
79
  }
109
- return channelId;
110
80
  }
111
81
 
112
82
  private int calcTotalPercent(long downloadedBytes, long contentLength) {
@@ -121,50 +91,58 @@ public class DownloadService extends IntentService {
121
91
 
122
92
  @Override
123
93
  protected void onHandleIntent(Intent intent) {
124
- assert intent != null;
125
- String url = intent.getStringExtra(URL);
126
- String id = intent.getStringExtra(ID);
127
- String documentsDir = intent.getStringExtra(DOCDIR);
128
- String dest = intent.getStringExtra(FILEDEST);
129
- String version = intent.getStringExtra(VERSION);
130
- String sessionKey = intent.getStringExtra(SESSIONKEY);
131
- String checksum = intent.getStringExtra(CHECKSUM);
132
- boolean isManifest = intent.getBooleanExtra(IS_MANIFEST, false);
133
-
134
- Log.d(TAG + " DownloadService", "onHandleIntent isManifest: " + isManifest);
135
- if (isManifest) {
136
- JSONArray manifest = DataManager.getInstance().getAndClearManifest();
137
- if (manifest != null) {
138
- handleManifestDownload(
94
+ try {
95
+ wakeLock.acquire(10 * 60 * 1000L);
96
+ assert intent != null;
97
+ String url = intent.getStringExtra(URL);
98
+ String id = intent.getStringExtra(ID);
99
+ String documentsDir = intent.getStringExtra(DOCDIR);
100
+ String dest = intent.getStringExtra(FILEDEST);
101
+ String version = intent.getStringExtra(VERSION);
102
+ String sessionKey = intent.getStringExtra(SESSIONKEY);
103
+ String checksum = intent.getStringExtra(CHECKSUM);
104
+ boolean isManifest = intent.getBooleanExtra(IS_MANIFEST, false);
105
+
106
+ Log.d(
107
+ TAG + " DownloadService",
108
+ "onHandleIntent isManifest: " + isManifest
109
+ );
110
+ if (isManifest) {
111
+ JSONArray manifest = DataManager.getInstance().getAndClearManifest();
112
+ if (manifest != null) {
113
+ handleManifestDownload(
114
+ id,
115
+ documentsDir,
116
+ dest,
117
+ version,
118
+ sessionKey,
119
+ manifest.toString()
120
+ );
121
+ } else {
122
+ Log.e(TAG + " DownloadService", "Manifest is null");
123
+ publishResults(
124
+ "",
125
+ id,
126
+ version,
127
+ checksum,
128
+ sessionKey,
129
+ "Manifest is null",
130
+ false
131
+ );
132
+ }
133
+ } else {
134
+ handleSingleFileDownload(
135
+ url,
139
136
  id,
140
137
  documentsDir,
141
138
  dest,
142
139
  version,
143
140
  sessionKey,
144
- manifest.toString()
145
- );
146
- } else {
147
- Log.e(TAG + " DownloadService", "Manifest is null");
148
- publishResults(
149
- "",
150
- id,
151
- version,
152
- checksum,
153
- sessionKey,
154
- "Manifest is null",
155
- false
141
+ checksum
156
142
  );
157
143
  }
158
- } else {
159
- handleSingleFileDownload(
160
- url,
161
- id,
162
- documentsDir,
163
- dest,
164
- version,
165
- sessionKey,
166
- checksum
167
- );
144
+ } finally {
145
+ wakeLock.release();
168
146
  }
169
147
  }
170
148
 
@@ -299,7 +277,6 @@ public class DownloadService extends IntentService {
299
277
  Log.e(TAG + " DownloadService", "Error in handleManifestDownload", e);
300
278
  publishResults("", id, version, "", sessionKey, e.getMessage(), true);
301
279
  }
302
- stopForegroundIfNeeded();
303
280
  }
304
281
 
305
282
  private void handleSingleFileDownload(
@@ -317,89 +294,107 @@ public class DownloadService extends IntentService {
317
294
  File tempFile = new File(documentsDir, "temp" + ".tmp"); // Temp file, where the downloaded data is stored
318
295
  try {
319
296
  URL u = new URL(url);
320
- HttpURLConnection httpConn = (HttpURLConnection) u.openConnection();
297
+ HttpURLConnection httpConn = null;
298
+ try {
299
+ httpConn = (HttpURLConnection) u.openConnection();
321
300
 
322
- // Reading progress file (if exist)
323
- long downloadedBytes = 0;
301
+ // Reading progress file (if exist)
302
+ long downloadedBytes = 0;
324
303
 
325
- if (infoFile.exists() && tempFile.exists()) {
326
- try (
327
- BufferedReader reader = new BufferedReader(new FileReader(infoFile))
328
- ) {
329
- String updateVersion = reader.readLine();
330
- if (!updateVersion.equals(version)) {
331
- clearDownloadData(documentsDir);
332
- downloadedBytes = 0;
333
- } else {
334
- downloadedBytes = tempFile.length();
304
+ if (infoFile.exists() && tempFile.exists()) {
305
+ try (
306
+ BufferedReader reader = new BufferedReader(new FileReader(infoFile))
307
+ ) {
308
+ String updateVersion = reader.readLine();
309
+ if (!updateVersion.equals(version)) {
310
+ clearDownloadData(documentsDir);
311
+ downloadedBytes = 0;
312
+ } else {
313
+ downloadedBytes = tempFile.length();
314
+ }
335
315
  }
316
+ } else {
317
+ clearDownloadData(documentsDir);
318
+ downloadedBytes = 0;
336
319
  }
337
- } else {
338
- clearDownloadData(documentsDir);
339
- downloadedBytes = 0;
340
- }
341
320
 
342
- if (downloadedBytes > 0) {
343
- httpConn.setRequestProperty("Range", "bytes=" + downloadedBytes + "-");
344
- }
321
+ if (downloadedBytes > 0) {
322
+ httpConn.setRequestProperty(
323
+ "Range",
324
+ "bytes=" + downloadedBytes + "-"
325
+ );
326
+ }
345
327
 
346
- int responseCode = httpConn.getResponseCode();
328
+ int responseCode = httpConn.getResponseCode();
347
329
 
348
- if (
349
- responseCode == HttpURLConnection.HTTP_OK ||
350
- responseCode == HttpURLConnection.HTTP_PARTIAL
351
- ) {
352
- String contentType = httpConn.getContentType();
353
- long contentLength = httpConn.getContentLength() + downloadedBytes;
330
+ if (
331
+ responseCode == HttpURLConnection.HTTP_OK ||
332
+ responseCode == HttpURLConnection.HTTP_PARTIAL
333
+ ) {
334
+ String contentType = httpConn.getContentType();
335
+ long contentLength = httpConn.getContentLength() + downloadedBytes;
354
336
 
355
- InputStream inputStream = httpConn.getInputStream();
356
- FileOutputStream outputStream = new FileOutputStream(
357
- tempFile,
358
- downloadedBytes > 0
359
- );
360
- if (downloadedBytes == 0) {
361
337
  try (
362
- BufferedWriter writer = new BufferedWriter(new FileWriter(infoFile))
338
+ InputStream inputStream = httpConn.getInputStream();
339
+ FileOutputStream outputStream = new FileOutputStream(
340
+ tempFile,
341
+ downloadedBytes > 0
342
+ )
363
343
  ) {
364
- writer.write(String.valueOf(version));
365
- }
366
- }
367
- // Updating the info file
368
- try (
369
- BufferedWriter writer = new BufferedWriter(new FileWriter(infoFile))
370
- ) {
371
- writer.write(String.valueOf(version));
372
- }
344
+ if (downloadedBytes == 0) {
345
+ try (
346
+ BufferedWriter writer = new BufferedWriter(
347
+ new FileWriter(infoFile)
348
+ )
349
+ ) {
350
+ writer.write(String.valueOf(version));
351
+ }
352
+ }
353
+ // Updating the info file
354
+ try (
355
+ BufferedWriter writer = new BufferedWriter(
356
+ new FileWriter(infoFile)
357
+ )
358
+ ) {
359
+ writer.write(String.valueOf(version));
360
+ }
373
361
 
374
- int bytesRead = -1;
375
- byte[] buffer = new byte[4096];
376
- int lastNotifiedPercent = 0;
377
- while ((bytesRead = inputStream.read(buffer)) != -1) {
378
- outputStream.write(buffer, 0, bytesRead);
379
- downloadedBytes += bytesRead;
380
- // Saving progress (flushing every 100 Ko)
381
- if (downloadedBytes % 102400 == 0) {
382
- outputStream.flush();
383
- }
384
- // Computing percentage
385
- int percent = calcTotalPercent(downloadedBytes, contentLength);
386
- while (lastNotifiedPercent + 10 <= percent) {
387
- lastNotifiedPercent += 10;
388
- notifyDownload(id, lastNotifiedPercent);
389
- }
390
- }
362
+ int bytesRead = -1;
363
+ byte[] buffer = new byte[4096];
364
+ int lastNotifiedPercent = 0;
365
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
366
+ outputStream.write(buffer, 0, bytesRead);
367
+ downloadedBytes += bytesRead;
368
+ // Saving progress (flushing every 100 Ko)
369
+ if (downloadedBytes % 102400 == 0) {
370
+ outputStream.flush();
371
+ }
372
+ // Computing percentage
373
+ int percent = calcTotalPercent(downloadedBytes, contentLength);
374
+ while (lastNotifiedPercent + 10 <= percent) {
375
+ lastNotifiedPercent += 10;
376
+ // Artificial delay using CPU-bound calculation to take ~5 seconds
377
+ double result = 0;
378
+ notifyDownload(id, lastNotifiedPercent);
379
+ }
380
+ }
391
381
 
392
- outputStream.close();
393
- inputStream.close();
382
+ outputStream.close();
383
+ inputStream.close();
394
384
 
395
- // Rename the temp file with the final name (dest)
396
- tempFile.renameTo(new File(documentsDir, dest));
397
- infoFile.delete();
398
- publishResults(dest, id, version, checksum, sessionKey, "", false);
399
- } else {
400
- infoFile.delete();
385
+ // Rename the temp file with the final name (dest)
386
+ tempFile.renameTo(new File(documentsDir, dest));
387
+ infoFile.delete();
388
+ publishResults(dest, id, version, checksum, sessionKey, "", false);
389
+ }
390
+ } else {
391
+ infoFile.delete();
392
+ }
393
+ } finally {
394
+ if (httpConn != null) {
395
+ httpConn.disconnect();
396
+ }
401
397
  }
402
- httpConn.disconnect();
403
398
  } catch (OutOfMemoryError e) {
404
399
  e.printStackTrace();
405
400
  publishResults(
@@ -423,7 +418,6 @@ public class DownloadService extends IntentService {
423
418
  false
424
419
  );
425
420
  }
426
- stopForegroundIfNeeded();
427
421
  }
428
422
 
429
423
  private void clearDownloadData(String docDir) {
@@ -581,15 +575,4 @@ public class DownloadService extends IntentService {
581
575
  }
582
576
  return sb.toString();
583
577
  }
584
-
585
- private void stopForegroundIfNeeded() {
586
- handler.removeCallbacks(notificationRunnable);
587
- if (isNotificationShown) {
588
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
589
- stopForeground(STOP_FOREGROUND_REMOVE);
590
- } else {
591
- stopForeground(true);
592
- }
593
- }
594
- }
595
578
  }
@@ -44,7 +44,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
44
44
  CAPPluginMethod(name: "isAutoUpdateAvailable", returnType: CAPPluginReturnPromise)
45
45
  ]
46
46
  public var implementation = CapacitorUpdater()
47
- private let PLUGIN_VERSION: String = "6.7.5"
47
+ private let PLUGIN_VERSION: String = "6.7.7-alpha.1"
48
48
  static let updateUrlDefault = "https://plugin.capgo.app/updates"
49
49
  static let statsUrlDefault = "https://plugin.capgo.app/stats"
50
50
  static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "6.7.5",
3
+ "version": "6.7.7-alpha.1",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Live update for capacitor apps",
6
6
  "main": "dist/plugin.cjs.js",