akanjs 3.0.0-beta.20 → 3.0.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +0 -1
- package/README.md +0 -1
- package/base/baseEnv.ts +40 -3
- package/client/cookie.ts +56 -20
- package/client/device.ts +47 -95
- package/client/frameConfig.ts +2 -2
- package/client/native.ts +44 -0
- package/client/router.ts +11 -1
- package/client/rscNavigation.ts +5 -0
- package/client/storage.ts +68 -39
- package/fetch/client/fetchClient.ts +13 -4
- package/index.ts +47 -46
- package/package.json +6 -87
- package/server/devtools/signalSerializer.ts +1 -2
- package/server/hmr/devHmrController.ts +29 -11
- package/server/resolver/signal.resolver.ts +1 -10
- package/server/routeTreeBuilder.ts +8 -11
- package/server/routing/apiRouter.ts +15 -2
- package/server/rscClient.tsx +1 -2
- package/server/ssrFromRscRenderer.tsx +2 -0
- package/server/webRouter.ts +1 -0
- package/signal/CrossSiteGuard.ts +34 -2
- package/signal/endpoint.ts +12 -7
- package/signal/endpointInfo.ts +13 -0
- package/signal/internal.ts +9 -5
- package/signal/serializer/fetch.serializer.ts +6 -3
- package/signal/slice.ts +34 -24
- package/store/baseSt.ts +0 -1
- package/store/storeInstance.ts +29 -17
- package/types/client/cookie.d.ts +6 -4
- package/types/client/device.d.ts +7 -10
- package/types/client/native.d.ts +26 -0
- package/types/client/rscNavigation.d.ts +4 -0
- package/types/client/storage.d.ts +8 -1
- package/types/index.d.ts +48 -44
- package/types/server/hmr/devHmrController.d.ts +2 -1
- package/types/server/resolver/signal.resolver.d.ts +0 -1
- package/types/server/rscClient.d.ts +0 -3
- package/types/signal/CrossSiteGuard.d.ts +7 -2
- package/types/signal/endpoint.d.ts +1 -1
- package/types/signal/endpointInfo.d.ts +3 -0
- package/types/signal/slice.d.ts +3 -2
- package/types/store/baseSt.d.ts +0 -13
- package/types/vendor/@akanjs/native/packages/cli/src/api.d.ts +182 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/build.d.ts +28 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/compat.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/dev.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/doctor.d.ts +37 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/plugin.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/signing.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/test.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/toolchain.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/commands/update.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/config.d.ts +278 -0
- package/types/vendor/@akanjs/native/packages/cli/src/index.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/acl.d.ts +21 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/apilevel.d.ts +40 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/apk.d.ts +36 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/args.d.ts +9 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/boot.d.ts +32 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/chrome.d.ts +6 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/codegen.d.ts +94 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/compat.d.ts +49 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/configkeys.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/csp.d.ts +51 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/env.d.ts +44 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/exec.d.ts +31 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/googleservices.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/hmr.d.ts +120 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/html.d.ts +20 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/icons.d.ts +44 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/image.d.ts +21 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/iossigning.d.ts +81 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/launch.d.ts +51 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/log.d.ts +42 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/manifestmerge.d.ts +18 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/maven.d.ts +97 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/names.d.ts +45 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/native-plugins.d.ts +67 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/nativeconfig.d.ts +11 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/permissions.d.ts +10 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/plist.d.ts +11 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/png.d.ts +11 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/prepare.d.ts +138 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/privacy.d.ts +13 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/project.d.ts +208 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/root.d.ts +1 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/routes.d.ts +1 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/serve.d.ts +17 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/signing.d.ts +14 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/spec.d.ts +96 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/toolchains.d.ts +150 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/updates.d.ts +77 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/vectors.d.ts +13 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/xml.d.ts +13 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/android.d.ts +57 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.d.ts +4 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/desktop.d.ts +40 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/index.d.ts +14 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/ios.d.ts +44 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/linux.d.ts +6 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/macos.d.ts +7 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/targets.d.ts +4 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/web-run.d.ts +15 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows.d.ts +8 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms.d.ts +1 -0
- package/types/vendor/@akanjs/native/packages/cli/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/packages/core/src/acl.d.ts +97 -0
- package/types/vendor/@akanjs/native/packages/core/src/boot.d.ts +66 -0
- package/types/vendor/@akanjs/native/packages/core/src/contract.d.ts +35 -0
- package/types/vendor/@akanjs/native/packages/core/src/errors.d.ts +27 -0
- package/types/vendor/@akanjs/native/packages/core/src/files.d.ts +23 -0
- package/types/vendor/@akanjs/native/packages/core/src/index.d.ts +14 -0
- package/types/vendor/@akanjs/native/packages/core/src/kernel.d.ts +112 -0
- package/types/vendor/@akanjs/native/packages/core/src/live.d.ts +12 -0
- package/types/vendor/@akanjs/native/packages/core/src/mime.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/core/src/plugin.d.ts +71 -0
- package/types/vendor/@akanjs/native/packages/core/src/protocol.d.ts +109 -0
- package/types/vendor/@akanjs/native/packages/core/src/runtime.d.ts +66 -0
- package/types/vendor/@akanjs/native/packages/core/src/state.d.ts +28 -0
- package/types/vendor/@akanjs/native/packages/core/src/testing.d.ts +41 -0
- package/types/vendor/@akanjs/native/packages/core/src/version.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/core/src/veto.d.ts +17 -0
- package/types/vendor/@akanjs/native/packages/core/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/deeplinks.d.ts +24 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/delta.d.ts +2 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/dispatcher.d.ts +95 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/ffi.d.ts +144 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/host.d.ts +11 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/lifecycle.d.ts +40 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/main.d.ts +4 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/page-veto.d.ts +17 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/paths.d.ts +25 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +179 -0
- package/types/vendor/@akanjs/native/packages/react/src/index.d.ts +8 -0
- package/types/vendor/@akanjs/native/packages/react/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/accessibility/src/announce.d.ts +8 -0
- package/types/vendor/@akanjs/native/plugins/accessibility/src/index.d.ts +47 -0
- package/types/vendor/@akanjs/native/plugins/accessibility/src/web.d.ts +4 -0
- package/types/vendor/@akanjs/native/plugins/accessibility/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/app/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/app/src/index.d.ts +66 -0
- package/types/vendor/@akanjs/native/plugins/app/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/app/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/app-state/src/index.d.ts +19 -0
- package/types/vendor/@akanjs/native/plugins/app-state/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/app-state/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/appearance/src/desktop.d.ts +9 -0
- package/types/vendor/@akanjs/native/plugins/appearance/src/index.d.ts +32 -0
- package/types/vendor/@akanjs/native/plugins/appearance/src/setting.d.ts +6 -0
- package/types/vendor/@akanjs/native/plugins/appearance/src/web.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/appearance/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/auth-session/src/args.d.ts +18 -0
- package/types/vendor/@akanjs/native/plugins/auth-session/src/desktop.d.ts +17 -0
- package/types/vendor/@akanjs/native/plugins/auth-session/src/index.d.ts +41 -0
- package/types/vendor/@akanjs/native/plugins/auth-session/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/autostart/src/desktop.d.ts +44 -0
- package/types/vendor/@akanjs/native/plugins/autostart/src/index.d.ts +44 -0
- package/types/vendor/@akanjs/native/plugins/autostart/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/badge/src/count.d.ts +4 -0
- package/types/vendor/@akanjs/native/plugins/badge/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/badge/src/index.d.ts +37 -0
- package/types/vendor/@akanjs/native/plugins/badge/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/badge/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/biometric/src/index.d.ts +53 -0
- package/types/vendor/@akanjs/native/plugins/biometric/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/browser/src/args.d.ts +8 -0
- package/types/vendor/@akanjs/native/plugins/browser/src/desktop.d.ts +9 -0
- package/types/vendor/@akanjs/native/plugins/browser/src/index.d.ts +36 -0
- package/types/vendor/@akanjs/native/plugins/browser/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/browser/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/camera/src/desktop.d.ts +5 -0
- package/types/vendor/@akanjs/native/plugins/camera/src/index.d.ts +55 -0
- package/types/vendor/@akanjs/native/plugins/camera/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/camera/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/clipboard/src/desktop.d.ts +8 -0
- package/types/vendor/@akanjs/native/plugins/clipboard/src/index.d.ts +40 -0
- package/types/vendor/@akanjs/native/plugins/clipboard/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/clipboard/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/device/src/desktop.d.ts +33 -0
- package/types/vendor/@akanjs/native/plugins/device/src/index.d.ts +55 -0
- package/types/vendor/@akanjs/native/plugins/device/src/web.d.ts +22 -0
- package/types/vendor/@akanjs/native/plugins/device/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/dialog/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/dialog/src/index.d.ts +60 -0
- package/types/vendor/@akanjs/native/plugins/dialog/src/options.d.ts +29 -0
- package/types/vendor/@akanjs/native/plugins/dialog/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/dialog/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/dock/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/dock/src/index.d.ts +46 -0
- package/types/vendor/@akanjs/native/plugins/dock/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/file-picker/src/common.d.ts +33 -0
- package/types/vendor/@akanjs/native/plugins/file-picker/src/desktop.d.ts +9 -0
- package/types/vendor/@akanjs/native/plugins/file-picker/src/index.d.ts +84 -0
- package/types/vendor/@akanjs/native/plugins/file-picker/src/web.d.ts +6 -0
- package/types/vendor/@akanjs/native/plugins/file-picker/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/filesystem/src/common.d.ts +49 -0
- package/types/vendor/@akanjs/native/plugins/filesystem/src/desktop.d.ts +8 -0
- package/types/vendor/@akanjs/native/plugins/filesystem/src/index.d.ts +123 -0
- package/types/vendor/@akanjs/native/plugins/filesystem/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/filesystem/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/geolocation/src/index.d.ts +93 -0
- package/types/vendor/@akanjs/native/plugins/geolocation/src/web.d.ts +11 -0
- package/types/vendor/@akanjs/native/plugins/geolocation/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/global-shortcut/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/global-shortcut/src/index.d.ts +52 -0
- package/types/vendor/@akanjs/native/plugins/global-shortcut/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/haptics/src/index.d.ts +31 -0
- package/types/vendor/@akanjs/native/plugins/haptics/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/haptics/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/http/src/common.d.ts +71 -0
- package/types/vendor/@akanjs/native/plugins/http/src/desktop.d.ts +5 -0
- package/types/vendor/@akanjs/native/plugins/http/src/index.d.ts +104 -0
- package/types/vendor/@akanjs/native/plugins/http/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/http/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/iap/src/index.d.ts +171 -0
- package/types/vendor/@akanjs/native/plugins/iap/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/keep-awake/src/desktop.d.ts +15 -0
- package/types/vendor/@akanjs/native/plugins/keep-awake/src/index.d.ts +33 -0
- package/types/vendor/@akanjs/native/plugins/keep-awake/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/keep-awake/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/keyboard/src/index.d.ts +42 -0
- package/types/vendor/@akanjs/native/plugins/keyboard/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/keyboard/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/local-notifications/src/desktop.d.ts +29 -0
- package/types/vendor/@akanjs/native/plugins/local-notifications/src/index.d.ts +126 -0
- package/types/vendor/@akanjs/native/plugins/local-notifications/src/schedule.d.ts +38 -0
- package/types/vendor/@akanjs/native/plugins/local-notifications/src/timers.d.ts +25 -0
- package/types/vendor/@akanjs/native/plugins/local-notifications/src/web.d.ts +4 -0
- package/types/vendor/@akanjs/native/plugins/local-notifications/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/menu/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/menu/src/index.d.ts +85 -0
- package/types/vendor/@akanjs/native/plugins/menu/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/network/src/index.d.ts +22 -0
- package/types/vendor/@akanjs/native/plugins/network/src/web.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/network/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/opener/src/desktop.d.ts +14 -0
- package/types/vendor/@akanjs/native/plugins/opener/src/index.d.ts +33 -0
- package/types/vendor/@akanjs/native/plugins/opener/src/url.d.ts +16 -0
- package/types/vendor/@akanjs/native/plugins/opener/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/opener/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/preferences/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/preferences/src/index.d.ts +26 -0
- package/types/vendor/@akanjs/native/plugins/preferences/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/preferences/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/push/src/index.d.ts +57 -0
- package/types/vendor/@akanjs/native/plugins/push/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/screen/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/screen/src/index.d.ts +70 -0
- package/types/vendor/@akanjs/native/plugins/screen/src/web.d.ts +18 -0
- package/types/vendor/@akanjs/native/plugins/screen/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/screen-orientation/src/index.d.ts +32 -0
- package/types/vendor/@akanjs/native/plugins/screen-orientation/src/types.d.ts +8 -0
- package/types/vendor/@akanjs/native/plugins/screen-orientation/src/web.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/screen-orientation/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/secure-storage/src/desktop.d.ts +16 -0
- package/types/vendor/@akanjs/native/plugins/secure-storage/src/index.d.ts +39 -0
- package/types/vendor/@akanjs/native/plugins/secure-storage/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/share/src/index.d.ts +55 -0
- package/types/vendor/@akanjs/native/plugins/share/src/options.d.ts +6 -0
- package/types/vendor/@akanjs/native/plugins/share/src/web.d.ts +5 -0
- package/types/vendor/@akanjs/native/plugins/share/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/single-instance/src/desktop.d.ts +8 -0
- package/types/vendor/@akanjs/native/plugins/single-instance/src/index.d.ts +25 -0
- package/types/vendor/@akanjs/native/plugins/single-instance/src/socket.d.ts +46 -0
- package/types/vendor/@akanjs/native/plugins/single-instance/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/splash-screen/src/index.d.ts +19 -0
- package/types/vendor/@akanjs/native/plugins/splash-screen/src/web.d.ts +4 -0
- package/types/vendor/@akanjs/native/plugins/splash-screen/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/sqlite/src/common.d.ts +34 -0
- package/types/vendor/@akanjs/native/plugins/sqlite/src/desktop.d.ts +6 -0
- package/types/vendor/@akanjs/native/plugins/sqlite/src/index.d.ts +115 -0
- package/types/vendor/@akanjs/native/plugins/sqlite/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/toast/src/index.d.ts +30 -0
- package/types/vendor/@akanjs/native/plugins/toast/src/queue.d.ts +23 -0
- package/types/vendor/@akanjs/native/plugins/toast/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/toast/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/tray/src/desktop.d.ts +3 -0
- package/types/vendor/@akanjs/native/plugins/tray/src/index.d.ts +113 -0
- package/types/vendor/@akanjs/native/plugins/tray/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/updates/src/desktop.d.ts +4 -0
- package/types/vendor/@akanjs/native/plugins/updates/src/index.d.ts +68 -0
- package/types/vendor/@akanjs/native/plugins/updates/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/window/src/desktop.d.ts +6 -0
- package/types/vendor/@akanjs/native/plugins/window/src/index.d.ts +185 -0
- package/types/vendor/@akanjs/native/plugins/window/src/web.d.ts +2 -0
- package/types/vendor/@akanjs/native/plugins/window/src.d.ts +1 -0
- package/types/vendor/@akanjs/native/plugins/window-state/src/desktop.d.ts +7 -0
- package/types/vendor/@akanjs/native/plugins/window-state/src/index.d.ts +33 -0
- package/types/vendor/@akanjs/native/plugins/window-state/src/state.d.ts +39 -0
- package/types/vendor/@akanjs/native/plugins/window-state/src.d.ts +1 -0
- package/types/webkit/index.d.ts +0 -2
- package/types/webkit/nativeNavigation.d.ts +25 -0
- package/types/webkit/nativePurchase.d.ts +37 -0
- package/types/webkit/useCamera.d.ts +13 -15
- package/types/webkit/useGeoLocation.d.ts +4 -5
- package/types/webkit/usePurchase.d.ts +12 -16
- package/ui/Link/Anchor.tsx +2 -5
- package/ui/System/Client.tsx +2 -6
- package/vendor/@akanjs/native/LICENSE +21 -0
- package/vendor/@akanjs/native/README.ko.md +88 -0
- package/vendor/@akanjs/native/README.md +93 -0
- package/vendor/@akanjs/native/THIRD_PARTY_NOTICES.md +237 -0
- package/vendor/@akanjs/native/native/android/maven.lock.json +1751 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeAcl.kt +243 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeActivity.kt +936 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeApplication.kt +189 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeAssetServer.kt +225 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeBridge.kt +444 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeCompat.kt +55 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeContract.kt +99 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeEd25519.kt +100 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeFileProvider.kt +71 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeKernel.kt +324 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativePlugin.kt +361 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeSpec.kt +100 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeUpdates.kt +305 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeVectors.kt +132 -0
- package/vendor/@akanjs/native/native/desktop/Cargo.lock +2565 -0
- package/vendor/@akanjs/native/native/desktop/Cargo.toml +49 -0
- package/vendor/@akanjs/native/native/desktop/build.rs +19 -0
- package/vendor/@akanjs/native/native/desktop/rust-toolchain.toml +7 -0
- package/vendor/@akanjs/native/native/desktop/src/accelerator.rs +466 -0
- package/vendor/@akanjs/native/native/desktop/src/autostart.rs +158 -0
- package/vendor/@akanjs/native/native/desktop/src/camera.rs +53 -0
- package/vendor/@akanjs/native/native/desktop/src/chrome.rs +710 -0
- package/vendor/@akanjs/native/native/desktop/src/contract.rs +105 -0
- package/vendor/@akanjs/native/native/desktop/src/devproxy.rs +234 -0
- package/vendor/@akanjs/native/native/desktop/src/dialog_args.rs +189 -0
- package/vendor/@akanjs/native/native/desktop/src/dock.rs +209 -0
- package/vendor/@akanjs/native/native/desktop/src/hotkey.rs +209 -0
- package/vendor/@akanjs/native/native/desktop/src/js_panels.rs +125 -0
- package/vendor/@akanjs/native/native/desktop/src/json.rs +272 -0
- package/vendor/@akanjs/native/native/desktop/src/keychain.rs +151 -0
- package/vendor/@akanjs/native/native/desktop/src/lib.rs +2185 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/appearance.rs +177 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/camera.rs +11 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/clipboard.rs +48 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/device.rs +9 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/dialogs.rs +348 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/dock.rs +146 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/hotkey.rs +228 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/keychain.rs +243 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/menu.rs +445 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/mod.rs +116 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/notify.rs +211 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/open.rs +79 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/power.rs +155 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/screen.rs +158 -0
- package/vendor/@akanjs/native/native/desktop/src/linux/tray.rs +604 -0
- package/vendor/@akanjs/native/native/desktop/src/menu.rs +517 -0
- package/vendor/@akanjs/native/native/desktop/src/navigation.rs +381 -0
- package/vendor/@akanjs/native/native/desktop/src/notify.rs +411 -0
- package/vendor/@akanjs/native/native/desktop/src/notify_schedule.rs +382 -0
- package/vendor/@akanjs/native/native/desktop/src/page_menu.rs +287 -0
- package/vendor/@akanjs/native/native/desktop/src/panels.rs +333 -0
- package/vendor/@akanjs/native/native/desktop/src/placement.rs +92 -0
- package/vendor/@akanjs/native/native/desktop/src/routes.rs +153 -0
- package/vendor/@akanjs/native/native/desktop/src/screen.rs +190 -0
- package/vendor/@akanjs/native/native/desktop/src/tray.rs +279 -0
- package/vendor/@akanjs/native/native/desktop/src/vectors.rs +126 -0
- package/vendor/@akanjs/native/native/desktop/src/win/appearance.rs +51 -0
- package/vendor/@akanjs/native/native/desktop/src/win/autostart.rs +77 -0
- package/vendor/@akanjs/native/native/desktop/src/win/camera.rs +34 -0
- package/vendor/@akanjs/native/native/desktop/src/win/clipboard.rs +106 -0
- package/vendor/@akanjs/native/native/desktop/src/win/device.rs +80 -0
- package/vendor/@akanjs/native/native/desktop/src/win/dialogs.rs +917 -0
- package/vendor/@akanjs/native/native/desktop/src/win/dock.rs +228 -0
- package/vendor/@akanjs/native/native/desktop/src/win/hotkey.rs +110 -0
- package/vendor/@akanjs/native/native/desktop/src/win/keychain.rs +103 -0
- package/vendor/@akanjs/native/native/desktop/src/win/menu.rs +500 -0
- package/vendor/@akanjs/native/native/desktop/src/win/mod.rs +100 -0
- package/vendor/@akanjs/native/native/desktop/src/win/msgwin.rs +86 -0
- package/vendor/@akanjs/native/native/desktop/src/win/notify.rs +334 -0
- package/vendor/@akanjs/native/native/desktop/src/win/open.rs +127 -0
- package/vendor/@akanjs/native/native/desktop/src/win/power.rs +64 -0
- package/vendor/@akanjs/native/native/desktop/src/win/registry.rs +87 -0
- package/vendor/@akanjs/native/native/desktop/src/win/screen.rs +127 -0
- package/vendor/@akanjs/native/native/desktop/src/win/tray.rs +280 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeAcl.swift +241 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeApp.swift +285 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeBridge.swift +407 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeContract.swift +106 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeKernel.swift +317 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativePlugin.swift +250 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeSchemeHandler.swift +209 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeShell.swift +161 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeSpec.swift +143 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeUpdates.swift +270 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeVectors.swift +155 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeViewController.swift +371 -0
- package/vendor/@akanjs/native/packages/cli/src/api.ts +600 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/build.ts +101 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/compat.ts +53 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/dev.ts +249 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/doctor.ts +536 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/plugin.ts +164 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/signing.ts +32 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/test.ts +130 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/toolchain.ts +143 -0
- package/vendor/@akanjs/native/packages/cli/src/commands/update.ts +168 -0
- package/vendor/@akanjs/native/packages/cli/src/config.ts +257 -0
- package/vendor/@akanjs/native/packages/cli/src/index.ts +77 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/acl.ts +420 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/apilevel.ts +245 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/apk.ts +203 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/args.ts +44 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/boot.ts +73 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/chrome.ts +89 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/codegen.ts +1128 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/compat.ts +185 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/configkeys.ts +91 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/csp.ts +198 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/env.ts +257 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/exec.ts +104 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/googleservices.ts +53 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/hmr.ts +534 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/html.ts +63 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/icons.ts +316 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/image.ts +175 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/iossigning.ts +295 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/launch.ts +98 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/log.ts +105 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/manifestmerge.ts +107 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/maven.ts +244 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/names.ts +202 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/native-plugins.ts +326 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/nativeconfig.ts +68 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/permissions.ts +80 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/plist.ts +139 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/png.ts +240 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/prepare.ts +290 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/privacy.ts +64 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/project.ts +710 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/root.ts +18 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/routes.ts +3 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/serve.ts +83 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/signing.ts +117 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/spec.ts +521 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/toolchains.ts +579 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +160 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/vectors.ts +121 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/xml.ts +72 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +1320 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.ts +78 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/desktop.ts +279 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/index.ts +31 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/ios.ts +801 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/linux.ts +52 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/macos.ts +97 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/targets.ts +12 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/web-run.ts +69 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/web.ts +28 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/windows.ts +82 -0
- package/vendor/@akanjs/native/packages/core/contract.json +96 -0
- package/vendor/@akanjs/native/packages/core/src/acl.ts +272 -0
- package/vendor/@akanjs/native/packages/core/src/boot.ts +97 -0
- package/vendor/@akanjs/native/packages/core/src/contract.ts +100 -0
- package/vendor/@akanjs/native/packages/core/src/errors.ts +95 -0
- package/vendor/@akanjs/native/packages/core/src/files.ts +105 -0
- package/vendor/@akanjs/native/packages/core/src/index.ts +35 -0
- package/vendor/@akanjs/native/packages/core/src/kernel.ts +281 -0
- package/vendor/@akanjs/native/packages/core/src/live.ts +62 -0
- package/vendor/@akanjs/native/packages/core/src/mime.ts +8 -0
- package/vendor/@akanjs/native/packages/core/src/plugin.ts +358 -0
- package/vendor/@akanjs/native/packages/core/src/protocol.ts +194 -0
- package/vendor/@akanjs/native/packages/core/src/runtime.ts +520 -0
- package/vendor/@akanjs/native/packages/core/src/state.ts +46 -0
- package/vendor/@akanjs/native/packages/core/src/testing.ts +176 -0
- package/vendor/@akanjs/native/packages/core/src/version.ts +2 -0
- package/vendor/@akanjs/native/packages/core/src/veto.ts +55 -0
- package/vendor/@akanjs/native/packages/core/vectors/acl.json +57 -0
- package/vendor/@akanjs/native/packages/core/vectors/bridge.json +76 -0
- package/vendor/@akanjs/native/packages/core/vectors/ed25519.json +29 -0
- package/vendor/@akanjs/native/packages/core/vectors/ids.json +73 -0
- package/vendor/@akanjs/native/packages/core/vectors/navigation.json +75 -0
- package/vendor/@akanjs/native/packages/core/vectors/ranges.json +39 -0
- package/vendor/@akanjs/native/packages/core/vectors/retained.json +17 -0
- package/vendor/@akanjs/native/packages/core/vectors/routes.json +66 -0
- package/vendor/@akanjs/native/packages/core/vectors/scope.json +143 -0
- package/vendor/@akanjs/native/packages/desktop/src/deeplinks.ts +143 -0
- package/vendor/@akanjs/native/packages/desktop/src/delta.ts +174 -0
- package/vendor/@akanjs/native/packages/desktop/src/dispatcher.ts +679 -0
- package/vendor/@akanjs/native/packages/desktop/src/ffi.ts +76 -0
- package/vendor/@akanjs/native/packages/desktop/src/host.ts +355 -0
- package/vendor/@akanjs/native/packages/desktop/src/lifecycle.ts +142 -0
- package/vendor/@akanjs/native/packages/desktop/src/main.ts +133 -0
- package/vendor/@akanjs/native/packages/desktop/src/page-veto.ts +103 -0
- package/vendor/@akanjs/native/packages/desktop/src/paths.ts +59 -0
- package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +232 -0
- package/vendor/@akanjs/native/packages/react/src/index.ts +23 -0
- package/vendor/@akanjs/native/plugins/accessibility/android/AccessibilityPlugin.kt +96 -0
- package/vendor/@akanjs/native/plugins/accessibility/ios/AccessibilityPlugin.swift +92 -0
- package/vendor/@akanjs/native/plugins/accessibility/native-plugin.json +21 -0
- package/vendor/@akanjs/native/plugins/accessibility/src/announce.ts +71 -0
- package/vendor/@akanjs/native/plugins/accessibility/src/index.ts +77 -0
- package/vendor/@akanjs/native/plugins/accessibility/src/web.ts +52 -0
- package/vendor/@akanjs/native/plugins/app/android/AppPlugin.kt +72 -0
- package/vendor/@akanjs/native/plugins/app/ios/AppPlugin.swift +52 -0
- package/vendor/@akanjs/native/plugins/app/native-plugin.json +21 -0
- package/vendor/@akanjs/native/plugins/app/src/desktop.ts +64 -0
- package/vendor/@akanjs/native/plugins/app/src/index.ts +77 -0
- package/vendor/@akanjs/native/plugins/app/src/web.ts +12 -0
- package/vendor/@akanjs/native/plugins/app-state/android/AppStatePlugin.kt +54 -0
- package/vendor/@akanjs/native/plugins/app-state/ios/AppStatePlugin.swift +58 -0
- package/vendor/@akanjs/native/plugins/app-state/native-plugin.json +17 -0
- package/vendor/@akanjs/native/plugins/app-state/src/index.ts +42 -0
- package/vendor/@akanjs/native/plugins/app-state/src/web.ts +33 -0
- package/vendor/@akanjs/native/plugins/appearance/android/AppearancePlugin.kt +133 -0
- package/vendor/@akanjs/native/plugins/appearance/ios/AppearancePlugin.swift +109 -0
- package/vendor/@akanjs/native/plugins/appearance/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/appearance/src/desktop.ts +133 -0
- package/vendor/@akanjs/native/plugins/appearance/src/index.ts +62 -0
- package/vendor/@akanjs/native/plugins/appearance/src/setting.ts +18 -0
- package/vendor/@akanjs/native/plugins/appearance/src/web.ts +25 -0
- package/vendor/@akanjs/native/plugins/auth-session/android/AuthSessionPlugin.kt +171 -0
- package/vendor/@akanjs/native/plugins/auth-session/ios/AuthSessionPlugin.swift +112 -0
- package/vendor/@akanjs/native/plugins/auth-session/native-plugin.json +19 -0
- package/vendor/@akanjs/native/plugins/auth-session/src/args.ts +62 -0
- package/vendor/@akanjs/native/plugins/auth-session/src/desktop.ts +133 -0
- package/vendor/@akanjs/native/plugins/auth-session/src/index.ts +39 -0
- package/vendor/@akanjs/native/plugins/autostart/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/autostart/src/desktop.ts +189 -0
- package/vendor/@akanjs/native/plugins/autostart/src/index.ts +51 -0
- package/vendor/@akanjs/native/plugins/badge/ios/BadgePlugin.swift +92 -0
- package/vendor/@akanjs/native/plugins/badge/native-plugin.json +15 -0
- package/vendor/@akanjs/native/plugins/badge/src/count.ts +12 -0
- package/vendor/@akanjs/native/plugins/badge/src/desktop.ts +24 -0
- package/vendor/@akanjs/native/plugins/badge/src/index.ts +40 -0
- package/vendor/@akanjs/native/plugins/badge/src/web.ts +37 -0
- package/vendor/@akanjs/native/plugins/biometric/android/BiometricPlugin.kt +179 -0
- package/vendor/@akanjs/native/plugins/biometric/ios/BiometricPlugin.swift +129 -0
- package/vendor/@akanjs/native/plugins/biometric/native-plugin.json +22 -0
- package/vendor/@akanjs/native/plugins/biometric/src/index.ts +100 -0
- package/vendor/@akanjs/native/plugins/browser/android/BrowserPlugin.kt +178 -0
- package/vendor/@akanjs/native/plugins/browser/ios/BrowserPlugin.swift +63 -0
- package/vendor/@akanjs/native/plugins/browser/native-plugin.json +22 -0
- package/vendor/@akanjs/native/plugins/browser/src/args.ts +34 -0
- package/vendor/@akanjs/native/plugins/browser/src/desktop.ts +40 -0
- package/vendor/@akanjs/native/plugins/browser/src/index.ts +47 -0
- package/vendor/@akanjs/native/plugins/browser/src/web.ts +60 -0
- package/vendor/@akanjs/native/plugins/camera/android/CameraPlugin.kt +365 -0
- package/vendor/@akanjs/native/plugins/camera/ios/CameraPlugin.swift +296 -0
- package/vendor/@akanjs/native/plugins/camera/native-plugin.json +32 -0
- package/vendor/@akanjs/native/plugins/camera/src/desktop.ts +27 -0
- package/vendor/@akanjs/native/plugins/camera/src/index.ts +85 -0
- package/vendor/@akanjs/native/plugins/camera/src/web.ts +267 -0
- package/vendor/@akanjs/native/plugins/clipboard/android/ClipboardPlugin.kt +51 -0
- package/vendor/@akanjs/native/plugins/clipboard/ios/ClipboardPlugin.swift +35 -0
- package/vendor/@akanjs/native/plugins/clipboard/native-plugin.json +17 -0
- package/vendor/@akanjs/native/plugins/clipboard/src/desktop.ts +66 -0
- package/vendor/@akanjs/native/plugins/clipboard/src/index.ts +72 -0
- package/vendor/@akanjs/native/plugins/clipboard/src/web.ts +69 -0
- package/vendor/@akanjs/native/plugins/device/android/DevicePlugin.kt +70 -0
- package/vendor/@akanjs/native/plugins/device/ios/DevicePlugin.swift +80 -0
- package/vendor/@akanjs/native/plugins/device/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/device/src/desktop.ts +276 -0
- package/vendor/@akanjs/native/plugins/device/src/index.ts +72 -0
- package/vendor/@akanjs/native/plugins/device/src/web.ts +162 -0
- package/vendor/@akanjs/native/plugins/dialog/android/DialogPlugin.kt +260 -0
- package/vendor/@akanjs/native/plugins/dialog/ios/DialogPlugin.swift +198 -0
- package/vendor/@akanjs/native/plugins/dialog/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/dialog/src/desktop.ts +80 -0
- package/vendor/@akanjs/native/plugins/dialog/src/index.ts +87 -0
- package/vendor/@akanjs/native/plugins/dialog/src/options.ts +111 -0
- package/vendor/@akanjs/native/plugins/dialog/src/web.ts +296 -0
- package/vendor/@akanjs/native/plugins/dock/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/dock/src/desktop.ts +34 -0
- package/vendor/@akanjs/native/plugins/dock/src/index.ts +46 -0
- package/vendor/@akanjs/native/plugins/file-picker/android/FilePickerPlugin.kt +316 -0
- package/vendor/@akanjs/native/plugins/file-picker/ios/FilePickerPlugin.swift +366 -0
- package/vendor/@akanjs/native/plugins/file-picker/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/file-picker/src/common.ts +125 -0
- package/vendor/@akanjs/native/plugins/file-picker/src/desktop.ts +164 -0
- package/vendor/@akanjs/native/plugins/file-picker/src/index.ts +187 -0
- package/vendor/@akanjs/native/plugins/file-picker/src/web.ts +158 -0
- package/vendor/@akanjs/native/plugins/filesystem/android/FilesystemPlugin.kt +561 -0
- package/vendor/@akanjs/native/plugins/filesystem/ios/FilesystemPlugin.swift +596 -0
- package/vendor/@akanjs/native/plugins/filesystem/native-plugin.json +45 -0
- package/vendor/@akanjs/native/plugins/filesystem/src/common.ts +150 -0
- package/vendor/@akanjs/native/plugins/filesystem/src/desktop.ts +438 -0
- package/vendor/@akanjs/native/plugins/filesystem/src/index.ts +179 -0
- package/vendor/@akanjs/native/plugins/filesystem/src/web.ts +334 -0
- package/vendor/@akanjs/native/plugins/geolocation/android/GeolocationPlugin.kt +360 -0
- package/vendor/@akanjs/native/plugins/geolocation/ios/GeolocationPlugin.swift +284 -0
- package/vendor/@akanjs/native/plugins/geolocation/native-plugin.json +23 -0
- package/vendor/@akanjs/native/plugins/geolocation/src/index.ts +155 -0
- package/vendor/@akanjs/native/plugins/geolocation/src/web.ts +132 -0
- package/vendor/@akanjs/native/plugins/global-shortcut/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/global-shortcut/src/desktop.ts +36 -0
- package/vendor/@akanjs/native/plugins/global-shortcut/src/index.ts +55 -0
- package/vendor/@akanjs/native/plugins/haptics/android/HapticsPlugin.kt +127 -0
- package/vendor/@akanjs/native/plugins/haptics/ios/HapticsPlugin.swift +127 -0
- package/vendor/@akanjs/native/plugins/haptics/native-plugin.json +19 -0
- package/vendor/@akanjs/native/plugins/haptics/src/index.ts +34 -0
- package/vendor/@akanjs/native/plugins/haptics/src/web.ts +53 -0
- package/vendor/@akanjs/native/plugins/http/android/HttpPlugin.kt +234 -0
- package/vendor/@akanjs/native/plugins/http/android/HttpUrl.kt +182 -0
- package/vendor/@akanjs/native/plugins/http/ios/HttpPlugin.swift +228 -0
- package/vendor/@akanjs/native/plugins/http/ios/HttpUrl.swift +166 -0
- package/vendor/@akanjs/native/plugins/http/native-plugin.json +27 -0
- package/vendor/@akanjs/native/plugins/http/src/common.ts +294 -0
- package/vendor/@akanjs/native/plugins/http/src/desktop.ts +69 -0
- package/vendor/@akanjs/native/plugins/http/src/index.ts +181 -0
- package/vendor/@akanjs/native/plugins/http/src/web.ts +40 -0
- package/vendor/@akanjs/native/plugins/iap/android/IapPlugin.kt +358 -0
- package/vendor/@akanjs/native/plugins/iap/ios/IapPlugin.swift +306 -0
- package/vendor/@akanjs/native/plugins/iap/native-plugin.json +28 -0
- package/vendor/@akanjs/native/plugins/iap/src/index.ts +206 -0
- package/vendor/@akanjs/native/plugins/keep-awake/android/KeepAwakePlugin.kt +48 -0
- package/vendor/@akanjs/native/plugins/keep-awake/ios/KeepAwakePlugin.swift +36 -0
- package/vendor/@akanjs/native/plugins/keep-awake/native-plugin.json +17 -0
- package/vendor/@akanjs/native/plugins/keep-awake/src/desktop.ts +127 -0
- package/vendor/@akanjs/native/plugins/keep-awake/src/index.ts +79 -0
- package/vendor/@akanjs/native/plugins/keep-awake/src/web.ts +78 -0
- package/vendor/@akanjs/native/plugins/keyboard/android/KeyboardPlugin.kt +77 -0
- package/vendor/@akanjs/native/plugins/keyboard/ios/KeyboardPlugin.swift +93 -0
- package/vendor/@akanjs/native/plugins/keyboard/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/keyboard/src/index.ts +78 -0
- package/vendor/@akanjs/native/plugins/keyboard/src/web.ts +57 -0
- package/vendor/@akanjs/native/plugins/local-notifications/android/LocalNotificationReceiver.kt +38 -0
- package/vendor/@akanjs/native/plugins/local-notifications/android/LocalNotifications.kt +284 -0
- package/vendor/@akanjs/native/plugins/local-notifications/android/LocalNotificationsPlugin.kt +248 -0
- package/vendor/@akanjs/native/plugins/local-notifications/ios/LocalNotificationsPlugin.swift +279 -0
- package/vendor/@akanjs/native/plugins/local-notifications/native-plugin.json +35 -0
- package/vendor/@akanjs/native/plugins/local-notifications/src/desktop.ts +196 -0
- package/vendor/@akanjs/native/plugins/local-notifications/src/index.ts +174 -0
- package/vendor/@akanjs/native/plugins/local-notifications/src/schedule.ts +164 -0
- package/vendor/@akanjs/native/plugins/local-notifications/src/timers.ts +72 -0
- package/vendor/@akanjs/native/plugins/local-notifications/src/web.ts +158 -0
- package/vendor/@akanjs/native/plugins/menu/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/menu/src/desktop.ts +52 -0
- package/vendor/@akanjs/native/plugins/menu/src/index.ts +107 -0
- package/vendor/@akanjs/native/plugins/network/android/NetworkPlugin.kt +124 -0
- package/vendor/@akanjs/native/plugins/network/ios/NetworkPlugin.swift +82 -0
- package/vendor/@akanjs/native/plugins/network/native-plugin.json +19 -0
- package/vendor/@akanjs/native/plugins/network/src/index.ts +59 -0
- package/vendor/@akanjs/native/plugins/network/src/web.ts +43 -0
- package/vendor/@akanjs/native/plugins/opener/android/OpenerPlugin.kt +81 -0
- package/vendor/@akanjs/native/plugins/opener/ios/OpenerPlugin.swift +83 -0
- package/vendor/@akanjs/native/plugins/opener/native-plugin.json +25 -0
- package/vendor/@akanjs/native/plugins/opener/src/desktop.ts +88 -0
- package/vendor/@akanjs/native/plugins/opener/src/index.ts +35 -0
- package/vendor/@akanjs/native/plugins/opener/src/url.ts +39 -0
- package/vendor/@akanjs/native/plugins/opener/src/web.ts +33 -0
- package/vendor/@akanjs/native/plugins/preferences/android/PreferencesPlugin.kt +44 -0
- package/vendor/@akanjs/native/plugins/preferences/ios/PreferencesPlugin.swift +47 -0
- package/vendor/@akanjs/native/plugins/preferences/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/preferences/src/desktop.ts +59 -0
- package/vendor/@akanjs/native/plugins/preferences/src/index.ts +75 -0
- package/vendor/@akanjs/native/plugins/preferences/src/web.ts +55 -0
- package/vendor/@akanjs/native/plugins/push/android/AkanNativeMessagingService.kt +17 -0
- package/vendor/@akanjs/native/plugins/push/android/PushPlugin.kt +257 -0
- package/vendor/@akanjs/native/plugins/push/ios/PushPlugin.swift +169 -0
- package/vendor/@akanjs/native/plugins/push/native-plugin.json +23 -0
- package/vendor/@akanjs/native/plugins/push/src/index.ts +73 -0
- package/vendor/@akanjs/native/plugins/screen/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/screen/src/desktop.ts +50 -0
- package/vendor/@akanjs/native/plugins/screen/src/index.ts +107 -0
- package/vendor/@akanjs/native/plugins/screen/src/web.ts +92 -0
- package/vendor/@akanjs/native/plugins/screen-orientation/android/ScreenOrientationPlugin.kt +113 -0
- package/vendor/@akanjs/native/plugins/screen-orientation/ios/ScreenOrientationPlugin.swift +150 -0
- package/vendor/@akanjs/native/plugins/screen-orientation/native-plugin.json +17 -0
- package/vendor/@akanjs/native/plugins/screen-orientation/src/index.ts +69 -0
- package/vendor/@akanjs/native/plugins/screen-orientation/src/types.ts +26 -0
- package/vendor/@akanjs/native/plugins/screen-orientation/src/web.ts +67 -0
- package/vendor/@akanjs/native/plugins/secure-storage/android/SecureStoragePlugin.kt +184 -0
- package/vendor/@akanjs/native/plugins/secure-storage/ios/SecureStoragePlugin.swift +145 -0
- package/vendor/@akanjs/native/plugins/secure-storage/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/secure-storage/src/desktop.ts +332 -0
- package/vendor/@akanjs/native/plugins/secure-storage/src/index.ts +33 -0
- package/vendor/@akanjs/native/plugins/share/android/SharePlugin.kt +218 -0
- package/vendor/@akanjs/native/plugins/share/ios/SharePlugin.swift +142 -0
- package/vendor/@akanjs/native/plugins/share/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/share/src/index.ts +87 -0
- package/vendor/@akanjs/native/plugins/share/src/options.ts +43 -0
- package/vendor/@akanjs/native/plugins/share/src/web.ts +116 -0
- package/vendor/@akanjs/native/plugins/single-instance/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/single-instance/src/desktop.ts +63 -0
- package/vendor/@akanjs/native/plugins/single-instance/src/index.ts +32 -0
- package/vendor/@akanjs/native/plugins/single-instance/src/socket.ts +248 -0
- package/vendor/@akanjs/native/plugins/splash-screen/android/SplashScreenPlugin.kt +19 -0
- package/vendor/@akanjs/native/plugins/splash-screen/ios/SplashScreenPlugin.swift +20 -0
- package/vendor/@akanjs/native/plugins/splash-screen/native-plugin.json +17 -0
- package/vendor/@akanjs/native/plugins/splash-screen/src/index.ts +24 -0
- package/vendor/@akanjs/native/plugins/splash-screen/src/web.ts +17 -0
- package/vendor/@akanjs/native/plugins/sqlite/android/SqlStatements.kt +121 -0
- package/vendor/@akanjs/native/plugins/sqlite/android/SqlitePlugin.kt +327 -0
- package/vendor/@akanjs/native/plugins/sqlite/ios/SqlitePlugin.swift +361 -0
- package/vendor/@akanjs/native/plugins/sqlite/native-plugin.json +18 -0
- package/vendor/@akanjs/native/plugins/sqlite/src/common.ts +221 -0
- package/vendor/@akanjs/native/plugins/sqlite/src/desktop.ts +140 -0
- package/vendor/@akanjs/native/plugins/sqlite/src/index.ts +114 -0
- package/vendor/@akanjs/native/plugins/toast/android/ToastPlugin.kt +27 -0
- package/vendor/@akanjs/native/plugins/toast/native-plugin.json +14 -0
- package/vendor/@akanjs/native/plugins/toast/src/index.ts +41 -0
- package/vendor/@akanjs/native/plugins/toast/src/queue.ts +77 -0
- package/vendor/@akanjs/native/plugins/toast/src/web.ts +130 -0
- package/vendor/@akanjs/native/plugins/tray/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/tray/src/desktop.ts +73 -0
- package/vendor/@akanjs/native/plugins/tray/src/index.ts +111 -0
- package/vendor/@akanjs/native/plugins/updates/android/UpdatesPlugin.kt +290 -0
- package/vendor/@akanjs/native/plugins/updates/ios/UpdatesPlugin.swift +292 -0
- package/vendor/@akanjs/native/plugins/updates/native-plugin.json +19 -0
- package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +558 -0
- package/vendor/@akanjs/native/plugins/updates/src/index.ts +95 -0
- package/vendor/@akanjs/native/plugins/window/native-plugin.json +32 -0
- package/vendor/@akanjs/native/plugins/window/src/desktop.ts +170 -0
- package/vendor/@akanjs/native/plugins/window/src/index.ts +342 -0
- package/vendor/@akanjs/native/plugins/window/src/web.ts +43 -0
- package/vendor/@akanjs/native/plugins/window-state/native-plugin.json +10 -0
- package/vendor/@akanjs/native/plugins/window-state/src/desktop.ts +73 -0
- package/vendor/@akanjs/native/plugins/window-state/src/index.ts +35 -0
- package/vendor/@akanjs/native/plugins/window-state/src/state.ts +146 -0
- package/webkit/bootCsr.tsx +26 -14
- package/webkit/index.ts +0 -2
- package/webkit/nativeNavigation.ts +116 -0
- package/webkit/nativePurchase.ts +93 -0
- package/webkit/useCamera.tsx +76 -71
- package/webkit/useCsrValues.ts +10 -124
- package/webkit/useGeoLocation.tsx +11 -13
- package/webkit/usePurchase.tsx +68 -123
- package/capacitor.base.config.ts +0 -140
- package/client/capacitor.ts +0 -252
- package/types/capacitor.base.config.d.ts +0 -3
- package/types/client/capacitor.d.ts +0 -290
- package/types/webkit/useCodepush.d.ts +0 -16
- package/types/webkit/useContact.d.ts +0 -11
- package/webkit/useCodepush.tsx +0 -76
- package/webkit/useContact.tsx +0 -45
|
@@ -0,0 +1,936 @@
|
|
|
1
|
+
package com.akanjs.runtime
|
|
2
|
+
|
|
3
|
+
import android.Manifest
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import android.content.ActivityNotFoundException
|
|
6
|
+
import android.content.Context
|
|
7
|
+
import android.content.Intent
|
|
8
|
+
import android.content.pm.ApplicationInfo
|
|
9
|
+
import android.content.pm.PackageManager
|
|
10
|
+
import android.content.res.Configuration
|
|
11
|
+
import android.graphics.Bitmap
|
|
12
|
+
import android.graphics.Color
|
|
13
|
+
import android.graphics.Insets
|
|
14
|
+
import android.graphics.drawable.ColorDrawable
|
|
15
|
+
import android.net.Uri
|
|
16
|
+
import android.os.Build
|
|
17
|
+
import android.os.Bundle
|
|
18
|
+
import android.util.Log
|
|
19
|
+
import android.view.View
|
|
20
|
+
import android.view.ViewGroup
|
|
21
|
+
import android.view.ViewTreeObserver
|
|
22
|
+
import android.view.Window
|
|
23
|
+
import android.view.WindowInsets
|
|
24
|
+
import android.view.WindowInsetsController
|
|
25
|
+
import android.view.WindowManager
|
|
26
|
+
import android.app.AlertDialog
|
|
27
|
+
import android.webkit.ConsoleMessage
|
|
28
|
+
import android.webkit.GeolocationPermissions
|
|
29
|
+
import android.webkit.JsPromptResult
|
|
30
|
+
import android.webkit.JsResult
|
|
31
|
+
import android.webkit.PermissionRequest
|
|
32
|
+
import android.webkit.RenderProcessGoneDetail
|
|
33
|
+
import android.webkit.ValueCallback
|
|
34
|
+
import android.webkit.WebChromeClient
|
|
35
|
+
import android.webkit.WebResourceRequest
|
|
36
|
+
import android.webkit.WebResourceResponse
|
|
37
|
+
import android.webkit.WebSettings
|
|
38
|
+
import android.webkit.WebView
|
|
39
|
+
import android.webkit.WebViewClient
|
|
40
|
+
import android.widget.EditText
|
|
41
|
+
import android.widget.FrameLayout
|
|
42
|
+
import android.window.OnBackInvokedCallback
|
|
43
|
+
import android.window.OnBackInvokedDispatcher
|
|
44
|
+
import com.akanjs.generated.AkanNativeGeneratedPlugins
|
|
45
|
+
import java.io.File
|
|
46
|
+
import org.json.JSONObject
|
|
47
|
+
|
|
48
|
+
internal const val TAG = "AkanNative"
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The Android shell (docs/architecture.md §3.5): one framework Activity hosting a WebView on
|
|
52
|
+
* https://app.localhost. No AppCompat, no AndroidX. Decisions verified in
|
|
53
|
+
* docs/research/android.md: MessagePort bridge, own ContentProvider, IME padding, back handling.
|
|
54
|
+
*/
|
|
55
|
+
class AkanNativeActivity : Activity(), AkanNativePluginContext.Host {
|
|
56
|
+
private lateinit var webView: WebView
|
|
57
|
+
private lateinit var bridge: AkanNativeBridge
|
|
58
|
+
private lateinit var server: AkanNativeAssetServer
|
|
59
|
+
private lateinit var root: FrameLayout
|
|
60
|
+
private lateinit var shell: JSONObject
|
|
61
|
+
|
|
62
|
+
private class PendingResult(val plugin: String, val key: String, val callback: (Int, Intent?) -> Unit)
|
|
63
|
+
private val results = HashMap<Int, PendingResult>()
|
|
64
|
+
/** Requests of a previous process, restored from the saved state (plugins.md C6): code → (plugin, key). */
|
|
65
|
+
private val restoredResults = HashMap<Int, Pair<String, String>>()
|
|
66
|
+
private val permissionResults = HashMap<Int, (Map<String, Boolean>) -> Unit>()
|
|
67
|
+
private var nextRequest = 1000
|
|
68
|
+
|
|
69
|
+
/** Read by init.js requests on the WebView's IO thread (initScript). */
|
|
70
|
+
@Volatile private var currentInsets = AkanNativeInsets(0f, 0f, 0f, 0f, false, 0f)
|
|
71
|
+
private val insetsListeners = ArrayList<(AkanNativeInsets) -> Unit>()
|
|
72
|
+
/** Keyboard mode "resize" (O6-1): pad the WebView's container by the IME. */
|
|
73
|
+
private var imeResize = true
|
|
74
|
+
private val keyboardListeners = ArrayList<(AkanNativeKeyboardTransition) -> Unit>()
|
|
75
|
+
|
|
76
|
+
private val debuggable get() = (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
|
77
|
+
|
|
78
|
+
// ---------------------------------------------------------------- lifecycle
|
|
79
|
+
|
|
80
|
+
override fun attachBaseContext(newBase: Context) {
|
|
81
|
+
super.attachBaseContext(newBase)
|
|
82
|
+
// Below API 31 the app's light or dark setting (appearance plugin) is an override of the
|
|
83
|
+
// night bits, applied before the resources exist; it survives rotation and system switches.
|
|
84
|
+
if (Build.VERSION.SDK_INT < 31) AkanNativeCompat.storedNightMode(newBase)?.let { night ->
|
|
85
|
+
applyOverrideConfiguration(Configuration().apply { uiMode = if (night) Configuration.UI_MODE_NIGHT_YES else Configuration.UI_MODE_NIGHT_NO })
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
90
|
+
super.onCreate(savedInstanceState)
|
|
91
|
+
// Theme.DeviceDefault.DayNight has an action bar and no NoActionBar variant in the framework.
|
|
92
|
+
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
93
|
+
edgeToEdge()
|
|
94
|
+
shell = readAssetJson("akan-native/shell.json")
|
|
95
|
+
imeResize = shell.optString("keyboardResize", "resize") != "none" // O6-1: before the page runs
|
|
96
|
+
AkanNativeExternal.extra = shell.optJSONArray("externalSchemes")?.let { a -> (0 until a.length()).map { a.optString(it) } } ?: emptyList()
|
|
97
|
+
restorePending(savedInstanceState)
|
|
98
|
+
|
|
99
|
+
// A WebView too old to parse the page shows a white screen; say what to do instead.
|
|
100
|
+
val chromium = webViewMajor()
|
|
101
|
+
val minimum = shell.optInt("minWebViewVersion", 94)
|
|
102
|
+
if (chromium in 1 until minimum) return showWebViewTooOld(chromium, minimum)
|
|
103
|
+
|
|
104
|
+
if (debuggable || shell.optBoolean("devtools")) WebView.setWebContentsDebuggingEnabled(true) // WV-2
|
|
105
|
+
webView = WebView(this)
|
|
106
|
+
applyBackground()
|
|
107
|
+
webView.settings.apply {
|
|
108
|
+
javaScriptEnabled = true
|
|
109
|
+
domStorageEnabled = true
|
|
110
|
+
allowFileAccess = false
|
|
111
|
+
allowContentAccess = false
|
|
112
|
+
mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW
|
|
113
|
+
setSupportMultipleWindows(false)
|
|
114
|
+
javaScriptCanOpenWindowsAutomatically = false
|
|
115
|
+
setSupportZoom(false)
|
|
116
|
+
}
|
|
117
|
+
// The page follows prefers-color-scheme itself: no darkening by WebView.
|
|
118
|
+
if (Build.VERSION.SDK_INT >= 33) Api33.noAlgorithmicDarkening(webView.settings)
|
|
119
|
+
else @Suppress("DEPRECATION") { webView.settings.forceDark = WebSettings.FORCE_DARK_OFF }
|
|
120
|
+
|
|
121
|
+
bridge = AkanNativeBridge(webView)
|
|
122
|
+
bridge.acl = AkanNativeAcl.load(bootJson)
|
|
123
|
+
bridge.declarations = (runCatching { AkanNativeAcl.plain(org.json.JSONObject(bootJson)) }.getOrNull() as? Map<*, *>)?.get("plugins") as? Map<*, *> ?: emptyMap<String, Any?>()
|
|
124
|
+
bridge.dev = debuggable
|
|
125
|
+
server = AkanNativeAssetServer(assets, bridge, ::initScript)
|
|
126
|
+
server.root = AkanNativeApp.bundleRoot() // UP-2: a downloaded bundle, or null for assets/app; once per process
|
|
127
|
+
AkanNativeApp.windows++
|
|
128
|
+
// A recreated activity (configuration, process restore) brings no new link.
|
|
129
|
+
AkanNativeLinks.connected(if (savedInstanceState == null) AkanNativeLinks.urlOf(this, intent) else null)
|
|
130
|
+
// akan-native dev --hmr: debuggable builds only; the CLI never writes it into a release build either.
|
|
131
|
+
if (debuggable) server.devServer = AkanNativeAssetServer.devServerOrNull(shell.optString("devServer").ifEmpty { null })
|
|
132
|
+
server.devServer?.let { Log.i(TAG, "pages from $it (akan-native dev --hmr)") }
|
|
133
|
+
for ((id, create) in AkanNativeGeneratedPlugins.all) {
|
|
134
|
+
try {
|
|
135
|
+
bridge.register(id, create(AkanNativePluginContext(id, this, webView, this)))
|
|
136
|
+
} catch (e: Exception) {
|
|
137
|
+
Log.e(TAG, "plugin $id failed to start", e)
|
|
138
|
+
} catch (e: LinkageError) { // an API this Android lacks, reached without a version check
|
|
139
|
+
Log.e(TAG, "plugin $id needs an API this Android version does not have", e)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
webView.webViewClient = Client()
|
|
144
|
+
webView.webChromeClient = ChromeClient()
|
|
145
|
+
|
|
146
|
+
root = FrameLayout(this)
|
|
147
|
+
root.addView(webView, FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
|
|
148
|
+
setContentView(root)
|
|
149
|
+
installInsets()
|
|
150
|
+
holdSplash()
|
|
151
|
+
webView.loadUrl(AkanNativeAssetServer.ORIGIN + startPath())
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Dev builds (O4-5): the first page's path and query; never one of akan-native's own paths. Else "/". */
|
|
155
|
+
private fun startPath(): String {
|
|
156
|
+
val path = if (debuggable) shell.optString("startPath") else ""
|
|
157
|
+
val ok = path.startsWith("/") && !path.startsWith("//") && !path.startsWith("/__akan_native") && path.none { it.isWhitespace() }
|
|
158
|
+
return if (ok) path else "/"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The WebView's Chromium major from its user agent (Google, AOSP, Huawei and Amazon WebViews all
|
|
163
|
+
* say Chrome/N; Huawei's package version counts differently), else the package version; 0: unknown.
|
|
164
|
+
*/
|
|
165
|
+
private fun webViewMajor(): Int {
|
|
166
|
+
val agent = runCatching { WebSettings.getDefaultUserAgent(this) }.getOrNull() ?: ""
|
|
167
|
+
Regex("Chrome/(\\d+)").find(agent)?.let { return it.groupValues[1].toInt() }
|
|
168
|
+
return WebView.getCurrentWebViewPackage()?.versionName?.takeWhile { it.isDigit() }?.toIntOrNull() ?: 0
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** The shell's own screen for a WebView older than android.minWebViewVersion. */
|
|
172
|
+
private fun showWebViewTooOld(chromium: Int, minimum: Int) {
|
|
173
|
+
unsupportedWebView = true
|
|
174
|
+
Log.e(TAG, "Android System WebView $chromium is older than $minimum (android.minWebViewVersion): not loading the app")
|
|
175
|
+
val pkg = WebView.getCurrentWebViewPackage()?.packageName ?: "com.google.android.webview"
|
|
176
|
+
// Below API 31 the theme's window background is the splash (color and icon): paint over it.
|
|
177
|
+
val color = backgroundColor()
|
|
178
|
+
window.setBackgroundDrawable(ColorDrawable(color))
|
|
179
|
+
lightBars(Color.luminance(color) > 0.5f)
|
|
180
|
+
val pad = (24 * resources.displayMetrics.density).toInt()
|
|
181
|
+
val layout = android.widget.LinearLayout(this).apply {
|
|
182
|
+
orientation = android.widget.LinearLayout.VERTICAL
|
|
183
|
+
gravity = android.view.Gravity.CENTER
|
|
184
|
+
setPadding(pad, pad, pad, pad)
|
|
185
|
+
}
|
|
186
|
+
layout.addView(android.widget.TextView(this).apply {
|
|
187
|
+
text = "This app needs a newer version of Android System WebView (version $minimum or later; this device has $chromium)."
|
|
188
|
+
textSize = 17f
|
|
189
|
+
gravity = android.view.Gravity.CENTER
|
|
190
|
+
})
|
|
191
|
+
layout.addView(android.widget.Button(this).apply {
|
|
192
|
+
text = "Update"
|
|
193
|
+
setOnClickListener {
|
|
194
|
+
val market = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$pkg"))
|
|
195
|
+
try {
|
|
196
|
+
startActivity(market)
|
|
197
|
+
} catch (e: ActivityNotFoundException) {
|
|
198
|
+
runCatching { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$pkg"))) }
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
setContentView(layout)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** The WebView is too old: nothing else was created (showWebViewTooOld). */
|
|
206
|
+
private var unsupportedWebView = false
|
|
207
|
+
|
|
208
|
+
override fun onNewIntent(intent: Intent) {
|
|
209
|
+
super.onNewIntent(intent)
|
|
210
|
+
if (unsupportedWebView) return
|
|
211
|
+
setIntent(intent)
|
|
212
|
+
// A plugin's own answer (auth-session's callback) is not a deep link for app.urlOpen (R10).
|
|
213
|
+
val claimed = bridge.plugins().any { runCatching { it.claimsLink(intent) }.getOrDefault(false) }
|
|
214
|
+
if (!claimed) AkanNativeLinks.urlOf(this, intent)?.let(AkanNativeLinks::open)
|
|
215
|
+
for (plugin in bridge.plugins()) runCatching { plugin.onNewIntent(intent) }
|
|
216
|
+
// Dev builds: a relaunch with new env overrides (akan-native run) reloads the page with them.
|
|
217
|
+
if (debuggable && intent.hasExtra(EXTRA_ENV)) webView.reload()
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
221
|
+
super.onConfigurationChanged(newConfig)
|
|
222
|
+
if (unsupportedWebView) return
|
|
223
|
+
applyBackground() // dark mode switches without recreating the activity (configChanges has uiMode)
|
|
224
|
+
for (plugin in bridge.plugins()) runCatching { plugin.onConfigurationChanged(newConfig) }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
override fun onSaveInstanceState(outState: Bundle) {
|
|
228
|
+
super.onSaveInstanceState(outState)
|
|
229
|
+
if (unsupportedWebView) return
|
|
230
|
+
val pending = JSONObject()
|
|
231
|
+
for ((code, p) in results) pending.put(code.toString(), JSONObject().put("plugin", p.plugin).put("key", p.key))
|
|
232
|
+
outState.putString(STATE_PENDING, pending.toString())
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
override fun onDestroy() {
|
|
236
|
+
if (unsupportedWebView) return super.onDestroy()
|
|
237
|
+
bridge.windowEnded(this) // the window is gone: so is its page's document
|
|
238
|
+
for (plugin in bridge.plugins()) runCatching { plugin.destroy() }
|
|
239
|
+
(webView.parent as? ViewGroup)?.removeView(webView)
|
|
240
|
+
webView.destroy()
|
|
241
|
+
super.onDestroy()
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private fun restorePending(saved: Bundle?) {
|
|
245
|
+
val text = saved?.getString(STATE_PENDING) ?: return
|
|
246
|
+
val pending = runCatching { JSONObject(text) }.getOrNull() ?: return
|
|
247
|
+
for (key in pending.keys()) {
|
|
248
|
+
val entry = pending.getJSONObject(key)
|
|
249
|
+
restoredResults[key.toInt()] = entry.getString("plugin") to entry.getString("key")
|
|
250
|
+
nextRequest = maxOf(nextRequest, key.toInt() + 1)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private fun isNight() = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
|
255
|
+
|
|
256
|
+
/** The app's background color (config backgroundColor, backgroundColorDark in night mode). */
|
|
257
|
+
private fun backgroundColor(): Int {
|
|
258
|
+
val hex = if (isNight()) shell.optString("backgroundColorDark", "#000000") else shell.optString("backgroundColor", "#ffffff")
|
|
259
|
+
return runCatching { Color.parseColor(hex) }.getOrDefault(if (isNight()) Color.BLACK else Color.WHITE)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private fun applyBackground() {
|
|
263
|
+
// SH-3: paint the window and the WebView before the first frame.
|
|
264
|
+
val color = backgroundColor()
|
|
265
|
+
window.setBackgroundDrawable(ColorDrawable(color))
|
|
266
|
+
webView.setBackgroundColor(color)
|
|
267
|
+
// S1: dark bar icons on a light background, light ones on a dark background. The framework
|
|
268
|
+
// DayNight theme keeps them light in day mode, where they vanish on a light page. Following the
|
|
269
|
+
// painted color (not night mode) also fits an app that is dark in day mode.
|
|
270
|
+
lightBars(Color.luminance(color) > 0.5f)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Dark icons on light bars. Above API 30 through the insets controller; up to 30 with the legacy
|
|
275
|
+
* flags, which API 30's controller does not reliably override (react-native WindowUtil.kt uses
|
|
276
|
+
* the controller only above R). The flags word is read, changed and written back: setting it
|
|
277
|
+
* whole would drop the layout and immersive flags.
|
|
278
|
+
*/
|
|
279
|
+
@Suppress("DEPRECATION")
|
|
280
|
+
private fun lightBars(light: Boolean) {
|
|
281
|
+
if (Build.VERSION.SDK_INT > 30) return Api30.lightBars(window, light)
|
|
282
|
+
val decor = window.decorView
|
|
283
|
+
val bits = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
|
284
|
+
decor.systemUiVisibility = if (light) decor.systemUiVisibility or bits else decor.systemUiVisibility and bits.inv()
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* The page draws under the status and navigation bars and the display cutout on every version
|
|
289
|
+
* (SH-2): API 35+ enforces it, below that the window lays its content out between the bars unless
|
|
290
|
+
* told otherwise (react-native WindowUtil.kt, androidx EdgeToEdge). setDecorFitsSystemWindows is a
|
|
291
|
+
* no-op where it is enforced.
|
|
292
|
+
*/
|
|
293
|
+
@Suppress("DEPRECATION")
|
|
294
|
+
private fun edgeToEdge() {
|
|
295
|
+
val w = window
|
|
296
|
+
if (Build.VERSION.SDK_INT >= 30) Api30.decorFitsSystemWindows(w, false)
|
|
297
|
+
else w.decorView.systemUiVisibility = w.decorView.systemUiVisibility or
|
|
298
|
+
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
299
|
+
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
|
300
|
+
w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
|
301
|
+
if (Build.VERSION.SDK_INT < 35) {
|
|
302
|
+
w.statusBarColor = Color.TRANSPARENT
|
|
303
|
+
w.navigationBarColor = Color.TRANSPARENT
|
|
304
|
+
}
|
|
305
|
+
w.isStatusBarContrastEnforced = false // three-button navigation keeps its scrim (navigation bar contrast)
|
|
306
|
+
w.attributes = w.attributes.apply {
|
|
307
|
+
layoutInDisplayCutoutMode = if (Build.VERSION.SDK_INT >= 30) WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
|
|
308
|
+
else WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ---------------------------------------------------------------- init.js
|
|
313
|
+
|
|
314
|
+
private val bootJson by lazy { readAsset("akan-native/boot.json").trim() }
|
|
315
|
+
|
|
316
|
+
/** INIT_PREFIX + boot.json + "," + env + ");" (architecture §3.1). Dev builds accept env overrides. */
|
|
317
|
+
private fun initScript(): String {
|
|
318
|
+
// A downloaded bundle brings the env it was published with (UP-2).
|
|
319
|
+
var env = (if (AkanNativeFeatures.UPDATES) AkanNativeUpdates.active?.let { File(AkanNativeUpdates.bundleDirectory(it.bundle), "env.runtime.json").takeIf(File::isFile)?.readText()?.trim() } else null)
|
|
320
|
+
?: readAsset("akan-native/env.runtime.json").trim()
|
|
321
|
+
val overrides = if (debuggable) intent?.getStringExtra(EXTRA_ENV) else null
|
|
322
|
+
if (overrides != null) {
|
|
323
|
+
try {
|
|
324
|
+
val merged = JSONObject(env)
|
|
325
|
+
val extra = JSONObject(overrides)
|
|
326
|
+
for (key in extra.keys()) if (key.startsWith("PUBLIC_")) merged.put(key, extra.getString(key))
|
|
327
|
+
env = merged.toString()
|
|
328
|
+
} catch (e: Exception) {
|
|
329
|
+
Log.w(TAG, "ignoring bad $EXTRA_ENV extra", e)
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// The shell's origin and engine: one value every origin comparison uses (`__AKAN_NATIVE__.origin`).
|
|
333
|
+
val version = JSONObject.quote(WebView.getCurrentWebViewPackage()?.versionName ?: "")
|
|
334
|
+
val engine = "window.__AKAN_NATIVE__.origin=\"${AkanNativeAssetServer.ORIGIN}\";window.__AKAN_NATIVE__.engine=\"android-webview\";window.__AKAN_NATIVE__.engineVersion=$version;\n"
|
|
335
|
+
// A new document starts with the current safe area (N14); later changes are pushed.
|
|
336
|
+
return INIT_PREFIX + AkanNativeBridge.jsSafe(bootJson) + "," + AkanNativeBridge.jsSafe(env) + INIT_SUFFIX + engine + cssInsets(currentInsets)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private fun readAsset(path: String): String = assets.open(path).bufferedReader().use { it.readText() }
|
|
340
|
+
|
|
341
|
+
private fun readAssetJson(path: String): JSONObject = runCatching { JSONObject(readAsset(path)) }.getOrDefault(JSONObject())
|
|
342
|
+
|
|
343
|
+
// ---------------------------------------------------------------- WebView clients
|
|
344
|
+
|
|
345
|
+
private inner class Client : WebViewClient() {
|
|
346
|
+
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? =
|
|
347
|
+
server.intercept(request)
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* SH-4 and L0 (AkanNativeKernel.decideNavigation, the rule every host shares): the WebView never
|
|
351
|
+
* leaves the app origin. A top-level link of an external scheme opens in the system instead,
|
|
352
|
+
* at most once a second; frames load web content but open nothing (WebView asks about frames
|
|
353
|
+
* only for other schemes); everything else goes nowhere. true: not loaded here.
|
|
354
|
+
*/
|
|
355
|
+
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
|
|
356
|
+
val url = request.url
|
|
357
|
+
return when (AkanNativeKernel.decideNavigation(url.toString(), request.isForMainFrame, AkanNativeAssetServer.ORIGIN, AkanNativeExternal.extra)) {
|
|
358
|
+
AkanNativeNavigation.LOAD -> false
|
|
359
|
+
AkanNativeNavigation.DROP -> true.also { Log.i(TAG, "blocked a ${url.scheme}: navigation (${if (request.isForMainFrame) "top level" else "a frame"})") }
|
|
360
|
+
AkanNativeNavigation.OPEN -> {
|
|
361
|
+
if (!AkanNativeExternal.allowed()) Log.i(TAG, "not opening a ${url.scheme}: link: at most one per second leaves the app")
|
|
362
|
+
else try {
|
|
363
|
+
startActivity(Intent(Intent.ACTION_VIEW, url).addCategory(Intent.CATEGORY_BROWSABLE))
|
|
364
|
+
} catch (e: ActivityNotFoundException) {
|
|
365
|
+
Log.w(TAG, "no activity for $url")
|
|
366
|
+
}
|
|
367
|
+
true
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
override fun onPageFinished(view: WebView, url: String) {
|
|
373
|
+
root.requestApplyInsets() // push insets into the new document
|
|
374
|
+
if (splashConfig.optBoolean("autoHide", true)) hideSplash(SPLASH_FADE_MS)
|
|
375
|
+
startReadyTimer()
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
override fun doUpdateVisitedHistory(view: WebView, url: String, isReload: Boolean) {
|
|
379
|
+
// canGoBack() is stale inside this callback (verified): check on the next loop turn.
|
|
380
|
+
view.post { updateBackCallback() }
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean {
|
|
384
|
+
// Returning false kills the app. Start over with a fresh WebView (plugins.md S10).
|
|
385
|
+
Log.e(TAG, "WebView renderer gone (crashed=${detail.didCrash()}), recreating")
|
|
386
|
+
// The page is gone now, not when the activity is made again: its calls end and its
|
|
387
|
+
// subscriptions stop, so what arrives meanwhile waits for the next page (a renderer that
|
|
388
|
+
// ends ends the document, architecture review stage 3).
|
|
389
|
+
bridge.endDocument()
|
|
390
|
+
recreate()
|
|
391
|
+
return true
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private inner class ChromeClient : WebChromeClient() {
|
|
396
|
+
override fun onConsoleMessage(message: ConsoleMessage): Boolean { // WV-3
|
|
397
|
+
val priority = when (message.messageLevel()) {
|
|
398
|
+
ConsoleMessage.MessageLevel.ERROR -> Log.ERROR
|
|
399
|
+
ConsoleMessage.MessageLevel.WARNING -> Log.WARN
|
|
400
|
+
ConsoleMessage.MessageLevel.DEBUG -> Log.DEBUG
|
|
401
|
+
else -> Log.INFO
|
|
402
|
+
}
|
|
403
|
+
Log.println(priority, "AkanNativeConsole", message.message())
|
|
404
|
+
return true
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** getUserMedia (plugins.md S6): only for the app origin and only permissions the manifest declares. */
|
|
408
|
+
override fun onPermissionRequest(request: PermissionRequest) {
|
|
409
|
+
// The app origin exactly (scheme, host and port), not any page on that host name (L0).
|
|
410
|
+
if (request.origin.toString().trimEnd('/') != AkanNativeAssetServer.ORIGIN) return request.deny()
|
|
411
|
+
val wanted = HashMap<String, String>() // WebView resource → Android permission
|
|
412
|
+
for (resource in request.resources) {
|
|
413
|
+
when (resource) {
|
|
414
|
+
PermissionRequest.RESOURCE_VIDEO_CAPTURE -> wanted[resource] = Manifest.permission.CAMERA
|
|
415
|
+
PermissionRequest.RESOURCE_AUDIO_CAPTURE -> wanted[resource] = Manifest.permission.RECORD_AUDIO
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (wanted.isEmpty() || !wanted.values.all(::declares)) return request.deny()
|
|
419
|
+
requestPermissions(wanted.values.distinct().toTypedArray()) { granted ->
|
|
420
|
+
val allowed = wanted.filterValues { granted[it] == true }.keys.toTypedArray()
|
|
421
|
+
if (allowed.isEmpty()) request.deny() else request.grant(allowed)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* navigator.geolocation (plugins.md S6, C8): only for the app origin and only when the manifest
|
|
427
|
+
* declares location (a plugin or the app's `permissions.location`). Without this override
|
|
428
|
+
* WebView denies every request. Approximate location alone counts as allowed.
|
|
429
|
+
*/
|
|
430
|
+
override fun onGeolocationPermissionsShowPrompt(origin: String, callback: GeolocationPermissions.Callback) {
|
|
431
|
+
val wanted = listOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION).filter(::declares)
|
|
432
|
+
if (origin.trimEnd('/') != AkanNativeAssetServer.ORIGIN || wanted.isEmpty()) return callback.invoke(origin, false, false)
|
|
433
|
+
requestPermissions(wanted.toTypedArray()) { granted -> callback.invoke(origin, granted.values.any { it }, false) }
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// JS alert/confirm/prompt (plugins.md S7). The WebChromeClient defaults put the page URL in the
|
|
437
|
+
// title; these follow wry RustWebChromeClient.kt, plus prompt's default text (wry drops it)
|
|
438
|
+
// and localized framework button labels.
|
|
439
|
+
override fun onJsAlert(view: WebView, url: String, message: String, result: JsResult): Boolean {
|
|
440
|
+
if (isFinishing) return false.also { result.cancel() }
|
|
441
|
+
AlertDialog.Builder(this@AkanNativeActivity)
|
|
442
|
+
.setMessage(message)
|
|
443
|
+
.setPositiveButton(android.R.string.ok) { _, _ -> result.confirm() }
|
|
444
|
+
.setOnCancelListener { result.cancel() }
|
|
445
|
+
.show()
|
|
446
|
+
return true
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
override fun onJsConfirm(view: WebView, url: String, message: String, result: JsResult): Boolean {
|
|
450
|
+
if (isFinishing) return false.also { result.cancel() }
|
|
451
|
+
AlertDialog.Builder(this@AkanNativeActivity)
|
|
452
|
+
.setMessage(message)
|
|
453
|
+
.setPositiveButton(android.R.string.ok) { _, _ -> result.confirm() }
|
|
454
|
+
.setNegativeButton(android.R.string.cancel) { _, _ -> result.cancel() }
|
|
455
|
+
.setOnCancelListener { result.cancel() }
|
|
456
|
+
.show()
|
|
457
|
+
return true
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
override fun onJsPrompt(view: WebView, url: String, message: String, defaultValue: String?, result: JsPromptResult): Boolean {
|
|
461
|
+
if (isFinishing) return false.also { result.cancel() }
|
|
462
|
+
val input = EditText(this@AkanNativeActivity).apply {
|
|
463
|
+
setText(defaultValue ?: "")
|
|
464
|
+
setSingleLine()
|
|
465
|
+
}
|
|
466
|
+
AlertDialog.Builder(this@AkanNativeActivity)
|
|
467
|
+
.setMessage(message)
|
|
468
|
+
.setView(input)
|
|
469
|
+
.setPositiveButton(android.R.string.ok) { _, _ -> result.confirm(input.text.toString()) }
|
|
470
|
+
.setNegativeButton(android.R.string.cancel) { _, _ -> result.cancel() }
|
|
471
|
+
.setOnCancelListener { result.cancel() }
|
|
472
|
+
.show()
|
|
473
|
+
return true
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Full-screen video and element.requestFullscreen() (plugins.md S9). Capacitor and wry
|
|
477
|
+
// answer onShowCustomView with onCustomViewHidden(), i.e. no full screen at all; this puts
|
|
478
|
+
// the view over everything with the system bars hidden, and back leaves it.
|
|
479
|
+
override fun onShowCustomView(view: View, callback: CustomViewCallback) {
|
|
480
|
+
if (fullscreenView != null) return callback.onCustomViewHidden()
|
|
481
|
+
fullscreenView = view
|
|
482
|
+
fullscreenCallback = callback
|
|
483
|
+
view.setBackgroundColor(Color.BLACK)
|
|
484
|
+
(window.decorView as ViewGroup).addView(view, FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
|
|
485
|
+
systemBars(visible = false)
|
|
486
|
+
updateBackCallback()
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
override fun onHideCustomView() = removeFullscreenView()
|
|
490
|
+
|
|
491
|
+
// The default poster of a <video> without one is a grey play icon; browsers show nothing.
|
|
492
|
+
override fun getDefaultVideoPoster(): Bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
|
|
493
|
+
|
|
494
|
+
override fun onShowFileChooser(view: WebView, callback: ValueCallback<Array<Uri>>, params: FileChooserParams): Boolean {
|
|
495
|
+
// Without this, <input type=file> does nothing on Android (plugins.md S8).
|
|
496
|
+
try {
|
|
497
|
+
startActivityForResult("shell", "fileChooser", fileChooserIntent(params)) { code, data ->
|
|
498
|
+
callback.onReceiveValue(if (code == android.app.Activity.RESULT_OK) chosenFiles(data) else null)
|
|
499
|
+
}
|
|
500
|
+
} catch (e: ActivityNotFoundException) {
|
|
501
|
+
callback.onReceiveValue(null)
|
|
502
|
+
}
|
|
503
|
+
return true
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* The system document picker for <input type=file>, with its `accept` types and `multiple`
|
|
509
|
+
* (FileChooserParams.createIntent takes only the first type and one file).
|
|
510
|
+
*/
|
|
511
|
+
private fun fileChooserIntent(params: WebChromeClient.FileChooserParams): Intent {
|
|
512
|
+
val types = params.acceptTypes.orEmpty().flatMap { it.split(',') }.map { it.trim().lowercase() }.filter { it.isNotEmpty() }.mapNotNull { type ->
|
|
513
|
+
if (type.startsWith(".")) android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(type.drop(1)) else type.takeIf { '/' in it }
|
|
514
|
+
}.distinct()
|
|
515
|
+
return Intent(Intent.ACTION_OPEN_DOCUMENT).addCategory(Intent.CATEGORY_OPENABLE).apply {
|
|
516
|
+
type = types.singleOrNull() ?: "*/*"
|
|
517
|
+
if (types.size > 1) putExtra(Intent.EXTRA_MIME_TYPES, types.toTypedArray())
|
|
518
|
+
if (params.mode == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* What the picker returned, keeping only content: URIs of other apps' providers. A picker is
|
|
524
|
+
* any app that answers the intent: a file: URI or one of this app's own providers
|
|
525
|
+
* (AkanNativeFileProvider) would hand the page this app's private files to upload.
|
|
526
|
+
*/
|
|
527
|
+
private fun chosenFiles(data: Intent?): Array<Uri>? {
|
|
528
|
+
val uris = buildList {
|
|
529
|
+
data?.clipData?.let { clip -> for (i in 0 until clip.itemCount) clip.getItemAt(i).uri?.let(::add) }
|
|
530
|
+
if (isEmpty()) data?.data?.let(::add)
|
|
531
|
+
}
|
|
532
|
+
val allowed = uris.filter { uri ->
|
|
533
|
+
val authority = uri.authority
|
|
534
|
+
uri.scheme == "content" && authority != null && packageManager.resolveContentProvider(authority, 0)?.packageName.let { it != null && it != packageName }
|
|
535
|
+
}
|
|
536
|
+
if (allowed.size < uris.size) Log.w(TAG, "file chooser: ignored ${uris.size - allowed.size} file(s) that are not another app's content")
|
|
537
|
+
return allowed.takeIf { it.isNotEmpty() }?.toTypedArray()
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// ---------------------------------------------------------------- splash (SH-6)
|
|
541
|
+
|
|
542
|
+
private val splashConfig get() = shell.optJSONObject("splash") ?: JSONObject()
|
|
543
|
+
private var splashHold: ViewTreeObserver.OnPreDrawListener? = null
|
|
544
|
+
private var splashFadeOut = SPLASH_FADE_MS
|
|
545
|
+
private val splashTimeout = Runnable {
|
|
546
|
+
// capacitor-plugins/splash-screen warns the same way: the app looks slower than it is.
|
|
547
|
+
Log.w(TAG, "splash hidden after the ${splashConfig.optLong("timeout", 10_000)} ms timeout; call splash.hide() once the UI is ready (or raise splash.timeout)")
|
|
548
|
+
hideSplash(SPLASH_FADE_MS)
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Keeps the system splash screen (theme windowSplashScreen*) up until the page has loaded: the
|
|
553
|
+
* content does not draw while this pre-draw listener says no, which is all androidx
|
|
554
|
+
* SplashScreen.setKeepOnScreenCondition does (capacitor-plugins/splash-screen SplashScreen.java).
|
|
555
|
+
*/
|
|
556
|
+
private fun holdSplash() {
|
|
557
|
+
val hold = ViewTreeObserver.OnPreDrawListener { false }
|
|
558
|
+
root.viewTreeObserver.addOnPreDrawListener(hold)
|
|
559
|
+
splashHold = hold
|
|
560
|
+
root.postDelayed(splashTimeout, splashConfig.optLong("timeout", 10_000))
|
|
561
|
+
// Below API 31 the system removes the starting window with its own animation.
|
|
562
|
+
if (Build.VERSION.SDK_INT >= 31) Api31.fadeSplash(this) { splashFadeOut }
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// ---------------------------------------------------------------- insets (SH-2, useKeyboard)
|
|
566
|
+
|
|
567
|
+
/** Bars and cutout, the IME's bottom edge (0 when hidden) and whether the IME shows, in pixels. */
|
|
568
|
+
private class Measured(val bars: Insets, val imeBottom: Int, val imeVisible: Boolean)
|
|
569
|
+
|
|
570
|
+
private fun installInsets() {
|
|
571
|
+
root.setOnApplyWindowInsetsListener { view, insets ->
|
|
572
|
+
val m = if (Build.VERSION.SDK_INT >= 30) Api30.measure(insets) else legacyMeasure(insets)
|
|
573
|
+
val sys = m.bars
|
|
574
|
+
val density = resources.displayMetrics.density
|
|
575
|
+
// Keyboard height above the navigation bar, like react-native ReactRootView.
|
|
576
|
+
val keyboard = if (m.imeVisible) maxOf(0, m.imeBottom - sys.bottom) else 0
|
|
577
|
+
val next = AkanNativeInsets(sys.top / density, sys.right / density, sys.bottom / density, sys.left / density, m.imeVisible, keyboard / density)
|
|
578
|
+
if (next != currentInsets) {
|
|
579
|
+
val wasVisible = currentInsets.imeVisible
|
|
580
|
+
currentInsets = next
|
|
581
|
+
for (listener in insetsListeners.toList()) runCatching { listener(next) }
|
|
582
|
+
// API 29 has no inset animations: will and did together, when the keyboard shows or hides.
|
|
583
|
+
if (Build.VERSION.SDK_INT < 30 && wasVisible != next.imeVisible) {
|
|
584
|
+
val show = next.imeVisible
|
|
585
|
+
keyboardTransition(if (show) "willShow" else "willHide", next.imeHeight, 0)
|
|
586
|
+
keyboardTransition(if (show) "didShow" else "didHide", next.imeHeight, 0)
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
// N14: --akan-native-safe-area-* on every WebView (older than 140 has no env(safe-area-inset-*),
|
|
590
|
+
// capacitor SystemBars.java), the same names as on iOS, so a page reads one set of values.
|
|
591
|
+
if (::webView.isInitialized) webView.evaluateJavascript(cssInsets(next), null)
|
|
592
|
+
// "Resize" keyboard mode: shrink the WebView container by the IME so fixed bottom UI stays
|
|
593
|
+
// visible (WebView ignores interactive-widget). Do not consume the insets (crbug 461332423).
|
|
594
|
+
view.setPadding(0, 0, 0, if (m.imeVisible && imeResize) m.imeBottom else 0)
|
|
595
|
+
val bars = Insets.of(sys.left, sys.top, sys.right, if (m.imeVisible) 0 else sys.bottom)
|
|
596
|
+
if (Build.VERSION.SDK_INT >= 30) Api30.withBars(insets, bars)
|
|
597
|
+
else @Suppress("DEPRECATION") WindowInsets.Builder(insets).setSystemWindowInsets(bars).build()
|
|
598
|
+
}
|
|
599
|
+
if (Build.VERSION.SDK_INT >= 30) Api30.watchImeAnimation(root) { show, heightPx, duration, done ->
|
|
600
|
+
val phase = if (done) (if (show) "didShow" else "didHide") else (if (show) "willShow" else "willHide")
|
|
601
|
+
keyboardTransition(phase, if (show) heightPx / resources.displayMetrics.density else 0f, duration)
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
private fun keyboardTransition(phase: String, height: Float, durationMs: Long) {
|
|
606
|
+
val t = AkanNativeKeyboardTransition(phase, height, durationMs)
|
|
607
|
+
for (listener in keyboardListeners.toList()) runCatching { listener(t) }
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* API 29 has no inset types: the system window insets hold the bars and, with adjustResize, the
|
|
612
|
+
* IME; the stable insets hold the bars alone, so a system window bottom above the stable one is
|
|
613
|
+
* the keyboard (androidx WindowInsetsCompat's rule). The cutout comes separately.
|
|
614
|
+
*/
|
|
615
|
+
@Suppress("DEPRECATION")
|
|
616
|
+
private fun legacyMeasure(insets: WindowInsets): Measured {
|
|
617
|
+
val sw = insets.systemWindowInsets
|
|
618
|
+
val st = insets.stableInsets
|
|
619
|
+
val cut = insets.displayCutout
|
|
620
|
+
val imeVisible = sw.bottom > st.bottom
|
|
621
|
+
val bars = Insets.of(
|
|
622
|
+
maxOf(sw.left, cut?.safeInsetLeft ?: 0), maxOf(sw.top, cut?.safeInsetTop ?: 0),
|
|
623
|
+
maxOf(sw.right, cut?.safeInsetRight ?: 0), maxOf(minOf(sw.bottom, st.bottom), cut?.safeInsetBottom ?: 0),
|
|
624
|
+
)
|
|
625
|
+
return Measured(bars, if (imeVisible) sw.bottom else 0, imeVisible)
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/** The CSS variables for these insets, in CSS px; bottom is 0 while the keyboard shows (as WebView's env() does). */
|
|
629
|
+
private fun cssInsets(i: AkanNativeInsets): String {
|
|
630
|
+
val bottom = if (i.imeVisible) 0f else i.bottom
|
|
631
|
+
return "document.documentElement&&(function(s){s.setProperty('--akan-native-safe-area-top','${i.top}px');" +
|
|
632
|
+
"s.setProperty('--akan-native-safe-area-right','${i.right}px');s.setProperty('--akan-native-safe-area-bottom','${bottom}px');" +
|
|
633
|
+
"s.setProperty('--akan-native-safe-area-left','${i.left}px')})(document.documentElement.style);\n"
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// ---------------------------------------------------------------- full screen (plugins.md S9)
|
|
637
|
+
|
|
638
|
+
private var fullscreenView: View? = null
|
|
639
|
+
private var fullscreenCallback: WebChromeClient.CustomViewCallback? = null
|
|
640
|
+
|
|
641
|
+
private fun removeFullscreenView() {
|
|
642
|
+
val view = fullscreenView ?: return
|
|
643
|
+
fullscreenView = null
|
|
644
|
+
fullscreenCallback = null
|
|
645
|
+
(window.decorView as ViewGroup).removeView(view)
|
|
646
|
+
systemBars(visible = true)
|
|
647
|
+
updateBackCallback()
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Hides the system bars for a full-screen view (swipe brings them back for a moment) or shows
|
|
652
|
+
* them again. Below API 30 the immersive flags; never the window's FLAG_FULLSCREEN, which turns
|
|
653
|
+
* adjustResize off.
|
|
654
|
+
*/
|
|
655
|
+
@Suppress("DEPRECATION")
|
|
656
|
+
private fun systemBars(visible: Boolean) {
|
|
657
|
+
if (Build.VERSION.SDK_INT >= 30) return Api30.systemBars(window, visible)
|
|
658
|
+
val decor = window.decorView
|
|
659
|
+
val bits = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
660
|
+
decor.systemUiVisibility = if (visible) decor.systemUiVisibility and bits.inv() else decor.systemUiVisibility or bits
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
|
664
|
+
super.onWindowFocusChanged(hasFocus)
|
|
665
|
+
// Below API 30 a dialog or permission prompt clears the immersive flags: hide the bars again.
|
|
666
|
+
if (hasFocus && fullscreenView != null && Build.VERSION.SDK_INT < 30) systemBars(visible = false)
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/** Back or the page leaving: tell WebView (it exits document.fullscreenElement), then drop the view. */
|
|
670
|
+
private fun exitFullscreen() {
|
|
671
|
+
fullscreenCallback?.onCustomViewHidden()
|
|
672
|
+
removeFullscreenView()
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// ---------------------------------------------------------------- back (SH-5)
|
|
676
|
+
|
|
677
|
+
private var backInterceptor: (() -> Unit)? = null
|
|
678
|
+
|
|
679
|
+
/** What back does inside the app. false: nothing to do here (the root page without a listener). */
|
|
680
|
+
private fun handleBack(): Boolean {
|
|
681
|
+
val interceptor = backInterceptor
|
|
682
|
+
when {
|
|
683
|
+
fullscreenView != null -> exitFullscreen()
|
|
684
|
+
interceptor != null -> interceptor()
|
|
685
|
+
webView.canGoBack() -> webView.goBack()
|
|
686
|
+
else -> return false
|
|
687
|
+
}
|
|
688
|
+
webView.post { updateBackCallback() }
|
|
689
|
+
return true
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/** API 33+: the registered OnBackInvokedCallback (created only there: the interface is API 33). */
|
|
693
|
+
private var backCallback: Any? = null
|
|
694
|
+
private var backRegistered = false
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* API 33+: intercept back only while there is history, a page listener or a full-screen view, so
|
|
698
|
+
* the system back-to-home animation stays at the root. Below 33 onBackPressed() does the same.
|
|
699
|
+
*/
|
|
700
|
+
private fun updateBackCallback() {
|
|
701
|
+
if (Build.VERSION.SDK_INT < 33) return
|
|
702
|
+
val want = fullscreenView != null || backInterceptor != null || webView.canGoBack()
|
|
703
|
+
if (want != backRegistered) backCallback = Api33.setBackCallback(this, backCallback, want) { handleBack() }
|
|
704
|
+
backRegistered = want
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/** Below API 33 only (enableOnBackInvokedCallback takes it over from 33). */
|
|
708
|
+
@Deprecated("the platform calls it below API 33 only")
|
|
709
|
+
@Suppress("DEPRECATION")
|
|
710
|
+
override fun onBackPressed() {
|
|
711
|
+
if (unsupportedWebView) return super.onBackPressed()
|
|
712
|
+
if (handleBack()) return
|
|
713
|
+
// At the root: 31+ moves the task back and keeps the page; 29 and 30 would finish the activity.
|
|
714
|
+
if (Build.VERSION.SDK_INT < 31) moveTaskToBack(true) else super.onBackPressed()
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// ---------------------------------------------------------------- results and permissions (plugins.md C1, C3)
|
|
718
|
+
|
|
719
|
+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
720
|
+
val pending = results.remove(requestCode)
|
|
721
|
+
if (pending != null) return pending.callback(resultCode, data)
|
|
722
|
+
val restored = restoredResults.remove(requestCode)
|
|
723
|
+
if (restored != null) {
|
|
724
|
+
val plugin = bridge.plugin(restored.first)
|
|
725
|
+
if (plugin != null) runCatching { plugin.onRestoredActivityResult(restored.second, resultCode, data) }
|
|
726
|
+
else Log.w(TAG, "activity result for ${restored.first}/${restored.second} after process restart dropped")
|
|
727
|
+
return
|
|
728
|
+
}
|
|
729
|
+
super.onActivityResult(requestCode, resultCode, data)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
|
733
|
+
val callback = permissionResults.remove(requestCode) ?: return
|
|
734
|
+
// Empty when the request was cancelled (another one was showing): nothing was answered.
|
|
735
|
+
val answers = permissions.indices.associate { permissions[it] to (grantResults.getOrNull(it) == PackageManager.PERMISSION_GRANTED) }
|
|
736
|
+
permissionHistory.record(answers)
|
|
737
|
+
callback(answers)
|
|
738
|
+
permissionQueue.removeFirstOrNull()?.invoke() // the next request, one at a time
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
private fun declares(permission: String): Boolean = try {
|
|
742
|
+
packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS).requestedPermissions?.contains(permission) == true
|
|
743
|
+
} catch (e: PackageManager.NameNotFoundException) {
|
|
744
|
+
false
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
private val permissionHistory by lazy { AkanNativePermissionHistory(this) }
|
|
748
|
+
|
|
749
|
+
/** Requests waiting for the one on screen: Android cancels a request made while another shows. */
|
|
750
|
+
private val permissionQueue = ArrayDeque<() -> Unit>()
|
|
751
|
+
|
|
752
|
+
// ---------------------------------------------------------------- AkanNativePluginContext.Host
|
|
753
|
+
|
|
754
|
+
override fun emit(plugin: String, event: String, data: Any?) = bridge.emit(plugin, event, data)
|
|
755
|
+
|
|
756
|
+
override fun registerFile(file: File, mime: String): JSONObject = bridge.registerFile(file, mime)
|
|
757
|
+
|
|
758
|
+
override fun file(id: String): Pair<File, String>? = bridge.file(id)
|
|
759
|
+
|
|
760
|
+
override fun captureTarget(name: String): Pair<File, Uri> = AkanNativeFileProvider.target(this, name)
|
|
761
|
+
|
|
762
|
+
override fun startActivityForResult(plugin: String, key: String, intent: Intent, callback: (resultCode: Int, data: Intent?) -> Unit) {
|
|
763
|
+
val code = nextRequest++
|
|
764
|
+
results[code] = PendingResult(plugin, key, callback)
|
|
765
|
+
try {
|
|
766
|
+
startActivityForResult(intent, code)
|
|
767
|
+
} catch (e: RuntimeException) { // ActivityNotFoundException, SecurityException
|
|
768
|
+
results.remove(code)
|
|
769
|
+
throw e
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
override fun requestPermissions(permissions: Array<String>, callback: (granted: Map<String, Boolean>) -> Unit) {
|
|
774
|
+
val request: () -> Unit = {
|
|
775
|
+
val missing = permissions.filter { checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED }
|
|
776
|
+
if (missing.isEmpty()) {
|
|
777
|
+
callback(permissions.associateWith { true })
|
|
778
|
+
permissionQueue.removeFirstOrNull()?.invoke()
|
|
779
|
+
} else {
|
|
780
|
+
val code = nextRequest++
|
|
781
|
+
permissionResults[code] = { granted -> callback(permissions.associateWith { granted[it] ?: (checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED) }) }
|
|
782
|
+
requestPermissions(missing.toTypedArray(), code)
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (permissionResults.isEmpty()) request() else permissionQueue.addLast(request)
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
override fun permissionState(permission: String): String = when {
|
|
789
|
+
checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED -> AkanNativePermission.GRANTED
|
|
790
|
+
shouldShowRequestPermissionRationale(permission) -> AkanNativePermission.PROMPT_WITH_RATIONALE
|
|
791
|
+
permission in permissionHistory -> AkanNativePermission.DENIED
|
|
792
|
+
else -> AkanNativePermission.PROMPT
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
override fun insets(): AkanNativeInsets = currentInsets
|
|
796
|
+
|
|
797
|
+
override fun onInsetsChanged(listener: (AkanNativeInsets) -> Unit) {
|
|
798
|
+
insetsListeners.add(listener)
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
override fun setImeResize(resize: Boolean) {
|
|
802
|
+
if (imeResize == resize) return
|
|
803
|
+
imeResize = resize
|
|
804
|
+
root.requestApplyInsets()
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
override fun onKeyboardTransition(listener: (AkanNativeKeyboardTransition) -> Unit) {
|
|
808
|
+
keyboardListeners.add(listener)
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
override fun setBackInterceptor(interceptor: (() -> Unit)?) {
|
|
812
|
+
backInterceptor = interceptor
|
|
813
|
+
updateBackCallback()
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// ---------------------------------------------------------------- web bundle updates (UP-2)
|
|
817
|
+
|
|
818
|
+
private val readyTimeout = Runnable {
|
|
819
|
+
if (AkanNativeFeatures.UPDATES && AkanNativeUpdates.onTrial) serveBundle(AkanNativeUpdates.rollback())
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/** A bundle on trial must call notifyReady() within updates.readyTimeout of loading. */
|
|
823
|
+
private fun startReadyTimer() {
|
|
824
|
+
webView.removeCallbacks(readyTimeout)
|
|
825
|
+
if (!AkanNativeFeatures.UPDATES) return
|
|
826
|
+
val timeout = AkanNativeUpdates.config?.readyTimeoutMs ?: return
|
|
827
|
+
if (AkanNativeUpdates.onTrial) webView.postDelayed(readyTimeout, timeout)
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/** Serves another web bundle (null: the APK's own) and loads it from the start. */
|
|
831
|
+
override fun serveBundle(root: File?) {
|
|
832
|
+
webView.removeCallbacks(readyTimeout)
|
|
833
|
+
server.root = root
|
|
834
|
+
webView.loadUrl("${AkanNativeAssetServer.ORIGIN}/")
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
override fun hideSplash(fadeOutMs: Long) {
|
|
838
|
+
val hold = splashHold ?: return
|
|
839
|
+
splashHold = null
|
|
840
|
+
splashFadeOut = fadeOutMs
|
|
841
|
+
root.removeCallbacks(splashTimeout)
|
|
842
|
+
root.viewTreeObserver.removeOnPreDrawListener(hold)
|
|
843
|
+
root.invalidate()
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/** For plugins: whether the WebView has history to go back to. */
|
|
847
|
+
fun canGoBack(): Boolean = webView.canGoBack()
|
|
848
|
+
|
|
849
|
+
// ---------------------------------------------------------------- newer APIs (lib/apilevel.ts)
|
|
850
|
+
|
|
851
|
+
private object Api30 {
|
|
852
|
+
@Suppress("DEPRECATION") // deprecated in 35, where edge-to-edge is enforced and this is a no-op
|
|
853
|
+
fun decorFitsSystemWindows(window: Window, fits: Boolean) = window.setDecorFitsSystemWindows(fits)
|
|
854
|
+
|
|
855
|
+
fun lightBars(window: Window, light: Boolean) {
|
|
856
|
+
val bits = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS or WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
|
|
857
|
+
window.insetsController?.setSystemBarsAppearance(if (light) bits else 0, bits)
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
fun systemBars(window: Window, visible: Boolean) {
|
|
861
|
+
val controller = window.insetsController ?: return
|
|
862
|
+
if (visible) return controller.show(WindowInsets.Type.systemBars())
|
|
863
|
+
controller.hide(WindowInsets.Type.systemBars())
|
|
864
|
+
controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
private val bars get() = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
|
|
868
|
+
|
|
869
|
+
fun measure(insets: WindowInsets): Measured {
|
|
870
|
+
val ime = WindowInsets.Type.ime()
|
|
871
|
+
val visible = insets.isVisible(ime)
|
|
872
|
+
return Measured(insets.getInsets(bars), if (visible) insets.getInsets(ime).bottom else 0, visible)
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
fun withBars(insets: WindowInsets, value: Insets): WindowInsets = WindowInsets.Builder(insets).setInsets(bars, value).build()
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* The IME's show and hide animations: [report] (show, height px above the bars once it ends,
|
|
879
|
+
* duration ms, ended) at the start and at the end. At the start the view's root insets are
|
|
880
|
+
* already the end state.
|
|
881
|
+
*/
|
|
882
|
+
fun watchImeAnimation(view: View, report: (Boolean, Float, Long, Boolean) -> Unit) {
|
|
883
|
+
val ime = WindowInsets.Type.ime()
|
|
884
|
+
fun target(): Pair<Boolean, Float> {
|
|
885
|
+
val insets = view.rootWindowInsets ?: return false to 0f
|
|
886
|
+
val show = insets.isVisible(ime)
|
|
887
|
+
val height = maxOf(0, insets.getInsets(ime).bottom - insets.getInsets(WindowInsets.Type.systemBars()).bottom)
|
|
888
|
+
return show to height.toFloat()
|
|
889
|
+
}
|
|
890
|
+
view.setWindowInsetsAnimationCallback(object : android.view.WindowInsetsAnimation.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE) {
|
|
891
|
+
override fun onStart(animation: android.view.WindowInsetsAnimation, bounds: android.view.WindowInsetsAnimation.Bounds): android.view.WindowInsetsAnimation.Bounds {
|
|
892
|
+
if (animation.typeMask and ime != 0) target().let { (show, height) -> report(show, height, animation.durationMillis, false) }
|
|
893
|
+
return bounds
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
override fun onProgress(insets: WindowInsets, running: MutableList<android.view.WindowInsetsAnimation>): WindowInsets = insets
|
|
897
|
+
|
|
898
|
+
override fun onEnd(animation: android.view.WindowInsetsAnimation) {
|
|
899
|
+
if (animation.typeMask and ime != 0) target().let { (show, height) -> report(show, height, animation.durationMillis, true) }
|
|
900
|
+
}
|
|
901
|
+
})
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
private object Api31 {
|
|
906
|
+
fun fadeSplash(activity: Activity, duration: () -> Long) {
|
|
907
|
+
activity.splashScreen.setOnExitAnimationListener { view ->
|
|
908
|
+
view.animate().alpha(0f).setDuration(duration()).withEndAction { view.remove() }.start()
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
private object Api33 {
|
|
914
|
+
fun noAlgorithmicDarkening(settings: WebSettings) {
|
|
915
|
+
settings.isAlgorithmicDarkeningAllowed = false
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/** Registers or unregisters the back callback; returns the callback to keep. */
|
|
919
|
+
fun setBackCallback(activity: Activity, current: Any?, register: Boolean, onBack: () -> Unit): Any {
|
|
920
|
+
val callback = (current as? OnBackInvokedCallback) ?: OnBackInvokedCallback { onBack() }
|
|
921
|
+
if (register) activity.onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, callback)
|
|
922
|
+
else activity.onBackInvokedDispatcher.unregisterOnBackInvokedCallback(callback)
|
|
923
|
+
return callback
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
companion object {
|
|
928
|
+
/** Dev builds: JSON object of PUBLIC_ env overrides, e.g. am start --es akanNativeEnv '{"PUBLIC_X":"1"}'. */
|
|
929
|
+
const val EXTRA_ENV = "akanNativeEnv"
|
|
930
|
+
private const val STATE_PENDING = "akan-native.pendingResults"
|
|
931
|
+
private const val SPLASH_FADE_MS = 200L
|
|
932
|
+
// Must match @akanjs/native/core protocol.ts INIT_PREFIX / INIT_SUFFIX.
|
|
933
|
+
private const val INIT_PREFIX = "window.__AKAN_NATIVE__=(function(o,b,e){for(var k in b)o[k]=b[k];o.env=e;return o})(window.__AKAN_NATIVE__||{},"
|
|
934
|
+
private const val INIT_SUFFIX = ");\n"
|
|
935
|
+
}
|
|
936
|
+
}
|