@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,10 @@
1
+ package com.getcapacitor.annotation;
2
+
3
+ import java.lang.annotation.ElementType;
4
+ import java.lang.annotation.Retention;
5
+ import java.lang.annotation.RetentionPolicy;
6
+ import java.lang.annotation.Target;
7
+
8
+ @Retention(RetentionPolicy.RUNTIME)
9
+ @Target(ElementType.METHOD)
10
+ public @interface ActivityCallback {}
@@ -0,0 +1,35 @@
1
+ package com.getcapacitor.annotation;
2
+
3
+ import android.content.Intent;
4
+ import com.getcapacitor.PluginCall;
5
+ import java.lang.annotation.Retention;
6
+ import java.lang.annotation.RetentionPolicy;
7
+
8
+ /**
9
+ * Base annotation for all Plugins
10
+ */
11
+ @Retention(RetentionPolicy.RUNTIME)
12
+ public @interface CapacitorPlugin {
13
+ /**
14
+ * A custom name for the plugin, otherwise uses the
15
+ * simple class name.
16
+ */
17
+ String name() default "";
18
+
19
+ /**
20
+ * Request codes this plugin uses and responds to, in order to tie
21
+ * Android events back the plugin to handle.
22
+ *
23
+ * NOTE: This is a legacy option provided to support third party libraries
24
+ * not currently implementing the new AndroidX Activity Results API. Plugins
25
+ * without this limitation should use a registered callback with
26
+ * {@link com.getcapacitor.Plugin#startActivityForResult(PluginCall, Intent, String)}
27
+ */
28
+ int[] requestCodes() default {};
29
+
30
+ /**
31
+ * Permissions this plugin needs, in order to make permission requests
32
+ * easy if the plugin only needs basic permission prompting
33
+ */
34
+ Permission[] permissions() default {};
35
+ }
@@ -0,0 +1,22 @@
1
+ package com.getcapacitor.annotation;
2
+
3
+ import java.lang.annotation.Retention;
4
+ import java.lang.annotation.RetentionPolicy;
5
+
6
+ /**
7
+ * Permission annotation for use with @CapacitorPlugin
8
+ */
9
+ @Retention(RetentionPolicy.RUNTIME)
10
+ public @interface Permission {
11
+ /**
12
+ * An array of Android permission strings.
13
+ * Eg: {Manifest.permission.ACCESS_COARSE_LOCATION}
14
+ * or {"android.permission.ACCESS_COARSE_LOCATION"}
15
+ */
16
+ String[] strings() default {};
17
+
18
+ /**
19
+ * An optional name to use instead of the Android permission string.
20
+ */
21
+ String alias() default "";
22
+ }
@@ -0,0 +1,10 @@
1
+ package com.getcapacitor.annotation;
2
+
3
+ import java.lang.annotation.ElementType;
4
+ import java.lang.annotation.Retention;
5
+ import java.lang.annotation.RetentionPolicy;
6
+ import java.lang.annotation.Target;
7
+
8
+ @Retention(RetentionPolicy.RUNTIME)
9
+ @Target(ElementType.METHOD)
10
+ public @interface PermissionCallback {}
@@ -0,0 +1,42 @@
1
+ package com.getcapacitor.cordova;
2
+
3
+ import android.webkit.CookieManager;
4
+ import android.webkit.WebView;
5
+ import org.apache.cordova.ICordovaCookieManager;
6
+
7
+ class CapacitorCordovaCookieManager implements ICordovaCookieManager {
8
+
9
+ protected final WebView webView;
10
+ private final CookieManager cookieManager;
11
+
12
+ public CapacitorCordovaCookieManager(WebView webview) {
13
+ webView = webview;
14
+ cookieManager = CookieManager.getInstance();
15
+ cookieManager.setAcceptThirdPartyCookies(webView, true);
16
+ }
17
+
18
+ @Override
19
+ public void setCookiesEnabled(boolean accept) {
20
+ cookieManager.setAcceptCookie(accept);
21
+ }
22
+
23
+ @Override
24
+ public void setCookie(final String url, final String value) {
25
+ cookieManager.setCookie(url, value);
26
+ }
27
+
28
+ @Override
29
+ public String getCookie(final String url) {
30
+ return cookieManager.getCookie(url);
31
+ }
32
+
33
+ @Override
34
+ public void clearCookies() {
35
+ cookieManager.removeAllCookies(null);
36
+ }
37
+
38
+ @Override
39
+ public void flush() {
40
+ cookieManager.flush();
41
+ }
42
+ }
@@ -0,0 +1,39 @@
1
+ package com.getcapacitor.cordova;
2
+
3
+ import android.util.Pair;
4
+ import androidx.appcompat.app.AppCompatActivity;
5
+ import java.util.concurrent.Executors;
6
+ import org.apache.cordova.CordovaInterfaceImpl;
7
+ import org.apache.cordova.CordovaPlugin;
8
+ import org.json.JSONException;
9
+
10
+ public class MockCordovaInterfaceImpl extends CordovaInterfaceImpl {
11
+
12
+ public MockCordovaInterfaceImpl(AppCompatActivity activity) {
13
+ super(activity, Executors.newCachedThreadPool());
14
+ }
15
+
16
+ public CordovaPlugin getActivityResultCallback() {
17
+ return this.activityResultCallback;
18
+ }
19
+
20
+ /**
21
+ * Checks Cordova permission callbacks to handle permissions defined by a Cordova plugin.
22
+ * Returns true if Cordova is handling the permission request with a registered code.
23
+ *
24
+ * @param requestCode
25
+ * @param permissions
26
+ * @param grantResults
27
+ * @return true if Cordova handled the permission request, false if not
28
+ */
29
+ @SuppressWarnings("deprecation")
30
+ public boolean handlePermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException {
31
+ Pair<CordovaPlugin, Integer> callback = permissionResultCallbacks.getAndRemoveCallback(requestCode);
32
+ if (callback != null) {
33
+ callback.first.onRequestPermissionResult(callback.second, permissions, grantResults);
34
+ return true;
35
+ }
36
+
37
+ return false;
38
+ }
39
+ }
@@ -0,0 +1,282 @@
1
+ package com.getcapacitor.cordova;
2
+
3
+ import android.content.Context;
4
+ import android.content.Intent;
5
+ import android.os.Handler;
6
+ import android.view.View;
7
+ import android.webkit.ValueCallback;
8
+ import android.webkit.WebChromeClient;
9
+ import android.webkit.WebView;
10
+ import java.util.List;
11
+ import java.util.Map;
12
+ import org.apache.cordova.CordovaInterface;
13
+ import org.apache.cordova.CordovaPreferences;
14
+ import org.apache.cordova.CordovaResourceApi;
15
+ import org.apache.cordova.CordovaWebView;
16
+ import org.apache.cordova.CordovaWebViewEngine;
17
+ import org.apache.cordova.ICordovaCookieManager;
18
+ import org.apache.cordova.NativeToJsMessageQueue;
19
+ import org.apache.cordova.PluginEntry;
20
+ import org.apache.cordova.PluginManager;
21
+ import org.apache.cordova.PluginResult;
22
+
23
+ public class MockCordovaWebViewImpl implements CordovaWebView {
24
+
25
+ private Context context;
26
+ private PluginManager pluginManager;
27
+ private CordovaPreferences preferences;
28
+ private CordovaResourceApi resourceApi;
29
+ private NativeToJsMessageQueue nativeToJsMessageQueue;
30
+ private CordovaInterface cordova;
31
+ private CapacitorCordovaCookieManager cookieManager;
32
+ private WebView webView;
33
+ private boolean hasPausedEver;
34
+
35
+ public MockCordovaWebViewImpl(Context context) {
36
+ this.context = context;
37
+ }
38
+
39
+ @Override
40
+ public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {
41
+ this.cordova = cordova;
42
+ this.preferences = preferences;
43
+ this.pluginManager = new PluginManager(this, this.cordova, pluginEntries);
44
+ this.resourceApi = new CordovaResourceApi(this.context, this.pluginManager);
45
+ this.pluginManager.init();
46
+ }
47
+
48
+ public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences, WebView webView) {
49
+ this.cordova = cordova;
50
+ this.webView = webView;
51
+ this.preferences = preferences;
52
+ this.pluginManager = new PluginManager(this, this.cordova, pluginEntries);
53
+ this.resourceApi = new CordovaResourceApi(this.context, this.pluginManager);
54
+ nativeToJsMessageQueue = new NativeToJsMessageQueue();
55
+ nativeToJsMessageQueue.addBridgeMode(new CapacitorEvalBridgeMode(webView, this.cordova));
56
+ nativeToJsMessageQueue.setBridgeMode(0);
57
+ this.cookieManager = new CapacitorCordovaCookieManager(webView);
58
+ this.pluginManager.init();
59
+ }
60
+
61
+ public static class CapacitorEvalBridgeMode extends NativeToJsMessageQueue.BridgeMode {
62
+
63
+ private final WebView webView;
64
+ private final CordovaInterface cordova;
65
+
66
+ public CapacitorEvalBridgeMode(WebView webView, CordovaInterface cordova) {
67
+ this.webView = webView;
68
+ this.cordova = cordova;
69
+ }
70
+
71
+ @Override
72
+ public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) {
73
+ cordova
74
+ .getActivity()
75
+ .runOnUiThread(() -> {
76
+ String js = queue.popAndEncodeAsJs();
77
+ if (js != null) {
78
+ webView.evaluateJavascript(js, null);
79
+ }
80
+ });
81
+ }
82
+ }
83
+
84
+ @Override
85
+ public boolean isInitialized() {
86
+ return cordova != null;
87
+ }
88
+
89
+ @Override
90
+ public View getView() {
91
+ return this.webView;
92
+ }
93
+
94
+ @Override
95
+ public void loadUrlIntoView(String url, boolean recreatePlugins) {
96
+ if (url.equals("about:blank") || url.startsWith("javascript:")) {
97
+ webView.loadUrl(url);
98
+ return;
99
+ }
100
+ }
101
+
102
+ @Override
103
+ public void stopLoading() {}
104
+
105
+ @Override
106
+ public boolean canGoBack() {
107
+ return false;
108
+ }
109
+
110
+ @Override
111
+ public void clearCache() {}
112
+
113
+ @Deprecated
114
+ @Override
115
+ public void clearCache(boolean b) {}
116
+
117
+ @Override
118
+ public void clearHistory() {}
119
+
120
+ @Override
121
+ public boolean backHistory() {
122
+ return false;
123
+ }
124
+
125
+ @Override
126
+ public void handlePause(boolean keepRunning) {
127
+ if (!isInitialized()) {
128
+ return;
129
+ }
130
+ hasPausedEver = true;
131
+ pluginManager.onPause(keepRunning);
132
+ triggerDocumentEvent("pause");
133
+ // If app doesn't want to run in background
134
+ if (!keepRunning) {
135
+ // Pause JavaScript timers. This affects all webviews within the app!
136
+ this.setPaused(true);
137
+ }
138
+ }
139
+
140
+ @Override
141
+ public void onNewIntent(Intent intent) {
142
+ if (this.pluginManager != null) {
143
+ this.pluginManager.onNewIntent(intent);
144
+ }
145
+ }
146
+
147
+ @Override
148
+ public void handleResume(boolean keepRunning) {
149
+ if (!isInitialized()) {
150
+ return;
151
+ }
152
+ this.setPaused(false);
153
+ this.pluginManager.onResume(keepRunning);
154
+ if (hasPausedEver) {
155
+ triggerDocumentEvent("resume");
156
+ }
157
+ }
158
+
159
+ @Override
160
+ public void handleStart() {
161
+ if (!isInitialized()) {
162
+ return;
163
+ }
164
+ pluginManager.onStart();
165
+ }
166
+
167
+ @Override
168
+ public void handleStop() {
169
+ if (!isInitialized()) {
170
+ return;
171
+ }
172
+ pluginManager.onStop();
173
+ }
174
+
175
+ @Override
176
+ public void handleDestroy() {
177
+ if (!isInitialized()) {
178
+ return;
179
+ }
180
+ this.pluginManager.onDestroy();
181
+ }
182
+
183
+ @Deprecated
184
+ @Override
185
+ public void sendJavascript(String statememt) {
186
+ nativeToJsMessageQueue.addJavaScript(statememt);
187
+ }
188
+
189
+ public void eval(final String js, final ValueCallback<String> callback) {
190
+ Handler mainHandler = new Handler(context.getMainLooper());
191
+ mainHandler.post(() -> webView.evaluateJavascript(js, callback));
192
+ }
193
+
194
+ public void triggerDocumentEvent(final String eventName) {
195
+ eval("window.Capacitor.triggerEvent('" + eventName + "', 'document');", (s) -> {});
196
+ }
197
+
198
+ @Override
199
+ public void showWebPage(String url, boolean openExternal, boolean clearHistory, Map<String, Object> params) {}
200
+
201
+ @Deprecated
202
+ @Override
203
+ public boolean isCustomViewShowing() {
204
+ return false;
205
+ }
206
+
207
+ @Deprecated
208
+ @Override
209
+ public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {}
210
+
211
+ @Deprecated
212
+ @Override
213
+ public void hideCustomView() {}
214
+
215
+ @Override
216
+ public CordovaResourceApi getResourceApi() {
217
+ return this.resourceApi;
218
+ }
219
+
220
+ @Override
221
+ public void setButtonPlumbedToJs(int keyCode, boolean override) {}
222
+
223
+ @Override
224
+ public boolean isButtonPlumbedToJs(int keyCode) {
225
+ return false;
226
+ }
227
+
228
+ @Override
229
+ public void sendPluginResult(PluginResult cr, String callbackId) {
230
+ nativeToJsMessageQueue.addPluginResult(cr, callbackId);
231
+ }
232
+
233
+ @Override
234
+ public PluginManager getPluginManager() {
235
+ return this.pluginManager;
236
+ }
237
+
238
+ @Override
239
+ public CordovaWebViewEngine getEngine() {
240
+ return null;
241
+ }
242
+
243
+ @Override
244
+ public CordovaPreferences getPreferences() {
245
+ return this.preferences;
246
+ }
247
+
248
+ @Override
249
+ public ICordovaCookieManager getCookieManager() {
250
+ return cookieManager;
251
+ }
252
+
253
+ @Override
254
+ public String getUrl() {
255
+ return webView.getUrl();
256
+ }
257
+
258
+ @Override
259
+ public Context getContext() {
260
+ return this.webView.getContext();
261
+ }
262
+
263
+ @Override
264
+ public void loadUrl(String url) {
265
+ loadUrlIntoView(url, true);
266
+ }
267
+
268
+ @Override
269
+ public Object postMessage(String id, Object data) {
270
+ return pluginManager.postMessage(id, data);
271
+ }
272
+
273
+ public void setPaused(boolean value) {
274
+ if (value) {
275
+ webView.onPause();
276
+ webView.pauseTimers();
277
+ } else {
278
+ webView.onResume();
279
+ webView.resumeTimers();
280
+ }
281
+ }
282
+ }
@@ -0,0 +1,239 @@
1
+ package com.getcapacitor.plugin;
2
+
3
+ import com.getcapacitor.Bridge;
4
+ import com.getcapacitor.Logger;
5
+ import java.net.CookieManager;
6
+ import java.net.CookiePolicy;
7
+ import java.net.CookieStore;
8
+ import java.net.HttpCookie;
9
+ import java.net.URI;
10
+ import java.net.URISyntaxException;
11
+ import java.util.ArrayList;
12
+ import java.util.Collections;
13
+ import java.util.HashMap;
14
+ import java.util.List;
15
+ import java.util.Locale;
16
+ import java.util.Map;
17
+ import java.util.Objects;
18
+
19
+ public class CapacitorCookieManager extends CookieManager {
20
+
21
+ private final android.webkit.CookieManager webkitCookieManager;
22
+
23
+ private final String localUrl;
24
+
25
+ private final String serverUrl;
26
+
27
+ private final String TAG = "CapacitorCookies";
28
+
29
+ /**
30
+ * Create a new cookie manager with the default cookie store and policy
31
+ */
32
+ public CapacitorCookieManager(Bridge bridge) {
33
+ this(null, null, bridge);
34
+ }
35
+
36
+ /**
37
+ * Create a new cookie manager with specified cookie store and cookie policy.
38
+ * @param store a {@code CookieStore} to be used by CookieManager. if {@code null}, cookie
39
+ * manager will use a default one, which is an in-memory CookieStore implementation.
40
+ * @param policy a {@code CookiePolicy} instance to be used by cookie manager as policy
41
+ * callback. if {@code null}, ACCEPT_ORIGINAL_SERVER will be used.
42
+ */
43
+ public CapacitorCookieManager(CookieStore store, CookiePolicy policy, Bridge bridge) {
44
+ super(store, policy);
45
+ webkitCookieManager = android.webkit.CookieManager.getInstance();
46
+ this.localUrl = bridge.getLocalUrl();
47
+ this.serverUrl = bridge.getServerUrl();
48
+ }
49
+
50
+ public void removeSessionCookies() {
51
+ this.webkitCookieManager.removeSessionCookies(null);
52
+ }
53
+
54
+ public String getSanitizedDomain(String url) throws URISyntaxException {
55
+ if (this.serverUrl != null && !this.serverUrl.isEmpty() && (url == null || url.isEmpty() || this.serverUrl.contains(url))) {
56
+ url = this.serverUrl;
57
+ } else if (this.localUrl != null && !this.localUrl.isEmpty() && (url == null || url.isEmpty() || this.localUrl.contains(url))) {
58
+ url = this.localUrl;
59
+ } else try {
60
+ URI uri = new URI(url);
61
+ String scheme = uri.getScheme();
62
+ if (scheme == null || scheme.isEmpty()) {
63
+ url = "https://" + url;
64
+ }
65
+ } catch (URISyntaxException e) {
66
+ Logger.error(TAG, "Failed to get scheme from URL.", e);
67
+ }
68
+
69
+ try {
70
+ new URI(url);
71
+ } catch (Exception error) {
72
+ Logger.error(TAG, "Failed to get sanitized URL.", error);
73
+ throw error;
74
+ }
75
+ return url;
76
+ }
77
+
78
+ private String getDomainFromCookieString(String cookie) throws URISyntaxException {
79
+ String[] domain = cookie.toLowerCase(Locale.ROOT).split("domain=");
80
+ return getSanitizedDomain(domain.length <= 1 ? null : domain[1].split(";")[0].trim());
81
+ }
82
+
83
+ /**
84
+ * Gets the cookies for the given URL.
85
+ * @param url the URL for which the cookies are requested
86
+ * @return value the cookies as a string, using the format of the 'Cookie' HTTP request header
87
+ */
88
+ public String getCookieString(String url) {
89
+ try {
90
+ url = getSanitizedDomain(url);
91
+ Logger.info(TAG, "Getting cookies at: '" + url + "'");
92
+ return webkitCookieManager.getCookie(url);
93
+ } catch (Exception error) {
94
+ Logger.error(TAG, "Failed to get cookies at the given URL.", error);
95
+ }
96
+
97
+ return null;
98
+ }
99
+
100
+ /**
101
+ * Gets a cookie value for the given URL and key.
102
+ * @param url the URL for which the cookies are requested
103
+ * @param key the key of the cookie to search for
104
+ * @return the {@code HttpCookie} value of the cookie at the key,
105
+ * otherwise it will return a new empty {@code HttpCookie}
106
+ */
107
+ public HttpCookie getCookie(String url, String key) {
108
+ HttpCookie[] cookies = getCookies(url);
109
+ for (HttpCookie cookie : cookies) {
110
+ if (cookie.getName().equals(key)) {
111
+ return cookie;
112
+ }
113
+ }
114
+
115
+ return null;
116
+ }
117
+
118
+ /**
119
+ * Gets an array of {@code HttpCookie} given a URL.
120
+ * @param url the URL for which the cookies are requested
121
+ * @return an {@code HttpCookie} array of non-expired cookies
122
+ */
123
+ public HttpCookie[] getCookies(String url) {
124
+ try {
125
+ ArrayList<HttpCookie> cookieList = new ArrayList<>();
126
+ String cookieString = getCookieString(url);
127
+ if (cookieString != null) {
128
+ String[] singleCookie = cookieString.split(";");
129
+ for (String c : singleCookie) {
130
+ HttpCookie parsed = HttpCookie.parse(c).get(0);
131
+ parsed.setValue(parsed.getValue());
132
+ cookieList.add(parsed);
133
+ }
134
+ }
135
+ HttpCookie[] cookies = new HttpCookie[cookieList.size()];
136
+ return cookieList.toArray(cookies);
137
+ } catch (Exception ex) {
138
+ return new HttpCookie[0];
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Sets a cookie for the given URL. Any existing cookie with the same host, path and name will
144
+ * be replaced with the new cookie. The cookie being set will be ignored if it is expired.
145
+ * @param url the URL for which the cookie is to be set
146
+ * @param value the cookie as a string, using the format of the 'Set-Cookie' HTTP response header
147
+ */
148
+ public void setCookie(String url, String value) {
149
+ try {
150
+ url = getSanitizedDomain(url);
151
+ Logger.info(TAG, "Setting cookie '" + value + "' at: '" + url + "'");
152
+ webkitCookieManager.setCookie(url, value);
153
+ flush();
154
+ } catch (Exception error) {
155
+ Logger.error(TAG, "Failed to set cookie.", error);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Sets a cookie for the given URL. Any existing cookie with the same host, path and name will
161
+ * be replaced with the new cookie. The cookie being set will be ignored if it is expired.
162
+ * @param url the URL for which the cookie is to be set
163
+ * @param key the {@code HttpCookie} name to use for lookup
164
+ * @param value the value of the {@code HttpCookie} given a key
165
+ */
166
+ public void setCookie(String url, String key, String value) {
167
+ String cookieValue = key + "=" + value;
168
+ setCookie(url, cookieValue);
169
+ }
170
+
171
+ public void setCookie(String url, String key, String value, String expires, String path) {
172
+ String cookieValue = key + "=" + value + "; expires=" + expires + "; path=" + path;
173
+ setCookie(url, cookieValue);
174
+ }
175
+
176
+ /**
177
+ * Removes all cookies. This method is asynchronous.
178
+ */
179
+ public void removeAllCookies() {
180
+ webkitCookieManager.removeAllCookies(null);
181
+ flush();
182
+ }
183
+
184
+ /**
185
+ * Ensures all cookies currently accessible through the getCookie API are written to persistent
186
+ * storage. This call will block the caller until it is done and may perform I/O.
187
+ */
188
+ public void flush() {
189
+ webkitCookieManager.flush();
190
+ }
191
+
192
+ @Override
193
+ public void put(URI uri, Map<String, List<String>> responseHeaders) {
194
+ // make sure our args are valid
195
+ if ((uri == null) || (responseHeaders == null)) return;
196
+
197
+ // go over the headers
198
+ for (String headerKey : responseHeaders.keySet()) {
199
+ // ignore headers which aren't cookie related
200
+ if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
201
+
202
+ // process each of the headers
203
+ for (String headerValue : Objects.requireNonNull(responseHeaders.get(headerKey))) {
204
+ try {
205
+ // Set at the requested server url
206
+ setCookie(uri.toString(), headerValue);
207
+
208
+ // Set at the defined domain in the response or at default capacitor hosted url
209
+ setCookie(getDomainFromCookieString(headerValue), headerValue);
210
+ } catch (Exception ignored) {}
211
+ }
212
+ }
213
+ }
214
+
215
+ @Override
216
+ public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) {
217
+ // make sure our args are valid
218
+ if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
219
+
220
+ // save our url once
221
+ String url = uri.toString();
222
+
223
+ // prepare our response
224
+ Map<String, List<String>> res = new HashMap<>();
225
+
226
+ // get the cookie
227
+ String cookie = getCookieString(url);
228
+
229
+ // return it
230
+ if (cookie != null) res.put("Cookie", Collections.singletonList(cookie));
231
+ return res;
232
+ }
233
+
234
+ @Override
235
+ public CookieStore getCookieStore() {
236
+ // we don't want anyone to work with this cookie store directly
237
+ throw new UnsupportedOperationException();
238
+ }
239
+ }