@capacitor-plus/android 8.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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/capacitor/build.gradle +94 -0
  3. package/capacitor/lint-baseline.xml +136 -0
  4. package/capacitor/lint.xml +9 -0
  5. package/capacitor/proguard-rules.pro +28 -0
  6. package/capacitor/src/main/AndroidManifest.xml +3 -0
  7. package/capacitor/src/main/assets/native-bridge.js +1029 -0
  8. package/capacitor/src/main/java/com/getcapacitor/AndroidProtocolHandler.java +94 -0
  9. package/capacitor/src/main/java/com/getcapacitor/App.java +61 -0
  10. package/capacitor/src/main/java/com/getcapacitor/AppUUID.java +65 -0
  11. package/capacitor/src/main/java/com/getcapacitor/Bridge.java +1627 -0
  12. package/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java +212 -0
  13. package/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +467 -0
  14. package/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java +105 -0
  15. package/capacitor/src/main/java/com/getcapacitor/CapConfig.java +709 -0
  16. package/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java +57 -0
  17. package/capacitor/src/main/java/com/getcapacitor/FileUtils.java +303 -0
  18. package/capacitor/src/main/java/com/getcapacitor/InvalidPluginException.java +8 -0
  19. package/capacitor/src/main/java/com/getcapacitor/InvalidPluginMethodException.java +16 -0
  20. package/capacitor/src/main/java/com/getcapacitor/JSArray.java +51 -0
  21. package/capacitor/src/main/java/com/getcapacitor/JSExport.java +208 -0
  22. package/capacitor/src/main/java/com/getcapacitor/JSExportException.java +16 -0
  23. package/capacitor/src/main/java/com/getcapacitor/JSInjector.java +127 -0
  24. package/capacitor/src/main/java/com/getcapacitor/JSObject.java +164 -0
  25. package/capacitor/src/main/java/com/getcapacitor/JSValue.java +65 -0
  26. package/capacitor/src/main/java/com/getcapacitor/Logger.java +103 -0
  27. package/capacitor/src/main/java/com/getcapacitor/MessageHandler.java +157 -0
  28. package/capacitor/src/main/java/com/getcapacitor/NativePlugin.java +37 -0
  29. package/capacitor/src/main/java/com/getcapacitor/PermissionState.java +31 -0
  30. package/capacitor/src/main/java/com/getcapacitor/Plugin.java +1050 -0
  31. package/capacitor/src/main/java/com/getcapacitor/PluginCall.java +394 -0
  32. package/capacitor/src/main/java/com/getcapacitor/PluginConfig.java +116 -0
  33. package/capacitor/src/main/java/com/getcapacitor/PluginHandle.java +160 -0
  34. package/capacitor/src/main/java/com/getcapacitor/PluginInvocationException.java +16 -0
  35. package/capacitor/src/main/java/com/getcapacitor/PluginLoadException.java +19 -0
  36. package/capacitor/src/main/java/com/getcapacitor/PluginManager.java +56 -0
  37. package/capacitor/src/main/java/com/getcapacitor/PluginMethod.java +15 -0
  38. package/capacitor/src/main/java/com/getcapacitor/PluginMethodHandle.java +33 -0
  39. package/capacitor/src/main/java/com/getcapacitor/PluginResult.java +84 -0
  40. package/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java +37 -0
  41. package/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java +8 -0
  42. package/capacitor/src/main/java/com/getcapacitor/ServerPath.java +25 -0
  43. package/capacitor/src/main/java/com/getcapacitor/UriMatcher.java +184 -0
  44. package/capacitor/src/main/java/com/getcapacitor/WebViewListener.java +57 -0
  45. package/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java +758 -0
  46. package/capacitor/src/main/java/com/getcapacitor/annotation/ActivityCallback.java +10 -0
  47. package/capacitor/src/main/java/com/getcapacitor/annotation/CapacitorPlugin.java +35 -0
  48. package/capacitor/src/main/java/com/getcapacitor/annotation/Permission.java +22 -0
  49. package/capacitor/src/main/java/com/getcapacitor/annotation/PermissionCallback.java +10 -0
  50. package/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java +42 -0
  51. package/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaInterfaceImpl.java +39 -0
  52. package/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java +282 -0
  53. package/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java +239 -0
  54. package/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java +119 -0
  55. package/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java +119 -0
  56. package/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java +220 -0
  57. package/capacitor/src/main/java/com/getcapacitor/plugin/WebView.java +48 -0
  58. package/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java +358 -0
  59. package/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java +473 -0
  60. package/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java +465 -0
  61. package/capacitor/src/main/java/com/getcapacitor/plugin/util/ICapacitorHttpUrlConnection.java +15 -0
  62. package/capacitor/src/main/java/com/getcapacitor/plugin/util/MimeType.java +17 -0
  63. package/capacitor/src/main/java/com/getcapacitor/util/HostMask.java +123 -0
  64. package/capacitor/src/main/java/com/getcapacitor/util/InternalUtils.java +27 -0
  65. package/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java +166 -0
  66. package/capacitor/src/main/java/com/getcapacitor/util/PermissionHelper.java +114 -0
  67. package/capacitor/src/main/java/com/getcapacitor/util/WebColor.java +28 -0
  68. package/capacitor/src/main/res/layout/capacitor_bridge_layout_main.xml +15 -0
  69. package/capacitor/src/main/res/layout/no_webview.xml +14 -0
  70. package/capacitor/src/main/res/values/colors.xml +6 -0
  71. package/capacitor/src/main/res/values/strings.xml +3 -0
  72. package/capacitor/src/main/res/values/styles.xml +6 -0
  73. package/package.json +31 -0
