Skip to content
This repository was archived by the owner on Oct 12, 2024. It is now read-only.

Conversation

jiongxuan
Copy link
Contributor

@jiongxuan jiongxuan commented Oct 7, 2024

Description

This pull request introduces offline support and resolves CORS issues in the Android application. It integrates Capacitor for better performance and a modern architecture, replacing Cordova after evaluating their differences and benefits. To ensure compatibility with existing users, a new CapacitorMainActivity is added, allowing new installations to utilize the offline capabilities without affecting the current FullscreenActivity used by existing users. Additionally, the codebase has been modularized by introducing the LaunchDecider and WebViewRequestHandler classes to manage app launch behavior and WebView request handling respectively.

Problem:

  • Lack of Offline Support: The existing Android application requires an active internet connection to function, preventing users from accessing core features when offline.

  • CORS (Cross-Origin Resource Sharing) Issues: The app encounters CORS-related problems, limiting its ability to interact securely with local or self-hosted resources.

  • Security Concerns: There are significant security vulnerabilities related to network hijacking, which could lead to data breaches or unauthorized access if the app relies solely on external servers without proper safeguards.


Objective:

  • Enable Offline Functionality: Allow users to utilize the Android app's core features without needing an internet connection, enhancing accessibility and reliability.

  • Resolve CORS Issues: Configure WebView appropriately to eliminate CORS-related problems, ensuring secure and flexible interactions with various resources.

  • Enhance Security: Implement measures to prevent network hijacking and other security threats, ensuring that data interactions remain secure even when offline.


User Experience:

  • Enhanced Accessibility: Users can now access and use the app's functionalities even without an internet connection, making the app more reliable and user-friendly.

  • Seamless Experience for Existing Users: Existing users upgrading from older versions will continue using the app without any disruptions, maintaining data integrity and consistent functionality.

  • Offline Mode for New Installations: New installations will have offline capabilities enabled by default, allowing users to work without constant internet access.

  • Future Migration Plans: While the new offline solution is available for fresh installations, plans are in place to develop migration strategies to transition existing users to the new offline mode without affecting their current usage.


Technical Changes:

  • Introduced Capacitor:

    • Reasoning: Compared to Cordova, Capacitor offers better performance, a more modern architecture, and easier integration with native platforms. Capacitor provides a more robust bridge for web-native interactions, enhancing the app's capabilities and maintainability.
  • Added CapacitorMainActivity:

    • Purpose: Isolates the new Capacitor-based implementation from the existing FullscreenActivity, preventing mutual interference and ensuring stable operation for both new and existing users.
  • Introduced LaunchDecider Class:

    • Purpose: Manages the app's launch behavior based on whether the user performed a fresh installation or upgraded from a previous version.
    • Functionality: Utilizes SharedPreferences, PackageInfo, and file existence checks to determine the appropriate launch mode (MODE_ONLINE for existing users and MODE_OFFLINE for new installations).
    • Implementation: Ensures that users are directed to the correct activity (FullscreenActivity or CapacitorMainActivity) based on their installation status.
  • Extracted WebViewRequestHandler:

    • Purpose: Centralizes the handling of WebView requests, including URL loading and request interception, to avoid code duplication across activities.
    • Functionality: Manages both shouldOverrideUrlLoading and shouldInterceptRequest methods, ensuring consistent behavior and streamlined request processing.
  • Updated AndroidManifest.xml:

    • Configuration: Set FullscreenActivity as the default launcher activity and declared CapacitorMainActivity appropriately without a launcher intent filter.
    • Intent Handling: Ensured that FullscreenActivity manages the transition to CapacitorMainActivity based on the launch decision logic.
  • Refactored FullscreenActivity:

    • Integration: Incorporated LaunchDecider to determine the appropriate activity to launch during onCreate.
    • Stability Fix: Added checks to prevent wvContainer from causing crashes by verifying its initialization before attempting to remove views in onDestroy.

Issues Resolved

Check List

  • [ ✅ ] New functionality includes testing.
  • [ ✅ ] New functionality has been documented in the README if applicable.

jiongxuan and others added 30 commits September 13, 2024 09:27
…h it from the previous Activity

