From 4d58f6545421005d74a073cc8ebec0aa7eb5d11e Mon Sep 17 00:00:00 2001 From: Gabskit Date: Thu, 14 May 2026 20:27:55 -0600 Subject: [PATCH 1/4] hi --- node_modules/.bin/esbuild | 1 + node_modules/.bin/nanoid | 1 + node_modules/.bin/rollup | 1 + node_modules/@capacitor/android/LICENSE | 21 + .../@capacitor/android/capacitor/build.gradle | 94 + .../android/capacitor/lint-baseline.xml | 136 ++ .../@capacitor/android/capacitor/lint.xml | 9 + .../android/capacitor/proguard-rules.pro | 28 + .../capacitor/src/main/AndroidManifest.xml | 3 + .../src/main/assets/native-bridge.js | 1039 +++++++++++ .../getcapacitor/AndroidProtocolHandler.java | 94 + .../src/main/java/com/getcapacitor/App.java | 61 + .../main/java/com/getcapacitor/AppUUID.java | 65 + .../main/java/com/getcapacitor/Bridge.java | 1627 +++++++++++++++++ .../java/com/getcapacitor/BridgeActivity.java | 218 +++ .../getcapacitor/BridgeWebChromeClient.java | 467 +++++ .../com/getcapacitor/BridgeWebViewClient.java | 117 ++ .../main/java/com/getcapacitor/CapConfig.java | 709 +++++++ .../com/getcapacitor/CapacitorWebView.java | 57 + .../main/java/com/getcapacitor/FileUtils.java | 303 +++ .../getcapacitor/InvalidPluginException.java | 8 + .../InvalidPluginMethodException.java | 16 + .../main/java/com/getcapacitor/JSArray.java | 51 + .../main/java/com/getcapacitor/JSExport.java | 208 +++ .../com/getcapacitor/JSExportException.java | 16 + .../java/com/getcapacitor/JSInjector.java | 127 ++ .../main/java/com/getcapacitor/JSObject.java | 164 ++ .../main/java/com/getcapacitor/JSValue.java | 65 + .../main/java/com/getcapacitor/Logger.java | 103 ++ .../java/com/getcapacitor/MessageHandler.java | 157 ++ .../java/com/getcapacitor/NativePlugin.java | 37 + .../com/getcapacitor/PermissionState.java | 31 + .../main/java/com/getcapacitor/Plugin.java | 1050 +++++++++++ .../java/com/getcapacitor/PluginCall.java | 394 ++++ .../java/com/getcapacitor/PluginConfig.java | 116 ++ .../java/com/getcapacitor/PluginHandle.java | 160 ++ .../PluginInvocationException.java | 16 + .../com/getcapacitor/PluginLoadException.java | 19 + .../java/com/getcapacitor/PluginManager.java | 56 + .../java/com/getcapacitor/PluginMethod.java | 15 + .../com/getcapacitor/PluginMethodHandle.java | 33 + .../java/com/getcapacitor/PluginResult.java | 84 + .../java/com/getcapacitor/ProcessedRoute.java | 37 + .../java/com/getcapacitor/RouteProcessor.java | 8 + .../java/com/getcapacitor/ServerPath.java | 25 + .../java/com/getcapacitor/UriMatcher.java | 184 ++ .../com/getcapacitor/WebViewListener.java | 67 + .../com/getcapacitor/WebViewLocalServer.java | 773 ++++++++ .../annotation/ActivityCallback.java | 10 + .../annotation/CapacitorPlugin.java | 35 + .../getcapacitor/annotation/Permission.java | 22 + .../annotation/PermissionCallback.java | 10 + .../CapacitorCordovaCookieManager.java | 42 + .../cordova/MockCordovaInterfaceImpl.java | 39 + .../cordova/MockCordovaWebViewImpl.java | 282 +++ .../plugin/CapacitorCookieManager.java | 239 +++ .../getcapacitor/plugin/CapacitorCookies.java | 119 ++ .../getcapacitor/plugin/CapacitorHttp.java | 119 ++ .../com/getcapacitor/plugin/SystemBars.java | 346 ++++ .../java/com/getcapacitor/plugin/WebView.java | 48 + .../getcapacitor/plugin/util/AssetUtil.java | 358 ++++ .../util/CapacitorHttpUrlConnection.java | 515 ++++++ .../plugin/util/HttpRequestHandler.java | 465 +++++ .../util/ICapacitorHttpUrlConnection.java | 15 + .../getcapacitor/plugin/util/MimeType.java | 17 + .../java/com/getcapacitor/util/HostMask.java | 123 ++ .../com/getcapacitor/util/InternalUtils.java | 27 + .../java/com/getcapacitor/util/JSONUtils.java | 166 ++ .../getcapacitor/util/PermissionHelper.java | 114 ++ .../java/com/getcapacitor/util/WebColor.java | 28 + .../layout/capacitor_bridge_layout_main.xml | 15 + .../src/main/res/layout/no_webview.xml | 14 + .../capacitor/src/main/res/values/colors.xml | 6 + .../capacitor/src/main/res/values/strings.xml | 3 + .../capacitor/src/main/res/values/styles.xml | 6 + node_modules/@capacitor/android/package.json | 31 + node_modules/@capacitor/cli/LICENSE | 21 + node_modules/@capacitor/cli/README.md | 84 + .../cli/assets/android-template.tar.gz | Bin 0 -> 217362 bytes .../capacitor-cordova-android-plugins.tar.gz | Bin 0 -> 929 bytes .../capacitor-cordova-ios-plugins.tar.gz | Bin 0 -> 405 bytes .../cli/assets/ios-pods-template.tar.gz | Bin 0 -> 155305 bytes .../cli/assets/ios-spm-template.tar.gz | Bin 0 -> 155152 bytes node_modules/@capacitor/cli/bin/capacitor | 18 + .../@capacitor/cli/dist/android/add.js | 52 + .../@capacitor/cli/dist/android/build.js | 104 ++ .../@capacitor/cli/dist/android/common.js | 94 + .../@capacitor/cli/dist/android/doctor.js | 160 ++ .../@capacitor/cli/dist/android/open.js | 28 + .../@capacitor/cli/dist/android/run.js | 42 + .../@capacitor/cli/dist/android/update.js | 317 ++++ node_modules/@capacitor/cli/dist/colors.js | 26 + node_modules/@capacitor/cli/dist/common.js | 437 +++++ node_modules/@capacitor/cli/dist/config.js | 415 +++++ node_modules/@capacitor/cli/dist/cordova.js | 801 ++++++++ .../@capacitor/cli/dist/declarations.d.ts | 734 ++++++++ .../@capacitor/cli/dist/declarations.js | 2 + .../@capacitor/cli/dist/definitions.js | 13 + node_modules/@capacitor/cli/dist/errors.js | 27 + .../@capacitor/cli/dist/framework-configs.js | 109 ++ node_modules/@capacitor/cli/dist/index.js | 265 +++ node_modules/@capacitor/cli/dist/ios/add.js | 13 + node_modules/@capacitor/cli/dist/ios/build.js | 94 + .../@capacitor/cli/dist/ios/common.js | 125 ++ .../@capacitor/cli/dist/ios/doctor.js | 45 + node_modules/@capacitor/cli/dist/ios/open.js | 16 + node_modules/@capacitor/cli/dist/ios/run.js | 50 + .../@capacitor/cli/dist/ios/update.js | 604 ++++++ node_modules/@capacitor/cli/dist/ipc.js | 61 + node_modules/@capacitor/cli/dist/log.js | 39 + node_modules/@capacitor/cli/dist/plugin.js | 182 ++ node_modules/@capacitor/cli/dist/sysconfig.js | 35 + node_modules/@capacitor/cli/dist/tasks/add.js | 115 ++ .../@capacitor/cli/dist/tasks/build.js | 63 + .../@capacitor/cli/dist/tasks/config.js | 28 + .../@capacitor/cli/dist/tasks/copy.js | 210 +++ .../@capacitor/cli/dist/tasks/create.js | 10 + .../@capacitor/cli/dist/tasks/doctor.js | 68 + .../@capacitor/cli/dist/tasks/init.js | 138 ++ .../@capacitor/cli/dist/tasks/list.js | 50 + .../@capacitor/cli/dist/tasks/migrate-spm.js | 24 + .../@capacitor/cli/dist/tasks/migrate.js | 519 ++++++ .../@capacitor/cli/dist/tasks/new-plugin.js | 10 + .../@capacitor/cli/dist/tasks/open.js | 62 + node_modules/@capacitor/cli/dist/tasks/run.js | 120 ++ .../@capacitor/cli/dist/tasks/serve.js | 11 + .../@capacitor/cli/dist/tasks/sourcemaps.js | 39 + .../@capacitor/cli/dist/tasks/sync.js | 55 + .../@capacitor/cli/dist/tasks/telemetry.js | 41 + .../@capacitor/cli/dist/tasks/update.js | 99 + node_modules/@capacitor/cli/dist/telemetry.js | 119 ++ node_modules/@capacitor/cli/dist/util/cli.js | 25 + .../@capacitor/cli/dist/util/emoji.js | 13 + node_modules/@capacitor/cli/dist/util/fn.js | 13 + node_modules/@capacitor/cli/dist/util/fs.js | 43 + .../@capacitor/cli/dist/util/iosplugin.js | 66 + node_modules/@capacitor/cli/dist/util/js.js | 21 + .../@capacitor/cli/dist/util/livereload.js | 149 ++ .../@capacitor/cli/dist/util/monorepotools.js | 109 ++ .../@capacitor/cli/dist/util/native-run.js | 63 + node_modules/@capacitor/cli/dist/util/node.js | 54 + .../@capacitor/cli/dist/util/promise.js | 35 + node_modules/@capacitor/cli/dist/util/spm.js | 256 +++ .../@capacitor/cli/dist/util/subprocess.js | 37 + .../@capacitor/cli/dist/util/template.js | 10 + node_modules/@capacitor/cli/dist/util/term.js | 30 + node_modules/@capacitor/cli/dist/util/uuid.js | 11 + node_modules/@capacitor/cli/dist/util/xml.js | 55 + node_modules/@capacitor/cli/package.json | 88 + node_modules/@capacitor/core/LICENSE | 21 + node_modules/@capacitor/core/README.md | 3 + node_modules/@capacitor/core/cookies.md | 250 +++ node_modules/@capacitor/core/cordova.js | 1559 ++++++++++++++++ .../@capacitor/core/dist/capacitor.js | 3 + .../@capacitor/core/dist/capacitor.js.map | 1 + .../@capacitor/core/dist/index.cjs.js | 658 +++++++ .../@capacitor/core/dist/index.cjs.js.map | 1 + node_modules/@capacitor/core/dist/index.js | 646 +++++++ .../@capacitor/core/dist/index.js.map | 1 + node_modules/@capacitor/core/http.md | 683 +++++++ node_modules/@capacitor/core/package.json | 62 + node_modules/@capacitor/core/system-bars.md | 260 +++ .../@capacitor/core/types/core-plugins.d.ts | 372 ++++ .../core/types/definitions-internal.d.ts | 171 ++ .../@capacitor/core/types/definitions.d.ts | 76 + .../@capacitor/core/types/global.d.ts | 2 + node_modules/@capacitor/core/types/index.d.ts | 6 + .../@capacitor/core/types/runtime.d.ts | 9 + node_modules/@capacitor/core/types/util.d.ts | 28 + .../@capacitor/core/types/web-plugin.d.ts | 34 + .../filesystem/CapacitorFilesystem.podspec | 18 + node_modules/@capacitor/filesystem/LICENSE | 21 + .../@capacitor/filesystem/Package.swift | 30 + node_modules/@capacitor/filesystem/README.md | 808 ++++++++ .../filesystem/android/build.gradle | 91 + .../android/src/main/AndroidManifest.xml | 2 + .../plugins/filesystem/FilesystemErrors.kt | 103 ++ .../filesystem/FilesystemMethodOptions.kt | 151 ++ .../filesystem/FilesystemMethodResults.kt | 65 + .../plugins/filesystem/FilesystemPlugin.kt | 412 +++++ .../LegacyFilesystemImplementation.kt | 169 ++ .../filesystem/PluginResultExtensions.kt | 25 + .../@capacitor/filesystem/dist/docs.json | 1576 ++++++++++++++++ .../filesystem/dist/esm/definitions.d.ts | 698 +++++++ .../filesystem/dist/esm/definitions.js | 124 ++ .../filesystem/dist/esm/definitions.js.map | 1 + .../@capacitor/filesystem/dist/esm/index.d.ts | 4 + .../@capacitor/filesystem/dist/esm/index.js | 9 + .../filesystem/dist/esm/index.js.map | 1 + .../@capacitor/filesystem/dist/esm/web.d.ts | 99 + .../@capacitor/filesystem/dist/esm/web.js | 596 ++++++ .../@capacitor/filesystem/dist/esm/web.js.map | 1 + .../@capacitor/filesystem/dist/plugin.cjs.js | 737 ++++++++ .../filesystem/dist/plugin.cjs.js.map | 1 + .../@capacitor/filesystem/dist/plugin.js | 739 ++++++++ .../@capacitor/filesystem/dist/plugin.js.map | 1 + .../CAPPluginCall+Accelerators.swift | 73 + .../FilesystemConstants.swift | 63 + .../FilesystemPlugin/FilesystemError.swift | 57 + .../FilesystemLocationResolver.swift | 39 + 200 files changed, 31717 insertions(+) create mode 120000 node_modules/.bin/esbuild create mode 120000 node_modules/.bin/nanoid create mode 120000 node_modules/.bin/rollup create mode 100644 node_modules/@capacitor/android/LICENSE create mode 100644 node_modules/@capacitor/android/capacitor/build.gradle create mode 100644 node_modules/@capacitor/android/capacitor/lint-baseline.xml create mode 100644 node_modules/@capacitor/android/capacitor/lint.xml create mode 100644 node_modules/@capacitor/android/capacitor/proguard-rules.pro create mode 100644 node_modules/@capacitor/android/capacitor/src/main/AndroidManifest.xml create mode 100644 node_modules/@capacitor/android/capacitor/src/main/assets/native-bridge.js create mode 100755 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AndroidProtocolHandler.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/App.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AppUUID.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Bridge.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapConfig.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginException.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginMethodException.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSArray.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExport.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExportException.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSInjector.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSObject.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSValue.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Logger.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/MessageHandler.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PermissionState.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Plugin.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginCall.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginInvocationException.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginLoadException.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginManager.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethod.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethodHandle.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginResult.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ServerPath.java create mode 100755 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/UriMatcher.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java create mode 100755 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/ActivityCallback.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/CapacitorPlugin.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/Permission.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/PermissionCallback.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaInterfaceImpl.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/WebView.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/ICapacitorHttpUrlConnection.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/MimeType.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/HostMask.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/InternalUtils.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/PermissionHelper.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/WebColor.java create mode 100644 node_modules/@capacitor/android/capacitor/src/main/res/layout/capacitor_bridge_layout_main.xml create mode 100644 node_modules/@capacitor/android/capacitor/src/main/res/layout/no_webview.xml create mode 100644 node_modules/@capacitor/android/capacitor/src/main/res/values/colors.xml create mode 100644 node_modules/@capacitor/android/capacitor/src/main/res/values/strings.xml create mode 100644 node_modules/@capacitor/android/capacitor/src/main/res/values/styles.xml create mode 100644 node_modules/@capacitor/android/package.json create mode 100644 node_modules/@capacitor/cli/LICENSE create mode 100644 node_modules/@capacitor/cli/README.md create mode 100644 node_modules/@capacitor/cli/assets/android-template.tar.gz create mode 100644 node_modules/@capacitor/cli/assets/capacitor-cordova-android-plugins.tar.gz create mode 100644 node_modules/@capacitor/cli/assets/capacitor-cordova-ios-plugins.tar.gz create mode 100644 node_modules/@capacitor/cli/assets/ios-pods-template.tar.gz create mode 100644 node_modules/@capacitor/cli/assets/ios-spm-template.tar.gz create mode 100755 node_modules/@capacitor/cli/bin/capacitor create mode 100644 node_modules/@capacitor/cli/dist/android/add.js create mode 100644 node_modules/@capacitor/cli/dist/android/build.js create mode 100644 node_modules/@capacitor/cli/dist/android/common.js create mode 100644 node_modules/@capacitor/cli/dist/android/doctor.js create mode 100644 node_modules/@capacitor/cli/dist/android/open.js create mode 100644 node_modules/@capacitor/cli/dist/android/run.js create mode 100644 node_modules/@capacitor/cli/dist/android/update.js create mode 100644 node_modules/@capacitor/cli/dist/colors.js create mode 100644 node_modules/@capacitor/cli/dist/common.js create mode 100644 node_modules/@capacitor/cli/dist/config.js create mode 100644 node_modules/@capacitor/cli/dist/cordova.js create mode 100644 node_modules/@capacitor/cli/dist/declarations.d.ts create mode 100644 node_modules/@capacitor/cli/dist/declarations.js create mode 100644 node_modules/@capacitor/cli/dist/definitions.js create mode 100644 node_modules/@capacitor/cli/dist/errors.js create mode 100644 node_modules/@capacitor/cli/dist/framework-configs.js create mode 100644 node_modules/@capacitor/cli/dist/index.js create mode 100644 node_modules/@capacitor/cli/dist/ios/add.js create mode 100644 node_modules/@capacitor/cli/dist/ios/build.js create mode 100644 node_modules/@capacitor/cli/dist/ios/common.js create mode 100644 node_modules/@capacitor/cli/dist/ios/doctor.js create mode 100644 node_modules/@capacitor/cli/dist/ios/open.js create mode 100644 node_modules/@capacitor/cli/dist/ios/run.js create mode 100644 node_modules/@capacitor/cli/dist/ios/update.js create mode 100644 node_modules/@capacitor/cli/dist/ipc.js create mode 100644 node_modules/@capacitor/cli/dist/log.js create mode 100644 node_modules/@capacitor/cli/dist/plugin.js create mode 100644 node_modules/@capacitor/cli/dist/sysconfig.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/add.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/build.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/config.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/copy.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/create.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/doctor.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/init.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/list.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/migrate-spm.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/migrate.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/new-plugin.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/open.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/run.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/serve.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/sourcemaps.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/sync.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/telemetry.js create mode 100644 node_modules/@capacitor/cli/dist/tasks/update.js create mode 100644 node_modules/@capacitor/cli/dist/telemetry.js create mode 100644 node_modules/@capacitor/cli/dist/util/cli.js create mode 100644 node_modules/@capacitor/cli/dist/util/emoji.js create mode 100644 node_modules/@capacitor/cli/dist/util/fn.js create mode 100644 node_modules/@capacitor/cli/dist/util/fs.js create mode 100644 node_modules/@capacitor/cli/dist/util/iosplugin.js create mode 100644 node_modules/@capacitor/cli/dist/util/js.js create mode 100644 node_modules/@capacitor/cli/dist/util/livereload.js create mode 100644 node_modules/@capacitor/cli/dist/util/monorepotools.js create mode 100644 node_modules/@capacitor/cli/dist/util/native-run.js create mode 100644 node_modules/@capacitor/cli/dist/util/node.js create mode 100644 node_modules/@capacitor/cli/dist/util/promise.js create mode 100644 node_modules/@capacitor/cli/dist/util/spm.js create mode 100644 node_modules/@capacitor/cli/dist/util/subprocess.js create mode 100644 node_modules/@capacitor/cli/dist/util/template.js create mode 100644 node_modules/@capacitor/cli/dist/util/term.js create mode 100644 node_modules/@capacitor/cli/dist/util/uuid.js create mode 100644 node_modules/@capacitor/cli/dist/util/xml.js create mode 100644 node_modules/@capacitor/cli/package.json create mode 100644 node_modules/@capacitor/core/LICENSE create mode 100644 node_modules/@capacitor/core/README.md create mode 100644 node_modules/@capacitor/core/cookies.md create mode 100644 node_modules/@capacitor/core/cordova.js create mode 100644 node_modules/@capacitor/core/dist/capacitor.js create mode 100644 node_modules/@capacitor/core/dist/capacitor.js.map create mode 100644 node_modules/@capacitor/core/dist/index.cjs.js create mode 100644 node_modules/@capacitor/core/dist/index.cjs.js.map create mode 100644 node_modules/@capacitor/core/dist/index.js create mode 100644 node_modules/@capacitor/core/dist/index.js.map create mode 100644 node_modules/@capacitor/core/http.md create mode 100644 node_modules/@capacitor/core/package.json create mode 100644 node_modules/@capacitor/core/system-bars.md create mode 100644 node_modules/@capacitor/core/types/core-plugins.d.ts create mode 100644 node_modules/@capacitor/core/types/definitions-internal.d.ts create mode 100644 node_modules/@capacitor/core/types/definitions.d.ts create mode 100644 node_modules/@capacitor/core/types/global.d.ts create mode 100644 node_modules/@capacitor/core/types/index.d.ts create mode 100644 node_modules/@capacitor/core/types/runtime.d.ts create mode 100644 node_modules/@capacitor/core/types/util.d.ts create mode 100644 node_modules/@capacitor/core/types/web-plugin.d.ts create mode 100644 node_modules/@capacitor/filesystem/CapacitorFilesystem.podspec create mode 100644 node_modules/@capacitor/filesystem/LICENSE create mode 100644 node_modules/@capacitor/filesystem/Package.swift create mode 100644 node_modules/@capacitor/filesystem/README.md create mode 100644 node_modules/@capacitor/filesystem/android/build.gradle create mode 100644 node_modules/@capacitor/filesystem/android/src/main/AndroidManifest.xml create mode 100644 node_modules/@capacitor/filesystem/android/src/main/kotlin/com/capacitorjs/plugins/filesystem/FilesystemErrors.kt create mode 100644 node_modules/@capacitor/filesystem/android/src/main/kotlin/com/capacitorjs/plugins/filesystem/FilesystemMethodOptions.kt create mode 100644 node_modules/@capacitor/filesystem/android/src/main/kotlin/com/capacitorjs/plugins/filesystem/FilesystemMethodResults.kt create mode 100644 node_modules/@capacitor/filesystem/android/src/main/kotlin/com/capacitorjs/plugins/filesystem/FilesystemPlugin.kt create mode 100644 node_modules/@capacitor/filesystem/android/src/main/kotlin/com/capacitorjs/plugins/filesystem/LegacyFilesystemImplementation.kt create mode 100644 node_modules/@capacitor/filesystem/android/src/main/kotlin/com/capacitorjs/plugins/filesystem/PluginResultExtensions.kt create mode 100644 node_modules/@capacitor/filesystem/dist/docs.json create mode 100644 node_modules/@capacitor/filesystem/dist/esm/definitions.d.ts create mode 100644 node_modules/@capacitor/filesystem/dist/esm/definitions.js create mode 100644 node_modules/@capacitor/filesystem/dist/esm/definitions.js.map create mode 100644 node_modules/@capacitor/filesystem/dist/esm/index.d.ts create mode 100644 node_modules/@capacitor/filesystem/dist/esm/index.js create mode 100644 node_modules/@capacitor/filesystem/dist/esm/index.js.map create mode 100644 node_modules/@capacitor/filesystem/dist/esm/web.d.ts create mode 100644 node_modules/@capacitor/filesystem/dist/esm/web.js create mode 100644 node_modules/@capacitor/filesystem/dist/esm/web.js.map create mode 100644 node_modules/@capacitor/filesystem/dist/plugin.cjs.js create mode 100644 node_modules/@capacitor/filesystem/dist/plugin.cjs.js.map create mode 100644 node_modules/@capacitor/filesystem/dist/plugin.js create mode 100644 node_modules/@capacitor/filesystem/dist/plugin.js.map create mode 100644 node_modules/@capacitor/filesystem/ios/Sources/FilesystemPlugin/CAPPluginCall+Accelerators.swift create mode 100644 node_modules/@capacitor/filesystem/ios/Sources/FilesystemPlugin/FilesystemConstants.swift create mode 100644 node_modules/@capacitor/filesystem/ios/Sources/FilesystemPlugin/FilesystemError.swift create mode 100644 node_modules/@capacitor/filesystem/ios/Sources/FilesystemPlugin/FilesystemLocationResolver.swift diff --git a/node_modules/.bin/esbuild b/node_modules/.bin/esbuild new file mode 120000 index 0000000..c83ac07 --- /dev/null +++ b/node_modules/.bin/esbuild @@ -0,0 +1 @@ +../esbuild/bin/esbuild \ No newline at end of file diff --git a/node_modules/.bin/nanoid b/node_modules/.bin/nanoid new file mode 120000 index 0000000..e2be547 --- /dev/null +++ b/node_modules/.bin/nanoid @@ -0,0 +1 @@ +../nanoid/bin/nanoid.cjs \ No newline at end of file diff --git a/node_modules/.bin/rollup b/node_modules/.bin/rollup new file mode 120000 index 0000000..5939621 --- /dev/null +++ b/node_modules/.bin/rollup @@ -0,0 +1 @@ +../rollup/dist/bin/rollup \ No newline at end of file diff --git a/node_modules/@capacitor/android/LICENSE b/node_modules/@capacitor/android/LICENSE new file mode 100644 index 0000000..c3e903b --- /dev/null +++ b/node_modules/@capacitor/android/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-present Drifty Co. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@capacitor/android/capacitor/build.gradle b/node_modules/@capacitor/android/capacitor/build.gradle new file mode 100644 index 0000000..6ece3ed --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/build.gradle @@ -0,0 +1,94 @@ +ext { + androidxActivityVersion = project.hasProperty('androidxActivityVersion') ? rootProject.ext.androidxActivityVersion : '1.11.0' + androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1' + androidxCoordinatorLayoutVersion = project.hasProperty('androidxCoordinatorLayoutVersion') ? rootProject.ext.androidxCoordinatorLayoutVersion : '1.3.0' + androidxCoreVersion = project.hasProperty('androidxCoreVersion') ? rootProject.ext.androidxCoreVersion : '1.17.0' + androidxFragmentVersion = project.hasProperty('androidxFragmentVersion') ? rootProject.ext.androidxFragmentVersion : '1.8.9' + androidxWebkitVersion = project.hasProperty('androidxWebkitVersion') ? rootProject.ext.androidxWebkitVersion : '1.14.0' + junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2' + androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0' + androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0' + cordovaAndroidVersion = project.hasProperty('cordovaAndroidVersion') ? rootProject.ext.cordovaAndroidVersion : '14.0.1' +} + + +buildscript { + repositories { + google() + mavenCentral() + maven { + url = "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath 'com.android.tools.build:gradle:8.13.0' + + if (System.getenv("CAP_PUBLISH") == "true") { + classpath 'io.github.gradle-nexus:publish-plugin:1.3.0' + } + } +} + +tasks.withType(Javadoc).all { enabled = false } + +apply plugin: 'com.android.library' + +if (System.getenv("CAP_PUBLISH") == "true") { + apply plugin: 'io.github.gradle-nexus.publish-plugin' + apply from: file('../scripts/publish-root.gradle') + apply from: file('../scripts/publish-module.gradle') +} + +android { + namespace = "com.getcapacitor.android" + compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36 + defaultConfig { + minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24 + targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36 + versionCode 1 + versionName "1.0" + consumerProguardFiles 'proguard-rules.pro' + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + lintOptions { + baseline file("lint-baseline.xml") + abortOnError = true + warningsAsErrors = true + lintConfig = file('lint.xml') + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_21 + targetCompatibility JavaVersion.VERSION_21 + } + publishing { + singleVariant("release") + } +} + +repositories { + google() + mavenCentral() +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" + implementation "androidx.core:core:$androidxCoreVersion" + implementation "androidx.activity:activity:$androidxActivityVersion" + implementation "androidx.fragment:fragment:$androidxFragmentVersion" + implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" + implementation "androidx.webkit:webkit:$androidxWebkitVersion" + testImplementation "junit:junit:$junitVersion" + androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" + androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" + implementation "org.apache.cordova:framework:$cordovaAndroidVersion" + testImplementation 'org.json:json:20250517' + testImplementation 'org.mockito:mockito-core:5.20.0' +} + diff --git a/node_modules/@capacitor/android/capacitor/lint-baseline.xml b/node_modules/@capacitor/android/capacitor/lint-baseline.xml new file mode 100644 index 0000000..c1ed9cc --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/lint-baseline.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@capacitor/android/capacitor/lint.xml b/node_modules/@capacitor/android/capacitor/lint.xml new file mode 100644 index 0000000..b00604b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/lint.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/node_modules/@capacitor/android/capacitor/proguard-rules.pro b/node_modules/@capacitor/android/capacitor/proguard-rules.pro new file mode 100644 index 0000000..96db065 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/proguard-rules.pro @@ -0,0 +1,28 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Rules for Capacitor v3 plugins and annotations + -keep @com.getcapacitor.annotation.CapacitorPlugin public class * { + @com.getcapacitor.annotation.PermissionCallback ; + @com.getcapacitor.annotation.ActivityCallback ; + @com.getcapacitor.annotation.Permission ; + @com.getcapacitor.PluginMethod public ; + } + + -keep public class * extends com.getcapacitor.Plugin { *; } + +# Rules for Capacitor v2 plugins and annotations +# These are deprecated but can still be used with Capacitor for now +-keep @com.getcapacitor.NativePlugin public class * { + @com.getcapacitor.PluginMethod public ; +} + +# Rules for Cordova plugins +-keep public class * extends org.apache.cordova.* { + public ; + public ; +} \ No newline at end of file diff --git a/node_modules/@capacitor/android/capacitor/src/main/AndroidManifest.xml b/node_modules/@capacitor/android/capacitor/src/main/AndroidManifest.xml new file mode 100644 index 0000000..74b7379 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/node_modules/@capacitor/android/capacitor/src/main/assets/native-bridge.js b/node_modules/@capacitor/android/capacitor/src/main/assets/native-bridge.js new file mode 100644 index 0000000..f5e7cc4 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/assets/native-bridge.js @@ -0,0 +1,1039 @@ + +/*! Capacitor: https://capacitorjs.com/ - MIT License */ +/* Generated File. Do not edit. */ + +var nativeBridge = (function (exports) { + 'use strict'; + + var ExceptionCode; + (function (ExceptionCode) { + /** + * API is not implemented. + * + * This usually means the API can't be used because it is not implemented for + * the current platform. + */ + ExceptionCode["Unimplemented"] = "UNIMPLEMENTED"; + /** + * API is not available. + * + * This means the API can't be used right now because: + * - it is currently missing a prerequisite, such as network connectivity + * - it requires a particular platform or browser version + */ + ExceptionCode["Unavailable"] = "UNAVAILABLE"; + })(ExceptionCode || (ExceptionCode = {})); + class CapacitorException extends Error { + constructor(message, code, data) { + super(message); + this.message = message; + this.code = code; + this.data = data; + } + } + + // For removing exports for iOS/Android, keep let for reassignment + // eslint-disable-next-line + let dummy = {}; + const readFileAsBase64 = (file) => new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + const data = reader.result; + resolve(btoa(data)); + }; + reader.onerror = reject; + reader.readAsBinaryString(file); + }); + const convertFormData = async (formData) => { + const newFormData = []; + for (const pair of formData.entries()) { + const [key, value] = pair; + if (value instanceof File) { + const base64File = await readFileAsBase64(value); + newFormData.push({ + key, + value: base64File, + type: 'base64File', + contentType: value.type, + fileName: value.name, + }); + } + else { + newFormData.push({ key, value, type: 'string' }); + } + } + return newFormData; + }; + const convertBody = async (body, contentType) => { + if (body instanceof ReadableStream || body instanceof Uint8Array) { + let encodedData; + if (body instanceof ReadableStream) { + const reader = body.getReader(); + const chunks = []; + while (true) { + const { done, value } = await reader.read(); + if (done) + break; + chunks.push(value); + } + const concatenated = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0)); + let position = 0; + for (const chunk of chunks) { + concatenated.set(chunk, position); + position += chunk.length; + } + encodedData = concatenated; + } + else { + encodedData = body; + } + let data = new TextDecoder().decode(encodedData); + let type; + if (contentType === 'application/json') { + try { + data = JSON.parse(data); + } + catch (ignored) { + // ignore + } + type = 'json'; + } + else if (contentType === 'multipart/form-data') { + type = 'formData'; + } + else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) { + type = 'image'; + } + else if (contentType === 'application/octet-stream') { + type = 'binary'; + } + else { + type = 'text'; + } + return { + data, + type, + headers: { 'Content-Type': contentType || 'application/octet-stream' }, + }; + } + else if (body instanceof URLSearchParams) { + return { + data: body.toString(), + type: 'text', + }; + } + else if (body instanceof FormData) { + return { + data: await convertFormData(body), + type: 'formData', + }; + } + else if (body instanceof File) { + const fileData = await readFileAsBase64(body); + return { + data: fileData, + type: 'file', + headers: { 'Content-Type': body.type }, + }; + } + return { data: body, type: 'json' }; + }; + const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_'; + const CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM = 'u'; + // TODO: export as Cap function + const isRelativeOrProxyUrl = (url) => !url || !(url.startsWith('http:') || url.startsWith('https:')) || url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1; + // TODO: export as Cap function + const createProxyUrl = (url, win) => { + var _a, _b; + if (isRelativeOrProxyUrl(url)) + return url; + const bridgeUrl = new URL((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getServerUrl()) !== null && _b !== void 0 ? _b : ''); + bridgeUrl.pathname = CAPACITOR_HTTP_INTERCEPTOR; + bridgeUrl.searchParams.append(CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM, url); + return bridgeUrl.toString(); + }; + const initBridge = (w) => { + const getPlatformId = (win) => { + var _a, _b; + if (win === null || win === void 0 ? void 0 : win.androidBridge) { + return 'android'; + } + else if ((_b = (_a = win === null || win === void 0 ? void 0 : win.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.bridge) { + return 'ios'; + } + else { + return 'web'; + } + }; + const convertFileSrcServerUrl = (webviewServerUrl, filePath) => { + if (typeof filePath === 'string') { + if (filePath.startsWith('/')) { + return webviewServerUrl + '/_capacitor_file_' + filePath; + } + else if (filePath.startsWith('file://')) { + return webviewServerUrl + filePath.replace('file://', '/_capacitor_file_'); + } + else if (filePath.startsWith('content://')) { + return webviewServerUrl + filePath.replace('content:/', '/_capacitor_content_'); + } + } + return filePath; + }; + const initEvents = (win, cap) => { + cap.addListener = (pluginName, eventName, callback) => { + const callbackId = cap.nativeCallback(pluginName, 'addListener', { + eventName: eventName, + }, callback); + return { + remove: async () => { + var _a; + (_a = win === null || win === void 0 ? void 0 : win.console) === null || _a === void 0 ? void 0 : _a.debug('Removing listener', pluginName, eventName); + cap.removeListener(pluginName, callbackId, eventName, callback); + }, + }; + }; + cap.removeListener = (pluginName, callbackId, eventName, callback) => { + cap.nativeCallback(pluginName, 'removeListener', { + callbackId: callbackId, + eventName: eventName, + }, callback); + }; + cap.createEvent = (eventName, eventData) => { + const doc = win.document; + if (doc) { + const ev = doc.createEvent('Events'); + ev.initEvent(eventName, false, false); + if (eventData && typeof eventData === 'object') { + for (const i in eventData) { + // eslint-disable-next-line no-prototype-builtins + if (eventData.hasOwnProperty(i)) { + ev[i] = eventData[i]; + } + } + } + return ev; + } + return null; + }; + cap.triggerEvent = (eventName, target, eventData) => { + const doc = win.document; + const cordova = win.cordova; + eventData = eventData || {}; + const ev = cap.createEvent(eventName, eventData); + if (ev) { + if (target === 'document') { + if (cordova === null || cordova === void 0 ? void 0 : cordova.fireDocumentEvent) { + cordova.fireDocumentEvent(eventName, eventData); + return true; + } + else if (doc === null || doc === void 0 ? void 0 : doc.dispatchEvent) { + return doc.dispatchEvent(ev); + } + } + else if (target === 'window' && win.dispatchEvent) { + return win.dispatchEvent(ev); + } + else if (doc === null || doc === void 0 ? void 0 : doc.querySelector) { + const targetEl = doc.querySelector(target); + if (targetEl) { + return targetEl.dispatchEvent(ev); + } + } + } + return false; + }; + win.Capacitor = cap; + }; + const initLegacyHandlers = (win, cap) => { + // define cordova if it's not there already + win.cordova = win.cordova || {}; + const doc = win.document; + const nav = win.navigator; + if (nav) { + nav.app = nav.app || {}; + nav.app.exitApp = () => { + var _a; + if (!((_a = cap.Plugins) === null || _a === void 0 ? void 0 : _a.App)) { + win.console.warn('App plugin not installed'); + } + else { + cap.nativeCallback('App', 'exitApp', {}); + } + }; + } + if (doc) { + const docAddEventListener = doc.addEventListener; + doc.addEventListener = (...args) => { + var _a; + const eventName = args[0]; + const handler = args[1]; + if (eventName === 'deviceready' && handler) { + Promise.resolve().then(handler); + } + else if (eventName === 'backbutton' && cap.Plugins.App) { + // Add a dummy listener so Capacitor doesn't do the default + // back button action + if (!((_a = cap.Plugins) === null || _a === void 0 ? void 0 : _a.App)) { + win.console.warn('App plugin not installed'); + } + else { + cap.Plugins.App.addListener('backButton', () => { + // ignore + }); + } + } + return docAddEventListener.apply(doc, args); + }; + } + win.Capacitor = cap; + }; + const initVendor = (win, cap) => { + const Ionic = (win.Ionic = win.Ionic || {}); + const IonicWebView = (Ionic.WebView = Ionic.WebView || {}); + const Plugins = cap.Plugins; + IonicWebView.getServerBasePath = (callback) => { + var _a; + (_a = Plugins === null || Plugins === void 0 ? void 0 : Plugins.WebView) === null || _a === void 0 ? void 0 : _a.getServerBasePath().then((result) => { + callback(result.path); + }); + }; + IonicWebView.setServerAssetPath = (path) => { + var _a; + (_a = Plugins === null || Plugins === void 0 ? void 0 : Plugins.WebView) === null || _a === void 0 ? void 0 : _a.setServerAssetPath({ path }); + }; + IonicWebView.setServerBasePath = (path) => { + var _a; + (_a = Plugins === null || Plugins === void 0 ? void 0 : Plugins.WebView) === null || _a === void 0 ? void 0 : _a.setServerBasePath({ path }); + }; + IonicWebView.persistServerBasePath = () => { + var _a; + (_a = Plugins === null || Plugins === void 0 ? void 0 : Plugins.WebView) === null || _a === void 0 ? void 0 : _a.persistServerBasePath(); + }; + IonicWebView.convertFileSrc = (url) => cap.convertFileSrc(url); + win.Capacitor = cap; + win.Ionic.WebView = IonicWebView; + }; + const initLogger = (win, cap) => { + const BRIDGED_CONSOLE_METHODS = ['debug', 'error', 'info', 'log', 'trace', 'warn']; + const createLogFromNative = (c) => (result) => { + if (isFullConsole(c)) { + const success = result.success === true; + const tagStyles = success + ? 'font-style: italic; font-weight: lighter; color: gray' + : 'font-style: italic; font-weight: lighter; color: red'; + c.groupCollapsed('%cresult %c' + result.pluginId + '.' + result.methodName + ' (#' + result.callbackId + ')', tagStyles, 'font-style: italic; font-weight: bold; color: #444'); + if (result.success === false) { + c.error(result.error); + } + else { + c.dir(JSON.stringify(result.data)); + } + c.groupEnd(); + } + else { + if (result.success === false) { + c.error('LOG FROM NATIVE', result.error); + } + else { + c.log('LOG FROM NATIVE', result.data); + } + } + }; + const createLogToNative = (c) => (call) => { + if (isFullConsole(c)) { + c.groupCollapsed('%cnative %c' + call.pluginId + '.' + call.methodName + ' (#' + call.callbackId + ')', 'font-weight: lighter; color: gray', 'font-weight: bold; color: #000'); + c.dir(call); + c.groupEnd(); + } + else { + c.log('LOG TO NATIVE: ', call); + } + }; + const isFullConsole = (c) => { + if (!c) { + return false; + } + return typeof c.groupCollapsed === 'function' || typeof c.groupEnd === 'function' || typeof c.dir === 'function'; + }; + const serializeConsoleMessage = (msg) => { + try { + if (typeof msg === 'object') { + msg = JSON.stringify(msg); + } + return String(msg); + } + catch (e) { + return ''; + } + }; + const platform = getPlatformId(win); + if (platform == 'android' && typeof win.CapacitorSystemBarsAndroidInterface !== 'undefined') { + // add DOM ready listener for System Bars + document.addEventListener('DOMContentLoaded', function () { + win.CapacitorSystemBarsAndroidInterface.onDOMReady(); + }); + } + if (platform == 'android' || platform == 'ios') { + // patch document.cookie on Android/iOS + win.CapacitorCookiesDescriptor = + Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') || + Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie'); + let doPatchCookies = false; + // check if capacitor cookies is disabled before patching + if (platform === 'ios') { + // Use prompt to synchronously get capacitor cookies config. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + const payload = { + type: 'CapacitorCookies.isEnabled', + }; + const isCookiesEnabled = prompt(JSON.stringify(payload)); + if (isCookiesEnabled === 'true') { + doPatchCookies = true; + } + } + else if (typeof win.CapacitorCookiesAndroidInterface !== 'undefined') { + const isCookiesEnabled = win.CapacitorCookiesAndroidInterface.isEnabled(); + if (isCookiesEnabled === true) { + doPatchCookies = true; + } + } + if (doPatchCookies) { + Object.defineProperty(document, 'cookie', { + get: function () { + var _a, _b, _c; + if (platform === 'ios') { + // Use prompt to synchronously get cookies. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + const payload = { + type: 'CapacitorCookies.get', + }; + const res = prompt(JSON.stringify(payload)); + return res; + } + else if (typeof win.CapacitorCookiesAndroidInterface !== 'undefined') { + // return original document.cookie since Android does not support filtering of `httpOnly` cookies + return (_c = (_b = (_a = win.CapacitorCookiesDescriptor) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(document)) !== null && _c !== void 0 ? _c : ''; + } + }, + set: function (val) { + const cookiePairs = val.split(';'); + const domainSection = val.toLowerCase().split('domain=')[1]; + const domain = cookiePairs.length > 1 && domainSection != null && domainSection.length > 0 + ? domainSection.split(';')[0].trim() + : ''; + if (platform === 'ios') { + // Use prompt to synchronously set cookies. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + const payload = { + type: 'CapacitorCookies.set', + action: val, + domain, + }; + prompt(JSON.stringify(payload)); + } + else if (typeof win.CapacitorCookiesAndroidInterface !== 'undefined') { + win.CapacitorCookiesAndroidInterface.setCookie(domain, val); + } + }, + }); + } + // patch fetch / XHR on Android/iOS + // store original fetch & XHR functions + win.CapacitorWebFetch = window.fetch; + win.CapacitorWebXMLHttpRequest = { + abort: window.XMLHttpRequest.prototype.abort, + constructor: window.XMLHttpRequest.prototype.constructor, + fullObject: window.XMLHttpRequest, + getAllResponseHeaders: window.XMLHttpRequest.prototype.getAllResponseHeaders, + getResponseHeader: window.XMLHttpRequest.prototype.getResponseHeader, + open: window.XMLHttpRequest.prototype.open, + prototype: window.XMLHttpRequest.prototype, + send: window.XMLHttpRequest.prototype.send, + setRequestHeader: window.XMLHttpRequest.prototype.setRequestHeader, + }; + let doPatchHttp = false; + // check if capacitor http is disabled before patching + if (platform === 'ios') { + // Use prompt to synchronously get capacitor http config. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + const payload = { + type: 'CapacitorHttp', + }; + const isHttpEnabled = prompt(JSON.stringify(payload)); + if (isHttpEnabled === 'true') { + doPatchHttp = true; + } + } + else if (typeof win.CapacitorHttpAndroidInterface !== 'undefined') { + const isHttpEnabled = win.CapacitorHttpAndroidInterface.isEnabled(); + if (isHttpEnabled === true) { + doPatchHttp = true; + } + } + if (doPatchHttp) { + // fetch patch + window.fetch = async (resource, options) => { + const headers = new Headers(options === null || options === void 0 ? void 0 : options.headers); + const contentType = headers.get('Content-Type') || headers.get('content-type'); + if ((options === null || options === void 0 ? void 0 : options.body) instanceof FormData && + (contentType === null || contentType === void 0 ? void 0 : contentType.includes('multipart/form-data')) && + !contentType.includes('boundary')) { + headers.delete('Content-Type'); + headers.delete('content-type'); + options.headers = headers; + } + const request = new Request(resource, options); + if (request.url.startsWith(`${cap.getServerUrl()}/`)) { + return win.CapacitorWebFetch(resource, options); + } + const { method } = request; + if (method.toLocaleUpperCase() === 'GET' || + method.toLocaleUpperCase() === 'HEAD' || + method.toLocaleUpperCase() === 'OPTIONS' || + method.toLocaleUpperCase() === 'TRACE') { + // a workaround for following android webview issue: + // https://issues.chromium.org/issues/40450316 + // Sets the user-agent header to a custom value so that its not stripped + // on its way to the native layer + if (platform === 'android' && (options === null || options === void 0 ? void 0 : options.headers)) { + const userAgent = headers.get('User-Agent') || headers.get('user-agent'); + if (userAgent !== null) { + headers.set('x-cap-user-agent', userAgent); + options.headers = headers; + } + } + if (typeof resource === 'string') { + return await win.CapacitorWebFetch(createProxyUrl(resource, win), options); + } + else if (resource instanceof URL) { + const modifiedURL = new URL(createProxyUrl(resource.toString(), win)); + return await win.CapacitorWebFetch(modifiedURL, options); + } + else if (resource instanceof Request) { + const modifiedRequest = new Request(createProxyUrl(resource.url, win), resource); + return await win.CapacitorWebFetch(modifiedRequest, options); + } + } + const tag = `CapacitorHttp fetch ${Date.now()} ${resource}`; + console.time(tag); + try { + const { body } = request; + const optionHeaders = Object.fromEntries(request.headers.entries()); + const { data: requestData, type, headers: requestHeaders, } = await convertBody((options === null || options === void 0 ? void 0 : options.body) || body || undefined, optionHeaders['Content-Type'] || optionHeaders['content-type']); + const nativeHeaders = Object.assign(Object.assign({}, requestHeaders), optionHeaders); + if (platform === 'android') { + if (headers.has('User-Agent')) { + nativeHeaders['User-Agent'] = headers.get('User-Agent'); + } + if (headers.has('user-agent')) { + nativeHeaders['user-agent'] = headers.get('user-agent'); + } + } + const nativeResponse = await cap.nativePromise('CapacitorHttp', 'request', { + url: request.url, + method: method, + data: requestData, + dataType: type, + headers: nativeHeaders, + }); + const contentType = nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type']; + let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/json')) + ? JSON.stringify(nativeResponse.data) + : nativeResponse.data; + // use null data for 204 No Content HTTP response + if (nativeResponse.status === 204) { + data = null; + } + // intercept & parse response before returning + const response = new Response(data, { + headers: nativeResponse.headers, + status: nativeResponse.status, + }); + /* + * copy url to response, `cordova-plugin-ionic` uses this url from the response + * we need `Object.defineProperty` because url is an inherited getter on the Response + * see: https://stackoverflow.com/a/57382543 + * */ + Object.defineProperty(response, 'url', { + value: nativeResponse.url, + }); + console.timeEnd(tag); + return response; + } + catch (error) { + console.timeEnd(tag); + return Promise.reject(error); + } + }; + window.XMLHttpRequest = function () { + const xhr = new win.CapacitorWebXMLHttpRequest.constructor(); + Object.defineProperties(xhr, { + _headers: { + value: {}, + writable: true, + }, + _method: { + value: xhr.method, + writable: true, + }, + }); + const prototype = win.CapacitorWebXMLHttpRequest.prototype; + const isProgressEventAvailable = () => typeof ProgressEvent !== 'undefined' && ProgressEvent.prototype instanceof Event; + // XHR patch abort + prototype.abort = function () { + if (isRelativeOrProxyUrl(this._url)) { + return win.CapacitorWebXMLHttpRequest.abort.call(this); + } + this.readyState = 0; + setTimeout(() => { + this.dispatchEvent(new Event('abort')); + this.dispatchEvent(new Event('loadend')); + }); + }; + // XHR patch open + prototype.open = function (method, url) { + this._method = method.toLocaleUpperCase(); + this._url = url; + if (!this._method || + this._method === 'GET' || + this._method === 'HEAD' || + this._method === 'OPTIONS' || + this._method === 'TRACE') { + if (isRelativeOrProxyUrl(url)) { + return win.CapacitorWebXMLHttpRequest.open.call(this, method, url); + } + this._url = createProxyUrl(this._url, win); + return win.CapacitorWebXMLHttpRequest.open.call(this, method, this._url); + } + Object.defineProperties(this, { + readyState: { + get: function () { + var _a; + return (_a = this._readyState) !== null && _a !== void 0 ? _a : 0; + }, + set: function (val) { + this._readyState = val; + setTimeout(() => { + this.dispatchEvent(new Event('readystatechange')); + }); + }, + }, + }); + setTimeout(() => { + this.dispatchEvent(new Event('loadstart')); + }); + this.readyState = 1; + }; + // XHR patch set request header + prototype.setRequestHeader = function (header, value) { + // a workaround for the following android web view issue: + // https://issues.chromium.org/issues/40450316 + // Sets the user-agent header to a custom value so that its not stripped + // on its way to the native layer + if (platform === 'android' && (header === 'User-Agent' || header === 'user-agent')) { + header = 'x-cap-user-agent'; + } + if (isRelativeOrProxyUrl(this._url)) { + return win.CapacitorWebXMLHttpRequest.setRequestHeader.call(this, header, value); + } + this._headers[header] = value; + }; + // XHR patch send + prototype.send = function (body) { + if (isRelativeOrProxyUrl(this._url)) { + return win.CapacitorWebXMLHttpRequest.send.call(this, body); + } + const tag = `CapacitorHttp XMLHttpRequest ${Date.now()} ${this._url}`; + console.time(tag); + try { + this.readyState = 2; + Object.defineProperties(this, { + response: { + value: '', + writable: true, + }, + responseText: { + value: '', + writable: true, + }, + responseURL: { + value: '', + writable: true, + }, + status: { + value: 0, + writable: true, + }, + }); + convertBody(body).then(({ data, type, headers }) => { + let otherHeaders = this._headers != null && Object.keys(this._headers).length > 0 ? this._headers : undefined; + if (body instanceof FormData) { + if (!this._headers['Content-Type'] && !this._headers['content-type']) { + otherHeaders = Object.assign(Object.assign({}, otherHeaders), { 'Content-Type': `multipart/form-data; boundary=----WebKitFormBoundary${Math.random().toString(36).substring(2, 15)}` }); + } + } + // intercept request & pass to the bridge + cap + .nativePromise('CapacitorHttp', 'request', { + url: this._url, + method: this._method, + data: data !== null ? data : undefined, + headers: Object.assign(Object.assign({}, headers), otherHeaders), + dataType: type, + }) + .then((nativeResponse) => { + var _a; + // intercept & parse response before returning + if (this.readyState == 2) { + //TODO: Add progress event emission on native side + if (isProgressEventAvailable()) { + this.dispatchEvent(new ProgressEvent('progress', { + lengthComputable: true, + loaded: nativeResponse.data.length, + total: nativeResponse.data.length, + })); + } + this._headers = nativeResponse.headers; + this.status = nativeResponse.status; + if (this.responseType === '' || this.responseType === 'text') { + this.response = + typeof nativeResponse.data !== 'string' + ? JSON.stringify(nativeResponse.data) + : nativeResponse.data; + } + else { + this.response = nativeResponse.data; + } + this.responseText = ((_a = (nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type'])) === null || _a === void 0 ? void 0 : _a.startsWith('application/json')) + ? JSON.stringify(nativeResponse.data) + : nativeResponse.data; + this.responseURL = nativeResponse.url; + this.readyState = 4; + setTimeout(() => { + this.dispatchEvent(new Event('load')); + this.dispatchEvent(new Event('loadend')); + }); + } + console.timeEnd(tag); + }) + .catch((error) => { + this.status = error.status; + this._headers = error.headers; + this.response = error.data; + this.responseText = JSON.stringify(error.data); + this.responseURL = error.url; + this.readyState = 4; + if (isProgressEventAvailable()) { + this.dispatchEvent(new ProgressEvent('progress', { + lengthComputable: false, + loaded: 0, + total: 0, + })); + } + setTimeout(() => { + this.dispatchEvent(new Event('error')); + this.dispatchEvent(new Event('loadend')); + }); + console.timeEnd(tag); + }); + }); + } + catch (error) { + this.status = 500; + this._headers = {}; + this.response = error; + this.responseText = error.toString(); + this.responseURL = this._url; + this.readyState = 4; + if (isProgressEventAvailable()) { + this.dispatchEvent(new ProgressEvent('progress', { + lengthComputable: false, + loaded: 0, + total: 0, + })); + } + setTimeout(() => { + this.dispatchEvent(new Event('error')); + this.dispatchEvent(new Event('loadend')); + }); + console.timeEnd(tag); + } + }; + // XHR patch getAllResponseHeaders + prototype.getAllResponseHeaders = function () { + if (isRelativeOrProxyUrl(this._url)) { + return win.CapacitorWebXMLHttpRequest.getAllResponseHeaders.call(this); + } + let returnString = ''; + for (const key in this._headers) { + if (key != 'Set-Cookie') { + returnString += key + ': ' + this._headers[key] + '\r\n'; + } + } + return returnString; + }; + // XHR patch getResponseHeader + prototype.getResponseHeader = function (name) { + if (isRelativeOrProxyUrl(this._url)) { + return win.CapacitorWebXMLHttpRequest.getResponseHeader.call(this, name); + } + return this._headers[name]; + }; + Object.setPrototypeOf(xhr, prototype); + return xhr; + }; + Object.assign(window.XMLHttpRequest, win.CapacitorWebXMLHttpRequest.fullObject); + } + } + // patch window.console on iOS and store original console fns + const isIos = getPlatformId(win) === 'ios'; + if (win.console && isIos) { + Object.defineProperties(win.console, BRIDGED_CONSOLE_METHODS.reduce((props, method) => { + const consoleMethod = win.console[method].bind(win.console); + props[method] = { + value: (...args) => { + const msgs = [...args]; + cap.toNative('Console', 'log', { + level: method, + message: msgs.map(serializeConsoleMessage).join(' '), + }); + return consoleMethod(...args); + }, + }; + return props; + }, {})); + } + cap.logJs = (msg, level) => { + switch (level) { + case 'error': + win.console.error(msg); + break; + case 'warn': + win.console.warn(msg); + break; + case 'info': + win.console.info(msg); + break; + default: + win.console.log(msg); + } + }; + cap.logToNative = createLogToNative(win.console); + cap.logFromNative = createLogFromNative(win.console); + cap.handleError = (err) => win.console.error(err); + win.Capacitor = cap; + }; + function initNativeBridge(win) { + const cap = win.Capacitor || {}; + // keep a collection of callbacks for native response data + const callbacks = new Map(); + const webviewServerUrl = typeof win.WEBVIEW_SERVER_URL === 'string' ? win.WEBVIEW_SERVER_URL : ''; + cap.getServerUrl = () => webviewServerUrl; + cap.convertFileSrc = (filePath) => convertFileSrcServerUrl(webviewServerUrl, filePath); + // Counter of callback ids, randomized to avoid + // any issues during reloads if a call comes back with + // an existing callback id from an old session + let callbackIdCount = Math.floor(Math.random() * 134217728); + let postToNative = null; + const isNativePlatform = () => true; + const getPlatform = () => getPlatformId(win); + cap.getPlatform = getPlatform; + cap.isPluginAvailable = (name) => Object.prototype.hasOwnProperty.call(cap.Plugins, name); + cap.isNativePlatform = isNativePlatform; + // create the postToNative() fn if needed + if (getPlatformId(win) === 'android') { + // android platform + postToNative = (data) => { + var _a; + try { + win.androidBridge.postMessage(JSON.stringify(data)); + } + catch (e) { + (_a = win === null || win === void 0 ? void 0 : win.console) === null || _a === void 0 ? void 0 : _a.error(e); + } + }; + } + else if (getPlatformId(win) === 'ios') { + // ios platform + postToNative = (data) => { + var _a; + try { + data.type = data.type ? data.type : 'message'; + win.webkit.messageHandlers.bridge.postMessage(data); + } + catch (e) { + (_a = win === null || win === void 0 ? void 0 : win.console) === null || _a === void 0 ? void 0 : _a.error(e); + } + }; + } + cap.handleWindowError = (msg, url, lineNo, columnNo, err) => { + const str = msg.toLowerCase(); + if (str.indexOf('script error') > -1) ; + else { + const errObj = { + type: 'js.error', + error: { + message: msg, + url: url, + line: lineNo, + col: columnNo, + errorObject: JSON.stringify(err), + }, + }; + if (err !== null) { + cap.handleError(err); + } + postToNative(errObj); + } + return false; + }; + if (cap.DEBUG) { + window.onerror = cap.handleWindowError; + } + initLogger(win, cap); + /** + * Send a plugin method call to the native layer + */ + cap.toNative = (pluginName, methodName, options, storedCallback) => { + var _a, _b; + try { + if (typeof postToNative === 'function') { + let callbackId = '-1'; + if (storedCallback && + (typeof storedCallback.callback === 'function' || typeof storedCallback.resolve === 'function')) { + // store the call for later lookup + callbackId = String(++callbackIdCount); + callbacks.set(callbackId, storedCallback); + } + const callData = { + callbackId: callbackId, + pluginId: pluginName, + methodName: methodName, + options: options || {}, + }; + if (cap.isLoggingEnabled && pluginName !== 'Console') { + cap.logToNative(callData); + } + // post the call data to native + postToNative(callData); + return callbackId; + } + else { + (_a = win === null || win === void 0 ? void 0 : win.console) === null || _a === void 0 ? void 0 : _a.warn(`implementation unavailable for: ${pluginName}`); + } + } + catch (e) { + (_b = win === null || win === void 0 ? void 0 : win.console) === null || _b === void 0 ? void 0 : _b.error(e); + } + return null; + }; + if (win === null || win === void 0 ? void 0 : win.androidBridge) { + win.androidBridge.onmessage = function (event) { + returnResult(JSON.parse(event.data)); + }; + } + /** + * Process a response from the native layer. + */ + cap.fromNative = (result) => { + returnResult(result); + }; + const returnResult = (result) => { + var _a, _b; + if (cap.isLoggingEnabled && result.pluginId !== 'Console') { + cap.logFromNative(result); + } + // get the stored call, if it exists + try { + const storedCall = callbacks.get(result.callbackId); + if (storedCall) { + // looks like we've got a stored call + if (result.error) { + // ensure stacktraces by copying error properties to an Error + result.error = Object.keys(result.error).reduce((err, key) => { + // use any type to avoid importing util and compiling most of .ts files + err[key] = result.error[key]; + return err; + }, new cap.Exception('')); + } + if (typeof storedCall.callback === 'function') { + // callback + if (result.success) { + storedCall.callback(result.data); + } + else { + storedCall.callback(null, result.error); + } + } + else if (typeof storedCall.resolve === 'function') { + // promise + if (result.success) { + storedCall.resolve(result.data); + } + else { + storedCall.reject(result.error); + } + // no need to keep this stored callback + // around for a one time resolve promise + callbacks.delete(result.callbackId); + } + } + else if (!result.success && result.error) { + // no stored callback, but if there was an error let's log it + (_a = win === null || win === void 0 ? void 0 : win.console) === null || _a === void 0 ? void 0 : _a.warn(result.error); + } + if (result.save === false) { + callbacks.delete(result.callbackId); + } + } + catch (e) { + (_b = win === null || win === void 0 ? void 0 : win.console) === null || _b === void 0 ? void 0 : _b.error(e); + } + // always delete to prevent memory leaks + // overkill but we're not sure what apps will do with this data + delete result.data; + delete result.error; + }; + cap.nativeCallback = (pluginName, methodName, options, callback) => { + if (typeof options === 'function') { + console.warn(`Using a callback as the 'options' parameter of 'nativeCallback()' is deprecated.`); + callback = options; + options = null; + } + return cap.toNative(pluginName, methodName, options, { callback }); + }; + cap.nativePromise = (pluginName, methodName, options) => { + return new Promise((resolve, reject) => { + cap.toNative(pluginName, methodName, options, { + resolve: resolve, + reject: reject, + }); + }); + }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + cap.withPlugin = (_pluginId, _fn) => dummy; + cap.Exception = CapacitorException; + initEvents(win, cap); + initLegacyHandlers(win, cap); + initVendor(win, cap); + win.Capacitor = cap; + } + initNativeBridge(w); + }; + initBridge(typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}); + + dummy = initBridge; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; + +})({}); diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AndroidProtocolHandler.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AndroidProtocolHandler.java new file mode 100755 index 0000000..df893c7 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AndroidProtocolHandler.java @@ -0,0 +1,94 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package com.getcapacitor; + +import android.content.Context; +import android.content.res.AssetManager; +import android.net.Uri; +import android.util.TypedValue; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public class AndroidProtocolHandler { + + private Context context; + + public AndroidProtocolHandler(Context context) { + this.context = context; + } + + public InputStream openAsset(String path) throws IOException { + return context.getAssets().open(path, AssetManager.ACCESS_STREAMING); + } + + public InputStream openResource(Uri uri) { + assert uri.getPath() != null; + // The path must be of the form ".../asset_type/asset_name.ext". + List pathSegments = uri.getPathSegments(); + String assetType = pathSegments.get(pathSegments.size() - 2); + String assetName = pathSegments.get(pathSegments.size() - 1); + + // Drop the file extension. + assetName = assetName.split("\\.")[0]; + try { + // Use the application context for resolving the resource package name so that we do + // not use the browser's own resources. Note that if 'context' here belongs to the + // test suite, it does not have a separate application context. In that case we use + // the original context object directly. + if (context.getApplicationContext() != null) { + context = context.getApplicationContext(); + } + int fieldId = getFieldId(context, assetType, assetName); + int valueType = getValueType(context, fieldId); + if (valueType == TypedValue.TYPE_STRING) { + return context.getResources().openRawResource(fieldId); + } else { + Logger.error("Asset not of type string: " + uri); + } + } catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException e) { + Logger.error("Unable to open resource URL: " + uri, e); + } + return null; + } + + private static int getFieldId(Context context, String assetType, String assetName) + throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { + Class d = context.getClassLoader().loadClass(context.getPackageName() + ".R$" + assetType); + java.lang.reflect.Field field = d.getField(assetName); + return field.getInt(null); + } + + public InputStream openFile(String filePath) throws IOException { + String realPath = filePath.replace(Bridge.CAPACITOR_FILE_START, ""); + File localFile = new File(realPath); + return new FileInputStream(localFile); + } + + public InputStream openContentUrl(Uri uri) throws IOException { + Integer port = uri.getPort(); + String baseUrl = uri.getScheme() + "://" + uri.getHost(); + if (port != -1) { + baseUrl += ":" + port; + } + String realPath = uri.toString().replace(baseUrl + Bridge.CAPACITOR_CONTENT_START, "content:/"); + + InputStream stream = null; + try { + stream = context.getContentResolver().openInputStream(Uri.parse(realPath)); + } catch (SecurityException e) { + Logger.error("Unable to open content URL: " + uri, e); + } + return stream; + } + + private static int getValueType(Context context, int fieldId) { + TypedValue value = new TypedValue(); + context.getResources().getValue(fieldId, value, true); + return value.type; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/App.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/App.java new file mode 100644 index 0000000..f46b633 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/App.java @@ -0,0 +1,61 @@ +package com.getcapacitor; + +import androidx.annotation.Nullable; + +public class App { + + /** + * Interface for callbacks when app status changes. + */ + public interface AppStatusChangeListener { + void onAppStatusChanged(Boolean isActive); + } + + /** + * Interface for callbacks when app is restored with pending plugin call. + */ + public interface AppRestoredListener { + void onAppRestored(PluginResult result); + } + + @Nullable + private AppStatusChangeListener statusChangeListener; + + @Nullable + private AppRestoredListener appRestoredListener; + + private boolean isActive = false; + + public boolean isActive() { + return isActive; + } + + /** + * Set the object to receive callbacks. + * @param listener + */ + public void setStatusChangeListener(@Nullable AppStatusChangeListener listener) { + this.statusChangeListener = listener; + } + + /** + * Set the object to receive callbacks. + * @param listener + */ + public void setAppRestoredListener(@Nullable AppRestoredListener listener) { + this.appRestoredListener = listener; + } + + protected void fireRestoredResult(PluginResult result) { + if (appRestoredListener != null) { + appRestoredListener.onAppRestored(result); + } + } + + public void fireStatusChange(boolean isActive) { + this.isActive = isActive; + if (statusChangeListener != null) { + statusChangeListener.onAppStatusChanged(isActive); + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AppUUID.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AppUUID.java new file mode 100644 index 0000000..3c1b1db --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/AppUUID.java @@ -0,0 +1,65 @@ +package com.getcapacitor; + +import android.content.Context; +import android.content.SharedPreferences; +import androidx.appcompat.app.AppCompatActivity; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Objects; +import java.util.UUID; + +public final class AppUUID { + + private static final String KEY = "CapacitorAppUUID"; + + public static String getAppUUID(AppCompatActivity activity) throws Exception { + assertAppUUID(activity); + return readUUID(activity); + } + + public static void regenerateAppUUID(AppCompatActivity activity) throws Exception { + try { + String uuid = generateUUID(); + writeUUID(activity, uuid); + } catch (NoSuchAlgorithmException ex) { + throw new Exception("Capacitor App UUID could not be generated."); + } + } + + private static void assertAppUUID(AppCompatActivity activity) throws Exception { + String uuid = readUUID(activity); + if (uuid.equals("")) { + regenerateAppUUID(activity); + } + } + + private static String generateUUID() throws NoSuchAlgorithmException { + MessageDigest salt = MessageDigest.getInstance("SHA-256"); + salt.update(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8)); + return bytesToHex(salt.digest()); + } + + private static String readUUID(AppCompatActivity activity) { + SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE); + return sharedPref.getString(KEY, ""); + } + + private static void writeUUID(AppCompatActivity activity, String uuid) { + SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putString(KEY, uuid); + editor.apply(); + } + + private static String bytesToHex(byte[] bytes) { + byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); + byte[] hexChars = new byte[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars, StandardCharsets.UTF_8); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Bridge.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Bridge.java new file mode 100644 index 0000000..d4995fb --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Bridge.java @@ -0,0 +1,1627 @@ +package com.getcapacitor; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.webkit.ServiceWorkerClient; +import android.webkit.ServiceWorkerController; +import android.webkit.ValueCallback; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; +import android.webkit.WebView; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContract; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.pm.PackageInfoCompat; +import androidx.fragment.app.Fragment; +import androidx.webkit.WebViewCompat; +import androidx.webkit.WebViewFeature; +import com.getcapacitor.android.R; +import com.getcapacitor.annotation.CapacitorPlugin; +import com.getcapacitor.annotation.Permission; +import com.getcapacitor.cordova.MockCordovaInterfaceImpl; +import com.getcapacitor.cordova.MockCordovaWebViewImpl; +import com.getcapacitor.util.HostMask; +import com.getcapacitor.util.InternalUtils; +import com.getcapacitor.util.PermissionHelper; +import com.getcapacitor.util.WebColor; +import java.io.File; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.cordova.ConfigXmlParser; +import org.apache.cordova.CordovaPreferences; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.PluginEntry; +import org.apache.cordova.PluginManager; +import org.json.JSONException; + +/** + * The Bridge class is the main engine of Capacitor. It manages + * loading and communicating with all Plugins, + * proxying Native events to Plugins, executing Plugin methods, + * communicating with the WebView, and a whole lot more. + * + * Generally, you'll not use Bridge directly, instead, extend from BridgeActivity + * to get a WebView instance and proxy native events automatically. + * + * If you want to use this Bridge in an existing Android app, please + * see the source for BridgeActivity for the methods you'll need to + * pass through to Bridge: + * + * BridgeActivity.java + */ +public class Bridge { + + private static final String PERMISSION_PREFS_NAME = "PluginPermStates"; + private static final String BUNDLE_LAST_PLUGIN_ID_KEY = "capacitorLastActivityPluginId"; + private static final String BUNDLE_LAST_PLUGIN_CALL_METHOD_NAME_KEY = "capacitorLastActivityPluginMethod"; + private static final String BUNDLE_PLUGIN_CALL_OPTIONS_SAVED_KEY = "capacitorLastPluginCallOptions"; + private static final String BUNDLE_PLUGIN_CALL_BUNDLE_KEY = "capacitorLastPluginCallBundle"; + private static final String LAST_BINARY_VERSION_CODE = "lastBinaryVersionCode"; + private static final String LAST_BINARY_VERSION_NAME = "lastBinaryVersionName"; + private static final String MINIMUM_ANDROID_WEBVIEW_ERROR = "System WebView is not supported"; + + // The name of the directory we use to look for index.html and the rest of our web assets + public static final String DEFAULT_WEB_ASSET_DIR = "public"; + public static final String CAPACITOR_HTTP_SCHEME = "http"; + public static final String CAPACITOR_HTTPS_SCHEME = "https"; + public static final String CAPACITOR_FILE_START = "/_capacitor_file_"; + public static final String CAPACITOR_CONTENT_START = "/_capacitor_content_"; + public static final String CAPACITOR_HTTP_INTERCEPTOR_START = "/_capacitor_http_interceptor_"; + + /** @deprecated CAPACITOR_HTTPS_INTERCEPTOR_START is no longer required. All proxied requests are handled via CAPACITOR_HTTP_INTERCEPTOR_START instead */ + @Deprecated + public static final String CAPACITOR_HTTPS_INTERCEPTOR_START = "/_capacitor_https_interceptor_"; + + public static final String CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM = "u"; + + public static final int DEFAULT_ANDROID_WEBVIEW_VERSION = 60; + public static final int MINIMUM_ANDROID_WEBVIEW_VERSION = 55; + public static final int DEFAULT_HUAWEI_WEBVIEW_VERSION = 10; + public static final int MINIMUM_HUAWEI_WEBVIEW_VERSION = 10; + + // Loaded Capacitor config + private CapConfig config; + + // A reference to the main activity for the app + private final AppCompatActivity context; + // A reference to the containing Fragment if used + private final Fragment fragment; + private WebViewLocalServer localServer; + private String localUrl; + private String appUrl; + private String appUrlConfig; + private HostMask appAllowNavigationMask; + private Set allowedOriginRules = new HashSet(); + private ArrayList authorities = new ArrayList<>(); + private ArrayList miscJSFileInjections = new ArrayList(); + private Boolean canInjectJS = true; + // A reference to the main WebView for the app + private final WebView webView; + public final MockCordovaInterfaceImpl cordovaInterface; + private CordovaWebView cordovaWebView; + private CordovaPreferences preferences; + private BridgeWebViewClient webViewClient; + private App app; + + // Our MessageHandler for sending and receiving data to the WebView + private final MessageHandler msgHandler; + + // The ThreadHandler for executing plugin calls + private final HandlerThread handlerThread = new HandlerThread("CapacitorPlugins"); + + // Our Handler for posting plugin calls. Created from the ThreadHandler + private Handler taskHandler = null; + + private final List> initialPlugins; + + private final List pluginInstances; + + // A map of Plugin Id's to PluginHandle's + private Map plugins = new HashMap<>(); + + // Stored plugin calls that we're keeping around to call again someday + private Map savedCalls = new HashMap<>(); + + // The call IDs of saved plugin calls with associated plugin id for handling permissions + private Map> savedPermissionCallIds = new HashMap<>(); + + // Store a plugin that started a new activity, in case we need to resume + // the app and return that data back + private PluginCall pluginCallForLastActivity; + + // Any URI that was passed to the app on start + private Uri intentUri; + + // A list of listeners that trigger when webView events occur + private List webViewListeners = new ArrayList<>(); + + // An interface to manipulate route resolving + private RouteProcessor routeProcessor; + + // A pre-determined path to load the bridge + private ServerPath serverPath; + + /** + * Create the Bridge with a reference to the main {@link Activity} for the + * app, and a reference to the {@link WebView} our app will use. + * @param context + * @param webView + * @deprecated Use {@link Bridge.Builder} to create Bridge instances + */ + @Deprecated + public Bridge( + AppCompatActivity context, + WebView webView, + List> initialPlugins, + MockCordovaInterfaceImpl cordovaInterface, + PluginManager pluginManager, + CordovaPreferences preferences, + CapConfig config + ) { + this(context, null, null, webView, initialPlugins, new ArrayList<>(), cordovaInterface, pluginManager, preferences, config); + } + + private Bridge( + AppCompatActivity context, + ServerPath serverPath, + Fragment fragment, + WebView webView, + List> initialPlugins, + List pluginInstances, + MockCordovaInterfaceImpl cordovaInterface, + PluginManager pluginManager, + CordovaPreferences preferences, + CapConfig config + ) { + this.app = new App(); + this.serverPath = serverPath; + this.context = context; + this.fragment = fragment; + this.webView = webView; + this.webViewClient = new BridgeWebViewClient(this); + this.initialPlugins = initialPlugins; + this.pluginInstances = pluginInstances; + this.cordovaInterface = cordovaInterface; + this.preferences = preferences; + + // Start our plugin execution threads and handlers + handlerThread.start(); + taskHandler = new Handler(handlerThread.getLooper()); + + this.config = config != null ? config : CapConfig.loadDefault(getActivity()); + Logger.init(this.config); + + // Initialize web view and message handler for it + this.initWebView(); + this.setAllowedOriginRules(); + this.msgHandler = new MessageHandler(this, webView, pluginManager); + + // Grab any intent info that our app was launched with + Intent intent = context.getIntent(); + this.intentUri = intent.getData(); + // Register our core plugins + this.registerAllPlugins(); + + this.loadWebView(); + } + + private void setAllowedOriginRules() { + String[] appAllowNavigationConfig = this.config.getAllowNavigation(); + String authority = this.getHost(); + String scheme = this.getScheme(); + allowedOriginRules.add(scheme + "://" + authority); + if (this.getServerUrl() != null) { + allowedOriginRules.add(this.getServerUrl()); + } + if (appAllowNavigationConfig != null) { + for (String allowNavigation : appAllowNavigationConfig) { + if (!allowNavigation.startsWith("http")) { + allowedOriginRules.add("https://" + allowNavigation); + } else { + allowedOriginRules.add(allowNavigation); + } + } + authorities.addAll(Arrays.asList(appAllowNavigationConfig)); + } + this.appAllowNavigationMask = HostMask.Parser.parse(appAllowNavigationConfig); + } + + public App getApp() { + return app; + } + + private void loadWebView() { + final boolean html5mode = this.config.isHTML5Mode(); + + // Start the local web server + JSInjector injector = getJSInjector(); + if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) { + String allowedOrigin = Uri.parse(appUrl).buildUpon().path(null).fragment(null).clearQuery().build().toString(); + try { + WebViewCompat.addDocumentStartJavaScript(webView, injector.getScriptString(), Collections.singleton(allowedOrigin)); + injector = null; + } catch (IllegalArgumentException ex) { + Logger.warn("Invalid url, using fallback"); + } + } + localServer = new WebViewLocalServer(context, this, injector, authorities, html5mode); + localServer.hostAssets(DEFAULT_WEB_ASSET_DIR); + + Logger.debug("Loading app at " + appUrl); + + webView.setWebChromeClient(new BridgeWebChromeClient(this)); + webView.setWebViewClient(this.webViewClient); + + if (config.isResolveServiceWorkerRequests()) { + ServiceWorkerController swController = ServiceWorkerController.getInstance(); + swController.setServiceWorkerClient( + new ServiceWorkerClient() { + @Override + public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) { + return getLocalServer().shouldInterceptRequest(request); + } + } + ); + } + + if (!isDeployDisabled() && !isNewBinary()) { + SharedPreferences prefs = getContext().getSharedPreferences( + com.getcapacitor.plugin.WebView.WEBVIEW_PREFS_NAME, + Activity.MODE_PRIVATE + ); + String path = prefs.getString(com.getcapacitor.plugin.WebView.CAP_SERVER_PATH, null); + if (path != null && !path.isEmpty() && new File(path).exists()) { + setServerBasePath(path); + } + } + if (!this.isMinimumWebViewInstalled()) { + String errorUrl = this.getErrorUrl(); + if (errorUrl != null) { + webView.loadUrl(errorUrl); + return; + } else { + Logger.error(MINIMUM_ANDROID_WEBVIEW_ERROR); + } + } + + // If serverPath configured, start server based on provided path + if (serverPath != null) { + if (serverPath.getType() == ServerPath.PathType.ASSET_PATH) { + setServerAssetPath(serverPath.getPath()); + } else { + setServerBasePath(serverPath.getPath()); + } + } else { + // Get to work + webView.loadUrl(appUrl); + } + } + + @SuppressLint("WebViewApiAvailability") + public boolean isMinimumWebViewInstalled() { + PackageManager pm = getContext().getPackageManager(); + + // Check getCurrentWebViewPackage() directly if above Android 8 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + PackageInfo info = WebView.getCurrentWebViewPackage(); + Pattern pattern = Pattern.compile("(\\d+)"); + Matcher matcher = pattern.matcher(info.versionName); + if (matcher.find()) { + String majorVersionStr = matcher.group(0); + int majorVersion = Integer.parseInt(majorVersionStr); + if (info.packageName.equals("com.huawei.webview")) { + return majorVersion >= config.getMinHuaweiWebViewVersion(); + } + return majorVersion >= config.getMinWebViewVersion(); + } else { + return false; + } + } + + // Otherwise manually check WebView versions + try { + PackageInfo info = InternalUtils.getPackageInfo(pm, "com.android.chrome"); + String majorVersionStr = info.versionName.split("\\.")[0]; + int majorVersion = Integer.parseInt(majorVersionStr); + return majorVersion >= config.getMinWebViewVersion(); + } catch (Exception ex) { + Logger.warn("Unable to get package info for 'com.google.android.webview'" + ex.toString()); + } + + try { + PackageInfo info = InternalUtils.getPackageInfo(pm, "com.android.webview"); + String majorVersionStr = info.versionName.split("\\.")[0]; + int majorVersion = Integer.parseInt(majorVersionStr); + return majorVersion >= config.getMinWebViewVersion(); + } catch (Exception ex) { + Logger.warn("Unable to get package info for 'com.android.webview'" + ex.toString()); + } + + final int amazonFireMajorWebViewVersion = extractWebViewMajorVersion(pm, "com.amazon.webview.chromium"); + if (amazonFireMajorWebViewVersion >= config.getMinWebViewVersion()) { + return true; + } + + // Could not detect any webview, return false + return false; + } + + private int extractWebViewMajorVersion(final PackageManager pm, final String webViewPackageName) { + try { + final PackageInfo info = InternalUtils.getPackageInfo(pm, webViewPackageName); + final String majorVersionStr = info.versionName.split("\\.")[0]; + final int majorVersion = Integer.parseInt(majorVersionStr); + return majorVersion; + } catch (Exception ex) { + Logger.warn(String.format("Unable to get package info for '%s' with err '%s'", webViewPackageName, ex)); + } + return 0; + } + + public boolean launchIntent(Uri url) { + /* + * Give plugins the chance to handle the url + */ + for (Map.Entry entry : plugins.entrySet()) { + Plugin plugin = entry.getValue().getInstance(); + if (plugin != null) { + Boolean shouldOverrideLoad = plugin.shouldOverrideLoad(url); + if (shouldOverrideLoad != null) { + return shouldOverrideLoad; + } + } + } + + if (url.getScheme().equals("data") || url.getScheme().equals("blob")) { + return false; + } + + Uri appUri = Uri.parse(appUrl); + if ( + !(appUri.getHost().equals(url.getHost()) && url.getScheme().equals(appUri.getScheme())) && + !appAllowNavigationMask.matches(url.getHost()) + ) { + try { + Intent openIntent = new Intent(Intent.ACTION_VIEW, url); + getContext().startActivity(openIntent); + } catch (ActivityNotFoundException e) { + // TODO - trigger an event + } + return true; + } + return false; + } + + private boolean isNewBinary() { + String versionCode = ""; + String versionName = ""; + SharedPreferences prefs = getContext().getSharedPreferences( + com.getcapacitor.plugin.WebView.WEBVIEW_PREFS_NAME, + Activity.MODE_PRIVATE + ); + String lastVersionCode = prefs.getString(LAST_BINARY_VERSION_CODE, null); + String lastVersionName = prefs.getString(LAST_BINARY_VERSION_NAME, null); + + try { + PackageManager pm = getContext().getPackageManager(); + PackageInfo pInfo = InternalUtils.getPackageInfo(pm, getContext().getPackageName()); + versionCode = Integer.toString((int) PackageInfoCompat.getLongVersionCode(pInfo)); + versionName = pInfo.versionName != null ? pInfo.versionName : ""; + } catch (Exception ex) { + Logger.error("Unable to get package info", ex); + } + + if (!versionCode.equals(lastVersionCode) || !versionName.equals(lastVersionName)) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(LAST_BINARY_VERSION_CODE, versionCode); + editor.putString(LAST_BINARY_VERSION_NAME, versionName); + editor.putString(com.getcapacitor.plugin.WebView.CAP_SERVER_PATH, ""); + editor.apply(); + return true; + } + return false; + } + + public boolean isDeployDisabled() { + return preferences.getBoolean("DisableDeploy", false); + } + + public boolean shouldKeepRunning() { + return preferences.getBoolean("KeepRunning", true); + } + + public void handleAppUrlLoadError(Exception ex) { + if (ex instanceof SocketTimeoutException) { + Logger.error( + "Unable to load app. Ensure the server is running at " + + appUrl + + ", or modify the " + + "appUrl setting in capacitor.config.json (make sure to npx cap copy after to commit changes).", + ex + ); + } + } + + public boolean isDevMode() { + return (getActivity().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } + + protected void setCordovaWebView(CordovaWebView cordovaWebView) { + this.cordovaWebView = cordovaWebView; + } + + /** + * Get the Context for the App + * @return + */ + public Context getContext() { + return this.context; + } + + /** + * Get the activity for the app + * @return + */ + public AppCompatActivity getActivity() { + return this.context; + } + + /** + * Get the fragment for the app, if applicable. This will likely be null unless Capacitor + * is being used embedded in a Native Android app. + * + * @return The fragment containing the Capacitor WebView. + */ + public Fragment getFragment() { + return this.fragment; + } + + /** + * Get the core WebView under Capacitor's control + * @return + */ + public WebView getWebView() { + return this.webView; + } + + /** + * Get the URI that was used to launch the app (if any) + * @return + */ + public Uri getIntentUri() { + return intentUri; + } + + /** + * Get scheme that is used to serve content + * @return + */ + public String getScheme() { + return this.config.getAndroidScheme(); + } + + /** + * Get host name that is used to serve content + * @return + */ + public String getHost() { + return this.config.getHostname(); + } + + /** + * Get the server url that is used to serve content + * @return + */ + public String getServerUrl() { + return this.config.getServerUrl(); + } + + public String getErrorUrl() { + String errorPath = this.config.getErrorPath(); + + if (errorPath != null && !errorPath.trim().isEmpty()) { + String authority = this.getHost(); + String scheme = this.getScheme(); + + String localUrl = scheme + "://" + authority; + + return localUrl + "/" + errorPath; + } + + return null; + } + + public String getAppUrl() { + return appUrl; + } + + public CapConfig getConfig() { + return this.config; + } + + public void reset() { + savedCalls = new HashMap<>(); + for (PluginHandle handle : this.plugins.values()) { + handle.getInstance().removeAllListeners(); + } + } + + /** + * Initialize the WebView, setting required flags + */ + @SuppressLint("SetJavaScriptEnabled") + private void initWebView() { + WebSettings settings = webView.getSettings(); + settings.setJavaScriptEnabled(true); + settings.setDomStorageEnabled(true); + settings.setGeolocationEnabled(true); + settings.setMediaPlaybackRequiresUserGesture(false); + settings.setJavaScriptCanOpenWindowsAutomatically(true); + if (this.config.isMixedContentAllowed()) { + settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + } + + String appendUserAgent = this.config.getAppendedUserAgentString(); + if (appendUserAgent != null) { + String defaultUserAgent = settings.getUserAgentString(); + settings.setUserAgentString(defaultUserAgent + " " + appendUserAgent); + } + String overrideUserAgent = this.config.getOverriddenUserAgentString(); + if (overrideUserAgent != null) { + settings.setUserAgentString(overrideUserAgent); + } + + String backgroundColor = this.config.getBackgroundColor(); + try { + if (backgroundColor != null) { + webView.setBackgroundColor(WebColor.parseColor(backgroundColor)); + } + } catch (IllegalArgumentException ex) { + Logger.debug("WebView background color not applied"); + } + + settings.setDisplayZoomControls(false); + settings.setBuiltInZoomControls(this.config.isZoomableWebView()); + + if (config.isInitialFocus()) { + webView.requestFocusFromTouch(); + } + + WebView.setWebContentsDebuggingEnabled(this.config.isWebContentsDebuggingEnabled()); + + appUrlConfig = this.getServerUrl(); + String authority = this.getHost(); + authorities.add(authority); + String scheme = this.getScheme(); + + localUrl = scheme + "://" + authority; + + if (appUrlConfig != null) { + try { + URL appUrlObject = new URL(appUrlConfig); + authorities.add(appUrlObject.getAuthority()); + localUrl = appUrlObject.getProtocol() + "://" + appUrlObject.getAuthority(); + } catch (Exception ex) { + Logger.error("Provided server url is invalid: " + ex.getMessage()); + return; + } + appUrl = appUrlConfig; + } else { + appUrl = localUrl; + // custom URL schemes requires path ending with / + if (!scheme.equals(Bridge.CAPACITOR_HTTP_SCHEME) && !scheme.equals(CAPACITOR_HTTPS_SCHEME)) { + appUrl += "/"; + } + } + + String appUrlPath = this.config.getStartPath(); + if (appUrlPath != null && !appUrlPath.trim().isEmpty()) { + appUrl += appUrlPath; + } + } + + /** + * Register our core Plugin APIs + */ + private void registerAllPlugins() { + this.registerPlugin(com.getcapacitor.plugin.CapacitorCookies.class); + this.registerPlugin(com.getcapacitor.plugin.WebView.class); + this.registerPlugin(com.getcapacitor.plugin.CapacitorHttp.class); + this.registerPlugin(com.getcapacitor.plugin.SystemBars.class); + + for (Class pluginClass : this.initialPlugins) { + this.registerPlugin(pluginClass); + } + + for (Plugin plugin : pluginInstances) { + registerPluginInstance(plugin); + } + } + + /** + * Register additional plugins + * @param pluginClasses the plugins to register + */ + public void registerPlugins(Class[] pluginClasses) { + for (Class plugin : pluginClasses) { + this.registerPlugin(plugin); + } + } + + public void registerPluginInstances(Plugin[] pluginInstances) { + for (Plugin plugin : pluginInstances) { + this.registerPluginInstance(plugin); + } + } + + @SuppressWarnings("deprecation") + private String getLegacyPluginName(Class pluginClass) { + NativePlugin legacyPluginAnnotation = pluginClass.getAnnotation(NativePlugin.class); + if (legacyPluginAnnotation == null) { + Logger.error("Plugin doesn't have the @CapacitorPlugin annotation. Please add it"); + return null; + } + + return legacyPluginAnnotation.name(); + } + + /** + * Register a plugin class + * @param pluginClass a class inheriting from Plugin + */ + public void registerPlugin(Class pluginClass) { + String pluginId = pluginId(pluginClass); + if (pluginId == null) return; + + try { + this.plugins.put(pluginId, new PluginHandle(this, pluginClass)); + } catch (InvalidPluginException ex) { + logInvalidPluginException(pluginClass); + } catch (PluginLoadException ex) { + logPluginLoadException(pluginClass, ex); + } + } + + public void registerPluginInstance(Plugin plugin) { + Class clazz = plugin.getClass(); + String pluginId = pluginId(clazz); + if (pluginId == null) return; + + try { + this.plugins.put(pluginId, new PluginHandle(this, plugin)); + } catch (InvalidPluginException ex) { + logInvalidPluginException(clazz); + } + } + + private String pluginId(Class clazz) { + String pluginName = pluginName(clazz); + String pluginId = clazz.getSimpleName(); + if (pluginName == null) return null; + + if (!pluginName.equals("")) { + pluginId = pluginName; + } + Logger.debug("Registering plugin instance: " + pluginId); + return pluginId; + } + + private String pluginName(Class clazz) { + String pluginName; + CapacitorPlugin pluginAnnotation = clazz.getAnnotation(CapacitorPlugin.class); + if (pluginAnnotation == null) { + pluginName = this.getLegacyPluginName(clazz); + } else { + pluginName = pluginAnnotation.name(); + } + + return pluginName; + } + + private void logInvalidPluginException(Class clazz) { + Logger.error( + "NativePlugin " + + clazz.getName() + + " is invalid. Ensure the @CapacitorPlugin annotation exists on the plugin class and" + + " the class extends Plugin" + ); + } + + private void logPluginLoadException(Class clazz, Exception ex) { + Logger.error("NativePlugin " + clazz.getName() + " failed to load", ex); + } + + public PluginHandle getPlugin(String pluginId) { + return this.plugins.get(pluginId); + } + + /** + * Find the plugin handle that responds to the given request code. This will + * fire after certain Android OS intent results/permission checks/etc. + * @param requestCode + * @return + */ + @Deprecated + @SuppressWarnings("deprecation") + public PluginHandle getPluginWithRequestCode(int requestCode) { + for (PluginHandle handle : this.plugins.values()) { + int[] requestCodes; + + CapacitorPlugin pluginAnnotation = handle.getPluginAnnotation(); + if (pluginAnnotation == null) { + // Check for legacy plugin annotation, @NativePlugin + NativePlugin legacyPluginAnnotation = handle.getLegacyPluginAnnotation(); + if (legacyPluginAnnotation == null) { + continue; + } + + if (legacyPluginAnnotation.permissionRequestCode() == requestCode) { + return handle; + } + + requestCodes = legacyPluginAnnotation.requestCodes(); + + for (int rc : requestCodes) { + if (rc == requestCode) { + return handle; + } + } + } else { + requestCodes = pluginAnnotation.requestCodes(); + + for (int rc : requestCodes) { + if (rc == requestCode) { + return handle; + } + } + } + } + return null; + } + + /** + * Call a method on a plugin. + * @param pluginId the plugin id to use to lookup the plugin handle + * @param methodName the name of the method to call + * @param call the call object to pass to the method + */ + public void callPluginMethod(String pluginId, final String methodName, final PluginCall call) { + try { + final PluginHandle plugin = this.getPlugin(pluginId); + + if (plugin == null) { + Logger.error("unable to find plugin : " + pluginId); + call.errorCallback("unable to find plugin : " + pluginId); + return; + } + + if (Logger.shouldLog()) { + Logger.verbose( + "callback: " + + call.getCallbackId() + + ", pluginId: " + + plugin.getId() + + ", methodName: " + + methodName + + ", methodData: " + + call.getData().toString() + ); + } + + Runnable currentThreadTask = () -> { + try { + plugin.invoke(methodName, call); + + if (call.isKeptAlive()) { + saveCall(call); + } + } catch (PluginLoadException | InvalidPluginMethodException ex) { + Logger.error("Unable to execute plugin method", ex); + } catch (Exception ex) { + Logger.error("Serious error executing plugin", ex); + throw new RuntimeException(ex); + } + }; + + taskHandler.post(currentThreadTask); + } catch (Exception ex) { + Logger.error(Logger.tags("callPluginMethod"), "error : " + ex, null); + call.errorCallback(ex.toString()); + } + } + + /** + * Evaluate JavaScript in the web view. This method + * executes on the main thread automatically. + * @param js the JS to execute + * @param callback an optional ValueCallback that will synchronously receive a value + * after calling the JS + */ + public void eval(final String js, final ValueCallback callback) { + Handler mainHandler = new Handler(context.getMainLooper()); + mainHandler.post(() -> webView.evaluateJavascript(js, callback)); + } + + public void logToJs(final String message, final String level) { + eval("window.Capacitor.logJs(\"" + message + "\", \"" + level + "\")", null); + } + + public void logToJs(final String message) { + logToJs(message, "log"); + } + + public void triggerJSEvent(final String eventName, final String target) { + eval("window.Capacitor.triggerEvent(\"" + eventName + "\", \"" + target + "\")", (s) -> {}); + } + + public void triggerJSEvent(final String eventName, final String target, final String data) { + eval("window.Capacitor.triggerEvent(\"" + eventName + "\", \"" + target + "\", " + data + ")", (s) -> {}); + } + + public void triggerWindowJSEvent(final String eventName) { + this.triggerJSEvent(eventName, "window"); + } + + public void triggerWindowJSEvent(final String eventName, final String data) { + this.triggerJSEvent(eventName, "window", data); + } + + public void triggerDocumentJSEvent(final String eventName) { + this.triggerJSEvent(eventName, "document"); + } + + public void triggerDocumentJSEvent(final String eventName, final String data) { + this.triggerJSEvent(eventName, "document", data); + } + + public void execute(Runnable runnable) { + taskHandler.post(runnable); + } + + public void executeOnMainThread(Runnable runnable) { + Handler mainHandler = new Handler(context.getMainLooper()); + + mainHandler.post(runnable); + } + + /** + * Retain a call between plugin invocations + * @param call + */ + public void saveCall(PluginCall call) { + this.savedCalls.put(call.getCallbackId(), call); + } + + /** + * Get a retained plugin call + * @param callbackId the callbackId to use to lookup the call with + * @return the stored call + */ + public PluginCall getSavedCall(String callbackId) { + if (callbackId == null) { + return null; + } + + return this.savedCalls.get(callbackId); + } + + PluginCall getPluginCallForLastActivity() { + PluginCall pluginCallForLastActivity = this.pluginCallForLastActivity; + this.pluginCallForLastActivity = null; + return pluginCallForLastActivity; + } + + void setPluginCallForLastActivity(PluginCall pluginCallForLastActivity) { + this.pluginCallForLastActivity = pluginCallForLastActivity; + } + + /** + * Release a retained call + * @param call a call to release + */ + public void releaseCall(PluginCall call) { + releaseCall(call.getCallbackId()); + } + + /** + * Release a retained call by its ID + * @param callbackId an ID of a callback to release + */ + public void releaseCall(String callbackId) { + this.savedCalls.remove(callbackId); + } + + /** + * Removes the earliest saved call prior to a permissions request for a given plugin and + * returns it. + * + * @return The saved plugin call + */ + protected PluginCall getPermissionCall(String pluginId) { + LinkedList permissionCallIds = this.savedPermissionCallIds.get(pluginId); + String savedCallId = null; + if (permissionCallIds != null) { + savedCallId = permissionCallIds.poll(); + } + + return getSavedCall(savedCallId); + } + + /** + * Save a call to be retrieved after requesting permissions. Calls are saved in order. + * + * @param call The plugin call to save. + */ + protected void savePermissionCall(PluginCall call) { + if (call != null) { + if (!savedPermissionCallIds.containsKey(call.getPluginId())) { + savedPermissionCallIds.put(call.getPluginId(), new LinkedList<>()); + } + + savedPermissionCallIds.get(call.getPluginId()).add(call.getCallbackId()); + saveCall(call); + } + } + + /** + * Register an Activity Result Launcher to the containing Fragment or Activity. + * + * @param contract A contract specifying that an activity can be called with an input of + * type I and produce an output of type O. + * @param callback The callback run on Activity Result. + * @return A registered Activity Result Launcher. + */ + public ActivityResultLauncher registerForActivityResult( + @NonNull final ActivityResultContract contract, + @NonNull final ActivityResultCallback callback + ) { + if (fragment != null) { + return fragment.registerForActivityResult(contract, callback); + } else { + return context.registerForActivityResult(contract, callback); + } + } + + /** + * Build the JSInjector that will be used to inject JS into files served to the app, + * to ensure that Capacitor's JS and the JS for all the plugins is loaded each time. + */ + private JSInjector getJSInjector() { + try { + String globalJS = JSExport.getGlobalJS(context, config.isLoggingEnabled(), isDevMode()); + String bridgeJS = JSExport.getBridgeJS(context); + String pluginJS = JSExport.getPluginJS(plugins.values()); + String cordovaJS = JSExport.getCordovaJS(context); + String cordovaPluginsJS = JSExport.getCordovaPluginJS(context); + String cordovaPluginsFileJS = JSExport.getCordovaPluginsFileJS(context); + String localUrlJS = "window.WEBVIEW_SERVER_URL = '" + localUrl + "';"; + String miscJS = JSExport.getMiscFileJS(miscJSFileInjections, context); + + miscJSFileInjections = new ArrayList<>(); + canInjectJS = false; + + return new JSInjector(globalJS, bridgeJS, pluginJS, cordovaJS, cordovaPluginsJS, cordovaPluginsFileJS, localUrlJS, miscJS); + } catch (Exception ex) { + Logger.error("Unable to export Capacitor JS. App will not function!", ex); + } + return null; + } + + /** + * Inject JavaScript from an external file before the WebView loads. + * @param path relative to public folder + */ + public void injectScriptBeforeLoad(String path) { + if (canInjectJS) { + miscJSFileInjections.add(path); + } + } + + /** + * Restore any saved bundle state data + * @param savedInstanceState + */ + public void restoreInstanceState(Bundle savedInstanceState) { + String lastPluginId = savedInstanceState.getString(BUNDLE_LAST_PLUGIN_ID_KEY); + String lastPluginCallMethod = savedInstanceState.getString(BUNDLE_LAST_PLUGIN_CALL_METHOD_NAME_KEY); + String lastOptionsJson = savedInstanceState.getString(BUNDLE_PLUGIN_CALL_OPTIONS_SAVED_KEY); + + if (lastPluginId != null) { + // If we have JSON blob saved, create a new plugin call with the original options + if (lastOptionsJson != null) { + try { + JSObject options = new JSObject(lastOptionsJson); + + pluginCallForLastActivity = new PluginCall( + msgHandler, + lastPluginId, + PluginCall.CALLBACK_ID_DANGLING, + lastPluginCallMethod, + options + ); + } catch (JSONException ex) { + Logger.error("Unable to restore plugin call, unable to parse persisted JSON object", ex); + } + } + + // Let the plugin restore any state it needs + Bundle bundleData = savedInstanceState.getBundle(BUNDLE_PLUGIN_CALL_BUNDLE_KEY); + PluginHandle lastPlugin = getPlugin(lastPluginId); + if (bundleData != null && lastPlugin != null) { + lastPlugin.getInstance().restoreState(bundleData); + } else { + Logger.error("Unable to restore last plugin call"); + } + } + } + + public void saveInstanceState(Bundle outState) { + Logger.debug("Saving instance state!"); + + // If there was a last PluginCall for a started activity, we need to + // persist it so we can load it again in case our app gets terminated + if (pluginCallForLastActivity != null) { + PluginCall call = pluginCallForLastActivity; + PluginHandle handle = getPlugin(call.getPluginId()); + + if (handle != null) { + Bundle bundle = handle.getInstance().saveInstanceState(); + if (bundle != null) { + outState.putString(BUNDLE_LAST_PLUGIN_ID_KEY, call.getPluginId()); + outState.putString(BUNDLE_LAST_PLUGIN_CALL_METHOD_NAME_KEY, call.getMethodName()); + outState.putString(BUNDLE_PLUGIN_CALL_OPTIONS_SAVED_KEY, call.getData().toString()); + outState.putBundle(BUNDLE_PLUGIN_CALL_BUNDLE_KEY, bundle); + } else { + Logger.error("Couldn't save last " + call.getPluginId() + "'s Plugin " + call.getMethodName() + " call"); + } + } + } + } + + @Deprecated + @SuppressWarnings("deprecation") + public void startActivityForPluginWithResult(PluginCall call, Intent intent, int requestCode) { + Logger.debug("Starting activity for result"); + + pluginCallForLastActivity = call; + + getActivity().startActivityForResult(intent, requestCode); + } + + /** + * Check for legacy Capacitor or Cordova plugins that may have registered to handle a permission + * request, and handle them if so. If not handled, false is returned. + * + * @param requestCode the code that was requested + * @param permissions the permissions requested + * @param grantResults the set of granted/denied permissions + * @return true if permission code was handled by a plugin explicitly, false if not + */ + @SuppressWarnings("deprecation") + boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + PluginHandle plugin = getPluginWithRequestCode(requestCode); + + if (plugin == null) { + boolean permissionHandled = false; + Logger.debug("Unable to find a Capacitor plugin to handle permission requestCode, trying Cordova plugins " + requestCode); + try { + permissionHandled = cordovaInterface.handlePermissionResult(requestCode, permissions, grantResults); + } catch (JSONException e) { + Logger.debug("Error on Cordova plugin permissions request " + e.getMessage()); + } + return permissionHandled; + } + + // Call deprecated method if using deprecated NativePlugin annotation + if (plugin.getPluginAnnotation() == null) { + plugin.getInstance().handleRequestPermissionsResult(requestCode, permissions, grantResults); + return true; + } + + return false; + } + + /** + * Saves permission states and rejects if permissions were not correctly defined in + * the AndroidManifest.xml file. + * + * @param plugin + * @param savedCall + * @param permissions + * @return true if permissions were saved and defined correctly, false if not + */ + protected boolean validatePermissions(Plugin plugin, PluginCall savedCall, Map permissions) { + SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_PREFS_NAME, Activity.MODE_PRIVATE); + + for (Map.Entry permission : permissions.entrySet()) { + String permString = permission.getKey(); + boolean isGranted = permission.getValue(); + + if (isGranted) { + // Permission granted. If previously denied, remove cached state + String state = prefs.getString(permString, null); + + if (state != null) { + SharedPreferences.Editor editor = prefs.edit(); + editor.remove(permString); + editor.apply(); + } + } else { + SharedPreferences.Editor editor = prefs.edit(); + + if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permString)) { + // Permission denied, can prompt again with rationale + editor.putString(permString, PermissionState.PROMPT_WITH_RATIONALE.toString()); + } else { + // Permission denied permanently, store this state for future reference + editor.putString(permString, PermissionState.DENIED.toString()); + } + + editor.apply(); + } + } + + String[] permStrings = permissions.keySet().toArray(new String[0]); + + if (!PermissionHelper.hasDefinedPermissions(getContext(), permStrings)) { + StringBuilder builder = new StringBuilder(); + builder.append("Missing the following permissions in AndroidManifest.xml:\n"); + String[] missing = PermissionHelper.getUndefinedPermissions(getContext(), permStrings); + for (String perm : missing) { + builder.append(perm + "\n"); + } + savedCall.reject(builder.toString()); + return false; + } + + return true; + } + + /** + * Helper to check all permissions and see the current states of each permission. + * + * @since 3.0.0 + * @return A mapping of permission aliases to the associated granted status. + */ + protected Map getPermissionStates(Plugin plugin) { + Map permissionsResults = new HashMap<>(); + CapacitorPlugin annotation = plugin.getPluginHandle().getPluginAnnotation(); + for (Permission perm : annotation.permissions()) { + // If a permission is defined with no permission constants, return GRANTED for it. + // Otherwise, get its true state. + if (perm.strings().length == 0 || (perm.strings().length == 1 && perm.strings()[0].isEmpty())) { + String key = perm.alias(); + if (!key.isEmpty()) { + PermissionState existingResult = permissionsResults.get(key); + + // auto set permission state to GRANTED if the alias is empty. + if (existingResult == null) { + permissionsResults.put(key, PermissionState.GRANTED); + } + } + } else { + for (String permString : perm.strings()) { + String key = perm.alias().isEmpty() ? permString : perm.alias(); + PermissionState permissionStatus; + if (ActivityCompat.checkSelfPermission(this.getContext(), permString) == PackageManager.PERMISSION_GRANTED) { + permissionStatus = PermissionState.GRANTED; + } else { + permissionStatus = PermissionState.PROMPT; + + // Check if there is a cached permission state for the "Never ask again" state + SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_PREFS_NAME, Activity.MODE_PRIVATE); + String state = prefs.getString(permString, null); + + if (state != null) { + permissionStatus = PermissionState.byState(state); + } + } + + PermissionState existingResult = permissionsResults.get(key); + + // multiple permissions with the same alias must all be true, otherwise all false. + if (existingResult == null || existingResult == PermissionState.GRANTED) { + permissionsResults.put(key, permissionStatus); + } + } + } + } + + return permissionsResults; + } + + /** + * Handle an activity result and pass it to a plugin that has indicated it wants to + * handle the result. + * @param requestCode + * @param resultCode + * @param data + */ + @SuppressWarnings("deprecation") + boolean onActivityResult(int requestCode, int resultCode, Intent data) { + PluginHandle plugin = getPluginWithRequestCode(requestCode); + + if (plugin == null || plugin.getInstance() == null) { + Logger.debug("Unable to find a Capacitor plugin to handle requestCode, trying Cordova plugins " + requestCode); + return cordovaInterface.onActivityResult(requestCode, resultCode, data); + } + + // deprecated, to be removed + PluginCall lastCall = plugin.getInstance().getSavedCall(); + + // If we don't have a saved last call (because our app was killed and restarted, for example), + // Then we should see if we have any saved plugin call information and generate a new, + // "dangling" plugin call (a plugin call that doesn't have a corresponding web callback) + // and then send that to the plugin + if (lastCall == null && pluginCallForLastActivity != null) { + plugin.getInstance().saveCall(pluginCallForLastActivity); + } + + plugin.getInstance().handleOnActivityResult(requestCode, resultCode, data); + + // Clear the plugin call we may have re-hydrated on app launch + pluginCallForLastActivity = null; + + return true; + } + + /** + * Handle an onNewIntent lifecycle event and notify the plugins + * @param intent + */ + public void onNewIntent(Intent intent) { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnNewIntent(intent); + } + + if (cordovaWebView != null) { + cordovaWebView.onNewIntent(intent); + } + } + + /** + * Handle an onConfigurationChanged event and notify the plugins + * @param newConfig + */ + public void onConfigurationChanged(Configuration newConfig) { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnConfigurationChanged(newConfig); + } + } + + /** + * Handle onRestart lifecycle event and notify the plugins + */ + public void onRestart() { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnRestart(); + } + } + + /** + * Handle onStart lifecycle event and notify the plugins + */ + public void onStart() { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnStart(); + } + + if (cordovaWebView != null) { + cordovaWebView.handleStart(); + } + } + + /** + * Handle onResume lifecycle event and notify the plugins + */ + public void onResume() { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnResume(); + } + + if (cordovaWebView != null) { + cordovaWebView.handleResume(this.shouldKeepRunning()); + } + } + + /** + * Handle onPause lifecycle event and notify the plugins + */ + public void onPause() { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnPause(); + } + + if (cordovaWebView != null) { + boolean keepRunning = this.shouldKeepRunning() || cordovaInterface.getActivityResultCallback() != null; + cordovaWebView.handlePause(keepRunning); + } + } + + /** + * Handle onStop lifecycle event and notify the plugins + */ + public void onStop() { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnStop(); + } + + if (cordovaWebView != null) { + cordovaWebView.handleStop(); + } + } + + /** + * Handle onDestroy lifecycle event and notify the plugins + */ + public void onDestroy() { + for (PluginHandle plugin : plugins.values()) { + plugin.getInstance().handleOnDestroy(); + } + + handlerThread.quitSafely(); + + if (cordovaWebView != null) { + cordovaWebView.handleDestroy(); + } + } + + /** + * Handle onDetachedFromWindow lifecycle event + */ + public void onDetachedFromWindow() { + webView.removeAllViews(); + webView.destroy(); + } + + public String getServerBasePath() { + return this.localServer.getBasePath(); + } + + /** + * Tell the local server to load files from the given + * file path instead of the assets path. + * @param path + */ + public void setServerBasePath(String path) { + localServer.hostFiles(path); + webView.post(() -> webView.loadUrl(appUrl)); + } + + /** + * Tell the local server to load files from the given + * asset path. + * @param path + */ + public void setServerAssetPath(String path) { + localServer.hostAssets(path); + webView.post(() -> webView.loadUrl(appUrl)); + } + + /** + * Reload the WebView + */ + public void reload() { + webView.post(() -> webView.loadUrl(appUrl)); + } + + public String getLocalUrl() { + return localUrl; + } + + public WebViewLocalServer getLocalServer() { + return localServer; + } + + public HostMask getAppAllowNavigationMask() { + return appAllowNavigationMask; + } + + public Set getAllowedOriginRules() { + return allowedOriginRules; + } + + public BridgeWebViewClient getWebViewClient() { + return this.webViewClient; + } + + public void setWebViewClient(BridgeWebViewClient client) { + this.webViewClient = client; + webView.setWebViewClient(client); + } + + List getWebViewListeners() { + return webViewListeners; + } + + void setWebViewListeners(List webViewListeners) { + this.webViewListeners = webViewListeners; + } + + RouteProcessor getRouteProcessor() { + return routeProcessor; + } + + void setRouteProcessor(RouteProcessor routeProcessor) { + this.routeProcessor = routeProcessor; + } + + ServerPath getServerPath() { + return serverPath; + } + + /** + * Add a listener that the WebViewClient can trigger on certain events. + * @param webViewListener A {@link WebViewListener} to add. + */ + public void addWebViewListener(WebViewListener webViewListener) { + webViewListeners.add(webViewListener); + } + + /** + * Remove a listener that the WebViewClient triggers on certain events. + * @param webViewListener A {@link WebViewListener} to remove. + */ + public void removeWebViewListener(WebViewListener webViewListener) { + webViewListeners.remove(webViewListener); + } + + public static class Builder { + + private Bundle instanceState = null; + private CapConfig config = null; + private List> plugins = new ArrayList<>(); + private List pluginInstances = new ArrayList<>(); + private AppCompatActivity activity; + private Fragment fragment; + private RouteProcessor routeProcessor; + private final List webViewListeners = new ArrayList<>(); + private ServerPath serverPath; + + public Builder(AppCompatActivity activity) { + this.activity = activity; + } + + public Builder(Fragment fragment) { + this.activity = (AppCompatActivity) fragment.getActivity(); + this.fragment = fragment; + } + + public Builder setInstanceState(Bundle instanceState) { + this.instanceState = instanceState; + return this; + } + + public Builder setConfig(CapConfig config) { + this.config = config; + return this; + } + + public Builder setPlugins(List> plugins) { + this.plugins = plugins; + return this; + } + + public Builder addPlugin(Class plugin) { + this.plugins.add(plugin); + return this; + } + + public Builder addPlugins(List> plugins) { + for (Class cls : plugins) { + this.addPlugin(cls); + } + + return this; + } + + public Builder addPluginInstance(Plugin plugin) { + this.pluginInstances.add(plugin); + return this; + } + + public Builder addPluginInstances(List plugins) { + this.pluginInstances.addAll(plugins); + return this; + } + + public Builder addWebViewListener(WebViewListener webViewListener) { + webViewListeners.add(webViewListener); + return this; + } + + public Builder addWebViewListeners(List webViewListeners) { + for (WebViewListener listener : webViewListeners) { + this.addWebViewListener(listener); + } + + return this; + } + + public Builder setRouteProcessor(RouteProcessor routeProcessor) { + this.routeProcessor = routeProcessor; + return this; + } + + public Builder setServerPath(ServerPath serverPath) { + this.serverPath = serverPath; + return this; + } + + public Bridge create() { + // Cordova initialization + ConfigXmlParser parser = new ConfigXmlParser(); + parser.parse(activity.getApplicationContext()); + CordovaPreferences preferences = parser.getPreferences(); + preferences.setPreferencesBundle(activity.getIntent().getExtras()); + List pluginEntries = parser.getPluginEntries(); + + MockCordovaInterfaceImpl cordovaInterface = new MockCordovaInterfaceImpl(activity); + if (instanceState != null) { + cordovaInterface.restoreInstanceState(instanceState); + } + + WebView webView = this.fragment != null ? fragment.getView().findViewById(R.id.webview) : activity.findViewById(R.id.webview); + MockCordovaWebViewImpl mockWebView = new MockCordovaWebViewImpl(activity.getApplicationContext()); + mockWebView.init(cordovaInterface, pluginEntries, preferences, webView); + PluginManager pluginManager = mockWebView.getPluginManager(); + cordovaInterface.onCordovaInit(pluginManager); + + // Bridge initialization + Bridge bridge = new Bridge( + activity, + serverPath, + fragment, + webView, + plugins, + pluginInstances, + cordovaInterface, + pluginManager, + preferences, + config + ); + + if (webView instanceof CapacitorWebView capacitorWebView) { + capacitorWebView.setBridge(bridge); + } + + bridge.setCordovaWebView(mockWebView); + bridge.setWebViewListeners(webViewListeners); + bridge.setRouteProcessor(routeProcessor); + + if (instanceState != null) { + bridge.restoreInstanceState(instanceState); + } + + return bridge; + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java new file mode 100644 index 0000000..bfd532c --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java @@ -0,0 +1,218 @@ +package com.getcapacitor; + +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import com.getcapacitor.android.R; +import java.util.ArrayList; +import java.util.List; + +public class BridgeActivity extends AppCompatActivity { + + protected Bridge bridge; + protected boolean keepRunning = true; + protected CapConfig config; + + protected int activityDepth = 0; + protected List> initialPlugins = new ArrayList<>(); + protected final Bridge.Builder bridgeBuilder = new Bridge.Builder(this); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + bridgeBuilder.setInstanceState(savedInstanceState); + getApplication().setTheme(R.style.AppTheme_NoActionBar); + setTheme(R.style.AppTheme_NoActionBar); + try { + setContentView(R.layout.capacitor_bridge_layout_main); + } catch (Exception ex) { + setContentView(R.layout.no_webview); + return; + } + + PluginManager loader = new PluginManager(getAssets()); + + try { + bridgeBuilder.addPlugins(loader.loadPluginClasses()); + } catch (PluginLoadException ex) { + Logger.error("Error loading plugins.", ex); + } + + this.load(); + } + + protected void load() { + Logger.debug("Starting BridgeActivity"); + + bridge = bridgeBuilder.addPlugins(initialPlugins).setConfig(config).create(); + + this.keepRunning = bridge.shouldKeepRunning(); + this.onNewIntent(getIntent()); + } + + public void registerPlugin(Class plugin) { + bridgeBuilder.addPlugin(plugin); + } + + public void registerPlugins(List> plugins) { + bridgeBuilder.addPlugins(plugins); + } + + public Bridge getBridge() { + return this.bridge; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if (bridge != null) { + bridge.saveInstanceState(outState); + } + } + + @Override + public void onStart() { + super.onStart(); + activityDepth++; + if (this.bridge != null) { + this.bridge.onStart(); + Logger.debug("App started"); + } + } + + @Override + public void onRestart() { + super.onRestart(); + if (this.bridge != null) { + this.bridge.onRestart(); + Logger.debug("App restarted"); + } + } + + @Override + public void onResume() { + super.onResume(); + if (bridge != null) { + bridge.getApp().fireStatusChange(true); + this.bridge.onResume(); + Logger.debug("App resumed"); + } + } + + @Override + public void onPause() { + super.onPause(); + if (bridge != null) { + this.bridge.onPause(); + Logger.debug("App paused"); + } + } + + @Override + public void onStop() { + super.onStop(); + if (bridge != null) { + activityDepth = Math.max(0, activityDepth - 1); + if (activityDepth == 0) { + bridge.getApp().fireStatusChange(false); + } + + this.bridge.onStop(); + Logger.debug("App stopped"); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (this.bridge != null) { + this.bridge.onDestroy(); + Logger.debug("App destroyed"); + } + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (this.bridge != null) { + this.bridge.onDetachedFromWindow(); + } + } + + /** + * Handles permission request results. + * + * Capacitor is backwards compatible such that plugins using legacy permission request codes + * may coexist with plugins using the AndroidX Activity v1.2 permission callback flow introduced + * in Capacitor 3.0. + * + * In this method, plugins are checked first for ownership of the legacy permission request code. + * If the {@link Bridge#onRequestPermissionsResult(int, String[], int[])} method indicates it has + * handled the permission, then the permission callback will be considered complete. Otherwise, + * the permission will be handled using the AndroidX Activity flow. + * + * @param requestCode the request code associated with the permission request + * @param permissions the Android permission strings requested + * @param grantResults the status result of the permission request + */ + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (this.bridge == null) { + return; + } + + if (!bridge.onRequestPermissionsResult(requestCode, permissions, grantResults)) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + /** + * Handles activity results. + * + * Capacitor is backwards compatible such that plugins using legacy activity result codes + * may coexist with plugins using the AndroidX Activity v1.2 activity callback flow introduced + * in Capacitor 3.0. + * + * In this method, plugins are checked first for ownership of the legacy request code. If the + * {@link Bridge#onActivityResult(int, int, Intent)} method indicates it has handled the activity + * result, then the callback will be considered complete. Otherwise, the result will be handled + * using the AndroidX Activiy flow. + * + * @param requestCode the request code associated with the activity result + * @param resultCode the result code + * @param data any data included with the activity result + */ + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (this.bridge == null) { + return; + } + + if (!bridge.onActivityResult(requestCode, resultCode, data)) { + super.onActivityResult(requestCode, resultCode, data); + } + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + + if (this.bridge == null || intent == null) { + return; + } + + this.bridge.onNewIntent(intent); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + if (this.bridge == null) { + return; + } + + this.bridge.onConfigurationChanged(newConfig); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java new file mode 100644 index 0000000..6ca1c8a --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java @@ -0,0 +1,467 @@ +package com.getcapacitor; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.MediaStore; +import android.view.View; +import android.webkit.ConsoleMessage; +import android.webkit.GeolocationPermissions; +import android.webkit.JsPromptResult; +import android.webkit.JsResult; +import android.webkit.MimeTypeMap; +import android.webkit.PermissionRequest; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.widget.EditText; +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.core.content.FileProvider; +import com.getcapacitor.util.PermissionHelper; +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Custom WebChromeClient handler, required for showing dialogs, confirms, etc. in our + * WebView instance. + */ +public class BridgeWebChromeClient extends WebChromeClient { + + private interface PermissionListener { + void onPermissionSelect(Boolean isGranted); + } + + private interface ActivityResultListener { + void onActivityResult(ActivityResult result); + } + + private ActivityResultLauncher permissionLauncher; + private ActivityResultLauncher activityLauncher; + private PermissionListener permissionListener; + private ActivityResultListener activityListener; + + private Bridge bridge; + + public BridgeWebChromeClient(Bridge bridge) { + this.bridge = bridge; + + ActivityResultCallback> permissionCallback = (Map isGranted) -> { + if (permissionListener != null) { + boolean granted = true; + for (Map.Entry permission : isGranted.entrySet()) { + if (!permission.getValue()) granted = false; + } + permissionListener.onPermissionSelect(granted); + } + }; + + permissionLauncher = bridge.registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), permissionCallback); + activityLauncher = bridge.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), (result) -> { + if (activityListener != null) { + activityListener.onActivityResult(result); + } + }); + } + + /** + * Render web content in `view`. + * + * Both this method and {@link #onHideCustomView()} are required for + * rendering web content in full screen. + * + * @see onShowCustomView() docs + */ + @Override + public void onShowCustomView(View view, CustomViewCallback callback) { + callback.onCustomViewHidden(); + super.onShowCustomView(view, callback); + } + + /** + * Render web content in the original Web View again. + * + * Do not remove this method--@see #onShowCustomView(View, CustomViewCallback). + */ + @Override + public void onHideCustomView() { + super.onHideCustomView(); + } + + @Override + public void onPermissionRequest(final PermissionRequest request) { + List permissionList = new ArrayList<>(); + if (Arrays.asList(request.getResources()).contains("android.webkit.resource.VIDEO_CAPTURE")) { + permissionList.add(Manifest.permission.CAMERA); + } + if (Arrays.asList(request.getResources()).contains("android.webkit.resource.AUDIO_CAPTURE")) { + permissionList.add(Manifest.permission.MODIFY_AUDIO_SETTINGS); + permissionList.add(Manifest.permission.RECORD_AUDIO); + } + if (!permissionList.isEmpty()) { + String[] permissions = permissionList.toArray(new String[0]); + permissionListener = (isGranted) -> { + if (isGranted) { + request.grant(request.getResources()); + } else { + request.deny(); + } + }; + permissionLauncher.launch(permissions); + } else { + request.grant(request.getResources()); + } + } + + /** + * Show the browser alert modal + * @param view + * @param url + * @param message + * @param result + * @return + */ + @Override + public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { + if (bridge.getActivity().isFinishing()) { + return true; + } + + AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); + builder + .setMessage(message) + .setPositiveButton("OK", (dialog, buttonIndex) -> { + dialog.dismiss(); + result.confirm(); + }) + .setOnCancelListener((dialog) -> { + dialog.dismiss(); + result.cancel(); + }); + + AlertDialog dialog = builder.create(); + + dialog.show(); + + return true; + } + + /** + * Show the browser confirm modal + * @param view + * @param url + * @param message + * @param result + * @return + */ + @Override + public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { + if (bridge.getActivity().isFinishing()) { + return true; + } + + final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); + + builder + .setMessage(message) + .setPositiveButton("OK", (dialog, buttonIndex) -> { + dialog.dismiss(); + result.confirm(); + }) + .setNegativeButton("Cancel", (dialog, buttonIndex) -> { + dialog.dismiss(); + result.cancel(); + }) + .setOnCancelListener((dialog) -> { + dialog.dismiss(); + result.cancel(); + }); + + AlertDialog dialog = builder.create(); + + dialog.show(); + + return true; + } + + /** + * Show the browser prompt modal + * @param view + * @param url + * @param message + * @param defaultValue + * @param result + * @return + */ + @Override + public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { + if (bridge.getActivity().isFinishing()) { + return true; + } + + final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); + final EditText input = new EditText(view.getContext()); + + builder + .setMessage(message) + .setView(input) + .setPositiveButton("OK", (dialog, buttonIndex) -> { + dialog.dismiss(); + + String inputText1 = input.getText().toString().trim(); + result.confirm(inputText1); + }) + .setNegativeButton("Cancel", (dialog, buttonIndex) -> { + dialog.dismiss(); + result.cancel(); + }) + .setOnCancelListener((dialog) -> { + dialog.dismiss(); + result.cancel(); + }); + + AlertDialog dialog = builder.create(); + + dialog.show(); + + return true; + } + + /** + * Handle the browser geolocation permission prompt + * @param origin + * @param callback + */ + @Override + public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { + super.onGeolocationPermissionsShowPrompt(origin, callback); + Logger.debug("onGeolocationPermissionsShowPrompt: DOING IT HERE FOR ORIGIN: " + origin); + final String[] geoPermissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }; + + if (!PermissionHelper.hasPermissions(bridge.getContext(), geoPermissions)) { + permissionListener = (isGranted) -> { + if (isGranted) { + callback.invoke(origin, true, false); + } else { + final String[] coarsePermission = { Manifest.permission.ACCESS_COARSE_LOCATION }; + if ( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && + PermissionHelper.hasPermissions(bridge.getContext(), coarsePermission) + ) { + callback.invoke(origin, true, false); + } else { + callback.invoke(origin, false, false); + } + } + }; + permissionLauncher.launch(geoPermissions); + } else { + // permission is already granted + callback.invoke(origin, true, false); + Logger.debug("onGeolocationPermissionsShowPrompt: has required permission"); + } + } + + @Override + public boolean onShowFileChooser( + WebView webView, + final ValueCallback filePathCallback, + final FileChooserParams fileChooserParams + ) { + List acceptTypes = Arrays.asList(fileChooserParams.getAcceptTypes()); + boolean captureEnabled = fileChooserParams.isCaptureEnabled(); + boolean capturePhoto = captureEnabled && acceptTypes.contains("image/*"); + final boolean captureVideo = captureEnabled && acceptTypes.contains("video/*"); + if ((capturePhoto || captureVideo)) { + if (isMediaCaptureSupported()) { + showMediaCaptureOrFilePicker(filePathCallback, fileChooserParams, captureVideo); + } else { + permissionListener = (isGranted) -> { + if (isGranted) { + showMediaCaptureOrFilePicker(filePathCallback, fileChooserParams, captureVideo); + } else { + Logger.warn(Logger.tags("FileChooser"), "Camera permission not granted"); + filePathCallback.onReceiveValue(null); + } + }; + final String[] camPermission = { Manifest.permission.CAMERA }; + permissionLauncher.launch(camPermission); + } + } else { + showFilePicker(filePathCallback, fileChooserParams); + } + + return true; + } + + private boolean isMediaCaptureSupported() { + String[] permissions = { Manifest.permission.CAMERA }; + return ( + PermissionHelper.hasPermissions(bridge.getContext(), permissions) || + !PermissionHelper.hasDefinedPermission(bridge.getContext(), Manifest.permission.CAMERA) + ); + } + + private void showMediaCaptureOrFilePicker(ValueCallback filePathCallback, FileChooserParams fileChooserParams, boolean isVideo) { + boolean shown; + if (isVideo) { + shown = showVideoCapturePicker(filePathCallback); + } else { + shown = showImageCapturePicker(filePathCallback); + } + if (!shown) { + Logger.warn(Logger.tags("FileChooser"), "Media capture intent could not be launched. Falling back to default file picker."); + showFilePicker(filePathCallback, fileChooserParams); + } + } + + @SuppressLint("QueryPermissionsNeeded") + private boolean showImageCapturePicker(final ValueCallback filePathCallback) { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + if (takePictureIntent.resolveActivity(bridge.getActivity().getPackageManager()) == null) { + return false; + } + + final Uri imageFileUri; + try { + imageFileUri = createImageFileUri(); + } catch (Exception ex) { + Logger.error("Unable to create temporary media capture file: " + ex.getMessage()); + return false; + } + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri); + activityListener = (activityResult) -> { + Uri[] result = null; + if (activityResult.getResultCode() == Activity.RESULT_OK) { + result = new Uri[] { imageFileUri }; + } + filePathCallback.onReceiveValue(result); + }; + activityLauncher.launch(takePictureIntent); + + return true; + } + + @SuppressLint("QueryPermissionsNeeded") + private boolean showVideoCapturePicker(final ValueCallback filePathCallback) { + Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + if (takeVideoIntent.resolveActivity(bridge.getActivity().getPackageManager()) == null) { + return false; + } + + activityListener = (activityResult) -> { + Uri[] result = null; + if (activityResult.getResultCode() == Activity.RESULT_OK) { + result = new Uri[] { activityResult.getData().getData() }; + } + filePathCallback.onReceiveValue(result); + }; + activityLauncher.launch(takeVideoIntent); + + return true; + } + + private void showFilePicker(final ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + Intent intent = fileChooserParams.createIntent(); + if (fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE) { + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + } + if (fileChooserParams.getAcceptTypes().length > 1 || intent.getType().startsWith(".")) { + String[] validTypes = getValidTypes(fileChooserParams.getAcceptTypes()); + intent.putExtra(Intent.EXTRA_MIME_TYPES, validTypes); + if (intent.getType().startsWith(".")) { + intent.setType(validTypes[0]); + } + } + try { + activityListener = (activityResult) -> { + Uri[] result; + Intent resultIntent = activityResult.getData(); + if (activityResult.getResultCode() == Activity.RESULT_OK && resultIntent.getClipData() != null) { + final int numFiles = resultIntent.getClipData().getItemCount(); + result = new Uri[numFiles]; + for (int i = 0; i < numFiles; i++) { + result[i] = resultIntent.getClipData().getItemAt(i).getUri(); + } + } else { + result = WebChromeClient.FileChooserParams.parseResult(activityResult.getResultCode(), resultIntent); + } + filePathCallback.onReceiveValue(result); + }; + activityLauncher.launch(intent); + } catch (ActivityNotFoundException e) { + filePathCallback.onReceiveValue(null); + } + } + + private String[] getValidTypes(String[] currentTypes) { + List validTypes = new ArrayList<>(); + MimeTypeMap mtm = MimeTypeMap.getSingleton(); + for (String mime : currentTypes) { + if (mime.startsWith(".")) { + String extension = mime.substring(1); + String extensionMime = mtm.getMimeTypeFromExtension(extension); + if (extensionMime != null && !validTypes.contains(extensionMime)) { + validTypes.add(extensionMime); + } + } else if (!validTypes.contains(mime)) { + validTypes.add(mime); + } + } + Object[] validObj = validTypes.toArray(); + return Arrays.copyOf(validObj, validObj.length, String[].class); + } + + @Override + public boolean onConsoleMessage(ConsoleMessage consoleMessage) { + String tag = Logger.tags("Console"); + if (consoleMessage.message() != null && isValidMsg(consoleMessage.message())) { + String msg = String.format( + "File: %s - Line %d - Msg: %s", + consoleMessage.sourceId(), + consoleMessage.lineNumber(), + consoleMessage.message() + ); + String level = consoleMessage.messageLevel().name(); + if ("ERROR".equalsIgnoreCase(level)) { + Logger.error(tag, msg, null); + } else if ("WARNING".equalsIgnoreCase(level)) { + Logger.warn(tag, msg); + } else if ("TIP".equalsIgnoreCase(level)) { + Logger.debug(tag, msg); + } else { + Logger.info(tag, msg); + } + } + return true; + } + + public boolean isValidMsg(String msg) { + return !(msg.contains("%cresult %c") || (msg.contains("%cnative %c")) || msg.equalsIgnoreCase("console.groupEnd")); + } + + private Uri createImageFileUri() throws IOException { + Activity activity = bridge.getActivity(); + File photoFile = createImageFile(activity); + return FileProvider.getUriForFile(activity, bridge.getContext().getPackageName() + ".fileprovider", photoFile); + } + + private File createImageFile(Activity activity) throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES); + + return File.createTempFile(imageFileName, ".jpg", storageDir); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java new file mode 100644 index 0000000..f9df97b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java @@ -0,0 +1,117 @@ +package com.getcapacitor; + +import android.graphics.Bitmap; +import android.net.Uri; +import android.webkit.RenderProcessGoneDetail; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import java.util.List; + +public class BridgeWebViewClient extends WebViewClient { + + private Bridge bridge; + + public BridgeWebViewClient(Bridge bridge) { + this.bridge = bridge; + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { + return bridge.getLocalServer().shouldInterceptRequest(request); + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + Uri url = request.getUrl(); + return bridge.launchIntent(url); + } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + List webViewListeners = bridge.getWebViewListeners(); + + if (webViewListeners != null && view.getProgress() == 100) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + listener.onPageLoaded(view); + } + } + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + + List webViewListeners = bridge.getWebViewListeners(); + if (webViewListeners != null) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + listener.onReceivedError(view); + } + } + + String errorPath = bridge.getErrorUrl(); + if (errorPath != null && request.isForMainFrame()) { + view.loadUrl(errorPath); + } + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + bridge.reset(); + List webViewListeners = bridge.getWebViewListeners(); + + if (webViewListeners != null) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + listener.onPageStarted(view); + } + } + } + + @Override + public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { + super.onReceivedHttpError(view, request, errorResponse); + + List webViewListeners = bridge.getWebViewListeners(); + if (webViewListeners != null) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + listener.onReceivedHttpError(view); + } + } + + String errorPath = bridge.getErrorUrl(); + if (errorPath != null && request.isForMainFrame()) { + view.loadUrl(errorPath); + } + } + + @Override + public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) { + super.onRenderProcessGone(view, detail); + boolean result = false; + + List webViewListeners = bridge.getWebViewListeners(); + if (webViewListeners != null) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + result = listener.onRenderProcessGone(view, detail) || result; + } + } + + return result; + } + + @Override + public void onPageCommitVisible(WebView view, String url) { + super.onPageCommitVisible(view, url); + + List webViewListeners = bridge.getWebViewListeners(); + if (webViewListeners != null) { + for (WebViewListener listener : bridge.getWebViewListeners()) { + listener.onPageCommitVisible(view, url); + } + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapConfig.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapConfig.java new file mode 100644 index 0000000..b20799b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapConfig.java @@ -0,0 +1,709 @@ +package com.getcapacitor; + +import static com.getcapacitor.Bridge.CAPACITOR_HTTPS_SCHEME; +import static com.getcapacitor.Bridge.DEFAULT_ANDROID_WEBVIEW_VERSION; +import static com.getcapacitor.Bridge.DEFAULT_HUAWEI_WEBVIEW_VERSION; +import static com.getcapacitor.Bridge.MINIMUM_ANDROID_WEBVIEW_VERSION; +import static com.getcapacitor.Bridge.MINIMUM_HUAWEI_WEBVIEW_VERSION; +import static com.getcapacitor.FileUtils.readFileFromAssets; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.res.AssetManager; +import androidx.annotation.Nullable; +import com.getcapacitor.util.JSONUtils; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Represents the configuration options for Capacitor + */ +public class CapConfig { + + private static final String LOG_BEHAVIOR_NONE = "none"; + private static final String LOG_BEHAVIOR_DEBUG = "debug"; + private static final String LOG_BEHAVIOR_PRODUCTION = "production"; + + // Server Config + private boolean html5mode = true; + private String serverUrl; + private String hostname = "localhost"; + private String androidScheme = CAPACITOR_HTTPS_SCHEME; + private String[] allowNavigation; + + // Android Config + private String overriddenUserAgentString; + private String appendedUserAgentString; + private String backgroundColor; + private boolean allowMixedContent = false; + private boolean captureInput = false; + private boolean webContentsDebuggingEnabled = false; + private boolean loggingEnabled = true; + private boolean initialFocus = true; + private boolean useLegacyBridge = false; + private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION; + private int minHuaweiWebViewVersion = DEFAULT_HUAWEI_WEBVIEW_VERSION; + private String errorPath; + private boolean zoomableWebView = false; + private boolean resolveServiceWorkerRequests = true; + + // Embedded + private String startPath; + + // Plugins + private Map pluginsConfiguration = null; + + // Config Object JSON (legacy) + private JSONObject configJSON = new JSONObject(); + + /** + * Constructs an empty config file. + */ + private CapConfig() {} + + /** + * Get an instance of the Config file object. + * @deprecated use {@link #loadDefault(Context)} to load an instance of the Config object + * from the capacitor.config.json file, or use the {@link CapConfig.Builder} to construct + * a CapConfig for embedded use. + * + * @param assetManager The AssetManager used to load the config file + * @param config JSON describing a configuration to use + */ + @Deprecated + public CapConfig(AssetManager assetManager, JSONObject config) { + if (config != null) { + this.configJSON = config; + } else { + // Load the capacitor.config.json + loadConfigFromAssets(assetManager, null); + } + + deserializeConfig(null); + } + + /** + * Constructs a Capacitor Configuration from config.json file. + * + * @param context The context. + * @return A loaded config file, if successful. + */ + public static CapConfig loadDefault(Context context) { + CapConfig config = new CapConfig(); + + if (context == null) { + Logger.error("Capacitor Config could not be created from file. Context must not be null."); + return config; + } + + config.loadConfigFromAssets(context.getAssets(), null); + config.deserializeConfig(context); + return config; + } + + /** + * Constructs a Capacitor Configuration from config.json file within the app assets. + * + * @param context The context. + * @param path A path relative to the root assets directory. + * @return A loaded config file, if successful. + */ + public static CapConfig loadFromAssets(Context context, String path) { + CapConfig config = new CapConfig(); + + if (context == null) { + Logger.error("Capacitor Config could not be created from file. Context must not be null."); + return config; + } + + config.loadConfigFromAssets(context.getAssets(), path); + config.deserializeConfig(context); + return config; + } + + /** + * Constructs a Capacitor Configuration from config.json file within the app file-space. + * + * @param context The context. + * @param path A path relative to the root of the app file-space. + * @return A loaded config file, if successful. + */ + public static CapConfig loadFromFile(Context context, String path) { + CapConfig config = new CapConfig(); + + if (context == null) { + Logger.error("Capacitor Config could not be created from file. Context must not be null."); + return config; + } + + config.loadConfigFromFile(path); + config.deserializeConfig(context); + return config; + } + + /** + * Constructs a Capacitor Configuration using ConfigBuilder. + * + * @param builder A config builder initialized with values + */ + private CapConfig(Builder builder) { + // Server Config + this.html5mode = builder.html5mode; + this.serverUrl = builder.serverUrl; + this.hostname = builder.hostname; + + if (this.validateScheme(builder.androidScheme)) { + this.androidScheme = builder.androidScheme; + } + + this.allowNavigation = builder.allowNavigation; + + // Android Config + this.overriddenUserAgentString = builder.overriddenUserAgentString; + this.appendedUserAgentString = builder.appendedUserAgentString; + this.backgroundColor = builder.backgroundColor; + this.allowMixedContent = builder.allowMixedContent; + this.captureInput = builder.captureInput; + this.webContentsDebuggingEnabled = builder.webContentsDebuggingEnabled; + this.loggingEnabled = builder.loggingEnabled; + this.initialFocus = builder.initialFocus; + this.useLegacyBridge = builder.useLegacyBridge; + this.minWebViewVersion = builder.minWebViewVersion; + this.minHuaweiWebViewVersion = builder.minHuaweiWebViewVersion; + this.errorPath = builder.errorPath; + this.zoomableWebView = builder.zoomableWebView; + this.resolveServiceWorkerRequests = builder.resolveServiceWorkerRequests; + + // Embedded + this.startPath = builder.startPath; + + // Plugins Config + this.pluginsConfiguration = builder.pluginsConfiguration; + } + + /** + * Loads a Capacitor Configuration JSON file into a Capacitor Configuration object. + * An optional path string can be provided to look for the config in a subdirectory path. + */ + private void loadConfigFromAssets(AssetManager assetManager, String path) { + if (path == null) { + path = ""; + } else { + // Add slash at the end to form a proper file path if going deeper in assets dir + if (path.charAt(path.length() - 1) != '/') { + path = path + "/"; + } + } + + try { + String jsonString = readFileFromAssets(assetManager, path + "capacitor.config.json"); + configJSON = new JSONObject(jsonString); + } catch (IOException ex) { + Logger.error("Unable to load capacitor.config.json. Run npx cap copy first", ex); + } catch (JSONException ex) { + Logger.error("Unable to parse capacitor.config.json. Make sure it's valid json", ex); + } + } + + /** + * Loads a Capacitor Configuration JSON file into a Capacitor Configuration object. + * An optional path string can be provided to look for the config in a subdirectory path. + */ + private void loadConfigFromFile(String path) { + if (path == null) { + path = ""; + } else { + // Add slash at the end to form a proper file path if going deeper in assets dir + if (path.charAt(path.length() - 1) != '/') { + path = path + "/"; + } + } + + try { + File configFile = new File(path + "capacitor.config.json"); + String jsonString = FileUtils.readFileFromDisk(configFile); + configJSON = new JSONObject(jsonString); + } catch (JSONException ex) { + Logger.error("Unable to parse capacitor.config.json. Make sure it's valid json", ex); + } catch (IOException ex) { + Logger.error("Unable to load capacitor.config.json.", ex); + } + } + + /** + * Deserializes the config from JSON into a Capacitor Configuration object. + */ + private void deserializeConfig(@Nullable Context context) { + boolean isDebug = context != null && (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + + // Server + html5mode = JSONUtils.getBoolean(configJSON, "server.html5mode", html5mode); + serverUrl = JSONUtils.getString(configJSON, "server.url", null); + hostname = JSONUtils.getString(configJSON, "server.hostname", hostname); + errorPath = JSONUtils.getString(configJSON, "server.errorPath", null); + startPath = JSONUtils.getString(configJSON, "server.appStartPath", null); + + String configSchema = JSONUtils.getString(configJSON, "server.androidScheme", androidScheme); + if (this.validateScheme(configSchema)) { + androidScheme = configSchema; + } + + allowNavigation = JSONUtils.getArray(configJSON, "server.allowNavigation", null); + + // Android + overriddenUserAgentString = JSONUtils.getString( + configJSON, + "android.overrideUserAgent", + JSONUtils.getString(configJSON, "overrideUserAgent", null) + ); + appendedUserAgentString = JSONUtils.getString( + configJSON, + "android.appendUserAgent", + JSONUtils.getString(configJSON, "appendUserAgent", null) + ); + backgroundColor = JSONUtils.getString( + configJSON, + "android.backgroundColor", + JSONUtils.getString(configJSON, "backgroundColor", null) + ); + allowMixedContent = JSONUtils.getBoolean( + configJSON, + "android.allowMixedContent", + JSONUtils.getBoolean(configJSON, "allowMixedContent", allowMixedContent) + ); + minWebViewVersion = JSONUtils.getInt(configJSON, "android.minWebViewVersion", DEFAULT_ANDROID_WEBVIEW_VERSION); + minHuaweiWebViewVersion = JSONUtils.getInt(configJSON, "android.minHuaweiWebViewVersion", DEFAULT_HUAWEI_WEBVIEW_VERSION); + captureInput = JSONUtils.getBoolean(configJSON, "android.captureInput", captureInput); + useLegacyBridge = JSONUtils.getBoolean(configJSON, "android.useLegacyBridge", useLegacyBridge); + webContentsDebuggingEnabled = JSONUtils.getBoolean(configJSON, "android.webContentsDebuggingEnabled", isDebug); + zoomableWebView = JSONUtils.getBoolean(configJSON, "android.zoomEnabled", JSONUtils.getBoolean(configJSON, "zoomEnabled", false)); + resolveServiceWorkerRequests = JSONUtils.getBoolean(configJSON, "android.resolveServiceWorkerRequests", true); + + String logBehavior = JSONUtils.getString( + configJSON, + "android.loggingBehavior", + JSONUtils.getString(configJSON, "loggingBehavior", LOG_BEHAVIOR_DEBUG) + ); + switch (logBehavior.toLowerCase(Locale.ROOT)) { + case LOG_BEHAVIOR_PRODUCTION: + loggingEnabled = true; + break; + case LOG_BEHAVIOR_NONE: + loggingEnabled = false; + break; + default: // LOG_BEHAVIOR_DEBUG + loggingEnabled = isDebug; + } + + initialFocus = JSONUtils.getBoolean( + configJSON, + "android.initialFocus", + JSONUtils.getBoolean(configJSON, "initialFocus", initialFocus) + ); + + // Plugins + pluginsConfiguration = deserializePluginsConfig(JSONUtils.getObject(configJSON, "plugins")); + } + + private boolean validateScheme(String scheme) { + List invalidSchemes = Arrays.asList("file", "ftp", "ftps", "ws", "wss", "about", "blob", "data"); + if (invalidSchemes.contains(scheme)) { + Logger.warn(scheme + " is not an allowed scheme. Defaulting to https."); + return false; + } + + // Non-http(s) schemes are not allowed to modify the URL path as of Android Webview 117 + if (!scheme.equals("http") && !scheme.equals("https")) { + Logger.warn( + "Using a non-standard scheme: " + scheme + " for Android. This is known to cause issues as of Android Webview 117." + ); + } + + return true; + } + + public boolean isHTML5Mode() { + return html5mode; + } + + public String getServerUrl() { + return serverUrl; + } + + public String getErrorPath() { + return errorPath; + } + + public String getHostname() { + return hostname; + } + + public String getStartPath() { + return startPath; + } + + public String getAndroidScheme() { + return androidScheme; + } + + public String[] getAllowNavigation() { + return allowNavigation; + } + + public String getOverriddenUserAgentString() { + return overriddenUserAgentString; + } + + public String getAppendedUserAgentString() { + return appendedUserAgentString; + } + + public String getBackgroundColor() { + return backgroundColor; + } + + public boolean isMixedContentAllowed() { + return allowMixedContent; + } + + public boolean isInputCaptured() { + return captureInput; + } + + public boolean isResolveServiceWorkerRequests() { + return resolveServiceWorkerRequests; + } + + public boolean isWebContentsDebuggingEnabled() { + return webContentsDebuggingEnabled; + } + + public boolean isZoomableWebView() { + return zoomableWebView; + } + + public boolean isLoggingEnabled() { + return loggingEnabled; + } + + public boolean isInitialFocus() { + return initialFocus; + } + + public boolean isUsingLegacyBridge() { + return useLegacyBridge; + } + + public int getMinWebViewVersion() { + if (minWebViewVersion < MINIMUM_ANDROID_WEBVIEW_VERSION) { + Logger.warn("Specified minimum webview version is too low, defaulting to " + MINIMUM_ANDROID_WEBVIEW_VERSION); + return MINIMUM_ANDROID_WEBVIEW_VERSION; + } + + return minWebViewVersion; + } + + public int getMinHuaweiWebViewVersion() { + if (minHuaweiWebViewVersion < MINIMUM_HUAWEI_WEBVIEW_VERSION) { + Logger.warn("Specified minimum Huawei webview version is too low, defaulting to " + MINIMUM_HUAWEI_WEBVIEW_VERSION); + return MINIMUM_HUAWEI_WEBVIEW_VERSION; + } + + return minHuaweiWebViewVersion; + } + + public PluginConfig getPluginConfiguration(String pluginId) { + PluginConfig pluginConfig = pluginsConfiguration.get(pluginId); + if (pluginConfig == null) { + pluginConfig = new PluginConfig(new JSONObject()); + } + + return pluginConfig; + } + + /** + * Get a JSON object value from the Capacitor config. + * @deprecated use {@link PluginConfig#getObject(String)} to access plugin config values. + * For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @return The value from the config, if exists. Null if not + */ + @Deprecated + public JSONObject getObject(String key) { + try { + return configJSON.getJSONObject(key); + } catch (Exception ex) {} + return null; + } + + /** + * Get a string value from the Capacitor config. + * @deprecated use {@link PluginConfig#getString(String, String)} to access plugin config + * values. For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @return The value from the config, if exists. Null if not + */ + @Deprecated + public String getString(String key) { + return JSONUtils.getString(configJSON, key, null); + } + + /** + * Get a string value from the Capacitor config. + * @deprecated use {@link PluginConfig#getString(String, String)} to access plugin config + * values. For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + @Deprecated + public String getString(String key, String defaultValue) { + return JSONUtils.getString(configJSON, key, defaultValue); + } + + /** + * Get a boolean value from the Capacitor config. + * @deprecated use {@link PluginConfig#getBoolean(String, boolean)} to access plugin config + * values. For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + @Deprecated + public boolean getBoolean(String key, boolean defaultValue) { + return JSONUtils.getBoolean(configJSON, key, defaultValue); + } + + /** + * Get an integer value from the Capacitor config. + * @deprecated use {@link PluginConfig#getInt(String, int)} to access the plugin config + * values. For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + @Deprecated + public int getInt(String key, int defaultValue) { + return JSONUtils.getInt(configJSON, key, defaultValue); + } + + /** + * Get a string array value from the Capacitor config. + * @deprecated use {@link PluginConfig#getArray(String)} to access the plugin config + * values. For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @return The value from the config, if exists. Null if not + */ + @Deprecated + public String[] getArray(String key) { + return JSONUtils.getArray(configJSON, key, null); + } + + /** + * Get a string array value from the Capacitor config. + * @deprecated use {@link PluginConfig#getArray(String, String[])} to access the plugin + * config values. For main Capacitor config values, use the appropriate getter. + * + * @param key A key to fetch from the config + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + @Deprecated + public String[] getArray(String key, String[] defaultValue) { + return JSONUtils.getArray(configJSON, key, defaultValue); + } + + private static Map deserializePluginsConfig(JSONObject pluginsConfig) { + Map pluginsMap = new HashMap<>(); + + // return an empty map if there is no pluginsConfig json + if (pluginsConfig == null) { + return pluginsMap; + } + + Iterator pluginIds = pluginsConfig.keys(); + + while (pluginIds.hasNext()) { + String pluginId = pluginIds.next(); + JSONObject value = null; + + try { + value = pluginsConfig.getJSONObject(pluginId); + PluginConfig pluginConfig = new PluginConfig(value); + pluginsMap.put(pluginId, pluginConfig); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + return pluginsMap; + } + + /** + * Builds a Capacitor Configuration in code + */ + public static class Builder { + + private Context context; + + // Server Config Values + private boolean html5mode = true; + private String serverUrl; + private String errorPath; + private String hostname = "localhost"; + private String androidScheme = CAPACITOR_HTTPS_SCHEME; + private String[] allowNavigation; + + // Android Config Values + private String overriddenUserAgentString; + private String appendedUserAgentString; + private String backgroundColor; + private boolean allowMixedContent = false; + private boolean captureInput = false; + private Boolean webContentsDebuggingEnabled = null; + private boolean loggingEnabled = true; + private boolean initialFocus = false; + private boolean useLegacyBridge = false; + private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION; + private int minHuaweiWebViewVersion = DEFAULT_HUAWEI_WEBVIEW_VERSION; + private boolean zoomableWebView = false; + private boolean resolveServiceWorkerRequests = true; + + // Embedded + private String startPath = null; + + // Plugins Config Object + private Map pluginsConfiguration = new HashMap<>(); + + /** + * Constructs a new CapConfig Builder. + * + * @param context The context + */ + public Builder(Context context) { + this.context = context; + } + + /** + * Builds a Capacitor Config from the builder. + * + * @return A new Capacitor Config + */ + public CapConfig create() { + if (webContentsDebuggingEnabled == null) { + webContentsDebuggingEnabled = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } + + return new CapConfig(this); + } + + public Builder setPluginsConfiguration(JSONObject pluginsConfiguration) { + this.pluginsConfiguration = deserializePluginsConfig(pluginsConfiguration); + return this; + } + + public Builder setHTML5mode(boolean html5mode) { + this.html5mode = html5mode; + return this; + } + + public Builder setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + return this; + } + + public Builder setErrorPath(String errorPath) { + this.errorPath = errorPath; + return this; + } + + public Builder setHostname(String hostname) { + this.hostname = hostname; + return this; + } + + public Builder setStartPath(String path) { + this.startPath = path; + return this; + } + + public Builder setAndroidScheme(String androidScheme) { + this.androidScheme = androidScheme; + return this; + } + + public Builder setAllowNavigation(String[] allowNavigation) { + this.allowNavigation = allowNavigation; + return this; + } + + public Builder setOverriddenUserAgentString(String overriddenUserAgentString) { + this.overriddenUserAgentString = overriddenUserAgentString; + return this; + } + + public Builder setAppendedUserAgentString(String appendedUserAgentString) { + this.appendedUserAgentString = appendedUserAgentString; + return this; + } + + public Builder setBackgroundColor(String backgroundColor) { + this.backgroundColor = backgroundColor; + return this; + } + + public Builder setAllowMixedContent(boolean allowMixedContent) { + this.allowMixedContent = allowMixedContent; + return this; + } + + public Builder setCaptureInput(boolean captureInput) { + this.captureInput = captureInput; + return this; + } + + public Builder setUseLegacyBridge(boolean useLegacyBridge) { + this.useLegacyBridge = useLegacyBridge; + return this; + } + + public Builder setResolveServiceWorkerRequests(boolean resolveServiceWorkerRequests) { + this.resolveServiceWorkerRequests = resolveServiceWorkerRequests; + return this; + } + + public Builder setWebContentsDebuggingEnabled(boolean webContentsDebuggingEnabled) { + this.webContentsDebuggingEnabled = webContentsDebuggingEnabled; + return this; + } + + public Builder setZoomableWebView(boolean zoomableWebView) { + this.zoomableWebView = zoomableWebView; + return this; + } + + public Builder setLoggingEnabled(boolean enabled) { + this.loggingEnabled = enabled; + return this; + } + + public Builder setInitialFocus(boolean focus) { + this.initialFocus = focus; + return this; + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java new file mode 100644 index 0000000..22f6f97 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java @@ -0,0 +1,57 @@ +package com.getcapacitor; + +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.KeyEvent; +import android.view.inputmethod.BaseInputConnection; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.webkit.WebView; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +public class CapacitorWebView extends WebView { + + private BaseInputConnection capInputConnection; + private Bridge bridge; + + public CapacitorWebView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setBridge(Bridge bridge) { + this.bridge = bridge; + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + CapConfig config; + if (bridge != null) { + config = bridge.getConfig(); + } else { + config = CapConfig.loadDefault(getContext()); + } + + boolean captureInput = config.isInputCaptured(); + if (captureInput) { + if (capInputConnection == null) { + capInputConnection = new BaseInputConnection(this, false); + } + return capInputConnection; + } + return super.onCreateInputConnection(outAttrs); + } + + @Override + @SuppressWarnings("deprecation") + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_MULTIPLE) { + evaluateJavascript("document.activeElement.value = document.activeElement.value + '" + event.getCharacters() + "';", null); + return false; + } + return super.dispatchKeyEvent(event); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java new file mode 100644 index 0000000..ce09e7c --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java @@ -0,0 +1,303 @@ +/** + * Portions adopted from react-native-image-crop-picker + * + * MIT License + + * Copyright (c) 2017 Ivan Pusic + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.getcapacitor; + +import android.content.ContentUris; +import android.content.Context; +import android.content.res.AssetManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.provider.OpenableColumns; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * Common File utilities, such as resolve content URIs and + * creating portable web paths from low-level files + */ +public class FileUtils { + + private static String CapacitorFileScheme = Bridge.CAPACITOR_FILE_START; + + public enum Type { + IMAGE("image"); + + private String type; + + Type(String type) { + this.type = type; + } + } + + public static String getPortablePath(Context c, String host, Uri u) { + String path = getFileUrlForUri(c, u); + if (path.startsWith("file://")) { + path = path.replace("file://", ""); + } + return host + Bridge.CAPACITOR_FILE_START + path; + } + + public static String getFileUrlForUri(final Context context, final Uri uri) { + // DocumentProvider + if (DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return legacyPrimaryPath(split[1]); + } else { + final int splitIndex = docId.indexOf(':', 1); + final String tag = docId.substring(0, splitIndex); + final String path = docId.substring(splitIndex + 1); + + String nonPrimaryVolume = getPathToNonPrimaryVolume(context, tag); + if (nonPrimaryVolume != null) { + String result = nonPrimaryVolume + "/" + path; + File file = new File(result); + if (file.exists() && file.canRead()) { + return result; + } + return null; + } + } + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[] { split[1] }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + // Return the remote address + if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + @SuppressWarnings("deprecation") + private static String legacyPrimaryPath(String pathPart) { + return Environment.getExternalStorageDirectory() + "/" + pathPart; + } + + /** + * Read a plaintext file from the assets directory. + * + * @param assetManager Used to open the file. + * @param fileName The path of the file to read. + * @return The contents of the file path. + * @throws IOException Thrown if any issues reading the provided file path. + */ + static String readFileFromAssets(AssetManager assetManager, String fileName) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(assetManager.open(fileName)))) { + StringBuilder buffer = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + buffer.append(line).append("\n"); + } + + return buffer.toString(); + } + } + + /** + * Read a plaintext file from within the app disk space. + * + * @param file The file to read. + * @return The contents of the file path. + * @throws IOException Thrown if any issues reading the provided file path. + */ + static String readFileFromDisk(File file) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + StringBuilder buffer = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + buffer.append(line).append("\n"); + } + + return buffer.toString(); + } + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + String path = null; + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { column }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + final int index = cursor.getColumnIndexOrThrow(column); + path = cursor.getString(index); + } + } catch (IllegalArgumentException ex) { + return getCopyFilePath(uri, context); + } finally { + if (cursor != null) cursor.close(); + } + if (path == null) { + return getCopyFilePath(uri, context); + } + return path; + } + + private static String getCopyFilePath(Uri uri, Context context) { + Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); + int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + cursor.moveToFirst(); + String name = (cursor.getString(nameIndex)); + String fileName = sanitizeFilename(name); + File file = new File(context.getFilesDir(), fileName); + try { + InputStream inputStream = context.getContentResolver().openInputStream(uri); + FileOutputStream outputStream = new FileOutputStream(file); + int read = 0; + int maxBufferSize = 1024 * 1024; + int bufferSize = Math.min(inputStream.available(), maxBufferSize); + final byte[] buffers = new byte[bufferSize]; + while ((read = inputStream.read(buffers)) != -1) { + outputStream.write(buffers, 0, read); + } + inputStream.close(); + outputStream.close(); + } catch (Exception e) { + return null; + } finally { + if (cursor != null) cursor.close(); + } + return file.getPath(); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Photos. + */ + private static boolean isGooglePhotosUri(Uri uri) { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); + } + + private static String getPathToNonPrimaryVolume(Context context, String tag) { + File[] volumes = context.getExternalCacheDirs(); + if (volumes != null) { + for (File volume : volumes) { + if (volume != null) { + String path = volume.getAbsolutePath(); + if (path != null) { + int index = path.indexOf(tag); + if (index != -1) { + return path.substring(0, index) + tag; + } + } + } + } + } + return null; + } + + private static String sanitizeFilename(String displayName) { + String[] badCharacters = new String[] { "..", "/" }; + String[] segments = displayName.split("/"); + String fileName = segments[segments.length - 1]; + for (String suspString : badCharacters) { + fileName = fileName.replace(suspString, "_"); + } + return fileName; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginException.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginException.java new file mode 100644 index 0000000..1757e32 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginException.java @@ -0,0 +1,8 @@ +package com.getcapacitor; + +class InvalidPluginException extends Exception { + + public InvalidPluginException(String s) { + super(s); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginMethodException.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginMethodException.java new file mode 100644 index 0000000..94be491 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/InvalidPluginMethodException.java @@ -0,0 +1,16 @@ +package com.getcapacitor; + +class InvalidPluginMethodException extends Exception { + + public InvalidPluginMethodException(String s) { + super(s); + } + + public InvalidPluginMethodException(Throwable t) { + super(t); + } + + public InvalidPluginMethodException(String s, Throwable t) { + super(s, t); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSArray.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSArray.java new file mode 100644 index 0000000..06b7f4d --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSArray.java @@ -0,0 +1,51 @@ +package com.getcapacitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; + +public class JSArray extends JSONArray { + + public JSArray() { + super(); + } + + public JSArray(String json) throws JSONException { + super(json); + } + + public JSArray(Collection copyFrom) { + super(copyFrom); + } + + public JSArray(Object array) throws JSONException { + super(array); + } + + @SuppressWarnings("unchecked") + public List toList() throws JSONException { + List items = new ArrayList<>(); + Object o = null; + for (int i = 0; i < this.length(); i++) { + o = this.get(i); + try { + items.add((E) this.get(i)); + } catch (Exception ex) { + throw new JSONException("Not all items are instances of the given type"); + } + } + return items; + } + + /** + * Create a new JSArray without throwing a error + */ + public static JSArray from(Object array) { + try { + return new JSArray(array); + } catch (JSONException ex) {} + return null; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExport.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExport.java new file mode 100644 index 0000000..2083c2c --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExport.java @@ -0,0 +1,208 @@ +package com.getcapacitor; + +import static com.getcapacitor.FileUtils.readFileFromAssets; + +import android.content.Context; +import android.text.TextUtils; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class JSExport { + + private static String CATCHALL_OPTIONS_PARAM = "_options"; + private static String CALLBACK_PARAM = "_callback"; + + public static String getGlobalJS(Context context, boolean loggingEnabled, boolean isDebug) { + return "window.Capacitor = { DEBUG: " + isDebug + ", isLoggingEnabled: " + loggingEnabled + ", Plugins: {} };"; + } + + public static String getMiscFileJS(ArrayList paths, Context context) { + List lines = new ArrayList<>(); + + for (String path : paths) { + try { + String fileContent = readFileFromAssets(context.getAssets(), "public/" + path); + lines.add(fileContent); + } catch (IOException ex) { + Logger.error("Unable to read public/" + path); + } + } + + return TextUtils.join("\n", lines); + } + + public static String getCordovaJS(Context context) { + String fileContent = ""; + try { + fileContent = readFileFromAssets(context.getAssets(), "public/cordova.js"); + } catch (IOException ex) { + Logger.error("Unable to read public/cordova.js file, Cordova plugins will not work"); + } + return fileContent; + } + + public static String getCordovaPluginsFileJS(Context context) { + String fileContent = ""; + try { + fileContent = readFileFromAssets(context.getAssets(), "public/cordova_plugins.js"); + } catch (IOException ex) { + Logger.error("Unable to read public/cordova_plugins.js file, Cordova plugins will not work"); + } + return fileContent; + } + + public static String getPluginJS(Collection plugins) { + List lines = new ArrayList<>(); + JSONArray pluginArray = new JSONArray(); + + lines.add("// Begin: Capacitor Plugin JS"); + for (PluginHandle plugin : plugins) { + lines.add( + "(function(w) {\n" + + "var a = (w.Capacitor = w.Capacitor || {});\n" + + "var p = (a.Plugins = a.Plugins || {});\n" + + "var t = (p['" + + plugin.getId() + + "'] = {});\n" + + "t.addListener = function(eventName, callback) {\n" + + " return w.Capacitor.addListener('" + + plugin.getId() + + "', eventName, callback);\n" + + "}" + ); + Collection methods = plugin.getMethods(); + for (PluginMethodHandle method : methods) { + if (method.getName().equals("addListener") || method.getName().equals("removeListener")) { + // Don't export add/remove listener, we do that automatically above as they are "special snowflakes" + continue; + } + lines.add(generateMethodJS(plugin, method)); + } + + lines.add("})(window);\n"); + pluginArray.put(createPluginHeader(plugin)); + } + + return TextUtils.join("\n", lines) + "\nwindow.Capacitor.PluginHeaders = " + pluginArray.toString() + ";"; + } + + public static String getCordovaPluginJS(Context context) { + return getFilesContent(context, "public/plugins"); + } + + public static String getFilesContent(Context context, String path) { + StringBuilder builder = new StringBuilder(); + try { + String[] content = context.getAssets().list(path); + if (content.length > 0) { + for (String file : content) { + if (!file.endsWith(".map")) { + builder.append(getFilesContent(context, path + "/" + file)); + } + } + } else { + return readFileFromAssets(context.getAssets(), path); + } + } catch (IOException ex) { + Logger.warn("Unable to read file at path " + path); + } + return builder.toString(); + } + + private static JSONObject createPluginHeader(PluginHandle plugin) { + JSONObject pluginObj = new JSONObject(); + Collection methods = plugin.getMethods(); + try { + String id = plugin.getId(); + JSONArray methodArray = new JSONArray(); + pluginObj.put("name", id); + + for (PluginMethodHandle method : methods) { + methodArray.put(createPluginMethodHeader(method)); + } + + pluginObj.put("methods", methodArray); + } catch (JSONException e) { + // ignore + } + return pluginObj; + } + + private static JSONObject createPluginMethodHeader(PluginMethodHandle method) { + JSONObject methodObj = new JSONObject(); + + try { + methodObj.put("name", method.getName()); + if (!method.getReturnType().equals(PluginMethod.RETURN_NONE)) { + methodObj.put("rtype", method.getReturnType()); + } + } catch (JSONException e) { + // ignore + } + + return methodObj; + } + + public static String getBridgeJS(Context context) throws JSExportException { + return getFilesContent(context, "native-bridge.js"); + } + + private static String generateMethodJS(PluginHandle plugin, PluginMethodHandle method) { + List lines = new ArrayList<>(); + + List args = new ArrayList<>(); + // Add the catch all param that will take a full javascript object to pass to the plugin + args.add(CATCHALL_OPTIONS_PARAM); + + String returnType = method.getReturnType(); + if (returnType.equals(PluginMethod.RETURN_CALLBACK)) { + args.add(CALLBACK_PARAM); + } + + // Create the method function declaration + lines.add("t['" + method.getName() + "'] = function(" + TextUtils.join(", ", args) + ") {"); + + switch (returnType) { + case PluginMethod.RETURN_NONE: + lines.add( + "return w.Capacitor.nativeCallback('" + + plugin.getId() + + "', '" + + method.getName() + + "', " + + CATCHALL_OPTIONS_PARAM + + ")" + ); + break; + case PluginMethod.RETURN_PROMISE: + lines.add( + "return w.Capacitor.nativePromise('" + plugin.getId() + "', '" + method.getName() + "', " + CATCHALL_OPTIONS_PARAM + ")" + ); + break; + case PluginMethod.RETURN_CALLBACK: + lines.add( + "return w.Capacitor.nativeCallback('" + + plugin.getId() + + "', '" + + method.getName() + + "', " + + CATCHALL_OPTIONS_PARAM + + ", " + + CALLBACK_PARAM + + ")" + ); + break; + default: + // TODO: Do something here? + } + + lines.add("}"); + + return TextUtils.join("\n", lines); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExportException.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExportException.java new file mode 100644 index 0000000..14b6043 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSExportException.java @@ -0,0 +1,16 @@ +package com.getcapacitor; + +public class JSExportException extends Exception { + + public JSExportException(String s) { + super(s); + } + + public JSExportException(Throwable t) { + super(t); + } + + public JSExportException(String s, Throwable t) { + super(s, t); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSInjector.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSInjector.java new file mode 100644 index 0000000..1ee6aa1 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSInjector.java @@ -0,0 +1,127 @@ +package com.getcapacitor; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; + +/** + * JSInject is responsible for returning Capacitor's core + * runtime JS and any plugin JS back into HTML page responses + * to the client. + */ +class JSInjector { + + private String globalJS; + private String bridgeJS; + private String pluginJS; + private String cordovaJS; + private String cordovaPluginsJS; + private String cordovaPluginsFileJS; + private String localUrlJS; + private String miscJS; + + public JSInjector( + String globalJS, + String bridgeJS, + String pluginJS, + String cordovaJS, + String cordovaPluginsJS, + String cordovaPluginsFileJS, + String localUrlJS + ) { + this(globalJS, bridgeJS, pluginJS, cordovaJS, cordovaPluginsJS, cordovaPluginsFileJS, localUrlJS, null); + } + + public JSInjector( + String globalJS, + String bridgeJS, + String pluginJS, + String cordovaJS, + String cordovaPluginsJS, + String cordovaPluginsFileJS, + String localUrlJS, + String miscJS + ) { + this.globalJS = globalJS; + this.bridgeJS = bridgeJS; + this.pluginJS = pluginJS; + this.cordovaJS = cordovaJS; + this.cordovaPluginsJS = cordovaPluginsJS; + this.cordovaPluginsFileJS = cordovaPluginsFileJS; + this.localUrlJS = localUrlJS; + this.miscJS = miscJS; + } + + /** + * Generates injectable JS content. + * This may be used in other forms of injecting that aren't using an InputStream. + * @return + */ + public String getScriptString() { + String scriptString = + globalJS + + "\n\n" + + localUrlJS + + "\n\n" + + bridgeJS + + "\n\n" + + pluginJS + + "\n\n" + + cordovaJS + + "\n\n" + + cordovaPluginsFileJS + + "\n\n" + + cordovaPluginsJS; + + if (miscJS != null) { + scriptString += "\n\n" + miscJS; + } + + return scriptString; + } + + /** + * Given an InputStream from the web server, prepend it with + * our JS stream + * @param responseStream + * @return + */ + public InputStream getInjectedStream(InputStream responseStream) { + String js = ""; + String html = this.readAssetStream(responseStream); + + // Insert the js string at the position after or before using StringBuilder + StringBuilder modifiedHtml = new StringBuilder(html); + if (html.contains("")) { + modifiedHtml.insert(html.indexOf("") + "".length(), "\n" + js + "\n"); + html = modifiedHtml.toString(); + } else if (html.contains("")) { + modifiedHtml.insert(html.indexOf(""), "\n" + js + "\n"); + html = modifiedHtml.toString(); + } else { + Logger.error("Unable to inject Capacitor, Plugins won't work"); + } + return new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)); + } + + private String readAssetStream(InputStream stream) { + try { + final int bufferSize = 1024; + final char[] buffer = new char[bufferSize]; + final StringBuilder out = new StringBuilder(); + Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8); + for (;;) { + int rsz = in.read(buffer, 0, buffer.length); + if (rsz < 0) break; + out.append(buffer, 0, rsz); + } + return out.toString(); + } catch (Exception e) { + Logger.error("Unable to process HTML asset file. This is a fatal error", e); + } + + return ""; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSObject.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSObject.java new file mode 100644 index 0000000..0e98707 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSObject.java @@ -0,0 +1,164 @@ +package com.getcapacitor; + +import androidx.annotation.Nullable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * A wrapper around JSONObject that isn't afraid to do simple + * JSON put operations without having to throw an exception + * for every little thing jeez + */ +public class JSObject extends JSONObject { + + public JSObject() { + super(); + } + + public JSObject(String json) throws JSONException { + super(json); + } + + public JSObject(JSONObject obj, String[] names) throws JSONException { + super(obj, names); + } + + /** + * Convert a pathetic JSONObject into a JSObject + * @param obj + */ + public static JSObject fromJSONObject(JSONObject obj) throws JSONException { + Iterator keysIter = obj.keys(); + List keys = new ArrayList<>(); + while (keysIter.hasNext()) { + keys.add(keysIter.next()); + } + + return new JSObject(obj, keys.toArray(new String[keys.size()])); + } + + @Override + @Nullable + public String getString(String key) { + return getString(key, null); + } + + @Nullable + public String getString(String key, @Nullable String defaultValue) { + try { + String value = super.getString(key); + if (!super.isNull(key)) { + return value; + } + } catch (JSONException ex) {} + return defaultValue; + } + + @Nullable + public Integer getInteger(String key) { + return getInteger(key, null); + } + + @Nullable + public Integer getInteger(String key, @Nullable Integer defaultValue) { + try { + return super.getInt(key); + } catch (JSONException e) {} + return defaultValue; + } + + @Nullable + public Boolean getBoolean(String key, @Nullable Boolean defaultValue) { + try { + return super.getBoolean(key); + } catch (JSONException e) {} + return defaultValue; + } + + /** + * Fetch boolean from jsonObject + */ + @Nullable + public Boolean getBool(String key) { + return getBoolean(key, null); + } + + @Nullable + public JSObject getJSObject(String name) { + try { + return getJSObject(name, null); + } catch (JSONException e) {} + return null; + } + + @Nullable + public JSObject getJSObject(String name, @Nullable JSObject defaultValue) throws JSONException { + try { + Object obj = get(name); + if (obj instanceof JSONObject) { + Iterator keysIter = ((JSONObject) obj).keys(); + List keys = new ArrayList<>(); + while (keysIter.hasNext()) { + keys.add(keysIter.next()); + } + + return new JSObject((JSONObject) obj, keys.toArray(new String[keys.size()])); + } + } catch (JSONException ex) {} + return defaultValue; + } + + @Override + public JSObject put(String key, boolean value) { + try { + super.put(key, value); + } catch (JSONException ex) {} + return this; + } + + @Override + public JSObject put(String key, int value) { + try { + super.put(key, value); + } catch (JSONException ex) {} + return this; + } + + @Override + public JSObject put(String key, long value) { + try { + super.put(key, value); + } catch (JSONException ex) {} + return this; + } + + @Override + public JSObject put(String key, double value) { + try { + super.put(key, value); + } catch (JSONException ex) {} + return this; + } + + @Override + public JSObject put(String key, Object value) { + try { + super.put(key, value); + } catch (JSONException ex) {} + return this; + } + + public JSObject put(String key, String value) { + try { + super.put(key, value); + } catch (JSONException ex) {} + return this; + } + + public JSObject putSafe(String key, Object value) throws JSONException { + return (JSObject) super.put(key, value); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSValue.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSValue.java new file mode 100644 index 0000000..d97ba91 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/JSValue.java @@ -0,0 +1,65 @@ +package com.getcapacitor; + +import org.json.JSONException; + +/** + * Represents a single user-data value of any type on the capacitor PluginCall object. + */ +public class JSValue { + + private final Object value; + + /** + * @param call The capacitor plugin call, used for accessing the value safely. + * @param name The name of the property to access. + */ + public JSValue(PluginCall call, String name) { + this.value = this.toValue(call, name); + } + + /** + * Returns the coerced but uncasted underlying value. + */ + public Object getValue() { + return this.value; + } + + @Override + public String toString() { + return this.getValue().toString(); + } + + /** + * Returns the underlying value as a JSObject, or throwing if it cannot. + * + * @throws JSONException If the underlying value is not a JSObject. + */ + public JSObject toJSObject() throws JSONException { + if (this.value instanceof JSObject) return (JSObject) this.value; + throw new JSONException("JSValue could not be coerced to JSObject."); + } + + /** + * Returns the underlying value as a JSArray, or throwing if it cannot. + * + * @throws JSONException If the underlying value is not a JSArray. + */ + public JSArray toJSArray() throws JSONException { + if (this.value instanceof JSArray) return (JSArray) this.value; + throw new JSONException("JSValue could not be coerced to JSArray."); + } + + /** + * Returns the underlying value this object represents, coercing it into a capacitor-friendly object if supported. + */ + private Object toValue(PluginCall call, String name) { + Object value = null; + value = call.getArray(name, null); + if (value != null) return value; + value = call.getObject(name, null); + if (value != null) return value; + value = call.getString(name, null); + if (value != null) return value; + return call.getData().opt(name); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Logger.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Logger.java new file mode 100644 index 0000000..9d24fed --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Logger.java @@ -0,0 +1,103 @@ +package com.getcapacitor; + +import android.text.TextUtils; +import android.util.Log; + +public class Logger { + + public static final String LOG_TAG_CORE = "Capacitor"; + public static CapConfig config; + + private static Logger instance; + + private static Logger getInstance() { + if (instance == null) { + instance = new Logger(); + } + return instance; + } + + public static void init(CapConfig config) { + Logger.getInstance().loadConfig(config); + } + + private void loadConfig(CapConfig config) { + Logger.config = config; + } + + public static String tags(String... subtags) { + if (subtags != null && subtags.length > 0) { + return LOG_TAG_CORE + "/" + TextUtils.join("/", subtags); + } + + return LOG_TAG_CORE; + } + + public static void verbose(String message) { + verbose(LOG_TAG_CORE, message); + } + + public static void verbose(String tag, String message) { + if (!shouldLog()) { + return; + } + + Log.v(tag, message); + } + + public static void debug(String message) { + debug(LOG_TAG_CORE, message); + } + + public static void debug(String tag, String message) { + if (!shouldLog()) { + return; + } + + Log.d(tag, message); + } + + public static void info(String message) { + info(LOG_TAG_CORE, message); + } + + public static void info(String tag, String message) { + if (!shouldLog()) { + return; + } + + Log.i(tag, message); + } + + public static void warn(String message) { + warn(LOG_TAG_CORE, message); + } + + public static void warn(String tag, String message) { + if (!shouldLog()) { + return; + } + + Log.w(tag, message); + } + + public static void error(String message) { + error(LOG_TAG_CORE, message, null); + } + + public static void error(String message, Throwable e) { + error(LOG_TAG_CORE, message, e); + } + + public static void error(String tag, String message, Throwable e) { + if (!shouldLog()) { + return; + } + + Log.e(tag, message, e); + } + + public static boolean shouldLog() { + return config == null || config.isLoggingEnabled(); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/MessageHandler.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/MessageHandler.java new file mode 100644 index 0000000..dc91c9b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/MessageHandler.java @@ -0,0 +1,157 @@ +package com.getcapacitor; + +import android.webkit.JavascriptInterface; +import android.webkit.WebView; +import androidx.webkit.JavaScriptReplyProxy; +import androidx.webkit.WebViewCompat; +import androidx.webkit.WebViewFeature; +import org.apache.cordova.PluginManager; + +/** + * MessageHandler handles messages from the WebView, dispatching them + * to plugins. + */ +public class MessageHandler { + + private Bridge bridge; + private WebView webView; + private PluginManager cordovaPluginManager; + private JavaScriptReplyProxy javaScriptReplyProxy; + + public MessageHandler(Bridge bridge, WebView webView, PluginManager cordovaPluginManager) { + this.bridge = bridge; + this.webView = webView; + this.cordovaPluginManager = cordovaPluginManager; + + if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER) && !bridge.getConfig().isUsingLegacyBridge()) { + WebViewCompat.WebMessageListener capListener = (view, message, sourceOrigin, isMainFrame, replyProxy) -> { + if (isMainFrame) { + postMessage(message.getData()); + javaScriptReplyProxy = replyProxy; + } else { + Logger.warn("Plugin execution is allowed in Main Frame only"); + } + }; + try { + WebViewCompat.addWebMessageListener(webView, "androidBridge", bridge.getAllowedOriginRules(), capListener); + } catch (Exception ex) { + webView.addJavascriptInterface(this, "androidBridge"); + } + } else { + webView.addJavascriptInterface(this, "androidBridge"); + } + } + + /** + * The main message handler that will be called from JavaScript + * to send a message to the native bridge. + * @param jsonStr + */ + @JavascriptInterface + @SuppressWarnings("unused") + public void postMessage(String jsonStr) { + try { + JSObject postData = new JSObject(jsonStr); + + String type = postData.getString("type"); + + boolean typeIsNotNull = type != null; + boolean isCordovaPlugin = typeIsNotNull && type.equals("cordova"); + boolean isJavaScriptError = typeIsNotNull && type.equals("js.error"); + + String callbackId = postData.getString("callbackId"); + + if (isCordovaPlugin) { + String service = postData.getString("service"); + String action = postData.getString("action"); + String actionArgs = postData.getString("actionArgs"); + + Logger.verbose( + Logger.tags("Plugin"), + "To native (Cordova plugin): callbackId: " + + callbackId + + ", service: " + + service + + ", action: " + + action + + ", actionArgs: " + + actionArgs + ); + + this.callCordovaPluginMethod(callbackId, service, action, actionArgs); + } else if (isJavaScriptError) { + Logger.error("JavaScript Error: " + jsonStr); + } else { + String pluginId = postData.getString("pluginId"); + String methodName = postData.getString("methodName"); + JSObject methodData = postData.getJSObject("options", new JSObject()); + + Logger.verbose( + Logger.tags("Plugin"), + "To native (Capacitor plugin): callbackId: " + callbackId + ", pluginId: " + pluginId + ", methodName: " + methodName + ); + + this.callPluginMethod(callbackId, pluginId, methodName, methodData); + } + } catch (Exception ex) { + Logger.error("Post message error:", ex); + } + } + + public void sendResponseMessage(PluginCall call, PluginResult successResult, PluginResult errorResult) { + try { + PluginResult data = new PluginResult(); + data.put("save", call.isKeptAlive()); + data.put("callbackId", call.getCallbackId()); + data.put("pluginId", call.getPluginId()); + data.put("methodName", call.getMethodName()); + + boolean pluginResultInError = errorResult != null; + if (pluginResultInError) { + data.put("success", false); + data.put("error", errorResult); + Logger.debug("Sending plugin error: " + data.toString()); + } else { + data.put("success", true); + if (successResult != null) { + data.put("data", successResult); + } + } + + boolean isValidCallbackId = !call.getCallbackId().equals(PluginCall.CALLBACK_ID_DANGLING); + if (isValidCallbackId) { + if (bridge.getConfig().isUsingLegacyBridge()) { + legacySendResponseMessage(data); + } else if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER) && javaScriptReplyProxy != null) { + javaScriptReplyProxy.postMessage(data.toString()); + } else { + legacySendResponseMessage(data); + } + } else { + bridge.getApp().fireRestoredResult(data); + } + } catch (Exception ex) { + Logger.error("sendResponseMessage: error: " + ex); + } + if (!call.isKeptAlive()) { + call.release(bridge); + } + } + + private void legacySendResponseMessage(PluginResult data) { + final String runScript = "window.Capacitor.fromNative(" + data.toString() + ")"; + final WebView webView = this.webView; + webView.post(() -> webView.evaluateJavascript(runScript, null)); + } + + private void callPluginMethod(String callbackId, String pluginId, String methodName, JSObject methodData) { + PluginCall call = new PluginCall(this, pluginId, callbackId, methodName, methodData); + bridge.callPluginMethod(pluginId, methodName, call); + } + + private void callCordovaPluginMethod(String callbackId, String service, String action, String actionArgs) { + bridge.execute(() -> { + cordovaPluginManager.exec(service, action, callbackId, actionArgs); + }); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java new file mode 100644 index 0000000..c430762 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/NativePlugin.java @@ -0,0 +1,37 @@ +package com.getcapacitor; + +import com.getcapacitor.annotation.CapacitorPlugin; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Base annotation for all Plugins + * @deprecated + *

Use {@link CapacitorPlugin} instead + */ +@Retention(RetentionPolicy.RUNTIME) +@Deprecated +public @interface NativePlugin { + /** + * Request codes this plugin uses and responds to, in order to tie + * Android events back the plugin to handle + */ + int[] requestCodes() default {}; + + /** + * Permissions this plugin needs, in order to make permission requests + * easy if the plugin only needs basic permission prompting + */ + String[] permissions() default {}; + + /** + * The request code to use when automatically requesting permissions + */ + int permissionRequestCode() default 9000; + + /** + * A custom name for the plugin, otherwise uses the + * simple class name. + */ + String name() default ""; +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PermissionState.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PermissionState.java new file mode 100644 index 0000000..382cff7 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PermissionState.java @@ -0,0 +1,31 @@ +package com.getcapacitor; + +import java.util.Locale; + +/** + * Represents the state of a permission + * + * @since 3.0.0 + */ +public enum PermissionState { + GRANTED("granted"), + DENIED("denied"), + PROMPT("prompt"), + PROMPT_WITH_RATIONALE("prompt-with-rationale"); + + private String state; + + PermissionState(String state) { + this.state = state; + } + + @Override + public String toString() { + return state; + } + + public static PermissionState byState(String state) { + state = state.toUpperCase(Locale.ROOT).replace('-', '_'); + return valueOf(state); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Plugin.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Plugin.java new file mode 100644 index 0000000..19c8b8b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/Plugin.java @@ -0,0 +1,1050 @@ +package com.getcapacitor; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Bundle; +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import com.getcapacitor.annotation.ActivityCallback; +import com.getcapacitor.annotation.CapacitorPlugin; +import com.getcapacitor.annotation.Permission; +import com.getcapacitor.annotation.PermissionCallback; +import com.getcapacitor.util.PermissionHelper; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import org.json.JSONException; + +/** + * Plugin is the base class for all plugins, containing a number of + * convenient features for interacting with the {@link Bridge}, managing + * plugin permissions, tracking lifecycle events, and more. + * + * You should inherit from this class when creating new plugins, along with + * adding the {@link CapacitorPlugin} annotation to add additional required + * metadata about the Plugin + */ +public class Plugin { + + // The key we will use inside of a persisted Bundle for the JSON blob + // for a plugin call options. + private static final String BUNDLE_PERSISTED_OPTIONS_JSON_KEY = "_json"; + + // Reference to the Bridge + protected Bridge bridge; + + // Reference to the PluginHandle wrapper for this Plugin + protected PluginHandle handle; + + /** + * A way for plugins to quickly save a call that they will need to reference + * between activity/permissions starts/requests + * + * @deprecated store calls on the bridge using the methods + * {@link com.getcapacitor.Bridge#saveCall(PluginCall)}, + * {@link com.getcapacitor.Bridge#getSavedCall(String)} and + * {@link com.getcapacitor.Bridge#releaseCall(PluginCall)} + */ + @Deprecated + protected PluginCall savedLastCall; + + // Stored event listeners + private final Map> eventListeners; + + /** + * Launchers used by the plugin to handle activity results + */ + private final Map> activityLaunchers = new HashMap<>(); + + /** + * Launchers used by the plugin to handle permission results + */ + private final Map> permissionLaunchers = new HashMap<>(); + + private String lastPluginCallId; + + // Stored results of an event if an event was fired and + // no listeners were attached yet. Only stores the last value. + private final Map> retainedEventArguments; + + public Plugin() { + eventListeners = new HashMap<>(); + retainedEventArguments = new HashMap<>(); + } + + /** + * Called when the plugin has been connected to the bridge + * and is ready to start initializing. + */ + public void load() {} + + /** + * Registers activity result launchers defined on plugins, used for permission requests and + * activities started for result. + */ + void initializeActivityLaunchers() { + List pluginClassMethods = new ArrayList<>(); + for ( + Class pluginCursor = getClass(); + !pluginCursor.getName().equals(Object.class.getName()); + pluginCursor = pluginCursor.getSuperclass() + ) { + pluginClassMethods.addAll(Arrays.asList(pluginCursor.getDeclaredMethods())); + } + + for (final Method method : pluginClassMethods) { + if (method.isAnnotationPresent(ActivityCallback.class)) { + // register callbacks annotated with ActivityCallback for activity results + ActivityResultLauncher launcher = bridge.registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + (result) -> triggerActivityCallback(method, result) + ); + + activityLaunchers.put(method.getName(), launcher); + } else if (method.isAnnotationPresent(PermissionCallback.class)) { + // register callbacks annotated with PermissionCallback for permission results + ActivityResultLauncher launcher = bridge.registerForActivityResult( + new ActivityResultContracts.RequestMultiplePermissions(), + (permissions) -> triggerPermissionCallback(method, permissions) + ); + + permissionLaunchers.put(method.getName(), launcher); + } + } + } + + private void triggerPermissionCallback(Method method, Map permissionResultMap) { + PluginCall savedCall = bridge.getPermissionCall(handle.getId()); + + // validate permissions and invoke the permission result callback + if (bridge.validatePermissions(this, savedCall, permissionResultMap)) { + try { + method.setAccessible(true); + method.invoke(this, savedCall); + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + + private void triggerActivityCallback(Method method, ActivityResult result) { + PluginCall savedCall = bridge.getSavedCall(lastPluginCallId); + if (savedCall == null) { + savedCall = bridge.getPluginCallForLastActivity(); + } + // invoke the activity result callback + try { + method.setAccessible(true); + method.invoke(this, savedCall, result); + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + /** + * Start activity for result with the provided Intent and resolve with the provided callback method name. + *

+ * If there is no registered activity callback for the method name passed in, the call will + * be rejected. Make sure a valid activity result callback method is registered using the + * {@link ActivityCallback} annotation. + * + * @param call the plugin call + * @param intent the intent used to start an activity + * @param callbackName the name of the callback to run when the launched activity is finished + * @since 3.0.0 + */ + public void startActivityForResult(PluginCall call, Intent intent, String callbackName) { + ActivityResultLauncher activityResultLauncher = getActivityLauncherOrReject(call, callbackName); + if (activityResultLauncher == null) { + // return when null since call was rejected in getLauncherOrReject + return; + } + bridge.setPluginCallForLastActivity(call); + lastPluginCallId = call.getCallbackId(); + bridge.saveCall(call); + activityResultLauncher.launch(intent); + } + + private void permissionActivityResult(PluginCall call, String[] permissionStrings, String callbackName) { + ActivityResultLauncher permissionResultLauncher = getPermissionLauncherOrReject(call, callbackName); + if (permissionResultLauncher == null) { + // return when null since call was rejected in getLauncherOrReject + return; + } + + bridge.savePermissionCall(call); + permissionResultLauncher.launch(permissionStrings); + } + + /** + * Get the main {@link Context} for the current Activity (your app) + * @return the Context for the current activity + */ + public Context getContext() { + return this.bridge.getContext(); + } + + /** + * Get the main {@link Activity} for the app + * @return the Activity for the current app + */ + public AppCompatActivity getActivity() { + return this.bridge.getActivity(); + } + + /** + * Set the Bridge instance for this plugin + * @param bridge + */ + public void setBridge(Bridge bridge) { + this.bridge = bridge; + } + + /** + * Get the Bridge instance for this plugin + */ + public Bridge getBridge() { + return this.bridge; + } + + /** + * Set the wrapper {@link PluginHandle} instance for this plugin that + * contains additional metadata about the Plugin instance (such + * as indexed methods for reflection, and {@link CapacitorPlugin} annotation data). + * @param pluginHandle + */ + public void setPluginHandle(PluginHandle pluginHandle) { + this.handle = pluginHandle; + } + + /** + * Return the wrapper {@link PluginHandle} for this plugin. + * + * This wrapper contains additional metadata about the plugin instance, + * such as indexed methods for reflection, and {@link CapacitorPlugin} annotation data). + * @return + */ + public PluginHandle getPluginHandle() { + return this.handle; + } + + /** + * Get the root App ID + * @return + */ + public String getAppId() { + return getContext().getPackageName(); + } + + /** + * Called to save a {@link PluginCall} in order to reference it + * later, such as in an activity or permissions result handler + * @deprecated use {@link Bridge#saveCall(PluginCall)} + * + * @param lastCall + */ + @Deprecated + public void saveCall(PluginCall lastCall) { + this.savedLastCall = lastCall; + } + + /** + * Set the last saved call to null to free memory + * @deprecated use {@link PluginCall#release(Bridge)} + */ + @Deprecated + public void freeSavedCall() { + this.savedLastCall.release(bridge); + this.savedLastCall = null; + } + + /** + * Get the last saved call, if any + * @deprecated use {@link Bridge#getSavedCall(String)} + * + * @return + */ + @Deprecated + public PluginCall getSavedCall() { + return this.savedLastCall; + } + + /** + * Get the config options for this plugin. + * + * @return a config object representing the plugin config options, or an empty config + * if none exists + */ + public PluginConfig getConfig() { + return bridge.getConfig().getPluginConfiguration(handle.getId()); + } + + /** + * Get the value for a key on the config for this plugin. + * @deprecated use {@link #getConfig()} and access config values using the methods available + * depending on the type. + * + * @param key the key for the config value + * @return some object containing the value from the config + */ + @Deprecated + public Object getConfigValue(String key) { + try { + PluginConfig pluginConfig = getConfig(); + return pluginConfig.getConfigJSON().get(key); + } catch (JSONException ex) { + return null; + } + } + + /** + * Check whether any of the given permissions has been defined in the AndroidManifest.xml + * @deprecated use {@link #isPermissionDeclared(String)} + * + * @param permissions + * @return + */ + @Deprecated + public boolean hasDefinedPermissions(String[] permissions) { + for (String permission : permissions) { + if (!PermissionHelper.hasDefinedPermission(getContext(), permission)) { + return false; + } + } + return true; + } + + /** + * Check if all annotated permissions have been defined in the AndroidManifest.xml + * @deprecated use {@link #isPermissionDeclared(String)} + * + * @return true if permissions are all defined in the Manifest + */ + @Deprecated + public boolean hasDefinedRequiredPermissions() { + CapacitorPlugin annotation = handle.getPluginAnnotation(); + if (annotation == null) { + // Check for legacy plugin annotation, @NativePlugin + NativePlugin legacyAnnotation = handle.getLegacyPluginAnnotation(); + return hasDefinedPermissions(legacyAnnotation.permissions()); + } else { + for (Permission perm : annotation.permissions()) { + for (String permString : perm.strings()) { + if (!PermissionHelper.hasDefinedPermission(getContext(), permString)) { + return false; + } + } + } + } + + return true; + } + + /** + * Checks if the given permission alias is correctly declared in AndroidManifest.xml + * @param alias a permission alias defined on the plugin + * @return true only if all permissions associated with the given alias are declared in the manifest + */ + public boolean isPermissionDeclared(String alias) { + CapacitorPlugin annotation = handle.getPluginAnnotation(); + if (annotation != null) { + for (Permission perm : annotation.permissions()) { + if (alias.equalsIgnoreCase(perm.alias())) { + boolean result = true; + for (String permString : perm.strings()) { + result = result && PermissionHelper.hasDefinedPermission(getContext(), permString); + } + + return result; + } + } + } + + Logger.error(String.format("isPermissionDeclared: No alias defined for %s " + "or missing @CapacitorPlugin annotation.", alias)); + return false; + } + + /** + * Check whether the given permission has been granted by the user + * @deprecated use {@link #getPermissionState(String)} and {@link #getPermissionStates()} to get + * the states of permissions defined on the Plugin in conjunction with the @CapacitorPlugin + * annotation. Use the Android API {@link ActivityCompat#checkSelfPermission(Context, String)} + * methods to check permissions with Android permission strings + * + * @param permission + * @return + */ + @Deprecated + public boolean hasPermission(String permission) { + return ActivityCompat.checkSelfPermission(this.getContext(), permission) == PackageManager.PERMISSION_GRANTED; + } + + /** + * If the plugin annotation specified a set of permissions, this method checks if each is + * granted + * @deprecated use {@link #getPermissionState(String)} or {@link #getPermissionStates()} to + * check whether permissions are granted or not + * + * @return + */ + @Deprecated + public boolean hasRequiredPermissions() { + CapacitorPlugin annotation = handle.getPluginAnnotation(); + if (annotation == null) { + // Check for legacy plugin annotation, @NativePlugin + NativePlugin legacyAnnotation = handle.getLegacyPluginAnnotation(); + for (String perm : legacyAnnotation.permissions()) { + if (ActivityCompat.checkSelfPermission(this.getContext(), perm) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + + return true; + } + + for (Permission perm : annotation.permissions()) { + for (String permString : perm.strings()) { + if (ActivityCompat.checkSelfPermission(this.getContext(), permString) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + } + + return true; + } + + /** + * Request all of the specified permissions in the CapacitorPlugin annotation (if any) + * + * If there is no registered permission callback for the PluginCall passed in, the call will + * be rejected. Make sure a valid permission callback method is registered using the + * {@link PermissionCallback} annotation. + * + * @since 3.0.0 + * @param call the plugin call + * @param callbackName the name of the callback to run when the permission request is complete + */ + protected void requestAllPermissions(@NonNull PluginCall call, @NonNull String callbackName) { + CapacitorPlugin annotation = handle.getPluginAnnotation(); + if (annotation != null) { + HashSet perms = new HashSet<>(); + for (Permission perm : annotation.permissions()) { + perms.addAll(Arrays.asList(perm.strings())); + } + + permissionActivityResult(call, perms.toArray(new String[0]), callbackName); + } + } + + /** + * Request permissions using an alias defined on the plugin. + * + * If there is no registered permission callback for the PluginCall passed in, the call will + * be rejected. Make sure a valid permission callback method is registered using the + * {@link PermissionCallback} annotation. + * + * @param alias an alias defined on the plugin + * @param call the plugin call involved in originating the request + * @param callbackName the name of the callback to run when the permission request is complete + */ + protected void requestPermissionForAlias(@NonNull String alias, @NonNull PluginCall call, @NonNull String callbackName) { + requestPermissionForAliases(new String[] { alias }, call, callbackName); + } + + /** + * Request permissions using aliases defined on the plugin. + * + * If there is no registered permission callback for the PluginCall passed in, the call will + * be rejected. Make sure a valid permission callback method is registered using the + * {@link PermissionCallback} annotation. + * + * @param aliases a set of aliases defined on the plugin + * @param call the plugin call involved in originating the request + * @param callbackName the name of the callback to run when the permission request is complete + */ + protected void requestPermissionForAliases(@NonNull String[] aliases, @NonNull PluginCall call, @NonNull String callbackName) { + if (aliases.length == 0) { + Logger.error("No permission alias was provided"); + return; + } + + String[] permissions = getPermissionStringsForAliases(aliases); + + if (permissions.length > 0) { + permissionActivityResult(call, permissions, callbackName); + } + } + + /** + * Gets the Android permission strings defined on the {@link CapacitorPlugin} annotation with + * the provided aliases. + * + * @param aliases aliases for permissions defined on the plugin + * @return Android permission strings associated with the provided aliases, if exists + */ + private String[] getPermissionStringsForAliases(@NonNull String[] aliases) { + CapacitorPlugin annotation = handle.getPluginAnnotation(); + HashSet perms = new HashSet<>(); + for (Permission perm : annotation.permissions()) { + if (Arrays.asList(aliases).contains(perm.alias())) { + perms.addAll(Arrays.asList(perm.strings())); + } + } + + return perms.toArray(new String[0]); + } + + /** + * Gets the activity launcher associated with the calling methodName, or rejects the call if + * no registered launcher exists + * + * @param call the plugin call + * @param methodName the name of the activity callback method + * @return a launcher, or null if none found + */ + private @Nullable ActivityResultLauncher getActivityLauncherOrReject(PluginCall call, String methodName) { + ActivityResultLauncher activityLauncher = activityLaunchers.get(methodName); + + // if there is no registered launcher, reject the call with an error and return null + if (activityLauncher == null) { + String registerError = + "There is no ActivityCallback method registered for the name: %s. " + + "Please define a callback method annotated with @ActivityCallback " + + "that receives arguments: (PluginCall, ActivityResult)"; + registerError = String.format(Locale.US, registerError, methodName); + Logger.error(registerError); + call.reject(registerError); + return null; + } + + return activityLauncher; + } + + /** + * Gets the permission launcher associated with the calling methodName, or rejects the call if + * no registered launcher exists + * + * @param call the plugin call + * @param methodName the name of the permission callback method + * @return a launcher, or null if none found + */ + private @Nullable ActivityResultLauncher getPermissionLauncherOrReject(PluginCall call, String methodName) { + ActivityResultLauncher permissionLauncher = permissionLaunchers.get(methodName); + + // if there is no registered launcher, reject the call with an error and return null + if (permissionLauncher == null) { + String registerError = + "There is no PermissionCallback method registered for the name: %s. " + + "Please define a callback method annotated with @PermissionCallback " + + "that receives arguments: (PluginCall)"; + registerError = String.format(Locale.US, registerError, methodName); + Logger.error(registerError); + call.reject(registerError); + return null; + } + + return permissionLauncher; + } + + /** + * Request all of the specified permissions in the CapacitorPlugin annotation (if any) + * + * @deprecated use {@link #requestAllPermissions(PluginCall, String)} in conjunction with @CapacitorPlugin + */ + @Deprecated + public void pluginRequestAllPermissions() { + NativePlugin legacyAnnotation = handle.getLegacyPluginAnnotation(); + ActivityCompat.requestPermissions(getActivity(), legacyAnnotation.permissions(), legacyAnnotation.permissionRequestCode()); + } + + /** + * Helper for requesting a specific permission + * + * @param permission the permission to request + * @param requestCode the requestCode to use to associate the result with the plugin + * @deprecated use {@link #requestPermissionForAlias(String, PluginCall, String)} in conjunction with @CapacitorPlugin + */ + @Deprecated + public void pluginRequestPermission(String permission, int requestCode) { + ActivityCompat.requestPermissions(getActivity(), new String[] { permission }, requestCode); + } + + /** + * Helper for requesting specific permissions + * @deprecated use {@link #requestPermissionForAliases(String[], PluginCall, String)} in conjunction + * with @CapacitorPlugin + * + * @param permissions the set of permissions to request + * @param requestCode the requestCode to use to associate the result with the plugin + */ + @Deprecated + public void pluginRequestPermissions(String[] permissions, int requestCode) { + ActivityCompat.requestPermissions(getActivity(), permissions, requestCode); + } + + /** + * Get the permission state for the provided permission alias. + * + * @param alias the permission alias to get + * @return the state of the provided permission alias or null + */ + public PermissionState getPermissionState(String alias) { + return getPermissionStates().get(alias); + } + + /** + * Helper to check all permissions defined on a plugin and see the state of each. + * + * @since 3.0.0 + * @return A mapping of permission aliases to the associated granted status. + */ + public Map getPermissionStates() { + return bridge.getPermissionStates(this); + } + + /** + * Add a listener for the given event + * @param eventName + * @param call + */ + private void addEventListener(String eventName, PluginCall call) { + List listeners = eventListeners.get(eventName); + if (listeners == null || listeners.isEmpty()) { + listeners = new ArrayList<>(); + eventListeners.put(eventName, listeners); + + // Must add the call before sending retained arguments + listeners.add(call); + + sendRetainedArgumentsForEvent(eventName); + } else { + listeners.add(call); + } + } + + /** + * Remove a listener from the given event + * @param eventName + * @param call + */ + private void removeEventListener(String eventName, PluginCall call) { + List listeners = eventListeners.get(eventName); + if (listeners == null) { + return; + } + + listeners.remove(call); + } + + /** + * Notify all listeners that an event occurred + * @param eventName + * @param data + */ + protected void notifyListeners(String eventName, JSObject data, boolean retainUntilConsumed) { + Logger.verbose(getLogTag(), "Notifying listeners for event " + eventName); + List listeners = eventListeners.get(eventName); + if (listeners == null || listeners.isEmpty()) { + Logger.debug(getLogTag(), "No listeners found for event " + eventName); + if (retainUntilConsumed) { + List argList = retainedEventArguments.get(eventName); + + if (argList == null) { + argList = new ArrayList(); + } + + argList.add(data); + retainedEventArguments.put(eventName, argList); + } + return; + } + + CopyOnWriteArrayList listenersCopy = new CopyOnWriteArrayList(listeners); + for (PluginCall call : listenersCopy) { + call.resolve(data); + } + } + + /** + * Notify all listeners that an event occurred + * This calls {@link Plugin#notifyListeners(String, JSObject, boolean)} + * with retainUntilConsumed set to false + * @param eventName + * @param data + */ + protected void notifyListeners(String eventName, JSObject data) { + notifyListeners(eventName, data, false); + } + + /** + * Check if there are any listeners for the given event + */ + protected boolean hasListeners(String eventName) { + List listeners = eventListeners.get(eventName); + if (listeners == null) { + return false; + } + return !listeners.isEmpty(); + } + + /** + * Send retained arguments (if any) for this event. This + * is called only when the first listener for an event is added + * @param eventName + */ + private void sendRetainedArgumentsForEvent(String eventName) { + // copy retained args and null source to prevent potential race conditions + List retainedArgs = retainedEventArguments.get(eventName); + if (retainedArgs == null) { + return; + } + + retainedEventArguments.remove(eventName); + + for (JSObject retained : retainedArgs) { + notifyListeners(eventName, retained); + } + } + + /** + * Exported plugin call for adding a listener to this plugin + * @param call + */ + @SuppressWarnings("unused") + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + public void addListener(PluginCall call) { + String eventName = call.getString("eventName"); + call.setKeepAlive(true); + addEventListener(eventName, call); + } + + /** + * Exported plugin call to remove a listener from this plugin + * @param call + */ + @SuppressWarnings("unused") + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + public void removeListener(PluginCall call) { + String eventName = call.getString("eventName"); + String callbackId = call.getString("callbackId"); + PluginCall savedCall = bridge.getSavedCall(callbackId); + if (savedCall != null) { + removeEventListener(eventName, savedCall); + bridge.releaseCall(savedCall); + } + } + + /** + * Exported plugin call to remove all listeners from this plugin + * @param call + */ + @SuppressWarnings("unused") + @PluginMethod(returnType = PluginMethod.RETURN_PROMISE) + public void removeAllListeners(PluginCall call) { + eventListeners.clear(); + call.resolve(); + } + + public void removeAllListeners() { + eventListeners.clear(); + } + + /** + * Exported plugin call for checking the granted status for each permission + * declared on the plugin. This plugin call responds with a mapping of permissions to + * the associated granted status. + * + * @since 3.0.0 + */ + @PluginMethod + @PermissionCallback + public void checkPermissions(PluginCall pluginCall) { + Map permissionsResult = getPermissionStates(); + + if (permissionsResult.size() == 0) { + // if no permissions are defined on the plugin, resolve undefined + pluginCall.resolve(); + } else { + JSObject permissionsResultJSON = new JSObject(); + for (Map.Entry entry : permissionsResult.entrySet()) { + permissionsResultJSON.put(entry.getKey(), entry.getValue()); + } + + pluginCall.resolve(permissionsResultJSON); + } + } + + /** + * Exported plugin call to request all permissions for this plugin. + * To manually request permissions within a plugin use: + * {@link #requestAllPermissions(PluginCall, String)}, or + * {@link #requestPermissionForAlias(String, PluginCall, String)}, or + * {@link #requestPermissionForAliases(String[], PluginCall, String)} + * + * @param call the plugin call + */ + @PluginMethod + public void requestPermissions(PluginCall call) { + CapacitorPlugin annotation = handle.getPluginAnnotation(); + if (annotation == null) { + handleLegacyPermission(call); + } else { + // handle permission requests for plugins defined with @CapacitorPlugin (since 3.0.0) + String[] permAliases = null; + Set autoGrantPerms = new HashSet<>(); + + // If call was made with a list of specific permission aliases to request, save them + // to be requested + JSArray providedPerms = call.getArray("permissions"); + List providedPermsList = null; + + if (providedPerms != null) { + try { + providedPermsList = providedPerms.toList(); + } catch (JSONException ignore) { + // do nothing + } + } + + // If call was made without any custom permissions, request all from plugin annotation + Set aliasSet = new HashSet<>(); + if (providedPermsList == null || providedPermsList.isEmpty()) { + for (Permission perm : annotation.permissions()) { + // If a permission is defined with no permission strings, separate it for auto-granting. + // Otherwise, the alias is added to the list to be requested. + if (perm.strings().length == 0 || (perm.strings().length == 1 && perm.strings()[0].isEmpty())) { + if (!perm.alias().isEmpty()) { + autoGrantPerms.add(perm.alias()); + } + } else { + aliasSet.add(perm.alias()); + } + } + + permAliases = aliasSet.toArray(new String[0]); + } else { + for (Permission perm : annotation.permissions()) { + if (providedPermsList.contains(perm.alias())) { + aliasSet.add(perm.alias()); + } + } + + if (aliasSet.isEmpty()) { + call.reject("No valid permission alias was requested of this plugin."); + } else { + permAliases = aliasSet.toArray(new String[0]); + } + } + + if (permAliases != null && permAliases.length > 0) { + // request permissions using provided aliases or all defined on the plugin + requestPermissionForAliases(permAliases, call, "checkPermissions"); + } else if (!autoGrantPerms.isEmpty()) { + // if the plugin only has auto-grant permissions, return all as GRANTED + JSObject permissionsResults = new JSObject(); + + for (String perm : autoGrantPerms) { + permissionsResults.put(perm, PermissionState.GRANTED.toString()); + } + + call.resolve(permissionsResults); + } else { + // no permissions are defined on the plugin, resolve undefined + call.resolve(); + } + } + } + + @SuppressWarnings("deprecation") + private void handleLegacyPermission(PluginCall call) { + // handle permission requests for plugins defined with @NativePlugin (prior to 3.0.0) + NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation(); + String[] perms = legacyAnnotation.permissions(); + if (perms.length > 0) { + saveCall(call); + pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode()); + } else { + call.resolve(); + } + } + + /** + * Handle request permissions result. A plugin using the deprecated {@link NativePlugin} + * should override this to handle the result, or this method will handle the result + * for our convenient requestPermissions call. + * @deprecated in favor of using callbacks in conjunction with {@link CapacitorPlugin} + * + * @param requestCode + * @param permissions + * @param grantResults + */ + @Deprecated + protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (!hasDefinedPermissions(permissions)) { + StringBuilder builder = new StringBuilder(); + builder.append("Missing the following permissions in AndroidManifest.xml:\n"); + String[] missing = PermissionHelper.getUndefinedPermissions(getContext(), permissions); + for (String perm : missing) { + builder.append(perm + "\n"); + } + savedLastCall.reject(builder.toString()); + savedLastCall = null; + } + } + + /** + * Called before the app is destroyed to give a plugin the chance to + * save the last call options for a saved plugin. By default, this + * method saves the full JSON blob of the options call. Since Bundle sizes + * may be limited, plugins that expect to be called with large data + * objects (such as a file), should override this method and selectively + * store option values in a {@link Bundle} to avoid exceeding limits. + * @return a new {@link Bundle} with fields set from the options of the last saved {@link PluginCall} + */ + protected Bundle saveInstanceState() { + PluginCall savedCall = bridge.getSavedCall(lastPluginCallId); + + if (savedCall == null) { + return null; + } + + Bundle ret = new Bundle(); + JSObject callData = savedCall.getData(); + + if (callData != null) { + ret.putString(BUNDLE_PERSISTED_OPTIONS_JSON_KEY, callData.toString()); + } + + return ret; + } + + /** + * Called when the app is opened with a previously un-handled + * activity response. If the plugin that started the activity + * stored data in {@link Plugin#saveInstanceState()} then this + * method will be called to allow the plugin to restore from that. + * @param state + */ + protected void restoreState(Bundle state) {} + + /** + * Handle activity result, should be overridden by each plugin + * + * @deprecated provide a callback method using the {@link ActivityCallback} annotation and use + * the {@link #startActivityForResult(PluginCall, Intent, String)} method + * + * @param requestCode + * @param resultCode + * @param data + */ + @Deprecated + protected void handleOnActivityResult(int requestCode, int resultCode, Intent data) {} + + /** + * Handle onNewIntent + * @param intent + */ + protected void handleOnNewIntent(Intent intent) {} + + /** + * Handle onConfigurationChanged + * @param newConfig + */ + protected void handleOnConfigurationChanged(Configuration newConfig) {} + + /** + * Handle onStart + */ + protected void handleOnStart() {} + + /** + * Handle onRestart + */ + protected void handleOnRestart() {} + + /** + * Handle onResume + */ + protected void handleOnResume() {} + + /** + * Handle onPause + */ + protected void handleOnPause() {} + + /** + * Handle onStop + */ + protected void handleOnStop() {} + + /** + * Handle onDestroy + */ + protected void handleOnDestroy() {} + + /** + * Give the plugins a chance to take control when a URL is about to be loaded in the WebView. + * Returning true causes the WebView to abort loading the URL. + * Returning false causes the WebView to continue loading the URL. + * Returning null will defer to the default Capacitor policy + */ + @SuppressWarnings("unused") + public Boolean shouldOverrideLoad(Uri url) { + return null; + } + + /** + * Start a new Activity. + * + * Note: This method must be used by all plugins instead of calling + * {@link Activity#startActivityForResult} as it associates the plugin with + * any resulting data from the new Activity even if this app + * is destroyed by the OS (to free up memory, for example). + * @param intent + * @param resultCode + */ + @Deprecated + protected void startActivityForResult(PluginCall call, Intent intent, int resultCode) { + bridge.startActivityForPluginWithResult(call, intent, resultCode); + } + + /** + * Execute the given runnable on the Bridge's task handler + * @param runnable + */ + public void execute(Runnable runnable) { + bridge.execute(runnable); + } + + /** + * Shortcut for getting the plugin log tag + * @param subTags + */ + protected String getLogTag(String... subTags) { + return Logger.tags(subTags); + } + + /** + * Gets a plugin log tag with the child's class name as subTag. + */ + protected String getLogTag() { + return Logger.tags(this.getClass().getSimpleName()); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginCall.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginCall.java new file mode 100644 index 0000000..7308f07 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginCall.java @@ -0,0 +1,394 @@ +package com.getcapacitor; + +import androidx.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Wraps a call from the web layer to native + */ +public class PluginCall { + + /** + * A special callback id that indicates there is no matching callback + * on the client to associate any PluginCall results back to. This is used + * in the case of an app resuming with saved instance data, for example. + */ + public static final String CALLBACK_ID_DANGLING = "-1"; + + private final MessageHandler msgHandler; + private final String pluginId; + private final String callbackId; + private final String methodName; + private final JSObject data; + + private boolean keepAlive = false; + + /** + * Indicates that this PluginCall was released, and should no longer be used + */ + @Deprecated + private boolean isReleased = false; + + public PluginCall(MessageHandler msgHandler, String pluginId, String callbackId, String methodName, JSObject data) { + this.msgHandler = msgHandler; + this.pluginId = pluginId; + this.callbackId = callbackId; + this.methodName = methodName; + this.data = data; + } + + public void successCallback(PluginResult successResult) { + if (CALLBACK_ID_DANGLING.equals(this.callbackId)) { + // don't send back response if the callbackId was "-1" + return; + } + + this.msgHandler.sendResponseMessage(this, successResult, null); + } + + public void resolve(JSObject data) { + PluginResult result = new PluginResult(data); + this.msgHandler.sendResponseMessage(this, result, null); + } + + public void resolve() { + this.msgHandler.sendResponseMessage(this, null, null); + } + + public void errorCallback(String msg) { + PluginResult errorResult = new PluginResult(); + + try { + errorResult.put("message", msg); + } catch (Exception jsonEx) { + Logger.error(Logger.tags("Plugin"), jsonEx.toString(), null); + } + + this.msgHandler.sendResponseMessage(this, null, errorResult); + } + + public void reject(String msg, String code, Exception ex, JSObject data) { + PluginResult errorResult = new PluginResult(); + + if (ex != null) { + Logger.error(Logger.tags("Plugin"), msg, ex); + } + + try { + errorResult.put("message", msg); + errorResult.put("code", code); + if (null != data) { + errorResult.put("data", data); + } + } catch (Exception jsonEx) { + Logger.error(Logger.tags("Plugin"), jsonEx.getMessage(), jsonEx); + } + + this.msgHandler.sendResponseMessage(this, null, errorResult); + } + + public void reject(String msg, Exception ex, JSObject data) { + reject(msg, null, ex, data); + } + + public void reject(String msg, String code, JSObject data) { + reject(msg, code, null, data); + } + + public void reject(String msg, String code, Exception ex) { + reject(msg, code, ex, null); + } + + public void reject(String msg, JSObject data) { + reject(msg, null, null, data); + } + + public void reject(String msg, Exception ex) { + reject(msg, null, ex, null); + } + + public void reject(String msg, String code) { + reject(msg, code, null, null); + } + + public void reject(String msg) { + reject(msg, null, null, null); + } + + public void unimplemented() { + unimplemented("not implemented"); + } + + public void unimplemented(String msg) { + reject(msg, "UNIMPLEMENTED", null, null); + } + + public void unavailable() { + unavailable("not available"); + } + + public void unavailable(String msg) { + reject(msg, "UNAVAILABLE", null, null); + } + + public String getPluginId() { + return this.pluginId; + } + + public String getCallbackId() { + return this.callbackId; + } + + public String getMethodName() { + return this.methodName; + } + + public JSObject getData() { + return this.data; + } + + @Nullable + public String getString(String name) { + return this.getString(name, null); + } + + @Nullable + public String getString(String name, @Nullable String defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof String) { + return (String) value; + } + return defaultValue; + } + + @Nullable + public Integer getInt(String name) { + return this.getInt(name, null); + } + + @Nullable + public Integer getInt(String name, @Nullable Integer defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof Integer) { + return (Integer) value; + } + return defaultValue; + } + + @Nullable + public Long getLong(String name) { + return this.getLong(name, null); + } + + @Nullable + public Long getLong(String name, @Nullable Long defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof Long) { + return (Long) value; + } + return defaultValue; + } + + @Nullable + public Float getFloat(String name) { + return this.getFloat(name, null); + } + + @Nullable + public Float getFloat(String name, @Nullable Float defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof Float) { + return (Float) value; + } + if (value instanceof Double) { + return ((Double) value).floatValue(); + } + if (value instanceof Integer) { + return ((Integer) value).floatValue(); + } + return defaultValue; + } + + @Nullable + public Double getDouble(String name) { + return this.getDouble(name, null); + } + + @Nullable + public Double getDouble(String name, @Nullable Double defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof Double) { + return (Double) value; + } + if (value instanceof Float) { + return ((Float) value).doubleValue(); + } + if (value instanceof Integer) { + return ((Integer) value).doubleValue(); + } + return defaultValue; + } + + @Nullable + public Boolean getBoolean(String name) { + return this.getBoolean(name, null); + } + + @Nullable + public Boolean getBoolean(String name, @Nullable Boolean defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof Boolean) { + return (Boolean) value; + } + return defaultValue; + } + + public JSObject getObject(String name) { + return this.getObject(name, null); + } + + @Nullable + public JSObject getObject(String name, JSObject defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof JSONObject) { + try { + return JSObject.fromJSONObject((JSONObject) value); + } catch (JSONException ex) { + return defaultValue; + } + } + return defaultValue; + } + + public JSArray getArray(String name) { + return this.getArray(name, null); + } + + /** + * Get a JSONArray and turn it into a JSArray + * @param name + * @param defaultValue + * @return + */ + @Nullable + public JSArray getArray(String name, JSArray defaultValue) { + Object value = this.data.opt(name); + if (value == null) { + return defaultValue; + } + + if (value instanceof JSONArray) { + try { + JSONArray valueArray = (JSONArray) value; + List items = new ArrayList<>(); + for (int i = 0; i < valueArray.length(); i++) { + items.add(valueArray.get(i)); + } + return new JSArray(items.toArray()); + } catch (JSONException ex) { + return defaultValue; + } + } + return defaultValue; + } + + /** + * @param name of the option to check + * @return boolean indicating if the plugin call has an option for the provided name. + * @deprecated Presence of a key should not be considered significant. + * Use typed accessors to check the value instead. + */ + @Deprecated + public boolean hasOption(String name) { + return this.data.has(name); + } + + /** + * Indicate that the Bridge should cache this call in order to call + * it again later. For example, the addListener system uses this to + * continuously call the call's callback (😆). + * @deprecated use {@link #setKeepAlive(Boolean)} instead + */ + @Deprecated + public void save() { + setKeepAlive(true); + } + + /** + * Indicate that the Bridge should cache this call in order to call + * it again later. For example, the addListener system uses this to + * continuously call the call's callback. + * + * @param keepAlive whether to keep the callback saved + */ + public void setKeepAlive(Boolean keepAlive) { + this.keepAlive = keepAlive; + } + + public void release(Bridge bridge) { + this.keepAlive = false; + bridge.releaseCall(this); + this.isReleased = true; + } + + /** + * @deprecated use {@link #isKeptAlive()} + * @return true if the plugin call is kept alive + */ + @Deprecated + public boolean isSaved() { + return isKeptAlive(); + } + + /** + * Gets the keepAlive value of the plugin call + * @return true if the plugin call is kept alive + */ + public boolean isKeptAlive() { + return keepAlive; + } + + @Deprecated + public boolean isReleased() { + return isReleased; + } + + class PluginCallDataTypeException extends Exception { + + PluginCallDataTypeException(String m) { + super(m); + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java new file mode 100644 index 0000000..0f00fc5 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java @@ -0,0 +1,116 @@ +package com.getcapacitor; + +import com.getcapacitor.util.JSONUtils; +import org.json.JSONObject; + +/** + * Represents the configuration options for plugins used by Capacitor + */ +public class PluginConfig { + + /** + * The object containing plugin config values. + */ + private final JSONObject config; + + /** + * Constructs a PluginsConfig with the provided JSONObject value. + * + * @param config A plugin configuration expressed as a JSON Object + */ + PluginConfig(JSONObject config) { + this.config = config; + } + + /** + * Get a string value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @return The value from the config, if exists. Null if not + */ + public String getString(String configKey) { + return getString(configKey, null); + } + + /** + * Get a string value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + public String getString(String configKey, String defaultValue) { + return JSONUtils.getString(config, configKey, defaultValue); + } + + /** + * Get a boolean value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + public boolean getBoolean(String configKey, boolean defaultValue) { + return JSONUtils.getBoolean(config, configKey, defaultValue); + } + + /** + * Get an integer value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + public int getInt(String configKey, int defaultValue) { + return JSONUtils.getInt(config, configKey, defaultValue); + } + + /** + * Get a string array value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @return The value from the config, if exists. Null if not + */ + public String[] getArray(String configKey) { + return getArray(configKey, null); + } + + /** + * Get a string array value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + public String[] getArray(String configKey, String[] defaultValue) { + return JSONUtils.getArray(config, configKey, defaultValue); + } + + /** + * Get a JSON object value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @return The value from the config, if exists. Null if not + */ + public JSONObject getObject(String configKey) { + return JSONUtils.getObject(config, configKey); + } + + /** + * Check if the PluginConfig is empty. + * + * @return true if the plugin config has no entries + */ + public boolean isEmpty() { + return config.length() == 0; + } + + /** + * Gets the JSON Object containing the config of the the provided plugin ID. + * + * @return The config for that plugin + */ + public JSONObject getConfigJSON() { + return config; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java new file mode 100644 index 0000000..bfdd922 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginHandle.java @@ -0,0 +1,160 @@ +package com.getcapacitor; + +import com.getcapacitor.annotation.CapacitorPlugin; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * PluginHandle is an instance of a plugin that has been registered + * and indexed. Think of it as a Plugin instance with extra metadata goodies + */ +public class PluginHandle { + + private final Bridge bridge; + private final Class pluginClass; + + private final Map pluginMethods = new HashMap<>(); + + private final String pluginId; + + @SuppressWarnings("deprecation") + private NativePlugin legacyPluginAnnotation; + + private CapacitorPlugin pluginAnnotation; + + private Plugin instance; + + @SuppressWarnings("deprecation") + private PluginHandle(Class clazz, Bridge bridge) throws InvalidPluginException { + this.bridge = bridge; + this.pluginClass = clazz; + + CapacitorPlugin pluginAnnotation = pluginClass.getAnnotation(CapacitorPlugin.class); + if (pluginAnnotation == null) { + // Check for legacy plugin annotation, @NativePlugin + NativePlugin legacyPluginAnnotation = pluginClass.getAnnotation(NativePlugin.class); + if (legacyPluginAnnotation == null) { + throw new InvalidPluginException("No @CapacitorPlugin annotation found for plugin " + pluginClass.getName()); + } + + if (!legacyPluginAnnotation.name().equals("")) { + this.pluginId = legacyPluginAnnotation.name(); + } else { + this.pluginId = pluginClass.getSimpleName(); + } + + this.legacyPluginAnnotation = legacyPluginAnnotation; + } else { + if (!pluginAnnotation.name().equals("")) { + this.pluginId = pluginAnnotation.name(); + } else { + this.pluginId = pluginClass.getSimpleName(); + } + + this.pluginAnnotation = pluginAnnotation; + } + + this.indexMethods(clazz); + } + + public PluginHandle(Bridge bridge, Class pluginClass) throws InvalidPluginException, PluginLoadException { + this(pluginClass, bridge); + this.load(); + } + + public PluginHandle(Bridge bridge, Plugin plugin) throws InvalidPluginException { + this(plugin.getClass(), bridge); + this.loadInstance(plugin); + } + + public Class getPluginClass() { + return pluginClass; + } + + public String getId() { + return this.pluginId; + } + + @SuppressWarnings("deprecation") + public NativePlugin getLegacyPluginAnnotation() { + return this.legacyPluginAnnotation; + } + + public CapacitorPlugin getPluginAnnotation() { + return this.pluginAnnotation; + } + + public Plugin getInstance() { + return this.instance; + } + + public Collection getMethods() { + return this.pluginMethods.values(); + } + + public Plugin load() throws PluginLoadException { + if (this.instance != null) { + return this.instance; + } + + try { + this.instance = this.pluginClass.getDeclaredConstructor().newInstance(); + return this.loadInstance(instance); + } catch (Exception ex) { + throw new PluginLoadException("Unable to load plugin instance. Ensure plugin is publicly accessible"); + } + } + + public Plugin loadInstance(Plugin plugin) { + this.instance = plugin; + this.instance.setPluginHandle(this); + this.instance.setBridge(this.bridge); + this.instance.load(); + this.instance.initializeActivityLaunchers(); + return this.instance; + } + + /** + * Call a method on a plugin. + * @param methodName the name of the method to call + * @param call the constructed PluginCall with parameters from the caller + * @throws InvalidPluginMethodException if no method was found on that plugin + */ + public void invoke(String methodName, PluginCall call) + throws PluginLoadException, InvalidPluginMethodException, InvocationTargetException, IllegalAccessException { + if (this.instance == null) { + // Can throw PluginLoadException + this.load(); + } + + PluginMethodHandle methodMeta = pluginMethods.get(methodName); + if (methodMeta == null) { + throw new InvalidPluginMethodException("No method " + methodName + " found for plugin " + pluginClass.getName()); + } + + methodMeta.getMethod().invoke(this.instance, call); + } + + /** + * Index all the known callable methods for a plugin for faster + * invocation later + */ + private void indexMethods(Class plugin) { + //Method[] methods = pluginClass.getDeclaredMethods(); + Method[] methods = pluginClass.getMethods(); + + for (Method methodReflect : methods) { + PluginMethod method = methodReflect.getAnnotation(PluginMethod.class); + + if (method == null) { + continue; + } + + PluginMethodHandle methodMeta = new PluginMethodHandle(methodReflect, method); + pluginMethods.put(methodReflect.getName(), methodMeta); + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginInvocationException.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginInvocationException.java new file mode 100644 index 0000000..ae6b0eb --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginInvocationException.java @@ -0,0 +1,16 @@ +package com.getcapacitor; + +class PluginInvocationException extends Exception { + + public PluginInvocationException(String s) { + super(s); + } + + public PluginInvocationException(Throwable t) { + super(t); + } + + public PluginInvocationException(String s, Throwable t) { + super(s, t); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginLoadException.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginLoadException.java new file mode 100644 index 0000000..8d81a38 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginLoadException.java @@ -0,0 +1,19 @@ +package com.getcapacitor; + +/** + * Thrown when a plugin fails to instantiate + */ +public class PluginLoadException extends Exception { + + public PluginLoadException(String s) { + super(s); + } + + public PluginLoadException(Throwable t) { + super(t); + } + + public PluginLoadException(String s, Throwable t) { + super(s, t); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginManager.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginManager.java new file mode 100644 index 0000000..540bc91 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginManager.java @@ -0,0 +1,56 @@ +package com.getcapacitor; + +import android.content.res.AssetManager; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class PluginManager { + + private final AssetManager assetManager; + + public PluginManager(AssetManager assetManager) { + this.assetManager = assetManager; + } + + public List> loadPluginClasses() throws PluginLoadException { + JSONArray pluginsJSON = parsePluginsJSON(); + ArrayList> pluginList = new ArrayList<>(); + + try { + for (int i = 0, size = pluginsJSON.length(); i < size; i++) { + JSONObject pluginJSON = pluginsJSON.getJSONObject(i); + String classPath = pluginJSON.getString("classpath"); + Class c = Class.forName(classPath); + pluginList.add(c.asSubclass(Plugin.class)); + } + } catch (JSONException e) { + throw new PluginLoadException("Could not parse capacitor.plugins.json as JSON"); + } catch (ClassNotFoundException e) { + throw new PluginLoadException("Could not find class by class path: " + e.getMessage()); + } + + return pluginList; + } + + private JSONArray parsePluginsJSON() throws PluginLoadException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(assetManager.open("capacitor.plugins.json")))) { + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line); + } + String jsonString = builder.toString(); + return new JSONArray(jsonString); + } catch (IOException e) { + throw new PluginLoadException("Could not load capacitor.plugins.json"); + } catch (JSONException e) { + throw new PluginLoadException("Could not parse capacitor.plugins.json as JSON"); + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethod.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethod.java new file mode 100644 index 0000000..8566304 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethod.java @@ -0,0 +1,15 @@ +package com.getcapacitor; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface PluginMethod { + String RETURN_PROMISE = "promise"; + + String RETURN_CALLBACK = "callback"; + + String RETURN_NONE = "none"; + + String returnType() default RETURN_PROMISE; +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethodHandle.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethodHandle.java new file mode 100644 index 0000000..a728c1f --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginMethodHandle.java @@ -0,0 +1,33 @@ +package com.getcapacitor; + +import java.lang.reflect.Method; + +public class PluginMethodHandle { + + // The reflect method reference + private final Method method; + // The name of the method + private final String name; + // The return type of the method (see PluginMethod for constants) + private final String returnType; + + public PluginMethodHandle(Method method, PluginMethod methodDecorator) { + this.method = method; + + this.name = method.getName(); + + this.returnType = methodDecorator.returnType(); + } + + public String getReturnType() { + return returnType; + } + + public String getName() { + return name; + } + + public Method getMethod() { + return method; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginResult.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginResult.java new file mode 100644 index 0000000..cdc169e --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/PluginResult.java @@ -0,0 +1,84 @@ +package com.getcapacitor; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +/** + * Wraps a result for web from calling a native plugin. + */ +public class PluginResult { + + private final JSObject json; + + public PluginResult() { + this(new JSObject()); + } + + public PluginResult(JSObject json) { + this.json = json; + } + + public PluginResult put(String name, boolean value) { + return this.jsonPut(name, value); + } + + public PluginResult put(String name, double value) { + return this.jsonPut(name, value); + } + + public PluginResult put(String name, int value) { + return this.jsonPut(name, value); + } + + public PluginResult put(String name, long value) { + return this.jsonPut(name, value); + } + + /** + * Format a date as an ISO string + */ + public PluginResult put(String name, Date value) { + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); + df.setTimeZone(tz); + return this.jsonPut(name, df.format(value)); + } + + public PluginResult put(String name, Object value) { + return this.jsonPut(name, value); + } + + public PluginResult put(String name, PluginResult value) { + return this.jsonPut(name, value.json); + } + + PluginResult jsonPut(String name, Object value) { + try { + this.json.put(name, value); + } catch (Exception ex) { + Logger.error(Logger.tags("Plugin"), "", ex); + } + return this; + } + + public String toString() { + return this.json.toString(); + } + + /** + * Return plugin metadata and information about the result, if it succeeded the data, or error information if it didn't. + * This is used for appRestoredResult, as it's technically a raw data response from a plugin. + * @return the raw data response from the plugin. + */ + public JSObject getWrappedResult() { + JSObject ret = new JSObject(); + ret.put("pluginId", this.json.getString("pluginId")); + ret.put("methodName", this.json.getString("methodName")); + ret.put("success", this.json.getBoolean("success", false)); + ret.put("data", this.json.getJSObject("data")); + ret.put("error", this.json.getJSObject("error")); + return ret; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java new file mode 100644 index 0000000..eb3d7b0 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java @@ -0,0 +1,37 @@ +package com.getcapacitor; + +/** + * An data class used in conjunction with RouteProcessor. + * + * @see com.getcapacitor.RouteProcessor + */ +public class ProcessedRoute { + + private String path; + private boolean isAsset; + private boolean ignoreAssetPath; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public boolean isAsset() { + return isAsset; + } + + public void setAsset(boolean asset) { + isAsset = asset; + } + + public boolean isIgnoreAssetPath() { + return ignoreAssetPath; + } + + public void setIgnoreAssetPath(boolean ignoreAssetPath) { + this.ignoreAssetPath = ignoreAssetPath; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java new file mode 100644 index 0000000..670c8bc --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java @@ -0,0 +1,8 @@ +package com.getcapacitor; + +/** + * An interface used in the processing of routes + */ +public interface RouteProcessor { + ProcessedRoute process(String basePath, String path); +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ServerPath.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ServerPath.java new file mode 100644 index 0000000..5b34b46 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/ServerPath.java @@ -0,0 +1,25 @@ +package com.getcapacitor; + +public class ServerPath { + + public enum PathType { + BASE_PATH, + ASSET_PATH + } + + private final PathType type; + private final String path; + + public ServerPath(PathType type, String path) { + this.type = type; + this.path = path; + } + + public PathType getType() { + return type; + } + + public String getPath() { + return path; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/UriMatcher.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/UriMatcher.java new file mode 100755 index 0000000..3a77a05 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/UriMatcher.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//package com.google.webviewlocalserver.third_party.android; +package com.getcapacitor; + +import android.net.Uri; +import com.getcapacitor.util.HostMask; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class UriMatcher { + + /** + * Creates the root node of the URI tree. + * + * @param code the code to match for the root URI + */ + public UriMatcher(Object code) { + mCode = code; + mWhich = -1; + mChildren = new ArrayList<>(); + mText = null; + } + + private UriMatcher() { + mCode = null; + mWhich = -1; + mChildren = new ArrayList<>(); + mText = null; + } + + /** + * Add a URI to match, and the code to return when this URI is + * matched. URI nodes may be exact match string, the token "*" + * that matches any text, or the token "#" that matches only + * numbers. + *

+ * Starting from API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, + * this method will accept a leading slash in the path. + * + * @param authority the authority to match + * @param path the path to match. * may be used as a wild card for + * any text, and # may be used as a wild card for numbers. + * @param code the code that is returned when a URI is matched + * against the given components. Must be positive. + */ + public void addURI(String scheme, String authority, String path, Object code) { + if (code == null) { + throw new IllegalArgumentException("Code can't be null"); + } + + String[] tokens = null; + if (path != null) { + String newPath = path; + // Strip leading slash if present. + if (!path.isEmpty() && path.charAt(0) == '/') { + newPath = path.substring(1); + } + tokens = PATH_SPLIT_PATTERN.split(newPath); + } + + int numTokens = tokens != null ? tokens.length : 0; + UriMatcher node = this; + for (int i = -2; i < numTokens; i++) { + String token; + if (i == -2) token = scheme; + else if (i == -1) token = authority; + else token = tokens[i]; + ArrayList children = node.mChildren; + int numChildren = children.size(); + UriMatcher child; + int j; + for (j = 0; j < numChildren; j++) { + child = children.get(j); + if (token.equals(child.mText)) { + node = child; + break; + } + } + if (j == numChildren) { + // Child not found, create it + child = new UriMatcher(); + if (i == -1 && token.contains("*")) { + child.mWhich = MASK; + } else if (token.equals("**")) { + child.mWhich = REST; + } else if (token.equals("*")) { + child.mWhich = TEXT; + } else { + child.mWhich = EXACT; + } + child.mText = token; + node.mChildren.add(child); + node = child; + } + } + node.mCode = code; + } + + static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/"); + + /** + * Try to match against the path in a url. + * + * @param uri The url whose path we will match against. + * @return The code for the matched node (added using addURI), + * or null if there is no matched node. + */ + public Object match(Uri uri) { + final List pathSegments = uri.getPathSegments(); + final int li = pathSegments.size(); + + UriMatcher node = this; + + if (li == 0 && uri.getAuthority() == null) { + return this.mCode; + } + + for (int i = -2; i < li; i++) { + String u; + if (i == -2) u = uri.getScheme(); + else if (i == -1) u = uri.getAuthority(); + else u = pathSegments.get(i); + ArrayList list = node.mChildren; + if (list == null) { + break; + } + node = null; + int lj = list.size(); + for (int j = 0; j < lj; j++) { + UriMatcher n = list.get(j); + which_switch: switch (n.mWhich) { + case MASK: + if (HostMask.Parser.parse(n.mText).matches(u)) { + node = n; + } + break; + case EXACT: + if (n.mText.equals(u)) { + node = n; + } + break; + case TEXT: + node = n; + break; + case REST: + return n.mCode; + } + if (node != null) { + break; + } + } + if (node == null) { + return null; + } + } + + return node.mCode; + } + + private static final int EXACT = 0; + private static final int TEXT = 1; + private static final int REST = 2; + private static final int MASK = 3; + + private Object mCode; + private int mWhich; + private String mText; + private ArrayList mChildren; +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java new file mode 100644 index 0000000..6031344 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewListener.java @@ -0,0 +1,67 @@ +package com.getcapacitor; + +import android.webkit.RenderProcessGoneDetail; +import android.webkit.WebView; + +/** + * Provides callbacks associated with the {@link BridgeWebViewClient} + */ +public abstract class WebViewListener { + + /** + * Callback for page load event. + * + * @param webView The WebView that loaded + */ + public void onPageLoaded(WebView webView) { + // Override me to add behavior to the page loaded event + } + + /** + * Callback for onReceivedError event. + * + * @param webView The WebView that loaded + */ + public void onReceivedError(WebView webView) { + // Override me to add behavior to handle the onReceivedError event + } + + /** + * Callback for onReceivedHttpError event. + * + * @param webView The WebView that loaded + */ + public void onReceivedHttpError(WebView webView) { + // Override me to add behavior to handle the onReceivedHttpError event + } + + /** + * Callback for page start event. + * + * @param webView The WebView that loaded + */ + public void onPageStarted(WebView webView) { + // Override me to add behavior to the page started event + } + + /** + * Callback for render process gone event. Return true if the state is handled. + * + * @param webView The WebView that loaded + * @return returns false by default if the listener is not overridden and used + */ + public boolean onRenderProcessGone(WebView webView, RenderProcessGoneDetail detail) { + // Override me to add behavior to the web view render process gone event + return false; + } + + /** + * Callback for page start event. + * + * @param view The WebView for which the navigation occurred. + * @param url The URL corresponding to the page navigation that triggered this callback. + */ + public void onPageCommitVisible(WebView view, String url) { + // Override me to add behavior to handle the onPageCommitVisible event + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java new file mode 100755 index 0000000..a39483d --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java @@ -0,0 +1,773 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ +package com.getcapacitor; + +import static com.getcapacitor.plugin.util.HttpRequestHandler.isDomainExcludedFromSSL; + +import android.content.Context; +import android.net.Uri; +import android.util.Base64; +import android.webkit.CookieManager; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import com.getcapacitor.plugin.util.CapacitorHttpUrlConnection; +import com.getcapacitor.plugin.util.HttpRequestHandler; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Helper class meant to be used with the android.webkit.WebView class to enable hosting assets, + * resources and other data on 'virtual' https:// URL. + * Hosting assets and resources on https:// URLs is desirable as it is compatible with the + * Same-Origin policy. + *

+ * This class is intended to be used from within the + * {@link android.webkit.WebViewClient#shouldInterceptRequest(android.webkit.WebView, String)} and + * {@link android.webkit.WebViewClient#shouldInterceptRequest(android.webkit.WebView, + * android.webkit.WebResourceRequest)} + * methods. + */ +public class WebViewLocalServer { + + private static final String capacitorFileStart = Bridge.CAPACITOR_FILE_START; + private static final String capacitorContentStart = Bridge.CAPACITOR_CONTENT_START; + private String basePath; + + private final UriMatcher uriMatcher; + private final AndroidProtocolHandler protocolHandler; + private final ArrayList authorities; + private boolean isAsset; + // Whether to route all requests to paths without extensions back to `index.html` + private final boolean html5mode; + private final JSInjector jsInjector; + private final Bridge bridge; + + /** + * A handler that produces responses for paths on the virtual asset server. + *

+ * Methods of this handler will be invoked on a background thread and care must be taken to + * correctly synchronize access to any shared state. + *

+ * On Android KitKat and above these methods may be called on more than one thread. This thread + * may be different than the thread on which the shouldInterceptRequest method was invoke. + * This means that on Android KitKat and above it is possible to block in this method without + * blocking other resources from loading. The number of threads used to parallelize loading + * is an internal implementation detail of the WebView and may change between updates which + * means that the amount of time spend blocking in this method should be kept to an absolute + * minimum. + */ + public abstract static class PathHandler { + + protected String mimeType; + private String encoding; + private String charset; + private int statusCode; + private String reasonPhrase; + private Map responseHeaders; + + public PathHandler() { + this(null, null, 200, "OK", null); + } + + public PathHandler(String encoding, String charset, int statusCode, String reasonPhrase, Map responseHeaders) { + this.encoding = encoding; + this.charset = charset; + this.statusCode = statusCode; + this.reasonPhrase = reasonPhrase; + Map tempResponseHeaders; + if (responseHeaders == null) { + tempResponseHeaders = new HashMap<>(); + } else { + tempResponseHeaders = responseHeaders; + } + tempResponseHeaders.put("Cache-Control", "no-cache"); + this.responseHeaders = tempResponseHeaders; + } + + public InputStream handle(WebResourceRequest request) { + return handle(request.getUrl()); + } + + public abstract InputStream handle(Uri url); + + public String getEncoding() { + return encoding; + } + + public String getCharset() { + return charset; + } + + public int getStatusCode() { + return statusCode; + } + + public String getReasonPhrase() { + return reasonPhrase; + } + + /** + * @deprecated This method may return incorrect headers in concurrent range requests. + *

+ * Use {@link #buildDefaultResponseHeaders()} instead, which returns a copy of the map. + *

+ * This method will be removed in a future major version of Capacitor. + *

+ */ + @Deprecated(forRemoval = true) // adjust version as appropriate + public Map getResponseHeaders() { + return responseHeaders; + } + + public Map buildDefaultResponseHeaders() { + return new HashMap<>(responseHeaders); + } + } + + WebViewLocalServer(Context context, Bridge bridge, JSInjector jsInjector, ArrayList authorities, boolean html5mode) { + uriMatcher = new UriMatcher(null); + this.html5mode = html5mode; + this.protocolHandler = new AndroidProtocolHandler(context.getApplicationContext()); + this.authorities = authorities; + this.bridge = bridge; + this.jsInjector = jsInjector; + } + + private static Uri parseAndVerifyUrl(String url) { + if (url == null) { + return null; + } + Uri uri = Uri.parse(url); + if (uri == null) { + Logger.error("Malformed URL: " + url); + return null; + } + String path = uri.getPath(); + if (path == null || path.isEmpty()) { + Logger.error("URL does not have a path: " + url); + return null; + } + return uri; + } + + /** + * Attempt to retrieve the WebResourceResponse associated with the given request. + * This method should be invoked from within + * {@link android.webkit.WebViewClient#shouldInterceptRequest(android.webkit.WebView, + * android.webkit.WebResourceRequest)}. + * + * @param request the request to process. + * @return a response if the request URL had a matching handler, null if no handler was found. + */ + public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) { + Uri loadingUrl = request.getUrl(); + + if (null != loadingUrl.getPath() && loadingUrl.getPath().startsWith(Bridge.CAPACITOR_HTTP_INTERCEPTOR_START)) { + Logger.debug("Handling CapacitorHttp request: " + loadingUrl); + try { + return handleCapacitorHttpRequest(request); + } catch (Exception e) { + Logger.error(e.getLocalizedMessage()); + return null; + } + } + + PathHandler handler; + synchronized (uriMatcher) { + handler = (PathHandler) uriMatcher.match(request.getUrl()); + } + if (handler == null) { + return null; + } + + if (isLocalFile(loadingUrl) || isMainUrl(loadingUrl) || !isAllowedUrl(loadingUrl) || isErrorUrl(loadingUrl)) { + Logger.debug("Handling local request: " + request.getUrl().toString()); + return handleLocalRequest(request, handler); + } else { + return handleProxyRequest(request, handler); + } + } + + private boolean isLocalFile(Uri uri) { + String path = uri.getPath(); + return path.startsWith(capacitorContentStart) || path.startsWith(capacitorFileStart); + } + + private boolean isErrorUrl(Uri uri) { + String url = uri.toString(); + return url.equals(bridge.getErrorUrl()); + } + + private boolean isMainUrl(Uri loadingUrl) { + return (bridge.getServerUrl() == null && loadingUrl.getHost().equalsIgnoreCase(bridge.getHost())); + } + + private boolean isAllowedUrl(Uri loadingUrl) { + return !(bridge.getServerUrl() == null && !bridge.getAppAllowNavigationMask().matches(loadingUrl.getHost())); + } + + private String getReasonPhraseFromResponseCode(int code) { + return switch (code) { + case 100 -> "Continue"; + case 101 -> "Switching Protocols"; + case 200 -> "OK"; + case 201 -> "Created"; + case 202 -> "Accepted"; + case 203 -> "Non-Authoritative Information"; + case 204 -> "No Content"; + case 205 -> "Reset Content"; + case 206 -> "Partial Content"; + case 300 -> "Multiple Choices"; + case 301 -> "Moved Permanently"; + case 302 -> "Found"; + case 303 -> "See Other"; + case 304 -> "Not Modified"; + case 400 -> "Bad Request"; + case 401 -> "Unauthorized"; + case 403 -> "Forbidden"; + case 404 -> "Not Found"; + case 405 -> "Method Not Allowed"; + case 406 -> "Not Acceptable"; + case 407 -> "Proxy Authentication Required"; + case 408 -> "Request Timeout"; + case 409 -> "Conflict"; + case 410 -> "Gone"; + case 500 -> "Internal Server Error"; + case 501 -> "Not Implemented"; + case 502 -> "Bad Gateway"; + case 503 -> "Service Unavailable"; + case 504 -> "Gateway Timeout"; + case 505 -> "HTTP Version Not Supported"; + default -> "Unknown"; + }; + } + + private WebResourceResponse handleCapacitorHttpRequest(WebResourceRequest request) throws IOException { + String urlString = request.getUrl().getQueryParameter(Bridge.CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM); + URL url = new URL(urlString); + JSObject headers = new JSObject(); + + for (Map.Entry header : request.getRequestHeaders().entrySet()) { + headers.put(header.getKey(), header.getValue()); + } + + // a workaround for the following android web view issue: + // https://issues.chromium.org/issues/40450316 + // x-cap-user-agent contains the user agent set in JavaScript + String userAgentValue = headers.getString("x-cap-user-agent"); + if (userAgentValue != null) { + headers.put("User-Agent", userAgentValue); + } + headers.remove("x-cap-user-agent"); + + HttpRequestHandler.HttpURLConnectionBuilder connectionBuilder = new HttpRequestHandler.HttpURLConnectionBuilder() + .setUrl(url) + .setMethod(request.getMethod()) + .setHeaders(headers) + .openConnection(); + + CapacitorHttpUrlConnection connection = connectionBuilder.build(); + + if (!isDomainExcludedFromSSL(bridge, url)) { + connection.setSSLSocketFactory(bridge); + } + + connection.connect(); + + String mimeType = null; + String encoding = null; + Map responseHeaders = new LinkedHashMap<>(); + for (Map.Entry> entry : connection.getHeaderFields().entrySet()) { + StringBuilder builder = new StringBuilder(); + for (String value : entry.getValue()) { + builder.append(value); + builder.append(", "); + } + builder.setLength(builder.length() - 2); + + if ("Content-Type".equalsIgnoreCase(entry.getKey())) { + String[] contentTypeParts = builder.toString().split(";"); + mimeType = contentTypeParts[0].trim(); + if (contentTypeParts.length > 1) { + String[] encodingParts = contentTypeParts[1].split("="); + if (encodingParts.length > 1) { + encoding = encodingParts[1].trim(); + } + } + } else { + responseHeaders.put(entry.getKey(), builder.toString()); + } + } + + InputStream inputStream = connection.getErrorStream(); + if (inputStream == null) { + inputStream = connection.getInputStream(); + } + + if (null == mimeType) { + mimeType = getMimeType(request.getUrl().getPath(), inputStream); + } + + int responseCode = connection.getResponseCode(); + String reasonPhrase = getReasonPhraseFromResponseCode(responseCode); + + return new WebResourceResponse(mimeType, encoding, responseCode, reasonPhrase, responseHeaders, inputStream); + } + + private WebResourceResponse handleLocalRequest(WebResourceRequest request, PathHandler handler) { + String path = request.getUrl().getPath(); + + Map requestHeaders = request.getRequestHeaders(); + String rangeString = requestHeaders.get("Range") != null ? requestHeaders.get("Range") : requestHeaders.get("range"); + + if (rangeString != null) { + InputStream responseStream = new LollipopLazyInputStream(handler, request); + String mimeType = getMimeType(path, responseStream); + Map tempResponseHeaders = handler.buildDefaultResponseHeaders(); + int statusCode = 206; + try { + int totalRange = responseStream.available(); + String[] parts = rangeString.split("="); + String[] streamParts = parts[1].split("-"); + String fromRange = streamParts[0]; + int range = totalRange - 1; + if (streamParts.length > 1) { + range = Integer.parseInt(streamParts[1]); + } + tempResponseHeaders.put("Accept-Ranges", "bytes"); + tempResponseHeaders.put("Content-Range", "bytes " + fromRange + "-" + range + "/" + totalRange); + } catch (IOException e) { + statusCode = 404; + } + return new WebResourceResponse( + mimeType, + handler.getEncoding(), + statusCode, + handler.getReasonPhrase(), + tempResponseHeaders, + responseStream + ); + } + + if (isLocalFile(request.getUrl()) || isErrorUrl(request.getUrl())) { + InputStream responseStream = new LollipopLazyInputStream(handler, request); + String mimeType = getMimeType(request.getUrl().getPath(), responseStream); + int statusCode = getStatusCode(responseStream, handler.getStatusCode()); + return new WebResourceResponse( + mimeType, + handler.getEncoding(), + statusCode, + handler.getReasonPhrase(), + handler.buildDefaultResponseHeaders(), + responseStream + ); + } + + if (path.equals("/cordova.js")) { + return new WebResourceResponse( + "application/javascript", + handler.getEncoding(), + handler.getStatusCode(), + handler.getReasonPhrase(), + handler.buildDefaultResponseHeaders(), + null + ); + } + + if (path.equals("/") || (!request.getUrl().getLastPathSegment().contains(".") && html5mode)) { + InputStream responseStream; + try { + String startPath = this.basePath + "/index.html"; + if (bridge.getRouteProcessor() != null) { + ProcessedRoute processedRoute = bridge.getRouteProcessor().process(this.basePath, "/index.html"); + startPath = processedRoute.getPath(); + isAsset = processedRoute.isAsset(); + } + + if (isAsset) { + responseStream = protocolHandler.openAsset(startPath); + } else { + responseStream = protocolHandler.openFile(startPath); + } + } catch (IOException e) { + Logger.error("Unable to open index.html", e); + return null; + } + + if (jsInjector != null) { + responseStream = jsInjector.getInjectedStream(responseStream); + } + + int statusCode = getStatusCode(responseStream, handler.getStatusCode()); + return new WebResourceResponse( + "text/html", + handler.getEncoding(), + statusCode, + handler.getReasonPhrase(), + handler.buildDefaultResponseHeaders(), + responseStream + ); + } + + if ("/favicon.ico".equalsIgnoreCase(path)) { + try { + return new WebResourceResponse("image/png", null, null); + } catch (Exception e) { + Logger.error("favicon handling failed", e); + } + } + + int periodIndex = path.lastIndexOf("."); + if (periodIndex >= 0) { + String ext = path.substring(path.lastIndexOf(".")); + + InputStream responseStream = new LollipopLazyInputStream(handler, request); + + // TODO: Conjure up a bit more subtlety than this + if (ext.equals(".html") && jsInjector != null) { + responseStream = jsInjector.getInjectedStream(responseStream); + } + + String mimeType = getMimeType(path, responseStream); + int statusCode = getStatusCode(responseStream, handler.getStatusCode()); + return new WebResourceResponse( + mimeType, + handler.getEncoding(), + statusCode, + handler.getReasonPhrase(), + handler.buildDefaultResponseHeaders(), + responseStream + ); + } + + return null; + } + + /** + * Prepends an {@code InputStream} with the JavaScript required by Capacitor. + * This method only changes the original {@code InputStream} if {@code WebView} does not + * support the {@code DOCUMENT_START_SCRIPT} feature. + * @param original the original {@code InputStream} + * @return the modified {@code InputStream} + */ + public InputStream getJavaScriptInjectedStream(InputStream original) { + if (jsInjector != null) { + return jsInjector.getInjectedStream(original); + } + return original; + } + + /** + * Instead of reading files from the filesystem/assets, proxy through to the URL + * and let an external server handle it. + * @param request + * @param handler + * @return + */ + private WebResourceResponse handleProxyRequest(WebResourceRequest request, PathHandler handler) { + if (jsInjector != null) { + final String method = request.getMethod(); + if (method.equals("GET")) { + try { + String url = request.getUrl().toString(); + Map headers = request.getRequestHeaders(); + boolean isHtmlText = false; + for (Map.Entry header : headers.entrySet()) { + if (header.getKey().equalsIgnoreCase("Accept") && header.getValue().toLowerCase().contains("text/html")) { + isHtmlText = true; + break; + } + } + if (isHtmlText) { + HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); + for (Map.Entry header : headers.entrySet()) { + conn.setRequestProperty(header.getKey(), header.getValue()); + } + String getCookie = CookieManager.getInstance().getCookie(url); + if (getCookie != null) { + conn.setRequestProperty("Cookie", getCookie); + } + conn.setRequestMethod(method); + conn.setReadTimeout(30 * 1000); + conn.setConnectTimeout(30 * 1000); + if (request.getUrl().getUserInfo() != null) { + byte[] userInfoBytes = request.getUrl().getUserInfo().getBytes(StandardCharsets.UTF_8); + String base64 = Base64.encodeToString(userInfoBytes, Base64.NO_WRAP); + conn.setRequestProperty("Authorization", "Basic " + base64); + } + + List cookies = conn.getHeaderFields().get("Set-Cookie"); + if (cookies != null) { + for (String cookie : cookies) { + CookieManager.getInstance().setCookie(url, cookie); + } + } + InputStream responseStream = conn.getInputStream(); + responseStream = jsInjector.getInjectedStream(responseStream); + + return new WebResourceResponse( + "text/html", + handler.getEncoding(), + handler.getStatusCode(), + handler.getReasonPhrase(), + handler.buildDefaultResponseHeaders(), + responseStream + ); + } + } catch (Exception ex) { + bridge.handleAppUrlLoadError(ex); + } + } + } + return null; + } + + private String getMimeType(String path, InputStream stream) { + String mimeType = null; + try { + mimeType = URLConnection.guessContentTypeFromName(path); // Does not recognize *.js + if (mimeType != null && path.endsWith(".js") && mimeType.equals("image/x-icon")) { + Logger.debug("We shouldn't be here"); + } + if (mimeType == null) { + if (path.endsWith(".js") || path.endsWith(".mjs")) { + // Make sure JS files get the proper mimetype to support ES modules + mimeType = "application/javascript"; + } else if (path.endsWith(".wasm")) { + mimeType = "application/wasm"; + } else { + mimeType = URLConnection.guessContentTypeFromStream(stream); + } + } + } catch (Exception ex) { + Logger.error("Unable to get mime type" + path, ex); + } + return mimeType; + } + + private int getStatusCode(InputStream stream, int defaultCode) { + int finalStatusCode = defaultCode; + try { + if (stream.available() == -1) { + finalStatusCode = 404; + } + } catch (IOException e) { + finalStatusCode = 500; + } + return finalStatusCode; + } + + /** + * Registers a handler for the given uri. The handler will be invoked + * every time the shouldInterceptRequest method of the instance is called with + * a matching uri. + * + * @param uri the uri to use the handler for. The scheme and authority (domain) will be matched + * exactly. The path may contain a '*' element which will match a single element of + * a path (so a handler registered for /a/* will be invoked for /a/b and /a/c.html + * but not for /a/b/b) or the '**' element which will match any number of path + * elements. + * @param handler the handler to use for the uri. + */ + void register(Uri uri, PathHandler handler) { + synchronized (uriMatcher) { + uriMatcher.addURI(uri.getScheme(), uri.getAuthority(), uri.getPath(), handler); + } + } + + /** + * Hosts the application's assets on an https:// URL. Assets from the local path + * assetPath/... will be available under + * https://{uuid}.androidplatform.net/assets/.... + * + * @param assetPath the local path in the application's asset folder which will be made + * available by the server (for example "/www"). + * @return prefixes under which the assets are hosted. + */ + public void hostAssets(String assetPath) { + this.isAsset = true; + this.basePath = assetPath; + createHostingDetails(); + } + + /** + * Hosts the application's files on an https:// URL. Files from the basePath + * basePath/... will be available under + * https://{uuid}.androidplatform.net/.... + * + * @param basePath the local path in the application's data folder which will be made + * available by the server (for example "/www"). + * @return prefixes under which the assets are hosted. + */ + public void hostFiles(final String basePath) { + this.isAsset = false; + this.basePath = basePath; + createHostingDetails(); + } + + private void createHostingDetails() { + final String assetPath = this.basePath; + + if (assetPath.indexOf('*') != -1) { + throw new IllegalArgumentException("assetPath cannot contain the '*' character."); + } + + PathHandler handler = new PathHandler() { + @Override + public InputStream handle(Uri url) { + InputStream stream = null; + String path = url.getPath(); + + // Pass path to routeProcessor if present + RouteProcessor routeProcessor = bridge.getRouteProcessor(); + boolean ignoreAssetPath = false; + if (routeProcessor != null) { + ProcessedRoute processedRoute = bridge.getRouteProcessor().process("", path); + path = processedRoute.getPath(); + isAsset = processedRoute.isAsset(); + ignoreAssetPath = processedRoute.isIgnoreAssetPath(); + } + + try { + if (path.startsWith(capacitorContentStart)) { + stream = protocolHandler.openContentUrl(url); + } else if (path.startsWith(capacitorFileStart)) { + stream = protocolHandler.openFile(path); + } else if (!isAsset) { + if (routeProcessor == null) { + path = basePath + url.getPath(); + } + + stream = protocolHandler.openFile(path); + } else if (ignoreAssetPath) { + stream = protocolHandler.openAsset(path); + } else { + stream = protocolHandler.openAsset(assetPath + path); + } + } catch (IOException e) { + Logger.error("Unable to open asset URL: " + url); + return null; + } + + return stream; + } + }; + + for (String authority : authorities) { + registerUriForScheme(Bridge.CAPACITOR_HTTP_SCHEME, handler, authority); + registerUriForScheme(Bridge.CAPACITOR_HTTPS_SCHEME, handler, authority); + + String customScheme = this.bridge.getScheme(); + if (!customScheme.equals(Bridge.CAPACITOR_HTTP_SCHEME) && !customScheme.equals(Bridge.CAPACITOR_HTTPS_SCHEME)) { + registerUriForScheme(customScheme, handler, authority); + } + } + } + + private void registerUriForScheme(String scheme, PathHandler handler, String authority) { + Uri.Builder uriBuilder = new Uri.Builder(); + uriBuilder.scheme(scheme); + uriBuilder.authority(authority); + uriBuilder.path(""); + Uri uriPrefix = uriBuilder.build(); + + register(Uri.withAppendedPath(uriPrefix, "/"), handler); + register(Uri.withAppendedPath(uriPrefix, "**"), handler); + } + + /** + * The KitKat WebView reads the InputStream on a separate threadpool. We can use that to + * parallelize loading. + */ + private abstract static class LazyInputStream extends InputStream { + + protected final PathHandler handler; + private InputStream is = null; + + public LazyInputStream(PathHandler handler) { + this.handler = handler; + } + + private InputStream getInputStream() { + if (is == null) { + is = handle(); + } + return is; + } + + protected abstract InputStream handle(); + + @Override + public int available() throws IOException { + InputStream is = getInputStream(); + return (is != null) ? is.available() : -1; + } + + @Override + public int read() throws IOException { + InputStream is = getInputStream(); + return (is != null) ? is.read() : -1; + } + + @Override + public int read(byte[] b) throws IOException { + InputStream is = getInputStream(); + return (is != null) ? is.read(b) : -1; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + InputStream is = getInputStream(); + return (is != null) ? is.read(b, off, len) : -1; + } + + @Override + public long skip(long n) throws IOException { + InputStream is = getInputStream(); + return (is != null) ? is.skip(n) : 0; + } + } + + // For L and above. + private static class LollipopLazyInputStream extends LazyInputStream { + + private WebResourceRequest request; + private InputStream is; + + public LollipopLazyInputStream(PathHandler handler, WebResourceRequest request) { + super(handler); + this.request = request; + } + + @Override + protected InputStream handle() { + return handler.handle(request); + } + } + + public String getBasePath() { + return this.basePath; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/ActivityCallback.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/ActivityCallback.java new file mode 100644 index 0000000..b8112f1 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/ActivityCallback.java @@ -0,0 +1,10 @@ +package com.getcapacitor.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ActivityCallback {} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/CapacitorPlugin.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/CapacitorPlugin.java new file mode 100644 index 0000000..903378d --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/CapacitorPlugin.java @@ -0,0 +1,35 @@ +package com.getcapacitor.annotation; + +import android.content.Intent; +import com.getcapacitor.PluginCall; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Base annotation for all Plugins + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface CapacitorPlugin { + /** + * A custom name for the plugin, otherwise uses the + * simple class name. + */ + String name() default ""; + + /** + * Request codes this plugin uses and responds to, in order to tie + * Android events back the plugin to handle. + * + * NOTE: This is a legacy option provided to support third party libraries + * not currently implementing the new AndroidX Activity Results API. Plugins + * without this limitation should use a registered callback with + * {@link com.getcapacitor.Plugin#startActivityForResult(PluginCall, Intent, String)} + */ + int[] requestCodes() default {}; + + /** + * Permissions this plugin needs, in order to make permission requests + * easy if the plugin only needs basic permission prompting + */ + Permission[] permissions() default {}; +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/Permission.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/Permission.java new file mode 100644 index 0000000..3511437 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/Permission.java @@ -0,0 +1,22 @@ +package com.getcapacitor.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Permission annotation for use with @CapacitorPlugin + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface Permission { + /** + * An array of Android permission strings. + * Eg: {Manifest.permission.ACCESS_COARSE_LOCATION} + * or {"android.permission.ACCESS_COARSE_LOCATION"} + */ + String[] strings() default {}; + + /** + * An optional name to use instead of the Android permission string. + */ + String alias() default ""; +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/PermissionCallback.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/PermissionCallback.java new file mode 100644 index 0000000..1b81ee0 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/annotation/PermissionCallback.java @@ -0,0 +1,10 @@ +package com.getcapacitor.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface PermissionCallback {} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java new file mode 100644 index 0000000..72ac4ee --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java @@ -0,0 +1,42 @@ +package com.getcapacitor.cordova; + +import android.webkit.CookieManager; +import android.webkit.WebView; +import org.apache.cordova.ICordovaCookieManager; + +class CapacitorCordovaCookieManager implements ICordovaCookieManager { + + protected final WebView webView; + private final CookieManager cookieManager; + + public CapacitorCordovaCookieManager(WebView webview) { + webView = webview; + cookieManager = CookieManager.getInstance(); + cookieManager.setAcceptThirdPartyCookies(webView, true); + } + + @Override + public void setCookiesEnabled(boolean accept) { + cookieManager.setAcceptCookie(accept); + } + + @Override + public void setCookie(final String url, final String value) { + cookieManager.setCookie(url, value); + } + + @Override + public String getCookie(final String url) { + return cookieManager.getCookie(url); + } + + @Override + public void clearCookies() { + cookieManager.removeAllCookies(null); + } + + @Override + public void flush() { + cookieManager.flush(); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaInterfaceImpl.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaInterfaceImpl.java new file mode 100644 index 0000000..7e8358d --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaInterfaceImpl.java @@ -0,0 +1,39 @@ +package com.getcapacitor.cordova; + +import android.util.Pair; +import androidx.appcompat.app.AppCompatActivity; +import java.util.concurrent.Executors; +import org.apache.cordova.CordovaInterfaceImpl; +import org.apache.cordova.CordovaPlugin; +import org.json.JSONException; + +public class MockCordovaInterfaceImpl extends CordovaInterfaceImpl { + + public MockCordovaInterfaceImpl(AppCompatActivity activity) { + super(activity, Executors.newCachedThreadPool()); + } + + public CordovaPlugin getActivityResultCallback() { + return this.activityResultCallback; + } + + /** + * Checks Cordova permission callbacks to handle permissions defined by a Cordova plugin. + * Returns true if Cordova is handling the permission request with a registered code. + * + * @param requestCode + * @param permissions + * @param grantResults + * @return true if Cordova handled the permission request, false if not + */ + @SuppressWarnings("deprecation") + public boolean handlePermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException { + Pair callback = permissionResultCallbacks.getAndRemoveCallback(requestCode); + if (callback != null) { + callback.first.onRequestPermissionResult(callback.second, permissions, grantResults); + return true; + } + + return false; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java new file mode 100644 index 0000000..1115429 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java @@ -0,0 +1,282 @@ +package com.getcapacitor.cordova; + +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.view.View; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import java.util.List; +import java.util.Map; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPreferences; +import org.apache.cordova.CordovaResourceApi; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.CordovaWebViewEngine; +import org.apache.cordova.ICordovaCookieManager; +import org.apache.cordova.NativeToJsMessageQueue; +import org.apache.cordova.PluginEntry; +import org.apache.cordova.PluginManager; +import org.apache.cordova.PluginResult; + +public class MockCordovaWebViewImpl implements CordovaWebView { + + private Context context; + private PluginManager pluginManager; + private CordovaPreferences preferences; + private CordovaResourceApi resourceApi; + private NativeToJsMessageQueue nativeToJsMessageQueue; + private CordovaInterface cordova; + private CapacitorCordovaCookieManager cookieManager; + private WebView webView; + private boolean hasPausedEver; + + public MockCordovaWebViewImpl(Context context) { + this.context = context; + } + + @Override + public void init(CordovaInterface cordova, List pluginEntries, CordovaPreferences preferences) { + this.cordova = cordova; + this.preferences = preferences; + this.pluginManager = new PluginManager(this, this.cordova, pluginEntries); + this.resourceApi = new CordovaResourceApi(this.context, this.pluginManager); + this.pluginManager.init(); + } + + public void init(CordovaInterface cordova, List pluginEntries, CordovaPreferences preferences, WebView webView) { + this.cordova = cordova; + this.webView = webView; + this.preferences = preferences; + this.pluginManager = new PluginManager(this, this.cordova, pluginEntries); + this.resourceApi = new CordovaResourceApi(this.context, this.pluginManager); + nativeToJsMessageQueue = new NativeToJsMessageQueue(); + nativeToJsMessageQueue.addBridgeMode(new CapacitorEvalBridgeMode(webView, this.cordova)); + nativeToJsMessageQueue.setBridgeMode(0); + this.cookieManager = new CapacitorCordovaCookieManager(webView); + this.pluginManager.init(); + } + + public static class CapacitorEvalBridgeMode extends NativeToJsMessageQueue.BridgeMode { + + private final WebView webView; + private final CordovaInterface cordova; + + public CapacitorEvalBridgeMode(WebView webView, CordovaInterface cordova) { + this.webView = webView; + this.cordova = cordova; + } + + @Override + public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) { + cordova + .getActivity() + .runOnUiThread(() -> { + String js = queue.popAndEncodeAsJs(); + if (js != null) { + webView.evaluateJavascript(js, null); + } + }); + } + } + + @Override + public boolean isInitialized() { + return cordova != null; + } + + @Override + public View getView() { + return this.webView; + } + + @Override + public void loadUrlIntoView(String url, boolean recreatePlugins) { + if (url.equals("about:blank") || url.startsWith("javascript:")) { + webView.loadUrl(url); + return; + } + } + + @Override + public void stopLoading() {} + + @Override + public boolean canGoBack() { + return false; + } + + @Override + public void clearCache() {} + + @Deprecated + @Override + public void clearCache(boolean b) {} + + @Override + public void clearHistory() {} + + @Override + public boolean backHistory() { + return false; + } + + @Override + public void handlePause(boolean keepRunning) { + if (!isInitialized()) { + return; + } + hasPausedEver = true; + pluginManager.onPause(keepRunning); + triggerDocumentEvent("pause"); + // If app doesn't want to run in background + if (!keepRunning) { + // Pause JavaScript timers. This affects all webviews within the app! + this.setPaused(true); + } + } + + @Override + public void onNewIntent(Intent intent) { + if (this.pluginManager != null) { + this.pluginManager.onNewIntent(intent); + } + } + + @Override + public void handleResume(boolean keepRunning) { + if (!isInitialized()) { + return; + } + this.setPaused(false); + this.pluginManager.onResume(keepRunning); + if (hasPausedEver) { + triggerDocumentEvent("resume"); + } + } + + @Override + public void handleStart() { + if (!isInitialized()) { + return; + } + pluginManager.onStart(); + } + + @Override + public void handleStop() { + if (!isInitialized()) { + return; + } + pluginManager.onStop(); + } + + @Override + public void handleDestroy() { + if (!isInitialized()) { + return; + } + this.pluginManager.onDestroy(); + } + + @Deprecated + @Override + public void sendJavascript(String statememt) { + nativeToJsMessageQueue.addJavaScript(statememt); + } + + public void eval(final String js, final ValueCallback callback) { + Handler mainHandler = new Handler(context.getMainLooper()); + mainHandler.post(() -> webView.evaluateJavascript(js, callback)); + } + + public void triggerDocumentEvent(final String eventName) { + eval("window.Capacitor.triggerEvent('" + eventName + "', 'document');", (s) -> {}); + } + + @Override + public void showWebPage(String url, boolean openExternal, boolean clearHistory, Map params) {} + + @Deprecated + @Override + public boolean isCustomViewShowing() { + return false; + } + + @Deprecated + @Override + public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {} + + @Deprecated + @Override + public void hideCustomView() {} + + @Override + public CordovaResourceApi getResourceApi() { + return this.resourceApi; + } + + @Override + public void setButtonPlumbedToJs(int keyCode, boolean override) {} + + @Override + public boolean isButtonPlumbedToJs(int keyCode) { + return false; + } + + @Override + public void sendPluginResult(PluginResult cr, String callbackId) { + nativeToJsMessageQueue.addPluginResult(cr, callbackId); + } + + @Override + public PluginManager getPluginManager() { + return this.pluginManager; + } + + @Override + public CordovaWebViewEngine getEngine() { + return null; + } + + @Override + public CordovaPreferences getPreferences() { + return this.preferences; + } + + @Override + public ICordovaCookieManager getCookieManager() { + return cookieManager; + } + + @Override + public String getUrl() { + return webView.getUrl(); + } + + @Override + public Context getContext() { + return this.webView.getContext(); + } + + @Override + public void loadUrl(String url) { + loadUrlIntoView(url, true); + } + + @Override + public Object postMessage(String id, Object data) { + return pluginManager.postMessage(id, data); + } + + public void setPaused(boolean value) { + if (value) { + webView.onPause(); + webView.pauseTimers(); + } else { + webView.onResume(); + webView.resumeTimers(); + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java new file mode 100644 index 0000000..cf4ab63 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java @@ -0,0 +1,239 @@ +package com.getcapacitor.plugin; + +import com.getcapacitor.Bridge; +import com.getcapacitor.Logger; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.CookieStore; +import java.net.HttpCookie; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; + +public class CapacitorCookieManager extends CookieManager { + + private final android.webkit.CookieManager webkitCookieManager; + + private final String localUrl; + + private final String serverUrl; + + private final String TAG = "CapacitorCookies"; + + /** + * Create a new cookie manager with the default cookie store and policy + */ + public CapacitorCookieManager(Bridge bridge) { + this(null, null, bridge); + } + + /** + * Create a new cookie manager with specified cookie store and cookie policy. + * @param store a {@code CookieStore} to be used by CookieManager. if {@code null}, cookie + * manager will use a default one, which is an in-memory CookieStore implementation. + * @param policy a {@code CookiePolicy} instance to be used by cookie manager as policy + * callback. if {@code null}, ACCEPT_ORIGINAL_SERVER will be used. + */ + public CapacitorCookieManager(CookieStore store, CookiePolicy policy, Bridge bridge) { + super(store, policy); + webkitCookieManager = android.webkit.CookieManager.getInstance(); + this.localUrl = bridge.getLocalUrl(); + this.serverUrl = bridge.getServerUrl(); + } + + public void removeSessionCookies() { + this.webkitCookieManager.removeSessionCookies(null); + } + + public String getSanitizedDomain(String url) throws URISyntaxException { + if (this.serverUrl != null && !this.serverUrl.isEmpty() && (url == null || url.isEmpty() || this.serverUrl.contains(url))) { + url = this.serverUrl; + } else if (this.localUrl != null && !this.localUrl.isEmpty() && (url == null || url.isEmpty() || this.localUrl.contains(url))) { + url = this.localUrl; + } else try { + URI uri = new URI(url); + String scheme = uri.getScheme(); + if (scheme == null || scheme.isEmpty()) { + url = "https://" + url; + } + } catch (URISyntaxException e) { + Logger.error(TAG, "Failed to get scheme from URL.", e); + } + + try { + new URI(url); + } catch (Exception error) { + Logger.error(TAG, "Failed to get sanitized URL.", error); + throw error; + } + return url; + } + + private String getDomainFromCookieString(String cookie) throws URISyntaxException { + String[] domain = cookie.toLowerCase(Locale.ROOT).split("domain="); + return getSanitizedDomain(domain.length <= 1 ? null : domain[1].split(";")[0].trim()); + } + + /** + * Gets the cookies for the given URL. + * @param url the URL for which the cookies are requested + * @return value the cookies as a string, using the format of the 'Cookie' HTTP request header + */ + public String getCookieString(String url) { + try { + url = getSanitizedDomain(url); + Logger.info(TAG, "Getting cookies at: '" + url + "'"); + return webkitCookieManager.getCookie(url); + } catch (Exception error) { + Logger.error(TAG, "Failed to get cookies at the given URL.", error); + } + + return null; + } + + /** + * Gets a cookie value for the given URL and key. + * @param url the URL for which the cookies are requested + * @param key the key of the cookie to search for + * @return the {@code HttpCookie} value of the cookie at the key, + * otherwise it will return a new empty {@code HttpCookie} + */ + public HttpCookie getCookie(String url, String key) { + HttpCookie[] cookies = getCookies(url); + for (HttpCookie cookie : cookies) { + if (cookie.getName().equals(key)) { + return cookie; + } + } + + return null; + } + + /** + * Gets an array of {@code HttpCookie} given a URL. + * @param url the URL for which the cookies are requested + * @return an {@code HttpCookie} array of non-expired cookies + */ + public HttpCookie[] getCookies(String url) { + try { + ArrayList cookieList = new ArrayList<>(); + String cookieString = getCookieString(url); + if (cookieString != null) { + String[] singleCookie = cookieString.split(";"); + for (String c : singleCookie) { + HttpCookie parsed = HttpCookie.parse(c).get(0); + parsed.setValue(parsed.getValue()); + cookieList.add(parsed); + } + } + HttpCookie[] cookies = new HttpCookie[cookieList.size()]; + return cookieList.toArray(cookies); + } catch (Exception ex) { + return new HttpCookie[0]; + } + } + + /** + * Sets a cookie for the given URL. Any existing cookie with the same host, path and name will + * be replaced with the new cookie. The cookie being set will be ignored if it is expired. + * @param url the URL for which the cookie is to be set + * @param value the cookie as a string, using the format of the 'Set-Cookie' HTTP response header + */ + public void setCookie(String url, String value) { + try { + url = getSanitizedDomain(url); + Logger.info(TAG, "Setting cookie '" + value + "' at: '" + url + "'"); + webkitCookieManager.setCookie(url, value); + flush(); + } catch (Exception error) { + Logger.error(TAG, "Failed to set cookie.", error); + } + } + + /** + * Sets a cookie for the given URL. Any existing cookie with the same host, path and name will + * be replaced with the new cookie. The cookie being set will be ignored if it is expired. + * @param url the URL for which the cookie is to be set + * @param key the {@code HttpCookie} name to use for lookup + * @param value the value of the {@code HttpCookie} given a key + */ + public void setCookie(String url, String key, String value) { + String cookieValue = key + "=" + value; + setCookie(url, cookieValue); + } + + public void setCookie(String url, String key, String value, String expires, String path) { + String cookieValue = key + "=" + value + "; expires=" + expires + "; path=" + path; + setCookie(url, cookieValue); + } + + /** + * Removes all cookies. This method is asynchronous. + */ + public void removeAllCookies() { + webkitCookieManager.removeAllCookies(null); + flush(); + } + + /** + * Ensures all cookies currently accessible through the getCookie API are written to persistent + * storage. This call will block the caller until it is done and may perform I/O. + */ + public void flush() { + webkitCookieManager.flush(); + } + + @Override + public void put(URI uri, Map> responseHeaders) { + // make sure our args are valid + if ((uri == null) || (responseHeaders == null)) return; + + // go over the headers + for (String headerKey : responseHeaders.keySet()) { + // ignore headers which aren't cookie related + if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue; + + // process each of the headers + for (String headerValue : Objects.requireNonNull(responseHeaders.get(headerKey))) { + try { + // Set at the requested server url + setCookie(uri.toString(), headerValue); + + // Set at the defined domain in the response or at default capacitor hosted url + setCookie(getDomainFromCookieString(headerValue), headerValue); + } catch (Exception ignored) {} + } + } + } + + @Override + public Map> get(URI uri, Map> requestHeaders) { + // make sure our args are valid + if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null"); + + // save our url once + String url = uri.toString(); + + // prepare our response + Map> res = new HashMap<>(); + + // get the cookie + String cookie = getCookieString(url); + + // return it + if (cookie != null) res.put("Cookie", Collections.singletonList(cookie)); + return res; + } + + @Override + public CookieStore getCookieStore() { + // we don't want anyone to work with this cookie store directly + throw new UnsupportedOperationException(); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java new file mode 100644 index 0000000..6ba4605 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java @@ -0,0 +1,119 @@ +package com.getcapacitor.plugin; + +import android.webkit.JavascriptInterface; +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginConfig; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; +import java.io.UnsupportedEncodingException; +import java.net.CookieHandler; +import java.net.HttpCookie; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + +@CapacitorPlugin +public class CapacitorCookies extends Plugin { + + CapacitorCookieManager cookieManager; + + @Override + public void load() { + this.bridge.getWebView().addJavascriptInterface(this, "CapacitorCookiesAndroidInterface"); + this.cookieManager = new CapacitorCookieManager(null, java.net.CookiePolicy.ACCEPT_ALL, this.bridge); + this.cookieManager.removeSessionCookies(); + CookieHandler.setDefault(this.cookieManager); + super.load(); + } + + @Override + protected void handleOnDestroy() { + super.handleOnDestroy(); + this.cookieManager.removeSessionCookies(); + } + + @JavascriptInterface + public boolean isEnabled() { + PluginConfig pluginConfig = getBridge().getConfig().getPluginConfiguration("CapacitorCookies"); + return pluginConfig.getBoolean("enabled", false); + } + + @JavascriptInterface + public void setCookie(String domain, String action) { + cookieManager.setCookie(domain, action); + } + + @PluginMethod + public void getCookies(PluginCall call) { + this.bridge.eval("document.cookie", (value) -> { + String cookies = value.substring(1, value.length() - 1); + String[] cookieArray = cookies.split(";"); + + JSObject cookieMap = new JSObject(); + + for (String cookie : cookieArray) { + if (cookie.length() > 0) { + String[] keyValue = cookie.split("=", 2); + + if (keyValue.length == 2) { + String key = keyValue[0].trim(); + String val = keyValue[1].trim(); + try { + key = URLDecoder.decode(keyValue[0].trim(), StandardCharsets.UTF_8.name()); + val = URLDecoder.decode(keyValue[1].trim(), StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException ignored) {} + + cookieMap.put(key, val); + } + } + } + + call.resolve(cookieMap); + }); + } + + @PluginMethod + public void setCookie(PluginCall call) { + String key = call.getString("key"); + if (null == key) { + call.reject("Must provide key"); + } + String value = call.getString("value"); + if (null == value) { + call.reject("Must provide value"); + } + String url = call.getString("url"); + String expires = call.getString("expires", ""); + String path = call.getString("path", "/"); + cookieManager.setCookie(url, key, value, expires, path); + call.resolve(); + } + + @PluginMethod + public void deleteCookie(PluginCall call) { + String key = call.getString("key"); + if (null == key) { + call.reject("Must provide key"); + } + String url = call.getString("url"); + cookieManager.setCookie(url, key + "=; Expires=Wed, 31 Dec 2000 23:59:59 GMT"); + call.resolve(); + } + + @PluginMethod + public void clearCookies(PluginCall call) { + String url = call.getString("url"); + HttpCookie[] cookies = cookieManager.getCookies(url); + for (HttpCookie cookie : cookies) { + cookieManager.setCookie(url, cookie.getName() + "=; Expires=Wed, 31 Dec 2000 23:59:59 GMT"); + } + call.resolve(); + } + + @PluginMethod + public void clearAllCookies(PluginCall call) { + cookieManager.removeAllCookies(); + call.resolve(); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java new file mode 100644 index 0000000..46bc174 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java @@ -0,0 +1,119 @@ +package com.getcapacitor.plugin; + +import android.Manifest; +import android.webkit.JavascriptInterface; +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginConfig; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; +import com.getcapacitor.annotation.Permission; +import com.getcapacitor.plugin.util.CapacitorHttpUrlConnection; +import com.getcapacitor.plugin.util.HttpRequestHandler; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@CapacitorPlugin( + permissions = { + @Permission(strings = { Manifest.permission.WRITE_EXTERNAL_STORAGE }, alias = "HttpWrite"), + @Permission(strings = { Manifest.permission.READ_EXTERNAL_STORAGE }, alias = "HttpRead") + } +) +public class CapacitorHttp extends Plugin { + + private final Map activeRequests = new ConcurrentHashMap<>(); + private final ExecutorService executor = Executors.newCachedThreadPool(); + + @Override + public void load() { + this.bridge.getWebView().addJavascriptInterface(this, "CapacitorHttpAndroidInterface"); + super.load(); + } + + @Override + protected void handleOnDestroy() { + super.handleOnDestroy(); + + for (Map.Entry entry : activeRequests.entrySet()) { + Runnable job = entry.getKey(); + PluginCall call = entry.getValue(); + + if (call.getData().has("activeCapacitorHttpUrlConnection")) { + try { + CapacitorHttpUrlConnection connection = (CapacitorHttpUrlConnection) call + .getData() + .get("activeCapacitorHttpUrlConnection"); + connection.disconnect(); + call.getData().remove("activeCapacitorHttpUrlConnection"); + } catch (Exception ignored) {} + } + + getBridge().releaseCall(call); + } + + activeRequests.clear(); + executor.shutdownNow(); + } + + private void http(final PluginCall call, final String httpMethod) { + Runnable asyncHttpCall = new Runnable() { + @Override + public void run() { + try { + JSObject response = HttpRequestHandler.request(call, httpMethod, getBridge()); + call.resolve(response); + } catch (Exception e) { + call.reject(e.getLocalizedMessage(), e.getClass().getSimpleName(), e); + } finally { + activeRequests.remove(this); + } + } + }; + + if (!executor.isShutdown()) { + activeRequests.put(asyncHttpCall, call); + executor.submit(asyncHttpCall); + } else { + call.reject("Failed to execute request - Http Plugin was shutdown"); + } + } + + @JavascriptInterface + public boolean isEnabled() { + PluginConfig pluginConfig = getBridge().getConfig().getPluginConfiguration("CapacitorHttp"); + return pluginConfig.getBoolean("enabled", false); + } + + @PluginMethod + public void request(final PluginCall call) { + this.http(call, null); + } + + @PluginMethod + public void get(final PluginCall call) { + this.http(call, "GET"); + } + + @PluginMethod + public void post(final PluginCall call) { + this.http(call, "POST"); + } + + @PluginMethod + public void put(final PluginCall call) { + this.http(call, "PUT"); + } + + @PluginMethod + public void patch(final PluginCall call) { + this.http(call, "PATCH"); + } + + @PluginMethod + public void delete(final PluginCall call) { + this.http(call, "DELETE"); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java new file mode 100644 index 0000000..b335b4b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java @@ -0,0 +1,346 @@ +package com.getcapacitor.plugin; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.Build; +import android.util.TypedValue; +import android.view.View; +import android.view.Window; +import android.webkit.JavascriptInterface; +import android.webkit.WebView; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import androidx.webkit.WebViewCompat; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.WebViewListener; +import com.getcapacitor.annotation.CapacitorPlugin; +import java.util.Locale; + +@CapacitorPlugin +public class SystemBars extends Plugin { + + static final String STYLE_LIGHT = "LIGHT"; + static final String STYLE_DARK = "DARK"; + static final String STYLE_DEFAULT = "DEFAULT"; + static final String BAR_STATUS_BAR = "StatusBar"; + static final String BAR_GESTURE_BAR = "NavigationBar"; + + static final String INSETS_HANDLING_CSS = "css"; + static final String INSETS_HANDLING_DISABLE = "disable"; + + // https://issues.chromium.org/issues/40699457 + private static final int WEBVIEW_VERSION_WITH_SAFE_AREA_FIX = 140; + // https://issues.chromium.org/issues/457682720 + private static final int WEBVIEW_VERSION_WITH_SAFE_AREA_KEYBOARD_FIX = 144; + + static final String viewportMetaJSFunction = """ + function capacitorSystemBarsCheckMetaViewport() { + const meta = document.querySelectorAll("meta[name=viewport]"); + if (meta.length == 0) { + return false; + } + // get the last found meta viewport tag + const metaContent = meta[meta.length - 1].content; + return metaContent.includes("viewport-fit=cover"); + } + capacitorSystemBarsCheckMetaViewport(); + """; + + private boolean insetHandlingEnabled = true; + private boolean hasViewportCover = false; + + private String currentStatusBarStyle = STYLE_DEFAULT; + private String currentGestureBarStyle = STYLE_DEFAULT; + + @Override + public void load() { + getBridge().getWebView().addJavascriptInterface(this, "CapacitorSystemBarsAndroidInterface"); + super.load(); + + initSystemBars(); + } + + @Override + protected void handleOnStart() { + super.handleOnStart(); + + this.getBridge().addWebViewListener( + new WebViewListener() { + @Override + public void onPageCommitVisible(WebView view, String url) { + super.onPageCommitVisible(view, url); + getBridge().getWebView().requestApplyInsets(); + } + } + ); + } + + @Override + protected void handleOnConfigurationChanged(Configuration newConfig) { + super.handleOnConfigurationChanged(newConfig); + + setStyle(currentGestureBarStyle, BAR_GESTURE_BAR); + setStyle(currentStatusBarStyle, BAR_STATUS_BAR); + } + + private void initSystemBars() { + String style = getConfig().getString("style", STYLE_DEFAULT).toUpperCase(Locale.US); + boolean hidden = getConfig().getBoolean("hidden", false); + + String insetsHandling = getConfig().getString("insetsHandling", "css"); + if (insetsHandling.equals(INSETS_HANDLING_DISABLE)) { + insetHandlingEnabled = false; + } + + initWindowInsetsListener(); + initSafeAreaCSSVariables(); + + getBridge().executeOnMainThread(() -> { + setStyle(style, ""); + setHidden(hidden, ""); + }); + } + + @PluginMethod + public void setStyle(final PluginCall call) { + String bar = call.getString("bar", ""); + String style = call.getString("style", STYLE_DEFAULT); + + getBridge().executeOnMainThread(() -> { + setStyle(style, bar); + call.resolve(); + }); + } + + @PluginMethod + public void show(final PluginCall call) { + String bar = call.getString("bar", ""); + + getBridge().executeOnMainThread(() -> { + setHidden(false, bar); + call.resolve(); + }); + } + + @PluginMethod + public void hide(final PluginCall call) { + String bar = call.getString("bar", ""); + + getBridge().executeOnMainThread(() -> { + setHidden(true, bar); + call.resolve(); + }); + } + + @PluginMethod + public void setAnimation(final PluginCall call) { + call.resolve(); + } + + @JavascriptInterface + public void onDOMReady() { + getActivity().runOnUiThread(() -> { + this.bridge.getWebView().evaluateJavascript(viewportMetaJSFunction, (res) -> { + hasViewportCover = res.equals("true"); + + getBridge().getWebView().requestApplyInsets(); + }); + }); + } + + private Insets calcSafeAreaInsets(WindowInsetsCompat insets) { + Insets safeArea = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()); + if (insets.isVisible(WindowInsetsCompat.Type.ime())) { + return Insets.of(safeArea.left, safeArea.top, safeArea.right, 0); + } + return Insets.of(safeArea.left, safeArea.top, safeArea.right, safeArea.bottom); + } + + private void initSafeAreaCSSVariables() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && insetHandlingEnabled) { + View v = (View) this.getBridge().getWebView().getParent(); + WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(v); + if (insets != null) { + Insets safeAreaInsets = calcSafeAreaInsets(insets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); + } + } + } + + private void initWindowInsetsListener() { + ViewCompat.setOnApplyWindowInsetsListener((View) getBridge().getWebView().getParent(), (v, insets) -> { + boolean shouldPassthroughInsets = getWebViewMajorVersion() >= WEBVIEW_VERSION_WITH_SAFE_AREA_FIX && hasViewportCover; + + Insets systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()); + Insets imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime()); + boolean keyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); + + if (shouldPassthroughInsets) { + // We need to correct for a possible shown IME + v.setPadding(0, 0, 0, keyboardVisible ? imeInsets.bottom : 0); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && hasViewportCover && insetHandlingEnabled) { + Insets safeAreaInsets = calcSafeAreaInsets(insets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); + } + + return new WindowInsetsCompat.Builder(insets) + .setInsets( + WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(), + Insets.of( + systemBarsInsets.left, + systemBarsInsets.top, + systemBarsInsets.right, + getBottomInset(systemBarsInsets, keyboardVisible) + ) + ) + .build(); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + // We need to correct for a possible shown IME + v.setPadding( + systemBarsInsets.left, + systemBarsInsets.top, + systemBarsInsets.right, + keyboardVisible ? imeInsets.bottom : systemBarsInsets.bottom + ); + } + + // Returning `WindowInsetsCompat.CONSUMED` breaks recalculation of safe area insets + // So we have to explicitly set insets to `0` + // See: https://issues.chromium.org/issues/461332423 + WindowInsetsCompat newInsets = new WindowInsetsCompat.Builder(insets) + .setInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(), Insets.of(0, 0, 0, 0)) + .build(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && hasViewportCover && insetHandlingEnabled) { + Insets safeAreaInsets = calcSafeAreaInsets(newInsets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); + } + + return newInsets; + }); + } + + private void injectSafeAreaCSS(int top, int right, int bottom, int left) { + // Convert pixels to density-independent pixels + float density = getActivity().getResources().getDisplayMetrics().density; + float topPx = top / density; + float rightPx = right / density; + float bottomPx = bottom / density; + float leftPx = left / density; + + // Execute JavaScript to inject the CSS + getBridge().executeOnMainThread(() -> { + if (bridge != null && bridge.getWebView() != null) { + String script = String.format( + Locale.US, + """ + try { + document.documentElement.style.setProperty("--safe-area-inset-top", "%dpx"); + document.documentElement.style.setProperty("--safe-area-inset-right", "%dpx"); + document.documentElement.style.setProperty("--safe-area-inset-bottom", "%dpx"); + document.documentElement.style.setProperty("--safe-area-inset-left", "%dpx"); + } catch(e) { console.error('Error injecting safe area CSS:', e); } + """, + (int) topPx, + (int) rightPx, + (int) bottomPx, + (int) leftPx + ); + + bridge.getWebView().evaluateJavascript(script, null); + } + }); + } + + private void setStyle(String style, String bar) { + if (style.equals(STYLE_DEFAULT)) { + style = getStyleForTheme(); + } + + Window window = getActivity().getWindow(); + WindowInsetsControllerCompat windowInsetsControllerCompat = WindowCompat.getInsetsController(window, window.getDecorView()); + if (bar.isEmpty() || bar.equals(BAR_STATUS_BAR)) { + currentStatusBarStyle = style; + windowInsetsControllerCompat.setAppearanceLightStatusBars(!style.equals(STYLE_DARK)); + } + + if (bar.isEmpty() || bar.equals(BAR_GESTURE_BAR)) { + currentGestureBarStyle = style; + windowInsetsControllerCompat.setAppearanceLightNavigationBars(!style.equals(STYLE_DARK)); + } + + getActivity().getWindow().getDecorView().setBackgroundColor(getThemeColor(getContext(), android.R.attr.windowBackground)); + } + + private void setHidden(boolean hide, String bar) { + Window window = getActivity().getWindow(); + WindowInsetsControllerCompat windowInsetsControllerCompat = WindowCompat.getInsetsController(window, window.getDecorView()); + + if (hide) { + if (bar.isEmpty() || bar.equals(BAR_STATUS_BAR)) { + windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.statusBars()); + } + if (bar.isEmpty() || bar.equals(BAR_GESTURE_BAR)) { + windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.navigationBars()); + } + return; + } + + if (bar.isEmpty() || bar.equals(BAR_STATUS_BAR)) { + windowInsetsControllerCompat.show(WindowInsetsCompat.Type.systemBars()); + } + if (bar.isEmpty() || bar.equals(BAR_GESTURE_BAR)) { + windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars()); + } + } + + private String getStyleForTheme() { + int currentNightMode = getActivity().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + if (currentNightMode != Configuration.UI_MODE_NIGHT_YES) { + return STYLE_LIGHT; + } + return STYLE_DARK; + } + + public int getThemeColor(Context context, int attrRes) { + TypedValue typedValue = new TypedValue(); + + Resources.Theme theme = context.getTheme(); + theme.resolveAttribute(attrRes, typedValue, true); + return typedValue.data; + } + + private Integer getWebViewMajorVersion() { + PackageInfo info = WebViewCompat.getCurrentWebViewPackage(getContext()); + if (info != null && info.versionName != null) { + String[] versionSegments = info.versionName.split("\\."); + return Integer.valueOf(versionSegments[0]); + } + + return 0; + } + + private int getBottomInset(Insets systemBarsInsets, boolean keyboardVisible) { + if (getWebViewMajorVersion() < WEBVIEW_VERSION_WITH_SAFE_AREA_KEYBOARD_FIX) { + // This is a workaround for webview versions that have a bug + // that causes the bottom inset to be incorrect if the IME is visible + // See: https://issues.chromium.org/issues/457682720 + + if (keyboardVisible) { + return 0; + } + } + + return systemBarsInsets.bottom; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/WebView.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/WebView.java new file mode 100644 index 0000000..096d62a --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/WebView.java @@ -0,0 +1,48 @@ +package com.getcapacitor.plugin; + +import android.app.Activity; +import android.content.SharedPreferences; +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; +import com.getcapacitor.annotation.CapacitorPlugin; + +@CapacitorPlugin +public class WebView extends Plugin { + + public static final String WEBVIEW_PREFS_NAME = "CapWebViewSettings"; + public static final String CAP_SERVER_PATH = "serverBasePath"; + + @PluginMethod + public void setServerAssetPath(PluginCall call) { + String path = call.getString("path"); + bridge.setServerAssetPath(path); + call.resolve(); + } + + @PluginMethod + public void setServerBasePath(PluginCall call) { + String path = call.getString("path"); + bridge.setServerBasePath(path); + call.resolve(); + } + + @PluginMethod + public void getServerBasePath(PluginCall call) { + String path = bridge.getServerBasePath(); + JSObject ret = new JSObject(); + ret.put("path", path); + call.resolve(ret); + } + + @PluginMethod + public void persistServerBasePath(PluginCall call) { + String path = bridge.getServerBasePath(); + SharedPreferences prefs = getContext().getSharedPreferences(WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(CAP_SERVER_PATH, path); + editor.apply(); + call.resolve(); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java new file mode 100644 index 0000000..3a7043b --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java @@ -0,0 +1,358 @@ +package com.getcapacitor.plugin.util; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.StrictMode; +import androidx.core.content.FileProvider; +import com.getcapacitor.Logger; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; + +/** + * Manager for assets. + */ +public final class AssetUtil { + + public static final int RESOURCE_ID_ZERO_VALUE = 0; + // Name of the storage folder + private static final String STORAGE_FOLDER = "/capacitorassets"; + + // Ref to the context passed through the constructor to access the + // resources and app directory. + private final Context context; + + /** + * Constructor + * + * @param context Application context. + */ + private AssetUtil(Context context) { + this.context = context; + } + + /** + * Static method to retrieve class instance. + * + * @param context Application context. + */ + public static AssetUtil getInstance(Context context) { + return new AssetUtil(context); + } + + /** + * The URI for a path. + * + * @param path The given path. + */ + public Uri parse(String path) { + if (path == null || path.isEmpty()) { + return Uri.EMPTY; + } else if (path.startsWith("res:")) { + return getUriForResourcePath(path); + } else if (path.startsWith("file:///")) { + return getUriFromPath(path); + } else if (path.startsWith("file://")) { + return getUriFromAsset(path); + } else if (path.startsWith("http")) { + return getUriFromRemote(path); + } else if (path.startsWith("content://")) { + return Uri.parse(path); + } + + return Uri.EMPTY; + } + + /** + * URI for a file. + * + * @param path Absolute path like file:///... + * + * @return URI pointing to the given path. + */ + private Uri getUriFromPath(String path) { + String absPath = path.replaceFirst("file://", "").replaceFirst("\\?.*$", ""); + File file = new File(absPath); + + if (!file.exists()) { + Logger.error("File not found: " + file.getAbsolutePath()); + return Uri.EMPTY; + } + + return getUriFromFile(file); + } + + /** + * URI for an asset. + * + * @param path Asset path like file://... + * + * @return URI pointing to the given path. + */ + private Uri getUriFromAsset(String path) { + String resPath = path.replaceFirst("file:/", "www").replaceFirst("\\?.*$", ""); + String fileName = resPath.substring(resPath.lastIndexOf('/') + 1); + File file = getTmpFile(fileName); + + if (file == null) return Uri.EMPTY; + + try { + AssetManager assets = context.getAssets(); + InputStream in = assets.open(resPath); + FileOutputStream out = new FileOutputStream(file); + copyFile(in, out); + } catch (Exception e) { + Logger.error("File not found: assets/" + resPath); + return Uri.EMPTY; + } + + return getUriFromFile(file); + } + + /** + * The URI for a resource. + * + * @param path The given relative path. + * + * @return URI pointing to the given path. + */ + private Uri getUriForResourcePath(String path) { + Resources res = context.getResources(); + String resPath = path.replaceFirst("res://", ""); + int resId = getResId(resPath); + + if (resId == 0) { + Logger.error("File not found: " + resPath); + return Uri.EMPTY; + } + + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + .authority(res.getResourcePackageName(resId)) + .appendPath(res.getResourceTypeName(resId)) + .appendPath(res.getResourceEntryName(resId)) + .build(); + } + + /** + * Uri from remote located content. + * + * @param path Remote address. + * + * @return Uri of the downloaded file. + */ + private Uri getUriFromRemote(String path) { + File file = getTmpFile(); + + if (file == null) return Uri.EMPTY; + + try { + URL url = new URL(path); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); + + StrictMode.setThreadPolicy(policy); + + connection.setRequestProperty("Connection", "close"); + connection.setConnectTimeout(5000); + connection.connect(); + + InputStream in = connection.getInputStream(); + FileOutputStream out = new FileOutputStream(file); + + copyFile(in, out); + return getUriFromFile(file); + } catch (MalformedURLException e) { + Logger.error(Logger.tags("Asset"), "Incorrect URL", e); + } catch (FileNotFoundException e) { + Logger.error(Logger.tags("Asset"), "Failed to create new File from HTTP Content", e); + } catch (IOException e) { + Logger.error(Logger.tags("Asset"), "No Input can be created from http Stream", e); + } + + return Uri.EMPTY; + } + + /** + * Copy content from input stream into output stream. + * + * @param in The input stream. + * @param out The output stream. + */ + private void copyFile(InputStream in, FileOutputStream out) { + byte[] buffer = new byte[1024]; + int read; + + try { + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + out.flush(); + out.close(); + } catch (Exception e) { + Logger.error("Error copying", e); + } + } + + /** + * Resource ID for drawable. + * + * @param resPath Resource path as string. + * + * @return The resource ID or 0 if not found. + */ + public int getResId(String resPath) { + int resId = getResId(context.getResources(), resPath); + + if (resId == 0) { + resId = getResId(Resources.getSystem(), resPath); + } + + return resId; + } + + /** + * Get resource ID. + * + * @param res The resources where to look for. + * @param resPath The name of the resource. + * + * @return The resource ID or 0 if not found. + */ + private int getResId(Resources res, String resPath) { + String pkgName = getPkgName(res); + String resName = getBaseName(resPath); + int resId; + + resId = res.getIdentifier(resName, "mipmap", pkgName); + + if (resId == 0) { + resId = res.getIdentifier(resName, "drawable", pkgName); + } + + if (resId == 0) { + resId = res.getIdentifier(resName, "raw", pkgName); + } + + return resId; + } + + /** + * Convert URI to Bitmap. + * + * @param uri Internal image URI + */ + public Bitmap getIconFromUri(Uri uri) throws IOException { + InputStream input = context.getContentResolver().openInputStream(uri); + return BitmapFactory.decodeStream(input); + } + + /** + * Extract name of drawable resource from path. + * + * @param resPath Resource path as string. + */ + private String getBaseName(String resPath) { + String drawable = resPath; + + if (drawable.contains("/")) { + drawable = drawable.substring(drawable.lastIndexOf('/') + 1); + } + + if (resPath.contains(".")) { + drawable = drawable.substring(0, drawable.lastIndexOf('.')); + } + + return drawable; + } + + /** + * Returns a file located under the external cache dir of that app. + * + * @return File with a random UUID name. + */ + private File getTmpFile() { + return getTmpFile(UUID.randomUUID().toString()); + } + + /** + * Returns a file located under the external cache dir of that app. + * + * @param name The name of the file. + * + * @return File with the provided name. + */ + private File getTmpFile(String name) { + File dir = context.getExternalCacheDir(); + + if (dir == null) { + dir = context.getCacheDir(); + } + + if (dir == null) { + Logger.error(Logger.tags("Asset"), "Missing cache dir", null); + return null; + } + + String storage = dir.toString() + STORAGE_FOLDER; + + //noinspection ResultOfMethodCallIgnored + new File(storage).mkdir(); + + return new File(storage, name); + } + + /** + * Get content URI for the specified file. + * + * @param file The file to get the URI. + * + * @return content://... + */ + private Uri getUriFromFile(File file) { + try { + String authority = context.getPackageName() + ".provider"; + return FileProvider.getUriForFile(context, authority, file); + } catch (IllegalArgumentException e) { + Logger.error("File not supported by provider", e); + return Uri.EMPTY; + } + } + + /** + * Package name specified by the resource bundle. + */ + private String getPkgName(Resources res) { + return res == Resources.getSystem() ? "android" : context.getPackageName(); + } + + public static int getResourceID(Context context, String resourceName, String dir) { + return context.getResources().getIdentifier(resourceName, dir, context.getPackageName()); + } + + public static String getResourceBaseName(String resPath) { + if (resPath == null) return null; + + if (resPath.contains("/")) { + return resPath.substring(resPath.lastIndexOf('/') + 1); + } + + if (resPath.contains(".")) { + return resPath.substring(0, resPath.lastIndexOf('.')); + } + + return resPath; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java new file mode 100644 index 0000000..6180d64 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/CapacitorHttpUrlConnection.java @@ -0,0 +1,515 @@ +package com.getcapacitor.plugin.util; + +import android.os.Build; +import android.os.LocaleList; +import android.text.TextUtils; +import com.getcapacitor.Bridge; +import com.getcapacitor.JSArray; +import com.getcapacitor.JSObject; +import com.getcapacitor.JSValue; +import com.getcapacitor.PluginCall; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.ProtocolException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLEncoder; +import java.net.UnknownServiceException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; +import org.json.JSONException; +import org.json.JSONObject; + +public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection { + + private final HttpURLConnection connection; + + /** + * Make a new CapacitorHttpUrlConnection instance, which wraps around HttpUrlConnection + * and provides some helper functions for setting request headers and the request body + * @param conn the base HttpUrlConnection. You can pass the value from + * {@code (HttpUrlConnection) URL.openConnection()} + */ + public CapacitorHttpUrlConnection(HttpURLConnection conn) { + connection = conn; + this.setDefaultRequestProperties(); + } + + /** + * Returns the underlying HttpUrlConnection value + * @return the underlying HttpUrlConnection value + */ + public HttpURLConnection getHttpConnection() { + return connection; + } + + public void disconnect() { + connection.disconnect(); + } + + /** + * Set the value of the {@code allowUserInteraction} field of + * this {@code URLConnection}. + * + * @param isAllowedInteraction the new value. + * @throws IllegalStateException if already connected + */ + public void setAllowUserInteraction(boolean isAllowedInteraction) { + connection.setAllowUserInteraction(isAllowedInteraction); + } + + /** + * Set the method for the URL request, one of: + *
    + *
  • GET + *
  • POST + *
  • HEAD + *
  • OPTIONS + *
  • PUT + *
  • DELETE + *
  • TRACE + *
are legal, subject to protocol restrictions. The default + * method is GET. + * + * @param method the HTTP method + * @exception ProtocolException if the method cannot be reset or if + * the requested method isn't valid for HTTP. + * @exception SecurityException if a security manager is set and the + * method is "TRACE", but the "allowHttpTrace" + * NetPermission is not granted. + */ + public void setRequestMethod(String method) throws ProtocolException { + connection.setRequestMethod(method); + } + + /** + * Sets a specified timeout value, in milliseconds, to be used + * when opening a communications link to the resource referenced + * by this URLConnection. If the timeout expires before the + * connection can be established, a + * java.net.SocketTimeoutException is raised. A timeout of zero is + * interpreted as an infinite timeout. + * + *

Warning: If the hostname resolves to multiple IP + * addresses, Android's default implementation of {@link HttpURLConnection} + * will try each in + * RFC 3484 order. If + * connecting to each of these addresses fails, multiple timeouts will + * elapse before the connect attempt throws an exception. Host names + * that support both IPv6 and IPv4 always have at least 2 IP addresses. + * + * @param timeout an {@code int} that specifies the connect + * timeout value in milliseconds + * @throws IllegalArgumentException if the timeout parameter is negative + */ + public void setConnectTimeout(int timeout) { + if (timeout < 0) { + throw new IllegalArgumentException("timeout can not be negative"); + } + connection.setConnectTimeout(timeout); + } + + /** + * Sets the read timeout to a specified timeout, in + * milliseconds. A non-zero value specifies the timeout when + * reading from Input stream when a connection is established to a + * resource. If the timeout expires before there is data available + * for read, a java.net.SocketTimeoutException is raised. A + * timeout of zero is interpreted as an infinite timeout. + * + * @param timeout an {@code int} that specifies the timeout + * value to be used in milliseconds + * @throws IllegalArgumentException if the timeout parameter is negative + */ + public void setReadTimeout(int timeout) { + if (timeout < 0) { + throw new IllegalArgumentException("timeout can not be negative"); + } + connection.setReadTimeout(timeout); + } + + /** + * Sets whether automatic HTTP redirects should be disabled + * @param disableRedirects the flag to determine if redirects should be followed + */ + public void setDisableRedirects(boolean disableRedirects) { + connection.setInstanceFollowRedirects(!disableRedirects); + } + + /** + * Sets the request headers given a JSObject of key-value pairs + * @param headers the JSObject values to map to the HttpUrlConnection request headers + */ + public void setRequestHeaders(JSObject headers) { + Iterator keys = headers.keys(); + while (keys.hasNext()) { + String key = keys.next(); + String value = headers.getString(key); + connection.setRequestProperty(key, value); + } + } + + /** + * Sets the value of the {@code doOutput} field for this + * {@code URLConnection} to the specified value. + *

+ * A URL connection can be used for input and/or output. Set the DoOutput + * flag to true if you intend to use the URL connection for output, + * false if not. The default is false. + * + * @param shouldDoOutput the new value. + * @throws IllegalStateException if already connected + */ + public void setDoOutput(boolean shouldDoOutput) { + connection.setDoOutput(shouldDoOutput); + } + + /** + * + * @param call + * @throws JSONException + * @throws IOException + */ + public void setRequestBody(PluginCall call, JSValue body) throws JSONException, IOException { + setRequestBody(call, body, null); + } + + /** + * + * @param call + * @throws JSONException + * @throws IOException + */ + public void setRequestBody(PluginCall call, JSValue body, String bodyType) throws JSONException, IOException { + String contentType = connection.getRequestProperty("Content-Type"); + String dataString = ""; + + if (contentType == null || contentType.isEmpty()) return; + + if (contentType.contains("application/json")) { + JSArray jsArray = null; + if (body != null) { + dataString = body.toString(); + } else { + jsArray = call.getArray("data", null); + } + if (jsArray != null) { + dataString = jsArray.toString(); + } else if (body == null) { + dataString = call.getString("data"); + } + this.writeRequestBody(dataString != null ? dataString : ""); + } else if (bodyType != null && bodyType.equals("file")) { + try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + os.write(Base64.getDecoder().decode(body.toString())); + } + os.flush(); + } + } else if (contentType.contains("application/x-www-form-urlencoded")) { + try { + JSObject obj = body.toJSObject(); + this.writeObjectRequestBody(obj); + } catch (Exception e) { + // Body is not a valid JSON, treat it as an already formatted string + this.writeRequestBody(body.toString()); + } + } else if (bodyType != null && bodyType.equals("formData")) { + String boundary = extractBoundaryFromContentType(contentType); + if (boundary == null) { + // If no boundary is provided, generate a random one and set the Content-Type header accordingly + // or otherwise servers will not be able to parse the request body. Browsers do this automatically + // but here we need to do this manually in order to comply with browser api behavior. + boundary = UUID.randomUUID().toString(); + connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); + } + + this.writeFormDataRequestBody(boundary, body.toJSArray()); + } else { + this.writeRequestBody(body.toString()); + } + } + + /** + * Writes the provided string to the HTTP connection managed by this instance. + * + * @param body The string value to write to the connection stream. + */ + private void writeRequestBody(String body) throws IOException { + try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) { + os.write(body.getBytes(StandardCharsets.UTF_8)); + os.flush(); + } + } + + private void writeObjectRequestBody(JSObject object) throws IOException, JSONException { + try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) { + Iterator keys = object.keys(); + while (keys.hasNext()) { + String key = keys.next(); + Object d = object.get(key); + os.writeBytes(URLEncoder.encode(key, "UTF-8")); + os.writeBytes("="); + os.writeBytes(URLEncoder.encode(d.toString(), "UTF-8")); + + if (keys.hasNext()) { + os.writeBytes("&"); + } + } + os.flush(); + } + } + + private void writeFormDataRequestBody(String boundary, JSArray entries) throws IOException, JSONException { + try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) { + String lineEnd = "\r\n"; + String twoHyphens = "--"; + + for (Object e : entries.toList()) { + if (e instanceof JSONObject) { + JSONObject entry = (JSONObject) e; + String type = entry.getString("type"); + String key = entry.getString("key"); + String value = entry.getString("value"); + if (type.equals("string")) { + os.writeBytes(twoHyphens + boundary + lineEnd); + os.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"" + lineEnd + lineEnd); + os.write(value.getBytes(StandardCharsets.UTF_8)); + os.writeBytes(lineEnd); + } else if (type.equals("base64File")) { + String fileName = entry.getString("fileName"); + String fileContentType = entry.getString("contentType"); + + os.writeBytes(twoHyphens + boundary + lineEnd); + os.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + fileName + "\"" + lineEnd); + os.writeBytes("Content-Type: " + fileContentType + lineEnd); + os.writeBytes("Content-Transfer-Encoding: binary" + lineEnd); + os.writeBytes(lineEnd); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + os.write(Base64.getDecoder().decode(value)); + } else { + os.write(android.util.Base64.decode(value, android.util.Base64.DEFAULT)); + } + + os.writeBytes(lineEnd); + } + } + } + + os.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); + os.flush(); + } + } + + /** + * Extracts the boundary value from the `Content-Type` header for multipart/form-data requests, if provided. + * + * The boundary value might be surrounded by double quotes (") which will be stripped away. + * + * @param contentType The `Content-Type` header string. + * @return The boundary value if found, otherwise `null`. + */ + public static String extractBoundaryFromContentType(String contentType) { + String boundaryPrefix = "boundary="; + int boundaryIndex = contentType.indexOf(boundaryPrefix); + if (boundaryIndex == -1) { + return null; + } + + // Extract the substring starting right after "boundary=" + String boundary = contentType.substring(boundaryIndex + boundaryPrefix.length()); + + // Find the end of the boundary value by looking for the next ";" + int endIndex = boundary.indexOf(";"); + if (endIndex != -1) { + boundary = boundary.substring(0, endIndex); + } + + // Remove surrounding double quotes if present + boundary = boundary.trim(); + if (boundary.startsWith("\"") && boundary.endsWith("\"")) { + boundary = boundary.substring(1, boundary.length() - 1); + } + + return boundary; + } + + /** + * Opens a communications link to the resource referenced by this + * URL, if such a connection has not already been established. + *

+ * If the {@code connect} method is called when the connection + * has already been opened (indicated by the {@code connected} + * field having the value {@code true}), the call is ignored. + *

+ * URLConnection objects go through two phases: first they are + * created, then they are connected. After being created, and + * before being connected, various options can be specified + * (e.g., doInput and UseCaches). After connecting, it is an + * error to try to set them. Operations that depend on being + * connected, like getContentLength, will implicitly perform the + * connection, if necessary. + * + * @throws SocketTimeoutException if the timeout expires before + * the connection can be established + * @exception IOException if an I/O error occurs while opening the + * connection. + */ + public void connect() throws IOException { + connection.connect(); + } + + /** + * Gets the status code from an HTTP response message. + * For example, in the case of the following status lines: + *

+     * HTTP/1.0 200 OK
+     * HTTP/1.0 401 Unauthorized
+     * 
+ * It will return 200 and 401 respectively. + * Returns -1 if no code can be discerned + * from the response (i.e., the response is not valid HTTP). + * @throws IOException if an error occurred connecting to the server. + * @return the HTTP Status-Code, or -1 + */ + public int getResponseCode() throws IOException { + return connection.getResponseCode(); + } + + /** + * Returns the value of this {@code URLConnection}'s {@code URL} + * field. + * + * @return the value of this {@code URLConnection}'s {@code URL} + * field. + */ + public URL getURL() { + return connection.getURL(); + } + + /** + * Returns the error stream if the connection failed + * but the server sent useful data nonetheless. The + * typical example is when an HTTP server responds + * with a 404, which will cause a FileNotFoundException + * to be thrown in connect, but the server sent an HTML + * help page with suggestions as to what to do. + * + *

This method will not cause a connection to be initiated. If + * the connection was not connected, or if the server did not have + * an error while connecting or if the server had an error but + * no error data was sent, this method will return null. This is + * the default. + * + * @return an error stream if any, null if there have been no + * errors, the connection is not connected or the server sent no + * useful data. + */ + @Override + public InputStream getErrorStream() { + return connection.getErrorStream(); + } + + /** + * Returns the value of the named header field. + *

+ * If called on a connection that sets the same header multiple times + * with possibly different values, only the last value is returned. + * + * + * @param name the name of a header field. + * @return the value of the named header field, or {@code null} + * if there is no such field in the header. + */ + @Override + public String getHeaderField(String name) { + return connection.getHeaderField(name); + } + + /** + * Returns an input stream that reads from this open connection. + * + * A SocketTimeoutException can be thrown when reading from the + * returned input stream if the read timeout expires before data + * is available for read. + * + * @return an input stream that reads from this open connection. + * @exception IOException if an I/O error occurs while + * creating the input stream. + * @exception UnknownServiceException if the protocol does not support + * input. + * @see #setReadTimeout(int) + */ + @Override + public InputStream getInputStream() throws IOException { + return connection.getInputStream(); + } + + /** + * Returns an unmodifiable Map of the header fields. + * The Map keys are Strings that represent the + * response-header field names. Each Map value is an + * unmodifiable List of Strings that represents + * the corresponding field values. + * + * @return a Map of header fields + */ + public Map> getHeaderFields() { + return connection.getHeaderFields(); + } + + /** + * Sets the default request properties on the newly created connection. + * This is called as early as possible to allow overrides by user-provided values. + */ + private void setDefaultRequestProperties() { + String acceptLanguage = buildDefaultAcceptLanguageProperty(); + if (!TextUtils.isEmpty(acceptLanguage)) { + connection.setRequestProperty("Accept-Language", acceptLanguage); + } + } + + /** + * Builds and returns a locale string describing the device's current locale preferences. + */ + private String buildDefaultAcceptLanguageProperty() { + Locale locale = LocaleList.getDefault().get(0); + String result = ""; + String lang = locale.getLanguage(); + String country = locale.getCountry(); + if (!TextUtils.isEmpty(lang)) { + if (!TextUtils.isEmpty(country)) { + result = String.format("%s-%s,%s;q=0.5", lang, country, lang); + } else { + result = String.format("%s;q=0.5", lang); + } + } + return result; + } + + public void setSSLSocketFactory(Bridge bridge) { + // Attach SSL Certificates if Enterprise Plugin is available + try { + Class sslPinningImpl = Class.forName("io.ionic.sslpinning.SSLPinning"); + Method method = sslPinningImpl.getDeclaredMethod("getSSLSocketFactory", Bridge.class); + SSLSocketFactory sslSocketFactory = (SSLSocketFactory) method.invoke( + sslPinningImpl.getDeclaredConstructor().newInstance(), + bridge + ); + if (sslSocketFactory != null) { + ((HttpsURLConnection) this.connection).setSSLSocketFactory(sslSocketFactory); + } + } catch (Exception ignored) {} + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java new file mode 100644 index 0000000..b47d57c --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java @@ -0,0 +1,465 @@ +package com.getcapacitor.plugin.util; + +import android.text.TextUtils; +import android.util.Base64; +import com.getcapacitor.Bridge; +import com.getcapacitor.JSArray; +import com.getcapacitor.JSObject; +import com.getcapacitor.JSValue; +import com.getcapacitor.PluginCall; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class HttpRequestHandler { + + /** + * An enum specifying conventional HTTP Response Types + * See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType + */ + public enum ResponseType { + ARRAY_BUFFER("arraybuffer"), + BLOB("blob"), + DOCUMENT("document"), + JSON("json"), + TEXT("text"); + + private final String name; + + ResponseType(String name) { + this.name = name; + } + + static final ResponseType DEFAULT = TEXT; + + public static ResponseType parse(String value) { + for (ResponseType responseType : values()) { + if (responseType.name.equalsIgnoreCase(value)) { + return responseType; + } + } + return DEFAULT; + } + } + + /** + * Internal builder class for building a CapacitorHttpUrlConnection + */ + public static class HttpURLConnectionBuilder { + + public Integer connectTimeout; + public Integer readTimeout; + public Boolean disableRedirects; + public JSObject headers; + public String method; + public URL url; + + public CapacitorHttpUrlConnection connection; + + public HttpURLConnectionBuilder setConnectTimeout(Integer connectTimeout) { + this.connectTimeout = connectTimeout; + return this; + } + + public HttpURLConnectionBuilder setReadTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + public HttpURLConnectionBuilder setDisableRedirects(Boolean disableRedirects) { + this.disableRedirects = disableRedirects; + return this; + } + + public HttpURLConnectionBuilder setHeaders(JSObject headers) { + this.headers = headers; + return this; + } + + public HttpURLConnectionBuilder setMethod(String method) { + this.method = method; + return this; + } + + public HttpURLConnectionBuilder setUrl(URL url) { + this.url = url; + return this; + } + + public HttpURLConnectionBuilder openConnection() throws IOException { + connection = new CapacitorHttpUrlConnection((HttpURLConnection) url.openConnection()); + + connection.setAllowUserInteraction(false); + connection.setRequestMethod(method); + + if (connectTimeout != null) connection.setConnectTimeout(connectTimeout); + if (readTimeout != null) connection.setReadTimeout(readTimeout); + if (disableRedirects != null) connection.setDisableRedirects(disableRedirects); + + connection.setRequestHeaders(headers); + return this; + } + + public HttpURLConnectionBuilder setUrlParams(JSObject params) throws MalformedURLException, URISyntaxException, JSONException { + return this.setUrlParams(params, true); + } + + public HttpURLConnectionBuilder setUrlParams(JSObject params, boolean shouldEncode) + throws URISyntaxException, MalformedURLException { + String initialQuery = url.getQuery(); + String initialQueryBuilderStr = initialQuery == null ? "" : initialQuery; + + Iterator keys = params.keys(); + + if (!keys.hasNext()) { + return this; + } + + StringBuilder urlQueryBuilder = new StringBuilder(initialQueryBuilderStr); + + // Build the new query string + while (keys.hasNext()) { + String key = keys.next(); + + // Attempt as JSONArray and fallback to string if it fails + try { + StringBuilder value = new StringBuilder(); + JSONArray arr = params.getJSONArray(key); + for (int x = 0; x < arr.length(); x++) { + this.addUrlParam(value, key, arr.getString(x), shouldEncode); + if (x != arr.length() - 1) { + value.append("&"); + } + } + if (urlQueryBuilder.length() > 0) { + urlQueryBuilder.append("&"); + } + urlQueryBuilder.append(value); + } catch (JSONException e) { + if (urlQueryBuilder.length() > 0) { + urlQueryBuilder.append("&"); + } + this.addUrlParam(urlQueryBuilder, key, params.getString(key), shouldEncode); + } + } + + String urlQuery = urlQueryBuilder.toString(); + + URI uri = url.toURI(); + String unEncodedUrlString = + uri.getScheme() + + "://" + + uri.getAuthority() + + uri.getPath() + + ((!urlQuery.equals("")) ? "?" + urlQuery : "") + + ((uri.getFragment() != null) ? uri.getFragment() : ""); + this.url = new URL(unEncodedUrlString); + + return this; + } + + private static void addUrlParam(StringBuilder sb, String key, String value, boolean shouldEncode) { + if (shouldEncode) { + try { + key = URLEncoder.encode(key, "UTF-8"); + value = URLEncoder.encode(value, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException(ex.getCause()); + } + } + sb.append(key).append("=").append(value); + } + + public CapacitorHttpUrlConnection build() { + return connection; + } + } + + /** + * Builds an HTTP Response given CapacitorHttpUrlConnection and ResponseType objects. + * Defaults to ResponseType.DEFAULT + * @param connection The CapacitorHttpUrlConnection to respond with + * @throws IOException Thrown if the InputStream is unable to be parsed correctly + * @throws JSONException Thrown if the JSON is unable to be parsed + */ + public static JSObject buildResponse(CapacitorHttpUrlConnection connection) throws IOException, JSONException { + return buildResponse(connection, ResponseType.DEFAULT); + } + + /** + * Builds an HTTP Response given CapacitorHttpUrlConnection and ResponseType objects + * @param connection The CapacitorHttpUrlConnection to respond with + * @param responseType The requested ResponseType + * @return A JSObject that contains the HTTPResponse to return to the browser + * @throws IOException Thrown if the InputStream is unable to be parsed correctly + * @throws JSONException Thrown if the JSON is unable to be parsed + */ + public static JSObject buildResponse(CapacitorHttpUrlConnection connection, ResponseType responseType) + throws IOException, JSONException { + int statusCode = connection.getResponseCode(); + + JSObject output = new JSObject(); + output.put("status", statusCode); + output.put("headers", buildResponseHeaders(connection)); + output.put("url", connection.getURL()); + output.put("data", readData(connection, responseType)); + + InputStream errorStream = connection.getErrorStream(); + if (errorStream != null) { + output.put("error", true); + } + + return output; + } + + /** + * Read the existing ICapacitorHttpUrlConnection data + * @param connection The ICapacitorHttpUrlConnection object to read in + * @param responseType The type of HTTP response to return to the API + * @return The parsed data from the connection + * @throws IOException Thrown if the InputStreams cannot be properly parsed + * @throws JSONException Thrown if the JSON is malformed when parsing as JSON + */ + public static Object readData(ICapacitorHttpUrlConnection connection, ResponseType responseType) throws IOException, JSONException { + InputStream errorStream = connection.getErrorStream(); + String contentType = connection.getHeaderField("Content-Type"); + + if (errorStream != null) { + if (isOneOf(contentType, MimeType.APPLICATION_JSON, MimeType.APPLICATION_VND_API_JSON)) { + return parseJSON(readStreamAsString(errorStream)); + } else { + return readStreamAsString(errorStream); + } + } else if (contentType != null && contentType.contains(MimeType.APPLICATION_JSON.getValue())) { + // backward compatibility + return parseJSON(readStreamAsString(connection.getInputStream())); + } else { + InputStream stream = connection.getInputStream(); + switch (responseType) { + case ARRAY_BUFFER: + case BLOB: + return readStreamAsBase64(stream); + case JSON: + return parseJSON(readStreamAsString(stream)); + case DOCUMENT: + case TEXT: + default: + return readStreamAsString(stream); + } + } + } + + /** + * Helper function for determining if the Content-Type is a typeof an existing Mime-Type + * @param contentType The Content-Type string to check for + * @param mimeTypes The Mime-Type values to check against + * @return + */ + public static boolean isOneOf(String contentType, MimeType... mimeTypes) { + if (contentType != null) { + for (MimeType mimeType : mimeTypes) { + if (contentType.contains(mimeType.getValue())) { + return true; + } + } + } + return false; + } + + /** + * Build the JSObject response headers based on the connection header map + * @param connection The CapacitorHttpUrlConnection connection + * @return A JSObject of the header values from the CapacitorHttpUrlConnection + */ + public static JSObject buildResponseHeaders(CapacitorHttpUrlConnection connection) { + JSObject output = new JSObject(); + + for (Map.Entry> entry : connection.getHeaderFields().entrySet()) { + String valuesString = TextUtils.join(", ", entry.getValue()); + output.put(entry.getKey(), valuesString); + } + + return output; + } + + /** + * Returns a JSObject or a JSArray based on a string-ified input + * @param input String-ified JSON that needs parsing + * @return A JSObject or JSArray + * @throws JSONException thrown if the JSON is malformed + */ + public static Object parseJSON(String input) throws JSONException { + JSONObject json = new JSONObject(); + try { + if ("null".equals(input.trim())) { + return JSONObject.NULL; + } else if ("true".equals(input.trim())) { + return true; + } else if ("false".equals(input.trim())) { + return false; + } else if (input.trim().length() <= 0) { + return ""; + } else if (input.trim().matches("^\".*\"$")) { + // a string enclosed in " " is a json value, return the string without the quotes + return input.trim().substring(1, input.trim().length() - 1); + } else if (input.trim().matches("^-?\\d+$")) { + return Integer.parseInt(input.trim()); + } else if (input.trim().matches("^-?\\d+(\\.\\d+)?$")) { + return Double.parseDouble(input.trim()); + } else { + try { + return new JSObject(input); + } catch (JSONException e) { + return new JSArray(input); + } + } + } catch (JSONException e) { + return input; + } + } + + /** + * Returns a string based on a base64 InputStream + * @param in The base64 InputStream to convert to a String + * @return String value of InputStream + * @throws IOException thrown if the InputStream is unable to be read as base64 + */ + public static String readStreamAsBase64(InputStream in) throws IOException { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; + int readBytes; + while ((readBytes = in.read(buffer)) != -1) { + out.write(buffer, 0, readBytes); + } + byte[] result = out.toByteArray(); + return Base64.encodeToString(result, 0, result.length, Base64.DEFAULT); + } + } + + /** + * Returns a string based on an InputStream + * @param in The InputStream to convert to a String + * @return String value of InputStream + * @throws IOException thrown if the InputStream is unable to be read + */ + public static String readStreamAsString(InputStream in) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + StringBuilder builder = new StringBuilder(); + String line = reader.readLine(); + while (line != null) { + builder.append(line); + line = reader.readLine(); + if (line != null) { + builder.append(System.getProperty("line.separator")); + } + } + return builder.toString(); + } + } + + /** + * Makes an Http Request based on the PluginCall parameters + * @param call The Capacitor PluginCall that contains the options need for an Http request + * @param httpMethod The HTTP method that overrides the PluginCall HTTP method + * @throws IOException throws an IO request when a connection can't be made + * @throws URISyntaxException thrown when the URI is malformed + * @throws JSONException thrown when the incoming JSON is malformed + */ + public static JSObject request(PluginCall call, String httpMethod, Bridge bridge) + throws IOException, URISyntaxException, JSONException { + String urlString = call.getString("url", ""); + JSObject headers = call.getObject("headers", new JSObject()); + JSObject params = call.getObject("params", new JSObject()); + Integer connectTimeout = call.getInt("connectTimeout"); + Integer readTimeout = call.getInt("readTimeout"); + Boolean disableRedirects = call.getBoolean("disableRedirects"); + Boolean shouldEncode = call.getBoolean("shouldEncodeUrlParams", true); + ResponseType responseType = ResponseType.parse(call.getString("responseType")); + String dataType = call.getString("dataType"); + + String method = httpMethod != null ? httpMethod.toUpperCase(Locale.ROOT) : call.getString("method", "GET").toUpperCase(Locale.ROOT); + + boolean isHttpMutate = method.equals("DELETE") || method.equals("PATCH") || method.equals("POST") || method.equals("PUT"); + + // a workaround for the following android web view issue: + // https://issues.chromium.org/issues/40450316 + // x-cap-user-agent contains the user agent set in JavaScript + String userAgentValue = headers.getString("x-cap-user-agent"); + if (userAgentValue != null) { + headers.put("User-Agent", userAgentValue); + } + headers.remove("x-cap-user-agent"); + + if (!headers.has("User-Agent") && !headers.has("user-agent")) { + headers.put("User-Agent", bridge.getConfig().getOverriddenUserAgentString()); + } + + URL url = new URL(urlString); + HttpURLConnectionBuilder connectionBuilder = new HttpURLConnectionBuilder() + .setUrl(url) + .setMethod(method) + .setHeaders(headers) + .setUrlParams(params, shouldEncode) + .setConnectTimeout(connectTimeout) + .setReadTimeout(readTimeout) + .setDisableRedirects(disableRedirects) + .openConnection(); + + CapacitorHttpUrlConnection connection = connectionBuilder.build(); + + if (null != bridge && !isDomainExcludedFromSSL(bridge, url)) { + connection.setSSLSocketFactory(bridge); + } + + // Set HTTP body on a non GET or HEAD request + if (isHttpMutate) { + JSValue data = new JSValue(call, "data"); + if (data.getValue() != null) { + connection.setDoOutput(true); + connection.setRequestBody(call, data, dataType); + } + } + + call.getData().put("activeCapacitorHttpUrlConnection", connection); + connection.connect(); + + JSObject response = buildResponse(connection, responseType); + + connection.disconnect(); + call.getData().remove("activeCapacitorHttpUrlConnection"); + + return response; + } + + public static Boolean isDomainExcludedFromSSL(Bridge bridge, URL url) { + try { + Class sslPinningImpl = Class.forName("io.ionic.sslpinning.SSLPinning"); + Method method = sslPinningImpl.getDeclaredMethod("isDomainExcluded", Bridge.class, URL.class); + return (Boolean) method.invoke(sslPinningImpl.getDeclaredConstructor().newInstance(), bridge, url); + } catch (Exception ignored) { + return false; + } + } + + @FunctionalInterface + public interface ProgressEmitter { + void emit(Integer bytes, Integer contentLength); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/ICapacitorHttpUrlConnection.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/ICapacitorHttpUrlConnection.java new file mode 100644 index 0000000..4ed8881 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/ICapacitorHttpUrlConnection.java @@ -0,0 +1,15 @@ +package com.getcapacitor.plugin.util; + +import java.io.IOException; +import java.io.InputStream; + +/** + * This interface was extracted from {@link CapacitorHttpUrlConnection} to enable mocking that class. + */ +public interface ICapacitorHttpUrlConnection { + InputStream getErrorStream(); + + String getHeaderField(String name); + + InputStream getInputStream() throws IOException; +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/MimeType.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/MimeType.java new file mode 100644 index 0000000..cfc90f8 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/MimeType.java @@ -0,0 +1,17 @@ +package com.getcapacitor.plugin.util; + +enum MimeType { + APPLICATION_JSON("application/json"), + APPLICATION_VND_API_JSON("application/vnd.api+json"), // https://jsonapi.org + TEXT_HTML("text/html"); + + private final String value; + + MimeType(String value) { + this.value = value; + } + + String getValue() { + return value; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/HostMask.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/HostMask.java new file mode 100644 index 0000000..486d0fd --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/HostMask.java @@ -0,0 +1,123 @@ +package com.getcapacitor.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public interface HostMask { + boolean matches(String host); + + class Parser { + + private static HostMask NOTHING = new Nothing(); + + public static HostMask parse(String[] masks) { + return masks == null ? NOTHING : HostMask.Any.parse(masks); + } + + public static HostMask parse(String mask) { + return mask == null ? NOTHING : HostMask.Simple.parse(mask); + } + } + + class Simple implements HostMask { + + private final List maskParts; + + private Simple(List maskParts) { + if (maskParts == null) { + throw new IllegalArgumentException("Mask parts can not be null"); + } + this.maskParts = maskParts; + } + + static Simple parse(String mask) { + List parts = Util.splitAndReverse(mask); + return new Simple(parts); + } + + @Override + public boolean matches(String host) { + if (host == null) { + return false; + } + List hostParts = Util.splitAndReverse(host); + int hostSize = hostParts.size(); + int maskSize = maskParts.size(); + if (maskSize > 1 && hostSize != maskSize) { + return false; + } + + int minSize = Math.min(hostSize, maskSize); + + for (int i = 0; i < minSize; i++) { + String maskPart = maskParts.get(i); + String hostPart = hostParts.get(i); + if (!Util.matches(maskPart, hostPart)) { + return false; + } + } + return true; + } + } + + class Any implements HostMask { + + private final List masks; + + Any(List masks) { + this.masks = masks; + } + + @Override + public boolean matches(String host) { + for (HostMask mask : masks) { + if (mask.matches(host)) { + return true; + } + } + return false; + } + + static Any parse(String... rawMasks) { + List masks = new ArrayList<>(); + for (String raw : rawMasks) { + masks.add(HostMask.Simple.parse(raw)); + } + return new Any(masks); + } + } + + class Nothing implements HostMask { + + @Override + public boolean matches(String host) { + return false; + } + } + + class Util { + + static boolean matches(String mask, String string) { + if (mask == null) { + return false; + } else if ("*".equals(mask)) { + return true; + } else if (string == null) { + return false; + } else { + return mask.toUpperCase().equals(string.toUpperCase()); + } + } + + static List splitAndReverse(String string) { + if (string == null) { + throw new IllegalArgumentException("Can not split null argument"); + } + List parts = Arrays.asList(string.split("\\.")); + Collections.reverse(parts); + return parts; + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/InternalUtils.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/InternalUtils.java new file mode 100644 index 0000000..b735415 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/InternalUtils.java @@ -0,0 +1,27 @@ +package com.getcapacitor.util; + +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; + +public class InternalUtils { + + public static PackageInfo getPackageInfo(PackageManager pm, String packageName) throws PackageManager.NameNotFoundException { + return InternalUtils.getPackageInfo(pm, packageName, 0); + } + + public static PackageInfo getPackageInfo(PackageManager pm, String packageName, long flags) + throws PackageManager.NameNotFoundException { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + return pm.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags)); + } else { + return getPackageInfoLegacy(pm, packageName, (int) flags); + } + } + + @SuppressWarnings("deprecation") + private static PackageInfo getPackageInfoLegacy(PackageManager pm, String packageName, long flags) + throws PackageManager.NameNotFoundException { + return pm.getPackageInfo(packageName, (int) flags); + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java new file mode 100644 index 0000000..1d2fc20 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java @@ -0,0 +1,166 @@ +package com.getcapacitor.util; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Helper methods for parsing JSON objects. + */ +public class JSONUtils { + + /** + * Get a string value from the given JSON object. + * + * @param jsonObject A JSON object to search + * @param key A key to fetch from the JSON object + * @param defaultValue A default value to return if the key cannot be found + * @return The value at the given key in the JSON object, or the default value + */ + public static String getString(JSONObject jsonObject, String key, String defaultValue) { + String k = getDeepestKey(key); + try { + JSONObject o = getDeepestObject(jsonObject, key); + + String value = o.getString(k); + if (value == null) { + return defaultValue; + } + return value; + } catch (JSONException ignore) { + // value was not found + } + + return defaultValue; + } + + /** + * Get a boolean value from the given JSON object. + * + * @param jsonObject A JSON object to search + * @param key A key to fetch from the JSON object + * @param defaultValue A default value to return if the key cannot be found + * @return The value at the given key in the JSON object, or the default value + */ + public static boolean getBoolean(JSONObject jsonObject, String key, boolean defaultValue) { + String k = getDeepestKey(key); + try { + JSONObject o = getDeepestObject(jsonObject, key); + + return o.getBoolean(k); + } catch (JSONException ignore) { + // value was not found + } + + return defaultValue; + } + + /** + * Get an int value from the given JSON object. + * + * @param jsonObject A JSON object to search + * @param key A key to fetch from the JSON object + * @param defaultValue A default value to return if the key cannot be found + * @return The value at the given key in the JSON object, or the default value + */ + public static int getInt(JSONObject jsonObject, String key, int defaultValue) { + String k = getDeepestKey(key); + try { + JSONObject o = getDeepestObject(jsonObject, key); + return o.getInt(k); + } catch (JSONException ignore) { + // value was not found + } + + return defaultValue; + } + + /** + * Get a JSON object value from the given JSON object. + * + * @param jsonObject A JSON object to search + * @param key A key to fetch from the JSON object + * @return The value from the config, if exists. Null if not + */ + public static JSONObject getObject(JSONObject jsonObject, String key) { + String k = getDeepestKey(key); + try { + JSONObject o = getDeepestObject(jsonObject, key); + + return o.getJSONObject(k); + } catch (JSONException ignore) { + // value was not found + } + + return null; + } + + /** + * Get a string array value from the given JSON object. + * + * @param jsonObject A JSON object to search + * @param key A key to fetch from the JSON object + * @param defaultValue A default value to return if the key cannot be found + * @return The value at the given key in the JSON object, or the default value + */ + public static String[] getArray(JSONObject jsonObject, String key, String[] defaultValue) { + String k = getDeepestKey(key); + try { + JSONObject o = getDeepestObject(jsonObject, key); + + JSONArray a = o.getJSONArray(k); + if (a == null) { + return defaultValue; + } + + int l = a.length(); + String[] value = new String[l]; + + for (int i = 0; i < l; i++) { + value[i] = (String) a.get(i); + } + + return value; + } catch (JSONException ignore) { + // value was not found + } + + return defaultValue; + } + + /** + * Given a JSON key path, gets the deepest key. + * + * @param key The key path + * @return The deepest key + */ + private static String getDeepestKey(String key) { + String[] parts = key.split("\\."); + if (parts.length > 0) { + return parts[parts.length - 1]; + } + + return null; + } + + /** + * Given a JSON object and key path, gets the deepest object in the path. + * + * @param jsonObject A JSON object + * @param key The key path to follow + * @return The deepest object along the key path + * @throws JSONException Thrown if any JSON errors + */ + private static JSONObject getDeepestObject(JSONObject jsonObject, String key) throws JSONException { + String[] parts = key.split("\\."); + JSONObject o = jsonObject; + + // Search until the second to last part of the key + for (int i = 0; i < parts.length - 1; i++) { + String k = parts[i]; + o = o.getJSONObject(k); + } + + return o; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/PermissionHelper.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/PermissionHelper.java new file mode 100644 index 0000000..e7b8332 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/PermissionHelper.java @@ -0,0 +1,114 @@ +package com.getcapacitor.util; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import androidx.core.app.ActivityCompat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * A helper class for checking permissions. + * + * @since 3.0.0 + */ +public class PermissionHelper { + + /** + * Checks if a list of given permissions are all granted by the user + * + * @since 3.0.0 + * @param permissions Permissions to check. + * @return True if all permissions are granted, false if at least one is not. + */ + public static boolean hasPermissions(Context context, String[] permissions) { + for (String perm : permissions) { + if (ActivityCompat.checkSelfPermission(context, perm) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + return true; + } + + /** + * Check whether the given permission has been defined in the AndroidManifest.xml + * + * @since 3.0.0 + * @param permission A permission to check. + * @return True if the permission has been defined in the Manifest, false if not. + */ + public static boolean hasDefinedPermission(Context context, String permission) { + boolean hasPermission = false; + String[] requestedPermissions = PermissionHelper.getManifestPermissions(context); + if (requestedPermissions != null && requestedPermissions.length > 0) { + List requestedPermissionsList = Arrays.asList(requestedPermissions); + ArrayList requestedPermissionsArrayList = new ArrayList<>(requestedPermissionsList); + if (requestedPermissionsArrayList.contains(permission)) { + hasPermission = true; + } + } + return hasPermission; + } + + /** + * Check whether all of the given permissions have been defined in the AndroidManifest.xml + * @param context the app context + * @param permissions a list of permissions + * @return true only if all permissions are defined in the AndroidManifest.xml + */ + public static boolean hasDefinedPermissions(Context context, String[] permissions) { + for (String permission : permissions) { + if (!PermissionHelper.hasDefinedPermission(context, permission)) { + return false; + } + } + + return true; + } + + /** + * Get the permissions defined in AndroidManifest.xml + * + * @since 3.0.0 + * @return The permissions defined in AndroidManifest.xml + */ + public static String[] getManifestPermissions(Context context) { + String[] requestedPermissions = null; + try { + PackageManager pm = context.getPackageManager(); + PackageInfo packageInfo = InternalUtils.getPackageInfo(pm, context.getPackageName(), PackageManager.GET_PERMISSIONS); + + if (packageInfo != null) { + requestedPermissions = packageInfo.requestedPermissions; + } + } catch (Exception ex) {} + return requestedPermissions; + } + + /** + * Given a list of permissions, return a new list with the ones not present in AndroidManifest.xml + * + * @since 3.0.0 + * @param neededPermissions The permissions needed. + * @return The permissions not present in AndroidManifest.xml + */ + public static String[] getUndefinedPermissions(Context context, String[] neededPermissions) { + ArrayList undefinedPermissions = new ArrayList<>(); + String[] requestedPermissions = getManifestPermissions(context); + if (requestedPermissions != null && requestedPermissions.length > 0) { + List requestedPermissionsList = Arrays.asList(requestedPermissions); + ArrayList requestedPermissionsArrayList = new ArrayList<>(requestedPermissionsList); + for (String permission : neededPermissions) { + if (!requestedPermissionsArrayList.contains(permission)) { + undefinedPermissions.add(permission); + } + } + String[] undefinedPermissionArray = new String[undefinedPermissions.size()]; + undefinedPermissionArray = undefinedPermissions.toArray(undefinedPermissionArray); + + return undefinedPermissionArray; + } + return neededPermissions; + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/WebColor.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/WebColor.java new file mode 100644 index 0000000..e055021 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/util/WebColor.java @@ -0,0 +1,28 @@ +package com.getcapacitor.util; + +import android.graphics.Color; + +public class WebColor { + + /** + * Parse the color string, and return the corresponding color-int. If the string cannot be parsed, throws an IllegalArgumentException exception. + * @param colorString The hexadecimal color string. The format is an RGB or RGBA hex string. + * @return The corresponding color as an int. + */ + public static int parseColor(String colorString) { + String formattedColor = colorString; + if (colorString.charAt(0) != '#') { + formattedColor = "#" + formattedColor; + } + + if (formattedColor.length() != 7 && formattedColor.length() != 9) { + throw new IllegalArgumentException("The encoded color space is invalid or unknown"); + } else if (formattedColor.length() == 7) { + return Color.parseColor(formattedColor); + } else { + // Convert to Android format #AARRGGBB from #RRGGBBAA + formattedColor = "#" + formattedColor.substring(7) + formattedColor.substring(1, 7); + return Color.parseColor(formattedColor); + } + } +} diff --git a/node_modules/@capacitor/android/capacitor/src/main/res/layout/capacitor_bridge_layout_main.xml b/node_modules/@capacitor/android/capacitor/src/main/res/layout/capacitor_bridge_layout_main.xml new file mode 100644 index 0000000..12f0b8f --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/res/layout/capacitor_bridge_layout_main.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/node_modules/@capacitor/android/capacitor/src/main/res/layout/no_webview.xml b/node_modules/@capacitor/android/capacitor/src/main/res/layout/no_webview.xml new file mode 100644 index 0000000..7228cc2 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/res/layout/no_webview.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/node_modules/@capacitor/android/capacitor/src/main/res/values/colors.xml b/node_modules/@capacitor/android/capacitor/src/main/res/values/colors.xml new file mode 100644 index 0000000..347d608 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/node_modules/@capacitor/android/capacitor/src/main/res/values/strings.xml b/node_modules/@capacitor/android/capacitor/src/main/res/values/strings.xml new file mode 100644 index 0000000..2db1111 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + This app requires a WebView to work + diff --git a/node_modules/@capacitor/android/capacitor/src/main/res/values/styles.xml b/node_modules/@capacitor/android/capacitor/src/main/res/values/styles.xml new file mode 100644 index 0000000..d326892 --- /dev/null +++ b/node_modules/@capacitor/android/capacitor/src/main/res/values/styles.xml @@ -0,0 +1,6 @@ + + + diff --git a/node_modules/@capacitor/android/package.json b/node_modules/@capacitor/android/package.json new file mode 100644 index 0000000..8ae93f3 --- /dev/null +++ b/node_modules/@capacitor/android/package.json @@ -0,0 +1,31 @@ +{ + "name": "@capacitor/android", + "version": "8.3.4", + "description": "Capacitor: Cross-platform apps with JavaScript and the web", + "homepage": "https://capacitorjs.com", + "author": "Ionic Team (https://ionic.io)", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/ionic-team/capacitor.git" + }, + "bugs": { + "url": "https://github.com/ionic-team/capacitor/issues" + }, + "files": [ + "capacitor/build.gradle", + "capacitor/lint-baseline.xml", + "capacitor/lint.xml", + "capacitor/proguard-rules.pro", + "capacitor/src/main/" + ], + "scripts": { + "verify": "./gradlew clean lint build test -b capacitor/build.gradle" + }, + "peerDependencies": { + "@capacitor/core": "^8.3.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/node_modules/@capacitor/cli/LICENSE b/node_modules/@capacitor/cli/LICENSE new file mode 100644 index 0000000..c3e903b --- /dev/null +++ b/node_modules/@capacitor/cli/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-present Drifty Co. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@capacitor/cli/README.md b/node_modules/@capacitor/cli/README.md new file mode 100644 index 0000000..b9471c3 --- /dev/null +++ b/node_modules/@capacitor/cli/README.md @@ -0,0 +1,84 @@ +# Capacitor CLI + +The Capacitor command-line interface (CLI) is a tool for creating and managing Capacitor applications. While it can be installed globally, it's recommended to install it locally in your project and execute through `npm` scripts. + +## Installation + +### Project Installation (Recommended) + +Install the CLI locally in your project: + +```bash +npm install @capacitor/cli --save-dev +``` + +### Global Installation + +While not recommended for project use, you can install the CLI globally: + +```bash +npm install -g @capacitor/cli +``` + +## Using Capacitor CLI + +The CLI can be used through the `capacitor` or `cap` command. When installed locally, use it through your project's `npm` scripts or `npx`. + +Common commands: + +- `cap init`: Initialize a new Capacitor project +- `cap add`: Add a native platform (ios, android) +- `cap sync`: Sync your web code to your native projects + +For detailed information, consult the [Getting Started guide](https://capacitorjs.com/docs/getting-started). + +## Local Development + +If you're contributing to the Capacitor CLI or testing local changes: + +1. Clone and setup: + + ```bash + git clone https://github.com/ionic-team/capacitor.git + cd cli + npm install + ``` + +2. Build the CLI: + + ```bash + npm run build + ``` + +3. Create a local link: + + ```bash + npm link + ``` + +4. Development workflow: + - Run `npm run watch` to automatically rebuild on changes + - Use `capacitor` or `cap` commands to test your changes + - Run `npm test` to execute the test suite + +## Debugging + +### Using VS Code Launch Configurations + +The CLI includes VS Code launch configurations for debugging. To debug a CLI command: + +1. Open the project in VS Code +2. Right now we don't have debugging working in the ts files, so select one of the .js files inside of /dist/\*\*.js +3. Place a breakpoint +4. Press F5 or go to Run > Start Debugging +5. Select a launch config and run filling out the path you want to run the cli in, and the command that you want run. + +You can add more configurations by copying and modifying the existing ones in `.vscode/launch.json`. + +## Contributing + +Contributions are welcome! Please read our [Contributing Guide](https://github.com/ionic-team/capacitor/blob/main/CONTRIBUTING.md) for details. + +### License + +- [MIT](https://github.com/ionic-team/capacitor/blob/HEAD/LICENSE) diff --git a/node_modules/@capacitor/cli/assets/android-template.tar.gz b/node_modules/@capacitor/cli/assets/android-template.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7ff28697788b7c0f1b389e0027f5c9c7e187ae24 GIT binary patch literal 217362 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 Z|C%`dbNzGubN!E9{|^&}?l1uU1OTz!r>Fn` literal 0 HcmV?d00001 diff --git a/node_modules/@capacitor/cli/assets/capacitor-cordova-android-plugins.tar.gz b/node_modules/@capacitor/cli/assets/capacitor-cordova-android-plugins.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e42df0a1a999f92f87e84941ac6bdca4179f5ed7 GIT binary patch literal 929 zcmV;S177?eiwFP!000006YW=BZ{j!<(>OSN=5U{S#y*}5+G1CQQkuy^`Vx;m$KnQhOEl8i; zPCI*|#`-rxsOhyDQ1RLggu1BP>9#7!YolfZD(I~W+QmW}tSShp1?NQlcb@fPVEg{U z>u>=|2s6rOk(F_dlKWtLPS^45tcFmiNG$Q?I{HKbg~5f{i)qu;EeEB!A1rH{8bODO z%8ek3NTI0_iV~ddutSk- zq;ZT8OgmW_{@RcJC&z0#$j&JrEDKA??m@D}jBBxPhA-5u9{6Y;$62T|Zdvy*ER;{`K)!DBkx5htO1C%iEC zUPxiyeG(rUtu4R7YDUbd6o*lTS)NdB7nfqW9_)*VfOj}L#0i0_=b-A&c43s8YiX$9 zySoKXg)-MXP)aE1L5!IuJCkyWpU%@_p+d4Y8=X={%{_d@OPm+${0MHwSJ%V88s336 zFP@U^$O4n>8Kl4*F~ep+)nlm?EreatSqaQqRrF z#&LeEa6dyaAcrLApTo=aQKYtwETz?Jv6Bq=eU^obd{i|RM5)%4Rab3ZJbrYepZg>?|;baqJ#Ti1EF@iy#Kux zFS-AnU91wec`fy9&p|d29*T(aSi_K3<^o02lxO DK}F9l literal 0 HcmV?d00001 diff --git a/node_modules/@capacitor/cli/assets/capacitor-cordova-ios-plugins.tar.gz b/node_modules/@capacitor/cli/assets/capacitor-cordova-ios-plugins.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..04c91203fccdfa5ef4cea55f67d1949fa7eae8a3 GIT binary patch literal 405 zcmV;G0c!pqiwFP!000006YZ1FOT#b}$9vvi@ooXp_H|oZC`<%T9t6?dL?pIZ8@DDU zNgd++-=)p$rYMS==pmoWBaio+d{3pyl4;qfjA_4?xvp8}?E^%N$75)1 z5=WiIp?$YR$q2kK8X_i`#L3vhAtp%(9`2?47c|;XG#SNj z?z_!}%+vI$W|=S85^@PEy&3>$U(kxd1jy;fAB1#44@_w;MH`1c`XNTvubZl(>aq3r z88DLy*43c4+xgkl`bt@`niie2G^W;R5M;Eb88=ehYd@1!U?XW`N~ttV z;0ef?6g-0|qZNV4F_4m<@YXd`v|>xC=4~Q@XFFv#SeKX<+}MP5uY#Mhx$D|=1&$1( z)n)>};D#JRYG~1>^_TFCyw&USs^5G9*Q9?12jphJL_YYlf3eMGtahb2WA*-fe4&5D z@SXm{c!-hH|E_#T|Nr9`I{u2^SN~7+AH`AZ^uH@k{|<-4;rNUfDp^uV01yBGjo!`U literal 0 HcmV?d00001 diff --git a/node_modules/@capacitor/cli/assets/ios-pods-template.tar.gz b/node_modules/@capacitor/cli/assets/ios-pods-template.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..03fa0895421d28bc5b58f1e34d84e475d1b0aabc GIT binary patch literal 155305 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�?l7uj)eN0|rOkkEiQG4jOcKCYwk+}0O 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 &9lBFsiqYmqn)@@Ly4B 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

*%Y1oC^I`NoJc_$7YH^-cjtFIEr&5%F~{$S`pM3 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 literal 0 HcmV?d00001 diff --git a/node_modules/@capacitor/cli/assets/ios-spm-template.tar.gz b/node_modules/@capacitor/cli/assets/ios-spm-template.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e7519c8d202c1c182f5ba780bf24312da1373732 GIT binary patch literal 155152 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

*k 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