@@ -0,0 +1,473 @@
1
+ package com.getcapacitor.plugin.util;
2
+
3
+ import android.os.Build;
4
+ import android.os.LocaleList;
5
+ import android.text.TextUtils;
6
+ import com.getcapacitor.Bridge;
7
+ import com.getcapacitor.JSArray;
8
+ import com.getcapacitor.JSObject;
9
+ import com.getcapacitor.JSValue;
10
+ import com.getcapacitor.PluginCall;
11
+ import java.io.DataOutputStream;
12
+ import java.io.IOException;
13
+ import java.io.InputStream;
14
+ import java.lang.reflect.Method;
15
+ import java.net.HttpURLConnection;
16
+ import java.net.ProtocolException;
17
+ import java.net.SocketTimeoutException;
18
+ import java.net.URL;
19
+ import java.net.URLEncoder;
20
+ import java.net.UnknownServiceException;
21
+ import java.nio.charset.StandardCharsets;
22
+ import java.util.Base64;
23
+ import java.util.Iterator;
24
+ import java.util.List;
25
+ import java.util.Locale;
26
+ import java.util.Map;
27
+ import javax.net.ssl.HttpsURLConnection;
28
+ import javax.net.ssl.SSLSocketFactory;
29
+ import org.json.JSONException;
30
+ import org.json.JSONObject;
31
+
32
+ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
33
+
34
+ private final HttpURLConnection connection;
35
+
36
+ /**
37
+ * Make a new CapacitorHttpUrlConnection instance, which wraps around HttpUrlConnection
38
+ * and provides some helper functions for setting request headers and the request body
39
+ * @param conn the base HttpUrlConnection. You can pass the value from
40
+ * {@code (HttpUrlConnection) URL.openConnection()}
41
+ */
42
+ public CapacitorHttpUrlConnection(HttpURLConnection conn) {
43
+ connection = conn;
44
+ this.setDefaultRequestProperties();
45
+ }
46
+
47
+ /**
48
+ * Returns the underlying HttpUrlConnection value
49
+ * @return the underlying HttpUrlConnection value
50
+ */
51
+ public HttpURLConnection getHttpConnection() {
52
+ return connection;
53
+ }
54
+
55
+ public void disconnect() {
56
+ connection.disconnect();
57
+ }
58
+
59
+ /**
60
+ * Set the value of the {@code allowUserInteraction} field of
61
+ * this {@code URLConnection}.
62
+ *
63
+ * @param isAllowedInteraction the new value.
64
+ * @throws IllegalStateException if already connected
65
+ */
66
+ public void setAllowUserInteraction(boolean isAllowedInteraction) {
67
+ connection.setAllowUserInteraction(isAllowedInteraction);
68
+ }
69
+
70
+ /**
71
+ * Set the method for the URL request, one of:
72
+ * <UL>
73
+ * <LI>GET
74
+ * <LI>POST
75
+ * <LI>HEAD
76
+ * <LI>OPTIONS
77
+ * <LI>PUT
78
+ * <LI>DELETE
79
+ * <LI>TRACE
80
+ * </UL> are legal, subject to protocol restrictions. The default
81
+ * method is GET.
82
+ *
83
+ * @param method the HTTP method
84
+ * @exception ProtocolException if the method cannot be reset or if
85
+ * the requested method isn't valid for HTTP.
86
+ * @exception SecurityException if a security manager is set and the
87
+ * method is "TRACE", but the "allowHttpTrace"
88
+ * NetPermission is not granted.
89
+ */
90
+ public void setRequestMethod(String method) throws ProtocolException {
91
+ connection.setRequestMethod(method);
92
+ }
93
+
94
+ /**
95
+ * Sets a specified timeout value, in milliseconds, to be used
96
+ * when opening a communications link to the resource referenced
97
+ * by this URLConnection. If the timeout expires before the
98
+ * connection can be established, a
99
+ * java.net.SocketTimeoutException is raised. A timeout of zero is
100
+ * interpreted as an infinite timeout.
101
+ *
102
+ * <p><strong>Warning</strong>: If the hostname resolves to multiple IP
103
+ * addresses, Android's default implementation of {@link HttpURLConnection}
104
+ * will try each in
105
+ * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order. If
106
+ * connecting to each of these addresses fails, multiple timeouts will
107
+ * elapse before the connect attempt throws an exception. Host names
108
+ * that support both IPv6 and IPv4 always have at least 2 IP addresses.
109
+ *
110
+ * @param timeout an {@code int} that specifies the connect
111
+ * timeout value in milliseconds
112
+ * @throws IllegalArgumentException if the timeout parameter is negative
113
+ */
114
+ public void setConnectTimeout(int timeout) {
115
+ if (timeout < 0) {
116
+ throw new IllegalArgumentException("timeout can not be negative");
117
+ }
118
+ connection.setConnectTimeout(timeout);
119
+ }
120
+
121
+ /**
122
+ * Sets the read timeout to a specified timeout, in
123
+ * milliseconds. A non-zero value specifies the timeout when
124
+ * reading from Input stream when a connection is established to a
125
+ * resource. If the timeout expires before there is data available
126
+ * for read, a java.net.SocketTimeoutException is raised. A
127
+ * timeout of zero is interpreted as an infinite timeout.
128
+ *
129
+ * @param timeout an {@code int} that specifies the timeout
130
+ * value to be used in milliseconds
131
+ * @throws IllegalArgumentException if the timeout parameter is negative
132
+ */
133
+ public void setReadTimeout(int timeout) {
134
+ if (timeout < 0) {
135
+ throw new IllegalArgumentException("timeout can not be negative");
136
+ }
137
+ connection.setReadTimeout(timeout);
138
+ }
139
+
140
+ /**
141
+ * Sets whether automatic HTTP redirects should be disabled
142
+ * @param disableRedirects the flag to determine if redirects should be followed
143
+ */
144
+ public void setDisableRedirects(boolean disableRedirects) {
145
+ connection.setInstanceFollowRedirects(!disableRedirects);
146
+ }
147
+
148
+ /**
149
+ * Sets the request headers given a JSObject of key-value pairs
150
+ * @param headers the JSObject values to map to the HttpUrlConnection request headers
151
+ */
152
+ public void setRequestHeaders(JSObject headers) {
153
+ Iterator<String> keys = headers.keys();
154
+ while (keys.hasNext()) {
155
+ String key = keys.next();
156
+ String value = headers.getString(key);
157
+ connection.setRequestProperty(key, value);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Sets the value of the {@code doOutput} field for this
163
+ * {@code URLConnection} to the specified value.
164
+ * <p>
165
+ * A URL connection can be used for input and/or output. Set the DoOutput
166
+ * flag to true if you intend to use the URL connection for output,
167
+ * false if not. The default is false.
168
+ *
169
+ * @param shouldDoOutput the new value.
170
+ * @throws IllegalStateException if already connected
171
+ */
172
+ public void setDoOutput(boolean shouldDoOutput) {
173
+ connection.setDoOutput(shouldDoOutput);
174
+ }
175
+
176
+ /**
177
+ *
178
+ * @param call
179
+ * @throws JSONException
180
+ * @throws IOException
181
+ */
182
+ public void setRequestBody(PluginCall call, JSValue body) throws JSONException, IOException {
183
+ setRequestBody(call, body, null);
184
+ }
185
+
186
+ /**
187
+ *
188
+ * @param call
189
+ * @throws JSONException
190
+ * @throws IOException
191
+ */
192
+ public void setRequestBody(PluginCall call, JSValue body, String bodyType) throws JSONException, IOException {
193
+ String contentType = connection.getRequestProperty("Content-Type");
194
+ String dataString = "";
195
+
196
+ if (contentType == null || contentType.isEmpty()) return;
197
+
198
+ if (contentType.contains("application/json")) {
199
+ JSArray jsArray = null;
200
+ if (body != null) {
201
+ dataString = body.toString();
202
+ } else {
203
+ jsArray = call.getArray("data", null);
204
+ }
205
+ if (jsArray != null) {
206
+ dataString = jsArray.toString();
207
+ } else if (body == null) {
208
+ dataString = call.getString("data");
209
+ }
210
+ this.writeRequestBody(dataString != null ? dataString : "");
211
+ } else if (bodyType != null && bodyType.equals("file")) {
212
+ try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
213
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
214
+ os.write(Base64.getDecoder().decode(body.toString()));
215
+ }
216
+ os.flush();
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
+ }
226
+ } else if (bodyType != null && bodyType.equals("formData")) {
227
+ this.writeFormDataRequestBody(contentType, body.toJSArray());
228
+ } else {
229
+ this.writeRequestBody(body.toString());
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Writes the provided string to the HTTP connection managed by this instance.
235
+ *
236
+ * @param body The string value to write to the connection stream.
237
+ */
238
+ private void writeRequestBody(String body) throws IOException {
239
+ try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
240
+ os.write(body.getBytes(StandardCharsets.UTF_8));
241
+ os.flush();
242
+ }
243
+ }
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(URLEncoder.encode(key, "UTF-8"));
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
+
263
+ private void writeFormDataRequestBody(String contentType, JSArray entries) throws IOException, JSONException {
264
+ try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
265
+ String boundary = contentType.split(";")[1].split("=")[1];
266
+ String lineEnd = "\r\n";
267
+ String twoHyphens = "--";
268
+
269
+ for (Object e : entries.toList()) {
270
+ if (e instanceof JSONObject) {
271
+ JSONObject entry = (JSONObject) e;
272
+ String type = entry.getString("type");
273
+ String key = entry.getString("key");
274
+ String value = entry.getString("value");
275
+ if (type.equals("string")) {
276
+ os.writeBytes(twoHyphens + boundary + lineEnd);
277
+ os.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"" + lineEnd + lineEnd);
278
+ os.write(value.getBytes(StandardCharsets.UTF_8));
279
+ os.writeBytes(lineEnd);
280
+ } else if (type.equals("base64File")) {
281
+ String fileName = entry.getString("fileName");
282
+ String fileContentType = entry.getString("contentType");
283
+
284
+ os.writeBytes(twoHyphens + boundary + lineEnd);
285
+ os.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + fileName + "\"" + lineEnd);
286
+ os.writeBytes("Content-Type: " + fileContentType + lineEnd);
287
+ os.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
288
+ os.writeBytes(lineEnd);
289
+
290
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
291
+ os.write(Base64.getDecoder().decode(value));
292
+ } else {
293
+ os.write(android.util.Base64.decode(value, android.util.Base64.DEFAULT));
294
+ }
295
+
296
+ os.writeBytes(lineEnd);
297
+ }
298
+ }
299
+ }
300
+
301
+ os.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
302
+ os.flush();
303
+ }
304
+ }
305
+
306
+ /**
307
+ * Opens a communications link to the resource referenced by this
308
+ * URL, if such a connection has not already been established.
309
+ * <p>
310
+ * If the {@code connect} method is called when the connection
311
+ * has already been opened (indicated by the {@code connected}
312
+ * field having the value {@code true}), the call is ignored.
313
+ * <p>
314
+ * URLConnection objects go through two phases: first they are
315
+ * created, then they are connected. After being created, and
316
+ * before being connected, various options can be specified
317
+ * (e.g., doInput and UseCaches). After connecting, it is an
318
+ * error to try to set them. Operations that depend on being
319
+ * connected, like getContentLength, will implicitly perform the
320
+ * connection, if necessary.
321
+ *
322
+ * @throws SocketTimeoutException if the timeout expires before
323
+ * the connection can be established
324
+ * @exception IOException if an I/O error occurs while opening the
325
+ * connection.
326
+ */
327
+ public void connect() throws IOException {
328
+ connection.connect();
329
+ }
330
+
331
+ /**
332
+ * Gets the status code from an HTTP response message.
333
+ * For example, in the case of the following status lines:
334
+ * <PRE>
335
+ * HTTP/1.0 200 OK
336
+ * HTTP/1.0 401 Unauthorized
337
+ * </PRE>
338
+ * It will return 200 and 401 respectively.
339
+ * Returns -1 if no code can be discerned
340
+ * from the response (i.e., the response is not valid HTTP).
341
+ * @throws IOException if an error occurred connecting to the server.
342
+ * @return the HTTP Status-Code, or -1
343
+ */
344
+ public int getResponseCode() throws IOException {
345
+ return connection.getResponseCode();
346
+ }
347
+
348
+ /**
349
+ * Returns the value of this {@code URLConnection}'s {@code URL}
350
+ * field.
351
+ *
352
+ * @return the value of this {@code URLConnection}'s {@code URL}
353
+ * field.
354
+ */
355
+ public URL getURL() {
356
+ return connection.getURL();
357
+ }
358
+
359
+ /**
360
+ * Returns the error stream if the connection failed
361
+ * but the server sent useful data nonetheless. The
362
+ * typical example is when an HTTP server responds
363
+ * with a 404, which will cause a FileNotFoundException
364
+ * to be thrown in connect, but the server sent an HTML
365
+ * help page with suggestions as to what to do.
366
+ *
367
+ * <p>This method will not cause a connection to be initiated. If
368
+ * the connection was not connected, or if the server did not have
369
+ * an error while connecting or if the server had an error but
370
+ * no error data was sent, this method will return null. This is
371
+ * the default.
372
+ *
373
+ * @return an error stream if any, null if there have been no
374
+ * errors, the connection is not connected or the server sent no
375
+ * useful data.
376
+ */
377
+ @Override
378
+ public InputStream getErrorStream() {
379
+ return connection.getErrorStream();
380
+ }
381
+
382
+ /**
383
+ * Returns the value of the named header field.
384
+ * <p>
385
+ * If called on a connection that sets the same header multiple times
386
+ * with possibly different values, only the last value is returned.
387
+ *
388
+ *
389
+ * @param name the name of a header field.
390
+ * @return the value of the named header field, or {@code null}
391
+ * if there is no such field in the header.
392
+ */
393
+ @Override
394
+ public String getHeaderField(String name) {
395
+ return connection.getHeaderField(name);
396
+ }
397
+
398
+ /**
399
+ * Returns an input stream that reads from this open connection.
400
+ *
401
+ * A SocketTimeoutException can be thrown when reading from the
402
+ * returned input stream if the read timeout expires before data
403
+ * is available for read.
404
+ *
405
+ * @return an input stream that reads from this open connection.
406
+ * @exception IOException if an I/O error occurs while
407
+ * creating the input stream.
408
+ * @exception UnknownServiceException if the protocol does not support
409
+ * input.
410
+ * @see #setReadTimeout(int)
411
+ */
412
+ @Override
413
+ public InputStream getInputStream() throws IOException {
414
+ return connection.getInputStream();
415
+ }
416
+
417
+ /**
418
+ * Returns an unmodifiable Map of the header fields.
419
+ * The Map keys are Strings that represent the
420
+ * response-header field names. Each Map value is an
421
+ * unmodifiable List of Strings that represents
422
+ * the corresponding field values.
423
+ *
424
+ * @return a Map of header fields
425
+ */
426
+ public Map<String, List<String>> getHeaderFields() {
427
+ return connection.getHeaderFields();
428
+ }
429
+
430
+ /**
431
+ * Sets the default request properties on the newly created connection.
432
+ * This is called as early as possible to allow overrides by user-provided values.
433
+ */
434
+ private void setDefaultRequestProperties() {
435
+ String acceptLanguage = buildDefaultAcceptLanguageProperty();
436
+ if (!TextUtils.isEmpty(acceptLanguage)) {
437
+ connection.setRequestProperty("Accept-Language", acceptLanguage);
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Builds and returns a locale string describing the device's current locale preferences.
443
+ */
444
+ private String buildDefaultAcceptLanguageProperty() {
445
+ Locale locale = LocaleList.getDefault().get(0);
446
+ String result = "";
447
+ String lang = locale.getLanguage();
448
+ String country = locale.getCountry();
449
+ if (!TextUtils.isEmpty(lang)) {
450
+ if (!TextUtils.isEmpty(country)) {
451
+ result = String.format("%s-%s,%s;q=0.5", lang, country, lang);
452
+ } else {
453
+ result = String.format("%s;q=0.5", lang);
454
+ }
455
+ }
456
+ return result;
457
+ }
458
+
459
+ public void setSSLSocketFactory(Bridge bridge) {
460
+ // Attach SSL Certificates if Enterprise Plugin is available
461
+ try {
462
+ Class<?> sslPinningImpl = Class.forName("io.ionic.sslpinning.SSLPinning");
463
+ Method method = sslPinningImpl.getDeclaredMethod("getSSLSocketFactory", Bridge.class);
464
+ SSLSocketFactory sslSocketFactory = (SSLSocketFactory) method.invoke(
465
+ sslPinningImpl.getDeclaredConstructor().newInstance(),
466
+ bridge
467
+ );
468
+ if (sslSocketFactory != null) {
469
+ ((HttpsURLConnection) this.connection).setSSLSocketFactory(sslSocketFactory);
470
+ }
471
+ } catch (Exception ignored) {}
472
+ }
473
+ }