@capacitor/android 6.0.0-alpha.2 → 6.0.0-beta.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.
@@ -22,7 +22,7 @@ buildscript {
22
22
  }
23
23
  }
24
24
  dependencies {
25
- classpath 'com.android.tools.build:gradle:8.2.0-rc02'
25
+ classpath 'com.android.tools.build:gradle:8.2.0'
26
26
 
27
27
  if (System.getenv("CAP_PUBLISH") == "true") {
28
28
  classpath 'io.github.gradle-nexus:publish-plugin:1.3.0'
@@ -90,7 +90,7 @@ dependencies {
90
90
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
91
91
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
92
92
  implementation "org.apache.cordova:framework:$cordovaAndroidVersion"
93
- testImplementation 'org.json:json:20230227'
93
+ testImplementation 'org.json:json:20231013'
94
94
  testImplementation 'org.mockito:mockito-inline:5.2.0'
95
95
  }
96
96
 
@@ -64,8 +64,52 @@ var nativeBridge = (function (exports) {
64
64
  }
65
65
  return newFormData;
66
66
  };
67
- const convertBody = async (body) => {
68
- if (body instanceof FormData) {
67
+ const convertBody = async (body, contentType) => {
68
+ if (body instanceof ReadableStream) {
69
+ const reader = body.getReader();
70
+ const chunks = [];
71
+ while (true) {
72
+ const { done, value } = await reader.read();
73
+ if (done)
74
+ break;
75
+ chunks.push(value);
76
+ }
77
+ const concatenated = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0));
78
+ let position = 0;
79
+ for (const chunk of chunks) {
80
+ concatenated.set(chunk, position);
81
+ position += chunk.length;
82
+ }
83
+ let data = new TextDecoder().decode(concatenated);
84
+ let type;
85
+ if (contentType === 'application/json') {
86
+ try {
87
+ data = JSON.parse(data);
88
+ }
89
+ catch (ignored) {
90
+ // ignore
91
+ }
92
+ type = 'json';
93
+ }
94
+ else if (contentType === 'multipart/form-data') {
95
+ type = 'formData';
96
+ }
97
+ else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) {
98
+ type = 'image';
99
+ }
100
+ else if (contentType === 'application/octet-stream') {
101
+ type = 'binary';
102
+ }
103
+ else {
104
+ type = 'text';
105
+ }
106
+ return {
107
+ data,
108
+ type,
109
+ headers: { 'Content-Type': contentType || 'application/octet-stream' },
110
+ };
111
+ }
112
+ else if (body instanceof FormData) {
69
113
  const formData = await convertFormData(body);
70
114
  const boundary = `${Date.now()}`;
71
115
  return {
@@ -432,8 +476,8 @@ var nativeBridge = (function (exports) {
432
476
  console.time(tag);
433
477
  try {
434
478
  const { body, method } = request;
435
- const { data: requestData, type, headers, } = await convertBody(body || undefined);
436
479
  const optionHeaders = Object.fromEntries(request.headers.entries());
480
+ const { data: requestData, type, headers, } = await convertBody((options === null || options === void 0 ? void 0 : options.body) || body || undefined, optionHeaders['Content-Type'] || optionHeaders['content-type']);
437
481
  const nativeResponse = await cap.nativePromise('CapacitorHttp', 'request', {
438
482
  url: request.url,
439
483
  method: method,
@@ -329,10 +329,27 @@ public class Bridge {
329
329
  Logger.warn("Unable to get package info for 'com.android.webview'" + ex.toString());
330
330
  }
331
331
 
332
+ final int amazonFireMajorWebViewVersion = extractWebViewMajorVersion(pm, "com.amazon.webview.chromium");
333
+ if (amazonFireMajorWebViewVersion >= config.getMinWebViewVersion()) {
334
+ return true;
335
+ }
336
+
332
337
  // Could not detect any webview, return false
333
338
  return false;
334
339
  }
335
340
 
341
+ private int extractWebViewMajorVersion(final PackageManager pm, final String webViewPackageName) {
342
+ try {
343
+ final PackageInfo info = InternalUtils.getPackageInfo(pm, webViewPackageName);
344
+ final String majorVersionStr = info.versionName.split("\\.")[0];
345
+ final int majorVersion = Integer.parseInt(majorVersionStr);
346
+ return majorVersion;
347
+ } catch (Exception ex) {
348
+ Logger.warn(String.format("Unable to get package info for '%s' with err '%s'", webViewPackageName, ex));
349
+ }
350
+ return 0;
351
+ }
352
+
336
353
  public boolean launchIntent(Uri url) {
337
354
  /*
338
355
  * Give plugins the chance to handle the url
@@ -304,6 +304,13 @@ public class CapConfig {
304
304
  return false;
305
305
  }
306
306
 
307
+ // Non-http(s) schemes are not allowed to modify the URL path as of Android Webview 117
308
+ if (!scheme.equals("http") && !scheme.equals("https")) {
309
+ Logger.warn(
310
+ "Using a non-standard scheme: " + scheme + " for Android. This is known to cause issues as of Android Webview 117."
311
+ );
312
+ }
313
+
307
314
  return true;
308
315
  }
309
316
 
@@ -215,6 +215,14 @@ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
215
215
  }
216
216
  os.flush();
217
217
  }
218
+ } else if (contentType.contains("application/x-www-form-urlencoded")) {
219
+ try {
220
+ JSObject obj = body.toJSObject();
221
+ this.writeObjectRequestBody(obj);
222
+ } catch (Exception e) {
223
+ // Body is not a valid JSON, treat it as an already formatted string
224
+ this.writeRequestBody(body.toString());
225
+ }
218
226
  } else if (bodyType != null && bodyType.equals("formData")) {
219
227
  this.writeFormDataRequestBody(contentType, body.toJSArray());
220
228
  } else {
@@ -234,6 +242,24 @@ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
234
242
  }
235
243
  }
236
244
 
245
+ private void writeObjectRequestBody(JSObject object) throws IOException, JSONException {
246
+ try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
247
+ Iterator<String> keys = object.keys();
248
+ while (keys.hasNext()) {
249
+ String key = keys.next();
250
+ Object d = object.get(key);
251
+ os.writeBytes(key);
252
+ os.writeBytes("=");
253
+ os.writeBytes(URLEncoder.encode(d.toString(), "UTF-8"));
254
+
255
+ if (keys.hasNext()) {
256
+ os.writeBytes("&");
257
+ }
258
+ }
259
+ os.flush();
260
+ }
261
+ }
262
+
237
263
  private void writeFormDataRequestBody(String contentType, JSArray entries) throws IOException, JSONException {
238
264
  try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
239
265
  String boundary = contentType.split(";")[1].split("=")[1];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/android",
3
- "version": "6.0.0-alpha.2",
3
+ "version": "6.0.0-beta.1",
4
4
  "description": "Capacitor: Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capacitorjs.com",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
@@ -23,7 +23,7 @@
23
23
  "verify": "./gradlew clean lint build test -b capacitor/build.gradle"
24
24
  },
25
25
  "peerDependencies": {
26
- "@capacitor/core": "^6.0.0-alpha.2"
26
+ "@capacitor/core": "^6.0.0-beta.1"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"