(temporarily replace it first, and make it compatible later)
Replaced direct Activity dependency with AppLifecycleObserver to track foreground state more accurately via the app's lifecycle.
…e and Activity

Refactored to ensure one-way dependency, fully decoupling JavaScriptInterface from Activity for better separation of concerns.
…line JS calls etc.

Integrated Capacitor Activity to maintain compatibility with the original JavaScriptInterface, ensuring JS can be invoked offline.
Implemented proper back press handling for WebView navigation, which was previously unsupported. Utilized OnBackPressedDispatcher with Kotlin lambda for cleaner and more efficient code.
…FullscreenActivity, ensuring it save and restore the storageHelper and web view state.
… the results to JavaScriptInterface.

JavaScriptInterface relies on onActivityResult to process results from external activities, we need to override this method and forward the results.

(Future: Replace to registerForActivityResult)
…ity method to call a JavaScript function if it exists.
…ling

Created WebViewRequestHandler class to handle both URL loading and web request interception. This extracts the logic from FullscreenActivity, making the handling of WebView requests reusable and maintainable across the H5 and Capacitor.
…WebViewRequestHandler

Refactored FullscreenActivity to use the newly extracted WebViewRequestHandler for URL loading and request interception. This reduces code duplication and centralizes the WebView handling logic.
- Added logic to decide if the user is on an upgraded version or a fresh install.
- Utilized SharedPreferences and PackageInfo to store the state and determine if the user should remain on FullscreenActivity (online mode) or switch to CapacitorMainActivity (offline mode).
- Checked for the presence of the SupKeyValStore file to further refine the decision for users on recent upgrades.
- Modified FullscreenActivity to use the newly created LaunchDecider to determine whether to launch CapacitorMainActivity or remain in FullscreenActivity.
- Adjusted onCreate to redirect users to CapacitorMainActivity based on LaunchDecider’s decision.
- Added logic to handle Intent forwarding when transitioning to the new activity.
- Fixed issue where wvContainer could cause a crash in onDestroy by checking initialization before removing the WebView.
- Introduced a new configuration field `LAUNCH_MODE` in `app_config.properties` to control launch behavior:
  - 0: Default behavior (read from SharedPreferences)
  - 1: Force online mode
  - 2: Force offline mode
- Prefixed existing configuration fields with `ONLINE_` to distinguish them:
  - `SERVICE_IS_LOCAL` → `ONLINE_SERVICE_IS_LOCAL`
  - `SERVICE_HOST` → `ONLINE_SERVICE_HOST`
  - `SERVICE_PROTOCOL` → `ONLINE_SERVICE_PROTOCOL`
- Updated `config.gradle` to handle the new `LAUNCH_MODE` and prefixed fields
- Modified `LaunchDecider.kt` to utilize `BuildConfig.LAUNCH_MODE` and handle forced modes
- Ensured existing logic is maintained when `LAUNCH_MODE` is set to 0 for backward compatibility
- Added section explaining how to configure the app for a self-hosted server.
- Clarified that self-hosted configuration applies when `LAUNCH_MODE` is set to `1` or `0` (for upgraded users).
…the FullScreenActivity WebView, including UA, domStorage etc.
…eplaced `webViewRequestHandler.interceptWebRequest` with `bridge.webViewClient.shouldInterceptRequest`
- Added recommendation to use Offline Mode in the online.md document with an explanation of benefits.
- Clarified `LAUNCH_MODE=0` behavior in offline.md, indicating it is intended for new installations and online mode.
- Provided detailed steps for configuring Offline Mode and Online Mode in separate documentation files.
- Linked mode-specific documentation from the main README for easier navigation.
…lity

Maintaining the "; wv" substring in the WebView's User-Agent is essential for the proper registration and operation of Service Workers within Capacitor. Removing or altering "; wv" disrupts the Service Worker's ability to intercept requests, leading to functionality issues.
… improvements

- Replaced "Offline Mode" with "Connectivity-Free Mode" for better clarity.
- Updated README and related documentation for easier understanding.
- Added clear instructions for configuring launch modes.
- Improved consistency between Online-Only Mode (Compatibility Mode) and new mode explanations.
@johannesjo johannesjo merged commit f6b9d1f into johannesjo:master Oct 11, 2024
1 check passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants