feat: migrate legacy native modules to Nitro Modules#22
Open
huhuanming wants to merge 86 commits intomainfrom
Open
feat: migrate legacy native modules to Nitro Modules#22huhuanming wants to merge 86 commits intomainfrom
huhuanming wants to merge 86 commits intomainfrom
Conversation
b985df0 to
13c4dfd
Compare
Unified native logging module with static OneKeyLog API that self-initializes
on first call, replacing react-native-file-logger's JS-configured approach.
- iOS: CocoaLumberjack backend with custom log file naming (app- prefix) and message-only formatter
- Android: SLF4J + logback-android backend
- Nitro HybridObject bridge for JS layer (write, getLogFilePaths, deleteLogFiles)
- Consistent log file naming across platforms (app- prefix + date)
- Same log config as existing: 20MB max, 3 files, daily rolling, {CachesDir}/logs
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- Remove unnecessary CocoaLumberjack import from iOS NativeLogger.swift - Add else branch in Android NativeLogger.kt write() for unknown levels - Use detachAndStopAllAppenders() in Android OneKeyLog to prevent duplicate logcat - Unify iOS logsDirectory path to use computed property (remove duplication) - Add sortedBy to Android getLogFilePaths() for consistent ordering with iOS Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Add file-based logging via OneKeyLog to 5 native modules: - device-utils: UI style changes, foldable detection, spanning state - keychain-module: keychain operations success/failure with OSStatus - cloud-kit-module: CloudKit CRUD operations and query results - check-biometric-auth-changed: biometric state change detection - get-random-values: error-only logging for SecRandomCopyBytes/SecureRandom Each module declares a dependency on ReactNativeNativeLogger (iOS podspec) and compileOnly project dependency (Android build.gradle where applicable). Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Add test page with log directory viewer, write operations (custom message, all levels, batch), and file management (refresh, delete). Registers the native-logger module in the example app route and package.json. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
New modules created via create-nitro-module.js will now include OneKeyLog dependency out of the box (podspec, build.gradle, imports). Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- Replace force unwrap with safe unwrap in iOS logsDirectory - Use detachAppender instead of detachAndStopAllAppenders on Android - Handle applicationContext null gracefully in Android OneKeyLog - Log failures in getLogFilePaths and deleteLogFiles (iOS + Android) - Redact keychain key names in log output for security - Replace setTimeout with await in test page Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- Remove all key name references from Keychain log messages for security - Add detailed comment explaining maximumNumberOfLogFiles off-by-one Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
HIGH: - H-2: Replace unsafe /tmp/logs fallback with no-op when context is null - H-3: Apply iOS file protection (completeUntilFirstUserAuthentication) - H-1: Add 4KB message truncation to prevent disk abuse MEDIUM: - M-1: Attach file appender to named "OneKey" logger instead of ROOT to prevent capturing third-party SLF4J output - M-2: Change compileOnly to implementation to prevent NoClassDefFoundError - M-3: Truncation also mitigates log injection via oversized messages - M-5: Fix TOCTOU race in iOS log archive with retry loop Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- P1: deleteLogFiles skips active app-latest.log to avoid breaking logger's open file handle (iOS + Android) - P2: Android logger uses retry-able cached getter instead of by-lazy, so if applicationContext is null at first access, logging can recover once context becomes available - P3: Log warning if iOS archive TOCTOU retry loop exhausts 1000 attempts - P4: Remove unused OneKeyLog imports from module template - P5: Use NSString.appendingPathComponent for iOS path construction Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- P1: Replace force unwrap with guard let in ReactNativeGetRandomValues (iOS) - P2: Remove duplicate error logging in KeychainModule wrapper (Core already logs) - P2: Change biometric auth change log level from warn to info - P2: Add @volatile to windowLayoutInfo for thread-safe reads from Promise.async - P2: Use error.localizedDescription in CloudKit logs for consistency - P3: Remove unnecessary UserDefaults.synchronize() call Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…log dir - Native-side log writes now use `HH:mm:ss | LEVEL : [tag] message` format - JS-side log writes remain unformatted (raw message preserved) - Add copy-to-clipboard button for log directory path in test page - Integrate native-logger into example app and update pod dependencies Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- iOS: call OneKeyLog via ObjC bridge (OneKeyLogBridge) to avoid Clang module build failure with NitroModules C++ headers - Android: call OneKeyLog.info directly in MainApplication.onCreate - Both log "Application started" with native timestamp format Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2b89c37 to
1403283
Compare
React Native autolinking generates project names from scoped npm package names by replacing `@`/`/` with `_`, so `@onekeyfe/react-native-native-logger` becomes `:onekeyfe_react-native-native-logger`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
ContentProvider.onCreate() runs between attachBaseContext() and Application.onCreate(), so the logger is ready for the earliest app-level startup logs. Consuming apps no longer need to call OneKeyLog.init() manually. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 5 new Nitro modules and extend device-utils for migrating all legacy RCTBridgeModule/ReactContextBaseJavaModule code to New Architecture: - react-native-bundle-update: JS bundle OTA update with SHA256 verification, ZIP extraction, PGP signature validation, and download progress events - react-native-app-update: Android APK download/install with notification progress (iOS stub) - react-native-perf-memory: Memory usage reporting (RSS) for iOS and Android - react-native-splash-screen: Legacy splash screen for Android < 12 (iOS stub) - react-native-webview-checker: Android WebView package info and Google Play Services availability check (iOS stub) - react-native-device-utils: Extended with LaunchOptions, ExitApp, and startup time tracking All modules use OneKeyLog for logging and follow the Nitro callback listener pattern for events (replacing NativeEventEmitter).
Add test pages for BundleUpdate, AppUpdate, PerfMemory, SplashScreen, and WebViewChecker modules. Also add LaunchOptions and ExitApp tests to the existing DeviceUtils test page.
…p-update - Use custom urlSession instead of URLSession.shared to prevent HTTPS bypass via HTTP redirects (iOS bundle-update) - Add HTTPS redirect detection after download completes (iOS bundle-update) - Enforce TLS 1.2 minimum on URLSession configuration (iOS bundle-update) - Use defer to guarantee isDownloading reset on all error paths (iOS bundle-update) - Wrap downloadAPK in try/finally to guarantee isDownloading reset (Android app-update) - Make verifyASC throw instead of silently succeeding without GPG verification (Android app-update) - Fix response.body!! force-unwrap crash in downloadASC (Android app-update) - Add readTimeout to OkHttpClient to prevent indefinite hangs (Android app-update) - Make testVerification return false instead of true when GPG is unimplemented (both platforms) - Remove dead downloadThread field and unused MessageDigest import (Android app-update) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…update Port GPG verification from app-monorepo desktop implementation to native modules: - iOS bundle-update: Gopenpgp framework integration via dynamic ObjC calls with graceful fallback - Android bundle-update: BouncyCastle bcpg for PGP cleartext signature verification - Android app-update: Full verifyASC implementation with SHA256 hash comparison - Embed OneKey developer GPG public key for signature validation - Add real test signatures from app-monorepo for testVerification() Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- native-logger: replace thread-unsafe SimpleDateFormat with DateTimeFormatter (Android), add NSLock around DateFormatter calls (iOS) - native-logger: add android.util.Log fallback when file logger is unavailable (Android) - bundle-update: add DispatchQueue for thread-safe access to listeners/isDownloading (iOS) - app-update: validate file paths against app directories to prevent path traversal (Android) - webview-checker: use WebView.getCurrentWebViewPackage() API 26+ with fallback candidates (Android) - device-utils: replace exit(0) with UIApplication suspend to avoid App Store rejection (iOS) - bundle-update: add symlink detection after zip extraction (Android) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- Fix Base64 encoding inconsistency between iOS/Android in get-random-values - Fix UTF-8 truncation at buffer boundaries in bundle-update readFileContent - Fix dead downloadTask property in iOS bundle-update, use session invalidation - Fix non-atomic write in bundle-update writeFallbackUpdateBundleDataFile - Fix clearCache not actually clearing cached files in app-update - Downgrade CloudKit recordID logging from info to debug level - Add ProGuard consumer rules for logback-android in native-logger - Flush log buffers before getLogFilePaths on both platforms Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Integrate Gopenpgp v3.3.0 xcframework directly into app-modules so app-monorepo no longer needs to separately import the GPG framework. Replace dynamic ObjC runtime calls (NSClassFromString/NSSelectorFromString) with direct typed Gopenpgp API imports for type safety and clarity. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…ata from logs Replace all android.util.Log and NSLog calls in react-native-lite-card with OneKeyLog (NativeLogger) for unified file-based logging. Remove plaintext PIN logging, cardInfo dumps, certificate serial numbers, and APDU response data from log output. Add native-logger as dependency on both Android (build.gradle) and iOS (podspec). Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
- Change Promise<Void> to Promise<Unit> in AppUpdate and BundleUpdate to match updated Nitro codegen specs - Fix smart cast issue with signatures in verifyAPK by extracting to local vals - Add missing deepLink parameter to LaunchOptions in DeviceUtils - Replace NitroModules.applicationContext with BuildConfig.DEBUG in lite-card LogUtil (module doesn't depend on nitro-modules) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Library module's BuildConfig.DEBUG won't reflect the host app's build type. Use Utils.getApp().applicationInfo.flags to check FLAG_DEBUGGABLE at runtime, which correctly detects the host app's debug state. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…teTestPage Dark theme, card layout, step-by-step pipeline (Download → Verify → Install) with animated progress bar, collapsible utilities section, and platform info. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…g, and APK cache verification - Fix relative path resolution: resolve to cacheDir/apks/ instead of root / - Add detailed error logging in buildFile and downloadAPK catch block - Verify existing APK via ASC SHA256 before re-downloading - Extract shared computeSha256 helper to reduce duplication - Update clearCache to clean cacheDir/apks/ directory (APK + ASC files) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
filePath is now inferred internally from the download URL's last path segment instead of being passed as a parameter. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…native layer - Fix event type mismatch: JS now listens for 'downloading' instead of 'update/downloading' - Native downloadAPK throws error instead of silently returning when already downloading Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…og results In verifyAPK and installAPK, debug builds (FLAG_DEBUGGABLE) now run all comparisons and log match/mismatch results but skip throwing exceptions, allowing testing with different-signed APKs. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Pipeline now has 5 steps: Download APK → Download ASC → Verify ASC → Verify APK → Install APK. Removed redundant ASC buttons from utilities. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Align with BundleUpdate convention: update/start, update/downloading, update/downloaded, update/error. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…rification - Add bcprov-jdk15to18 dependency (was missing, only bcpg was included) - Register BouncyCastleProvider at class init to fix "cannot create signature: no provider" - Add try/catch logging in verifyASC to capture exceptions before they propagate - Applied to both app-update and bundle-update modules Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…id Android built-in BC conflict Android ships a stripped-down "BC" provider that doesn't support SHA256withRSA. Passing our own BouncyCastleProvider() instance directly bypasses the name lookup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Declare FileProvider in library manifest (auto-merged into host app) - Add file_paths.xml exposing cacheDir/apks/ for FileProvider access - Add REQUEST_INSTALL_PACKAGES permission Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bcProvider was in ReactNativeBundleUpdate companion but used in BundleUpdateStoreAndroid.verifyGPGAndExtractSha256, causing unresolved reference error. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
…downloadBundle - Log progress percentage at each 1% increment during download - Add catch block to log exceptions before propagating - Deduplicate sendEvent calls by only emitting on progress change Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
- Log progress percentage at each 1% increment during URLSession download - Deduplicate progress callbacks by tracking previous progress value - Reset progress state on delegate reset Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Ensure parent directory exists before FileOutputStream - Log totalBytesRead, fileExists, and fileSize after download completes - Helps diagnose ENOENT issue after download Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d iOS Each validation step that can silently return null/empty now logs the specific failure reason, making it easy to diagnose why getJsBundlePath returns empty after bundle install. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…o file Store signatures as files at <bundleDir>/asc/<version>-signature.asc instead of SharedPreferences (Android) / UserDefaults (iOS) to avoid storage size issues with multiple versions. Also adds listAscFiles API and fixes installBundle passing empty signature in example. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…platforms Log file existence, size, and path on write; log existence and content size on read to help diagnose signature storage issues. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrate all legacy React Native Bridge native modules to Nitro Modules for New Architecture compatibility.
New Modules
Extended Modules
getLaunchOptions(),exitApp(), and startup time tracking (merged from LaunchOptionsManager + ExitModule)Key Changes
android.util.Log/NSLogaddXxxListener→ listener ID) replacingNativeEventEmitterBundleUpdateStore(iOS) /BundleUpdateStoreAndroid(Android) provide static access forgetJSBundleFile()before JS engine startsTest Plan