@capacitor/android 5.0.0-alpha.1 → 5.0.0-beta.0

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.
@@ -40,6 +40,7 @@ if (System.getenv("CAP_PUBLISH") == "true") {
40
40
  }
41
41
 
42
42
  android {
43
+ namespace "com.getcapacitor.android"
43
44
  compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
44
45
  defaultConfig {
45
46
  minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
@@ -59,6 +60,7 @@ android {
59
60
  baseline file("lint-baseline.xml")
60
61
  abortOnError true
61
62
  warningsAsErrors true
63
+ lintConfig file('lint.xml')
62
64
  }
63
65
  compileOptions {
64
66
  sourceCompatibility JavaVersion.VERSION_11
@@ -5,4 +5,5 @@
5
5
  <issue id="DiscouragedApi">
6
6
  <ignore path="src/main/java/com/getcapacitor/plugin/util/AssetUtil.java" />
7
7
  </issue>
8
+ <issue id="ObsoleteSdkInt" severity="informational" />
8
9
  </lint>
@@ -1,4 +1,3 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
- package="com.getcapacitor.android">
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
4
3
  </manifest>
@@ -384,9 +384,13 @@ var nativeBridge = (function (exports) {
384
384
  data: (options === null || options === void 0 ? void 0 : options.body) ? options.body : undefined,
385
385
  headers: headers,
386
386
  });
387
- const data = typeof nativeResponse.data === 'string'
387
+ let data = !nativeResponse.headers['Content-Type'].startsWith('application/json')
388
388
  ? nativeResponse.data
389
389
  : JSON.stringify(nativeResponse.data);
390
+ // use null data for 204 No Content HTTP response
391
+ if (nativeResponse.status === 204) {
392
+ data = null;
393
+ }
390
394
  // intercept & parse response before returning
391
395
  const response = new Response(data, {
392
396
  headers: nativeResponse.headers,
@@ -522,7 +526,7 @@ var nativeBridge = (function (exports) {
522
526
  this.status = nativeResponse.status;
523
527
  this.response = nativeResponse.data;
524
528
  this.responseText =
525
- typeof nativeResponse.data === 'string'
529
+ !nativeResponse.headers['Content-Type'].startsWith('application/json')
526
530
  ? nativeResponse.data
527
531
  : JSON.stringify(nativeResponse.data);
528
532
  this.responseURL = nativeResponse.url;
@@ -88,6 +88,8 @@ public class Bridge {
88
88
  public static final String CAPACITOR_CONTENT_START = "/_capacitor_content_";
89
89
  public static final int DEFAULT_ANDROID_WEBVIEW_VERSION = 60;
90
90
  public static final int MINIMUM_ANDROID_WEBVIEW_VERSION = 55;
91
+ public static final int DEFAULT_HUAWEI_WEBVIEW_VERSION = 10;
92
+ public static final int MINIMUM_HUAWEI_WEBVIEW_VERSION = 10;
91
93
 
92
94
  // Loaded Capacitor config
93
95
  private CapConfig config;
@@ -324,6 +326,11 @@ public class Bridge {
324
326
  // Check getCurrentWebViewPackage() directly if above Android 8
325
327
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
326
328
  PackageInfo info = WebView.getCurrentWebViewPackage();
329
+ if (info.packageName.equals("com.huawei.webview")) {
330
+ String majorVersionStr = info.versionName.split("\\.")[0];
331
+ int majorVersion = Integer.parseInt(majorVersionStr);
332
+ return majorVersion >= config.getMinHuaweiWebViewVersion();
333
+ }
327
334
  String majorVersionStr = info.versionName.split("\\.")[0];
328
335
  int majorVersion = Integer.parseInt(majorVersionStr);
329
336
  return majorVersion >= config.getMinWebViewVersion();
@@ -370,7 +377,15 @@ public class Bridge {
370
377
  }
371
378
  }
372
379
 
373
- if (!url.toString().startsWith(appUrl) && !appAllowNavigationMask.matches(url.getHost())) {
380
+ if (url.getScheme().equals("data")) {
381
+ return false;
382
+ }
383
+
384
+ Uri appUri = Uri.parse(appUrl);
385
+ if (
386
+ !(url.getHost().equals(appUri.getHost()) && url.getScheme().equals(appUri.getScheme())) &&
387
+ !appAllowNavigationMask.matches(url.getHost())
388
+ ) {
374
389
  try {
375
390
  Intent openIntent = new Intent(Intent.ACTION_VIEW, url);
376
391
  getContext().startActivity(openIntent);
@@ -2,7 +2,9 @@ package com.getcapacitor;
2
2
 
3
3
  import static com.getcapacitor.Bridge.CAPACITOR_HTTP_SCHEME;
4
4
  import static com.getcapacitor.Bridge.DEFAULT_ANDROID_WEBVIEW_VERSION;
5
+ import static com.getcapacitor.Bridge.DEFAULT_HUAWEI_WEBVIEW_VERSION;
5
6
  import static com.getcapacitor.Bridge.MINIMUM_ANDROID_WEBVIEW_VERSION;
7
+ import static com.getcapacitor.Bridge.MINIMUM_HUAWEI_WEBVIEW_VERSION;
6
8
  import static com.getcapacitor.FileUtils.readFileFromAssets;
7
9
 
8
10
  import android.content.Context;
@@ -48,6 +50,7 @@ public class CapConfig {
48
50
  private boolean initialFocus = true;
49
51
  private boolean useLegacyBridge = false;
50
52
  private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION;
53
+ private int minHuaweiWebViewVersion = DEFAULT_HUAWEI_WEBVIEW_VERSION;
51
54
  private String errorPath;
52
55
 
53
56
  // Embedded
@@ -172,6 +175,7 @@ public class CapConfig {
172
175
  this.initialFocus = builder.initialFocus;
173
176
  this.useLegacyBridge = builder.useLegacyBridge;
174
177
  this.minWebViewVersion = builder.minWebViewVersion;
178
+ this.minHuaweiWebViewVersion = builder.minHuaweiWebViewVersion;
175
179
  this.errorPath = builder.errorPath;
176
180
 
177
181
  // Embedded
@@ -263,6 +267,7 @@ public class CapConfig {
263
267
  JSONUtils.getBoolean(configJSON, "allowMixedContent", allowMixedContent)
264
268
  );
265
269
  minWebViewVersion = JSONUtils.getInt(configJSON, "android.minWebViewVersion", DEFAULT_ANDROID_WEBVIEW_VERSION);
270
+ minHuaweiWebViewVersion = JSONUtils.getInt(configJSON, "android.minHuaweiWebViewVersion", DEFAULT_HUAWEI_WEBVIEW_VERSION);
266
271
  captureInput = JSONUtils.getBoolean(configJSON, "android.captureInput", captureInput);
267
272
  useLegacyBridge = JSONUtils.getBoolean(configJSON, "android.useLegacyBridge", useLegacyBridge);
268
273
  webContentsDebuggingEnabled = JSONUtils.getBoolean(configJSON, "android.webContentsDebuggingEnabled", isDebug);
@@ -376,6 +381,15 @@ public class CapConfig {
376
381
  return minWebViewVersion;
377
382
  }
378
383
 
384
+ public int getMinHuaweiWebViewVersion() {
385
+ if (minHuaweiWebViewVersion < MINIMUM_HUAWEI_WEBVIEW_VERSION) {
386
+ Logger.warn("Specified minimum Huawei webview version is too low, defaulting to " + MINIMUM_HUAWEI_WEBVIEW_VERSION);
387
+ return MINIMUM_HUAWEI_WEBVIEW_VERSION;
388
+ }
389
+
390
+ return minHuaweiWebViewVersion;
391
+ }
392
+
379
393
  public PluginConfig getPluginConfiguration(String pluginId) {
380
394
  PluginConfig pluginConfig = pluginsConfiguration.get(pluginId);
381
395
  if (pluginConfig == null) {
@@ -535,6 +549,7 @@ public class CapConfig {
535
549
  private boolean initialFocus = false;
536
550
  private boolean useLegacyBridge = false;
537
551
  private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION;
552
+ private int minHuaweiWebViewVersion = DEFAULT_HUAWEI_WEBVIEW_VERSION;
538
553
 
539
554
  // Embedded
540
555
  private String startPath = null;
@@ -82,7 +82,7 @@ public class Plugin {
82
82
 
83
83
  // Stored results of an event if an event was fired and
84
84
  // no listeners were attached yet. Only stores the last value.
85
- private final Map<String, JSObject> retainedEventArguments;
85
+ private final Map<String, List<JSObject>> retainedEventArguments;
86
86
 
87
87
  public Plugin() {
88
88
  eventListeners = new HashMap<>();
@@ -664,7 +664,14 @@ public class Plugin {
664
664
  if (listeners == null || listeners.isEmpty()) {
665
665
  Logger.debug(getLogTag(), "No listeners found for event " + eventName);
666
666
  if (retainUntilConsumed) {
667
- retainedEventArguments.put(eventName, data);
667
+ List<JSObject> argList = retainedEventArguments.get(eventName);
668
+
669
+ if (argList == null) {
670
+ argList = new ArrayList<JSObject>();
671
+ }
672
+
673
+ argList.add(data);
674
+ retainedEventArguments.put(eventName, argList);
668
675
  }
669
676
  return;
670
677
  }
@@ -703,13 +710,17 @@ public class Plugin {
703
710
  * @param eventName
704
711
  */
705
712
  private void sendRetainedArgumentsForEvent(String eventName) {
706
- JSObject retained = retainedEventArguments.get(eventName);
707
- if (retained == null) {
713
+ // copy retained args and null source to prevent potential race conditions
714
+ List<JSObject> retainedArgs = retainedEventArguments.get(eventName);
715
+ if (retainedArgs == null) {
708
716
  return;
709
717
  }
710
718
 
711
- notifyListeners(eventName, retained);
712
719
  retainedEventArguments.remove(eventName);
720
+
721
+ for (JSObject retained : retainedArgs) {
722
+ notifyListeners(eventName, retained);
723
+ }
713
724
  }
714
725
 
715
726
  /**
@@ -17,7 +17,10 @@ import java.util.Objects;
17
17
  public class CapacitorCookieManager extends CookieManager {
18
18
 
19
19
  private final android.webkit.CookieManager webkitCookieManager;
20
- private final Bridge bridge;
20
+
21
+ private final String localUrl;
22
+
23
+ private final String serverUrl;
21
24
 
22
25
  /**
23
26
  * Create a new cookie manager with the default cookie store and policy
@@ -36,18 +39,19 @@ public class CapacitorCookieManager extends CookieManager {
36
39
  public CapacitorCookieManager(CookieStore store, CookiePolicy policy, Bridge bridge) {
37
40
  super(store, policy);
38
41
  webkitCookieManager = android.webkit.CookieManager.getInstance();
39
- this.bridge = bridge;
42
+ this.localUrl = bridge.getLocalUrl();
43
+ this.serverUrl = bridge.getServerUrl();
40
44
  }
41
45
 
42
46
  public String getSanitizedDomain(String url) {
43
47
  if (url == null || url.isEmpty()) {
44
- url = this.bridge.getLocalUrl();
48
+ url = this.localUrl;
45
49
  }
46
50
 
47
51
  try {
48
52
  new URI(url);
49
53
  } catch (Exception ex) {
50
- return this.bridge.getServerUrl();
54
+ return this.serverUrl;
51
55
  }
52
56
 
53
57
  return url;
@@ -31,8 +31,7 @@ public class CapacitorHttp extends Plugin {
31
31
  @Override
32
32
  public void run() {
33
33
  try {
34
- HttpRequestHandler.bridge = bridge;
35
- JSObject response = HttpRequestHandler.request(call, httpMethod);
34
+ JSObject response = HttpRequestHandler.request(call, httpMethod, getBridge());
36
35
  call.resolve(response);
37
36
  } catch (Exception e) {
38
37
  call.reject(e.getLocalizedMessage(), e.getClass().getSimpleName(), e);
@@ -27,8 +27,6 @@ import org.json.JSONObject;
27
27
 
28
28
  public class HttpRequestHandler {
29
29
 
30
- public static Bridge bridge = null;
31
-
32
30
  /**
33
31
  * An enum specifying conventional HTTP Response Types
34
32
  * See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
@@ -308,6 +306,9 @@ public class HttpRequestHandler {
308
306
  return new JSONObject().put("flag", "false");
309
307
  } else if (input.trim().length() <= 0) {
310
308
  return "";
309
+ } else if (input.trim().matches("^\".*\"$")) {
310
+ // a string enclosed in " " is a json value, return the string without the quotes
311
+ return input.trim().substring(1, input.trim().length() - 1);
311
312
  } else {
312
313
  try {
313
314
  return new JSObject(input);
@@ -367,7 +368,8 @@ public class HttpRequestHandler {
367
368
  * @throws URISyntaxException thrown when the URI is malformed
368
369
  * @throws JSONException thrown when the incoming JSON is malformed
369
370
  */
370
- public static JSObject request(PluginCall call, String httpMethod) throws IOException, URISyntaxException, JSONException {
371
+ public static JSObject request(PluginCall call, String httpMethod, Bridge bridge)
372
+ throws IOException, URISyntaxException, JSONException {
371
373
  String urlString = call.getString("url", "");
372
374
  JSObject headers = call.getObject("headers", new JSObject());
373
375
  JSObject params = call.getObject("params", new JSObject());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/android",
3
- "version": "5.0.0-alpha.1",
3
+ "version": "5.0.0-beta.0",
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,10 +23,10 @@
23
23
  "verify": "./gradlew clean lint build test -b capacitor/build.gradle"
24
24
  },
25
25
  "peerDependencies": {
26
- "@capacitor/core": "^5.0.0-alpha.0"
26
+ "@capacitor/core": "^5.0.0-alpha.1"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
30
30
  },
31
- "gitHead": "76202ca81b8e855df0ef8e5f6a36bd65ed1469a4"
31
+ "gitHead": "51a548b97129998de8c403b2a8eb0421135af812"
32
32
  }