@capgo/capacitor-updater 3.3.12 → 4.0.0-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.
- package/LICENCE +656 -160
- package/README.md +200 -137
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +130 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +36 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +316 -198
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +454 -244
- package/dist/docs.json +509 -121
- package/dist/esm/definitions.d.ts +201 -76
- package/dist/esm/web.d.ts +18 -16
- package/dist/esm/web.js +26 -24
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +26 -24
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +26 -24
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/BundleInfo.swift +94 -0
- package/ios/Plugin/BundleStatus.swift +41 -0
- package/ios/Plugin/CapacitorUpdater.swift +298 -82
- package/ios/Plugin/CapacitorUpdaterPlugin.m +3 -2
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +270 -163
- package/ios/Plugin/ObjectPreferences.swift +97 -0
- package/package.json +3 -2
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
package ee.forgr.capacitor_updater;
|
|
2
2
|
|
|
3
|
-
import android.app.Activity;
|
|
4
|
-
import android.content.Context;
|
|
5
3
|
import android.content.SharedPreferences;
|
|
6
|
-
import android.content.pm.PackageInfo;
|
|
7
|
-
import android.content.pm.PackageManager;
|
|
8
|
-
import android.os.Build;
|
|
9
4
|
import android.util.Log;
|
|
10
5
|
|
|
11
|
-
import com.android.volley.AuthFailureError;
|
|
12
6
|
import com.android.volley.Request;
|
|
13
7
|
import com.android.volley.RequestQueue;
|
|
14
8
|
import com.android.volley.Response;
|
|
15
9
|
import com.android.volley.VolleyError;
|
|
16
|
-
import com.android.volley.toolbox.
|
|
17
|
-
import com.
|
|
10
|
+
import com.android.volley.toolbox.JsonObjectRequest;
|
|
11
|
+
import com.getcapacitor.plugin.WebView;
|
|
18
12
|
|
|
19
13
|
import org.json.JSONException;
|
|
20
14
|
import org.json.JSONObject;
|
|
21
15
|
|
|
22
16
|
import java.io.BufferedInputStream;
|
|
23
17
|
import java.io.DataInputStream;
|
|
24
|
-
import java.io.DataOutputStream;
|
|
25
18
|
import java.io.File;
|
|
26
19
|
import java.io.FileInputStream;
|
|
27
20
|
import java.io.FileNotFoundException;
|
|
@@ -29,48 +22,45 @@ import java.io.FileOutputStream;
|
|
|
29
22
|
import java.io.FilenameFilter;
|
|
30
23
|
import java.io.IOException;
|
|
31
24
|
import java.io.InputStream;
|
|
32
|
-
import java.net.HttpURLConnection;
|
|
33
25
|
import java.net.URL;
|
|
34
26
|
import java.net.URLConnection;
|
|
35
27
|
import java.security.SecureRandom;
|
|
36
|
-
import java.util.
|
|
37
|
-
import java.util.
|
|
28
|
+
import java.util.ArrayList;
|
|
29
|
+
import java.util.Date;
|
|
30
|
+
import java.util.List;
|
|
38
31
|
import java.util.zip.ZipEntry;
|
|
39
32
|
import java.util.zip.ZipInputStream;
|
|
40
|
-
import java.util.ArrayList;
|
|
41
|
-
import android.provider.Settings.Secure;
|
|
42
33
|
|
|
43
34
|
interface Callback {
|
|
44
35
|
void callback(JSONObject jsonObject);
|
|
45
36
|
}
|
|
46
37
|
|
|
47
38
|
public class CapacitorUpdater {
|
|
48
|
-
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
49
|
-
static SecureRandom rnd = new SecureRandom();
|
|
50
|
-
|
|
51
|
-
private final
|
|
52
|
-
|
|
53
|
-
private final
|
|
54
|
-
private final
|
|
55
|
-
private String
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
40
|
+
private static final SecureRandom rnd = new SecureRandom();
|
|
41
|
+
|
|
42
|
+
private static final String INFO_SUFFIX = "_info";
|
|
43
|
+
|
|
44
|
+
private static final String FALLBACK_VERSION = "pastVersion";
|
|
45
|
+
private static final String NEXT_VERSION = "nextVersion";
|
|
46
|
+
private static final String bundleDirectory = "versions";
|
|
47
|
+
|
|
48
|
+
public static final String TAG = "Capacitor-updater";
|
|
49
|
+
public static final String pluginVersion = "4.0.0-alpha.1";
|
|
50
|
+
|
|
51
|
+
public SharedPreferences.Editor editor;
|
|
52
|
+
public SharedPreferences prefs;
|
|
53
|
+
|
|
54
|
+
public RequestQueue requestQueue;
|
|
58
55
|
|
|
56
|
+
public File documentsDir;
|
|
57
|
+
public String versionBuild = "";
|
|
58
|
+
public String versionCode = "";
|
|
59
|
+
public String versionOs = "";
|
|
60
|
+
|
|
61
|
+
public String statsUrl = "";
|
|
59
62
|
public String appId = "";
|
|
60
63
|
public String deviceID = "";
|
|
61
|
-
public final String pluginVersion = "3.3.12";
|
|
62
|
-
public String statsUrl = "";
|
|
63
|
-
|
|
64
|
-
public CapacitorUpdater (final Context context) throws PackageManager.NameNotFoundException {
|
|
65
|
-
this.context = context;
|
|
66
|
-
this.prefs = this.context.getSharedPreferences("CapWebViewSettings", Activity.MODE_PRIVATE);
|
|
67
|
-
this.editor = this.prefs.edit();
|
|
68
|
-
this.versionOs = Build.VERSION.RELEASE;
|
|
69
|
-
this.deviceID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
|
|
70
|
-
final PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
|
71
|
-
this.versionBuild = pInfo.versionName;
|
|
72
|
-
this.versionCode = Integer.toString(pInfo.versionCode);
|
|
73
|
-
}
|
|
74
64
|
|
|
75
65
|
private final FilenameFilter filter = new FilenameFilter() {
|
|
76
66
|
@Override
|
|
@@ -84,7 +74,7 @@ public class CapacitorUpdater {
|
|
|
84
74
|
return (percent * (max - min)) / 100 + min;
|
|
85
75
|
}
|
|
86
76
|
|
|
87
|
-
void notifyDownload(final int percent) {
|
|
77
|
+
void notifyDownload(final String id, final int percent) {
|
|
88
78
|
return;
|
|
89
79
|
}
|
|
90
80
|
|
|
@@ -94,8 +84,9 @@ public class CapacitorUpdater {
|
|
|
94
84
|
sb.append(AB.charAt(rnd.nextInt(AB.length())));
|
|
95
85
|
return sb.toString();
|
|
96
86
|
}
|
|
97
|
-
|
|
98
|
-
|
|
87
|
+
|
|
88
|
+
private File unzip(final String id, final File zipFile, final String dest) throws IOException {
|
|
89
|
+
final File targetDirectory = new File(this.documentsDir, dest);
|
|
99
90
|
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)));
|
|
100
91
|
try {
|
|
101
92
|
int count;
|
|
@@ -104,7 +95,7 @@ public class CapacitorUpdater {
|
|
|
104
95
|
final long lengthTotal = zipFile.length();
|
|
105
96
|
long lengthRead = bufferSize;
|
|
106
97
|
int percent = 0;
|
|
107
|
-
this.notifyDownload(75);
|
|
98
|
+
this.notifyDownload(id, 75);
|
|
108
99
|
|
|
109
100
|
ZipEntry entry;
|
|
110
101
|
while ((entry = zis.getNextEntry()) != null) {
|
|
@@ -135,7 +126,7 @@ public class CapacitorUpdater {
|
|
|
135
126
|
final int newPercent = (int)((lengthRead * 100) / lengthTotal);
|
|
136
127
|
if (lengthTotal > 1 && newPercent != percent) {
|
|
137
128
|
percent = newPercent;
|
|
138
|
-
this.notifyDownload(this.calcTotalPercent(percent, 75, 90));
|
|
129
|
+
this.notifyDownload(id, this.calcTotalPercent(percent, 75, 90));
|
|
139
130
|
}
|
|
140
131
|
|
|
141
132
|
lengthRead += entry.getCompressedSize();
|
|
@@ -145,7 +136,7 @@ public class CapacitorUpdater {
|
|
|
145
136
|
try {
|
|
146
137
|
zis.close();
|
|
147
138
|
} catch (final IOException e) {
|
|
148
|
-
Log.e(
|
|
139
|
+
Log.e(TAG, "Failed to close zip input stream", e);
|
|
149
140
|
}
|
|
150
141
|
}
|
|
151
142
|
}
|
|
@@ -154,14 +145,14 @@ public class CapacitorUpdater {
|
|
|
154
145
|
if (!sourceFile.exists()) {
|
|
155
146
|
throw new FileNotFoundException("Source file not found: " + sourceFile.getPath());
|
|
156
147
|
}
|
|
157
|
-
final File destinationFile = new File(this.
|
|
148
|
+
final File destinationFile = new File(this.documentsDir, dest);
|
|
158
149
|
destinationFile.getParentFile().mkdirs();
|
|
159
150
|
final String[] entries = sourceFile.list(this.filter);
|
|
160
151
|
if (entries == null || entries.length == 0) {
|
|
161
152
|
throw new IOException("Source file was not a directory or was empty: " + sourceFile.getPath());
|
|
162
153
|
}
|
|
163
|
-
if (entries.length == 1 && !
|
|
164
|
-
final File child = new File(sourceFile
|
|
154
|
+
if (entries.length == 1 && !"index.html".equals(entries[0])) {
|
|
155
|
+
final File child = new File(sourceFile, entries[0]);
|
|
165
156
|
child.renameTo(destinationFile);
|
|
166
157
|
} else {
|
|
167
158
|
sourceFile.renameTo(destinationFile);
|
|
@@ -169,14 +160,14 @@ public class CapacitorUpdater {
|
|
|
169
160
|
sourceFile.delete();
|
|
170
161
|
}
|
|
171
162
|
|
|
172
|
-
private File downloadFile(final String url, final String dest) throws IOException {
|
|
163
|
+
private File downloadFile(final String id, final String url, final String dest) throws IOException {
|
|
173
164
|
|
|
174
165
|
final URL u = new URL(url);
|
|
175
166
|
final URLConnection connection = u.openConnection();
|
|
176
167
|
final InputStream is = u.openStream();
|
|
177
168
|
final DataInputStream dis = new DataInputStream(is);
|
|
178
169
|
|
|
179
|
-
final File target = new File(this.
|
|
170
|
+
final File target = new File(this.documentsDir, dest);
|
|
180
171
|
target.getParentFile().mkdirs();
|
|
181
172
|
target.createNewFile();
|
|
182
173
|
final FileOutputStream fos = new FileOutputStream(target);
|
|
@@ -188,13 +179,13 @@ public class CapacitorUpdater {
|
|
|
188
179
|
|
|
189
180
|
int bytesRead = bufferSize;
|
|
190
181
|
int percent = 0;
|
|
191
|
-
this.notifyDownload(10);
|
|
182
|
+
this.notifyDownload(id, 10);
|
|
192
183
|
while ((length = dis.read(buffer))>0) {
|
|
193
184
|
fos.write(buffer, 0, length);
|
|
194
185
|
final int newPercent = (int)((bytesRead * 100) / totalLength);
|
|
195
186
|
if (totalLength > 1 && newPercent != percent) {
|
|
196
187
|
percent = newPercent;
|
|
197
|
-
this.notifyDownload(this.calcTotalPercent(percent, 10, 70));
|
|
188
|
+
this.notifyDownload(id, this.calcTotalPercent(percent, 10, 70));
|
|
198
189
|
}
|
|
199
190
|
bytesRead += length;
|
|
200
191
|
}
|
|
@@ -211,202 +202,329 @@ public class CapacitorUpdater {
|
|
|
211
202
|
}
|
|
212
203
|
}
|
|
213
204
|
if (!file.delete()) {
|
|
214
|
-
throw new IOException("Failed to delete " + file);
|
|
205
|
+
throw new IOException("Failed to delete: " + file);
|
|
215
206
|
}
|
|
216
207
|
}
|
|
217
208
|
|
|
218
|
-
|
|
219
|
-
this.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
this.
|
|
226
|
-
|
|
227
|
-
this.notifyDownload(
|
|
228
|
-
final
|
|
229
|
-
|
|
230
|
-
this.
|
|
231
|
-
this.
|
|
232
|
-
this.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
209
|
+
private void setCurrentBundle(final File bundle) {
|
|
210
|
+
this.editor.putString(WebView.CAP_SERVER_PATH, bundle.getPath());
|
|
211
|
+
Log.i(TAG, "Current bundle set to: " + bundle);
|
|
212
|
+
this.editor.commit();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public BundleInfo download(final String url, final String version) throws IOException {
|
|
216
|
+
final String id = this.randomString(10);
|
|
217
|
+
this.saveBundleInfo(id, new BundleInfo(id, version, BundleStatus.DOWNLOADING, new Date(System.currentTimeMillis())));
|
|
218
|
+
this.notifyDownload(id, 0);
|
|
219
|
+
final String idName = bundleDirectory + "/" + id;
|
|
220
|
+
this.notifyDownload(id, 5);
|
|
221
|
+
final File downloaded = this.downloadFile(id, url, this.randomString(10));
|
|
222
|
+
this.notifyDownload(id, 71);
|
|
223
|
+
final File unzipped = this.unzip(id, downloaded, this.randomString(10));
|
|
224
|
+
downloaded.delete();
|
|
225
|
+
this.notifyDownload(id, 91);
|
|
226
|
+
this.flattenAssets(unzipped, idName);
|
|
227
|
+
this.notifyDownload(id, 100);
|
|
228
|
+
this.saveBundleInfo(id, null);
|
|
229
|
+
BundleInfo info = new BundleInfo(id, version, BundleStatus.PENDING, new Date(System.currentTimeMillis()));
|
|
230
|
+
this.saveBundleInfo(id, info);
|
|
231
|
+
return info;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
public List<BundleInfo> list() {
|
|
235
|
+
final List<BundleInfo> res = new ArrayList<>();
|
|
236
|
+
final File destHot = new File(this.documentsDir, bundleDirectory);
|
|
237
|
+
Log.d(TAG, "list File : " + destHot.getPath());
|
|
240
238
|
if (destHot.exists()) {
|
|
241
239
|
for (final File i : destHot.listFiles()) {
|
|
242
|
-
|
|
240
|
+
final String id = i.getName();
|
|
241
|
+
res.add(this.getBundleInfo(id));
|
|
243
242
|
}
|
|
244
243
|
} else {
|
|
245
|
-
Log.i(
|
|
244
|
+
Log.i(TAG, "No versions available to list" + destHot);
|
|
246
245
|
}
|
|
247
246
|
return res;
|
|
248
247
|
}
|
|
249
248
|
|
|
250
|
-
public Boolean delete(final String
|
|
251
|
-
final
|
|
252
|
-
|
|
253
|
-
|
|
249
|
+
public Boolean delete(final String id) throws IOException {
|
|
250
|
+
final BundleInfo deleted = this.getBundleInfo(id);
|
|
251
|
+
final File bundle = new File(this.documentsDir, bundleDirectory + "/" + id);
|
|
252
|
+
if (bundle.exists()) {
|
|
253
|
+
this.deleteDirectory(bundle);
|
|
254
|
+
this.removeBundleInfo(id);
|
|
254
255
|
return true;
|
|
255
256
|
}
|
|
256
|
-
Log.
|
|
257
|
-
this.sendStats("delete",
|
|
257
|
+
Log.e(TAG, "Directory not removed: " + bundle.getPath());
|
|
258
|
+
this.sendStats("delete", deleted);
|
|
258
259
|
return false;
|
|
259
260
|
}
|
|
260
261
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
262
|
+
private File getBundleDirectory(final String id) {
|
|
263
|
+
return new File(this.documentsDir, bundleDirectory + "/" + id);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private boolean bundleExists(final File bundle) {
|
|
267
|
+
if(bundle == null || !bundle.exists()) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return new File(bundle.getPath(), "/index.html").exists();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
public Boolean set(final BundleInfo bundle) {
|
|
275
|
+
return this.set(bundle.getId());
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
public Boolean set(final String id) {
|
|
279
|
+
|
|
280
|
+
final BundleInfo existing = this.getBundleInfo(id);
|
|
281
|
+
final File bundle = this.getBundleDirectory(id);
|
|
282
|
+
|
|
283
|
+
Log.i(TAG, "Setting next active bundle: " + existing);
|
|
284
|
+
if (this.bundleExists(bundle)) {
|
|
285
|
+
this.setCurrentBundle(bundle);
|
|
286
|
+
this.setBundleStatus(id, BundleStatus.PENDING);
|
|
287
|
+
this.sendStats("set", existing);
|
|
270
288
|
return true;
|
|
271
289
|
}
|
|
272
|
-
this.sendStats("set_fail",
|
|
290
|
+
this.sendStats("set_fail", existing);
|
|
273
291
|
return false;
|
|
274
292
|
}
|
|
275
293
|
|
|
276
|
-
public void
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
final String versionBuild = this.versionBuild;
|
|
280
|
-
final String versionCode = this.versionCode;
|
|
281
|
-
final String versionOs = this.versionOs;
|
|
282
|
-
final String pluginVersion = this.pluginVersion;
|
|
283
|
-
final String versionName = this.getVersionName().equals("") ? "builtin" : this.getVersionName();
|
|
284
|
-
final StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
|
|
285
|
-
new Response.Listener<String>() {
|
|
286
|
-
@Override
|
|
287
|
-
public void onResponse(final String response) {
|
|
288
|
-
try {
|
|
289
|
-
final JSONObject jsonObject = new JSONObject(response);
|
|
290
|
-
callback.callback(jsonObject);
|
|
291
|
-
} catch (final JSONException e) {
|
|
292
|
-
Log.e(CapacitorUpdater.this.TAG, "Error parsing JSON", e);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}, new Response.ErrorListener() {
|
|
296
|
-
@Override
|
|
297
|
-
public void onErrorResponse(final VolleyError error) {
|
|
298
|
-
Log.e(CapacitorUpdater.this.TAG, "Error getting Latest" + error);
|
|
299
|
-
}
|
|
300
|
-
}) {
|
|
301
|
-
@Override
|
|
302
|
-
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
303
|
-
final Map<String, String> params = new HashMap<String, String>();
|
|
304
|
-
params.put("cap_platform", "android");
|
|
305
|
-
params.put("cap_device_id", deviceID);
|
|
306
|
-
params.put("cap_app_id", appId);
|
|
307
|
-
params.put("cap_version_build", versionBuild);
|
|
308
|
-
params.put("cap_version_code", versionCode);
|
|
309
|
-
params.put("cap_version_os", versionOs);
|
|
310
|
-
params.put("cap_version_name", versionName);
|
|
311
|
-
params.put("cap_plugin_version", pluginVersion);
|
|
312
|
-
return params;
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
final RequestQueue requestQueue = Volley.newRequestQueue(this.context);
|
|
316
|
-
requestQueue.add(stringRequest);
|
|
294
|
+
public void commit(final BundleInfo bundle) {
|
|
295
|
+
this.setBundleStatus(bundle.getId(), BundleStatus.SUCCESS);
|
|
296
|
+
this.setFallbackVersion(bundle);
|
|
317
297
|
}
|
|
318
298
|
|
|
319
|
-
public
|
|
320
|
-
|
|
299
|
+
public void reset() {
|
|
300
|
+
this.reset(false);
|
|
321
301
|
}
|
|
322
302
|
|
|
323
|
-
public
|
|
324
|
-
|
|
303
|
+
public void rollback(final BundleInfo bundle) {
|
|
304
|
+
this.setBundleStatus(bundle.getId(), BundleStatus.ERROR);
|
|
325
305
|
}
|
|
326
306
|
|
|
327
|
-
public void reset() {
|
|
328
|
-
|
|
329
|
-
this.
|
|
330
|
-
this.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
307
|
+
public void reset(final boolean internal) {
|
|
308
|
+
this.setCurrentBundle(new File("public"));
|
|
309
|
+
this.setFallbackVersion(null);
|
|
310
|
+
this.setNextVersion(null);
|
|
311
|
+
if(!internal) {
|
|
312
|
+
this.sendStats("reset", this.getCurrentBundle());
|
|
313
|
+
}
|
|
334
314
|
}
|
|
335
315
|
|
|
336
|
-
public void
|
|
337
|
-
|
|
338
|
-
final
|
|
339
|
-
final
|
|
340
|
-
final String
|
|
316
|
+
public void getLatest(final String updateUrl, final Callback callback) {
|
|
317
|
+
final String deviceID = this.deviceID;
|
|
318
|
+
final String appId = this.appId;
|
|
319
|
+
final String versionBuild = this.versionBuild;
|
|
320
|
+
final String versionCode = this.versionCode;
|
|
321
|
+
final String versionOs = this.versionOs;
|
|
322
|
+
final String pluginVersion = CapacitorUpdater.pluginVersion;
|
|
323
|
+
final String version = this.getCurrentBundle().getId();
|
|
341
324
|
try {
|
|
342
|
-
|
|
325
|
+
JSONObject json = new JSONObject();
|
|
343
326
|
json.put("platform", "android");
|
|
344
|
-
json.put("
|
|
327
|
+
json.put("device_id", deviceID);
|
|
328
|
+
json.put("app_id", appId);
|
|
329
|
+
json.put("version_build", versionBuild);
|
|
330
|
+
json.put("version_code", versionCode);
|
|
331
|
+
json.put("version_os", versionOs);
|
|
345
332
|
json.put("version_name", version);
|
|
346
|
-
json.put("
|
|
333
|
+
json.put("plugin_version", pluginVersion);
|
|
334
|
+
|
|
335
|
+
// Building a request
|
|
336
|
+
JsonObjectRequest request = new JsonObjectRequest(
|
|
337
|
+
Request.Method.POST,
|
|
338
|
+
updateUrl,
|
|
339
|
+
json,
|
|
340
|
+
new Response.Listener<JSONObject>() {
|
|
341
|
+
@Override
|
|
342
|
+
public void onResponse(JSONObject response) {
|
|
343
|
+
callback.callback(response);
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
new Response.ErrorListener(){
|
|
347
|
+
@Override
|
|
348
|
+
public void onErrorResponse(VolleyError error) {
|
|
349
|
+
Log.e(TAG, "Error getting Latest " + error);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
this.requestQueue.add(request);
|
|
353
|
+
} catch(JSONException ex){
|
|
354
|
+
// Catch if something went wrong with the params
|
|
355
|
+
Log.e(TAG, "Error getLatest JSONException " + ex);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
public void sendStats(final String action, final BundleInfo bundle) {
|
|
360
|
+
String statsUrl = this.statsUrl;
|
|
361
|
+
if (statsUrl == null || "".equals(statsUrl) || statsUrl.length() == 0) { return; }
|
|
362
|
+
try {
|
|
363
|
+
JSONObject json = new JSONObject();
|
|
364
|
+
json.put("platform", "android");
|
|
365
|
+
json.put("device_id", this.deviceID);
|
|
366
|
+
json.put("app_id", this.appId);
|
|
347
367
|
json.put("version_build", this.versionBuild);
|
|
348
368
|
json.put("version_code", this.versionCode);
|
|
349
369
|
json.put("version_os", this.versionOs);
|
|
350
|
-
json.put("
|
|
351
|
-
json.put("
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
370
|
+
json.put("version_name", bundle.getVersionName());
|
|
371
|
+
json.put("plugin_version", pluginVersion);
|
|
372
|
+
json.put("action", action);
|
|
373
|
+
|
|
374
|
+
// Building a request
|
|
375
|
+
JsonObjectRequest request = new JsonObjectRequest(
|
|
376
|
+
Request.Method.POST,
|
|
377
|
+
statsUrl,
|
|
378
|
+
json,
|
|
379
|
+
new Response.Listener<JSONObject>() {
|
|
380
|
+
@Override
|
|
381
|
+
public void onResponse(JSONObject response) {
|
|
382
|
+
Log.i(TAG, "Stats send for \"" + action + "\", version " + bundle.getVersionName());
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
new Response.ErrorListener(){
|
|
386
|
+
@Override
|
|
387
|
+
public void onErrorResponse(VolleyError error) {
|
|
388
|
+
Log.i(TAG, "Stats send for \"" + action + "\", version " + bundle.getVersionName());
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
this.requestQueue.add(request);
|
|
392
|
+
} catch(JSONException ex){
|
|
393
|
+
// Catch if something went wrong with the params
|
|
394
|
+
Log.e(TAG, "Error sendStats JSONException " + ex);
|
|
356
395
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
Log.e(CapacitorUpdater.this.TAG, "Stats error responseCode: " + responseCode);
|
|
375
|
-
} else {
|
|
376
|
-
Log.i(CapacitorUpdater.this.TAG, "Stats send for \"" + action + "\", version " + version);
|
|
377
|
-
}
|
|
378
|
-
} catch (final Exception ex) {
|
|
379
|
-
Log.e(CapacitorUpdater.this.TAG, "Error post stats", ex);
|
|
380
|
-
} finally {
|
|
381
|
-
if (con != null) {
|
|
382
|
-
con.disconnect();
|
|
383
|
-
}
|
|
384
|
-
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
public BundleInfo getBundleInfo(String id) {
|
|
399
|
+
if(id == null) {
|
|
400
|
+
id = BundleInfo.VERSION_UNKNOWN;
|
|
401
|
+
}
|
|
402
|
+
Log.d(TAG, "Getting info for bundle [" + id + "]");
|
|
403
|
+
BundleInfo result;
|
|
404
|
+
if(BundleInfo.ID_BUILTIN.equals(id)) {
|
|
405
|
+
result = new BundleInfo(id, (String) null, BundleStatus.SUCCESS, "");
|
|
406
|
+
} else {
|
|
407
|
+
try {
|
|
408
|
+
String stored = this.prefs.getString(id + INFO_SUFFIX, "");
|
|
409
|
+
result = BundleInfo.fromJSON(stored);
|
|
410
|
+
} catch (JSONException e) {
|
|
411
|
+
Log.e(TAG, "Failed to parse info for bundle [" + id + "] ", e);
|
|
412
|
+
result = new BundleInfo(id, (String) null, BundleStatus.PENDING, "");
|
|
385
413
|
}
|
|
386
|
-
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
Log.d(TAG, "Returning info [" + id + "] " + result);
|
|
417
|
+
return result;
|
|
387
418
|
}
|
|
388
419
|
|
|
389
|
-
public String
|
|
390
|
-
|
|
420
|
+
public BundleInfo getBundleInfoByName(final String versionName) {
|
|
421
|
+
final List<BundleInfo> installed = this.list();
|
|
422
|
+
for(final BundleInfo i : installed) {
|
|
423
|
+
if(i.getVersionName().equals(versionName)) {
|
|
424
|
+
return i;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
391
428
|
}
|
|
392
429
|
|
|
393
|
-
|
|
394
|
-
this.
|
|
430
|
+
private void removeBundleInfo(final String id) {
|
|
431
|
+
this.saveBundleInfo(id, null);
|
|
395
432
|
}
|
|
396
433
|
|
|
397
|
-
|
|
398
|
-
|
|
434
|
+
private void saveBundleInfo(final String id, final BundleInfo info) {
|
|
435
|
+
if(id == null || (info != null && (info.isBuiltin() || info.isUnknown()))) {
|
|
436
|
+
Log.d(TAG, "Not saving info for bundle: [" + id + "] " + info);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if(info == null) {
|
|
441
|
+
Log.d(TAG, "Removing info for bundle [" + id + "]");
|
|
442
|
+
this.editor.remove(id + INFO_SUFFIX);
|
|
443
|
+
} else {
|
|
444
|
+
final BundleInfo update = info.setId(id);
|
|
445
|
+
Log.d(TAG, "Storing info for bundle [" + id + "] " + update.toString());
|
|
446
|
+
this.editor.putString(id + INFO_SUFFIX, update.toString());
|
|
447
|
+
}
|
|
448
|
+
this.editor.commit();
|
|
399
449
|
}
|
|
400
450
|
|
|
401
|
-
public void
|
|
402
|
-
|
|
451
|
+
public void setVersionName(final String id, final String name) {
|
|
452
|
+
if(id != null) {
|
|
453
|
+
Log.d(TAG, "Setting name for bundle [" + id + "] to " + name);
|
|
454
|
+
BundleInfo info = this.getBundleInfo(id);
|
|
455
|
+
this.saveBundleInfo(id, info.setVersionName(name));
|
|
456
|
+
}
|
|
403
457
|
}
|
|
404
458
|
|
|
405
|
-
|
|
406
|
-
|
|
459
|
+
private void setBundleStatus(final String id, final BundleStatus status) {
|
|
460
|
+
if(id != null && status != null) {
|
|
461
|
+
BundleInfo info = this.getBundleInfo(id);
|
|
462
|
+
Log.d(TAG, "Setting status for bundle [" + id + "] to " + status);
|
|
463
|
+
this.saveBundleInfo(id, info.setStatus(status));
|
|
464
|
+
}
|
|
407
465
|
}
|
|
408
466
|
|
|
409
|
-
|
|
410
|
-
this.
|
|
467
|
+
private String getCurrentBundleId() {
|
|
468
|
+
if(this.isUsingBuiltin()) {
|
|
469
|
+
return BundleInfo.ID_BUILTIN;
|
|
470
|
+
} else {
|
|
471
|
+
final String path = this.getCurrentBundlePath();
|
|
472
|
+
return path.substring(path.lastIndexOf('/') + 1);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
public BundleInfo getCurrentBundle() {
|
|
477
|
+
return this.getBundleInfo(this.getCurrentBundleId());
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
public String getCurrentBundlePath() {
|
|
481
|
+
String path = this.prefs.getString(WebView.CAP_SERVER_PATH, "public");
|
|
482
|
+
if("".equals(path.trim())) {
|
|
483
|
+
return "public";
|
|
484
|
+
}
|
|
485
|
+
return path;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
public Boolean isUsingBuiltin() {
|
|
489
|
+
return this.getCurrentBundlePath().equals("public");
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
public BundleInfo getFallbackVersion() {
|
|
493
|
+
final String id = this.prefs.getString(FALLBACK_VERSION, BundleInfo.ID_BUILTIN);
|
|
494
|
+
return this.getBundleInfo(id);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
private void setFallbackVersion(final BundleInfo fallback) {
|
|
498
|
+
this.editor.putString(FALLBACK_VERSION,
|
|
499
|
+
fallback == null
|
|
500
|
+
? BundleInfo.ID_BUILTIN
|
|
501
|
+
: fallback.getId()
|
|
502
|
+
);
|
|
411
503
|
}
|
|
504
|
+
|
|
505
|
+
public BundleInfo getNextVersion() {
|
|
506
|
+
final String id = this.prefs.getString(NEXT_VERSION, "");
|
|
507
|
+
if(id != "") {
|
|
508
|
+
return this.getBundleInfo(id);
|
|
509
|
+
} else {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
public boolean setNextVersion(final String next) {
|
|
515
|
+
if (next == null) {
|
|
516
|
+
this.editor.remove(NEXT_VERSION);
|
|
517
|
+
} else {
|
|
518
|
+
final File bundle = this.getBundleDirectory(next);
|
|
519
|
+
if (!this.bundleExists(bundle)) {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
this.editor.putString(NEXT_VERSION, next);
|
|
524
|
+
this.setBundleStatus(next, BundleStatus.PENDING);
|
|
525
|
+
}
|
|
526
|
+
this.editor.commit();
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
|
|
412
530
|
}
|