Feature/session scope injection migration#6190
Open
SeniorZhai wants to merge 18 commits intomasterfrom
Open
Conversation
…ons after MixinDatabase validation
…pe-injection-migration
3e1e78b to
2b0d984
Compare
2b0d984 to
f38b27f
Compare
…pe-injection-migration # Conflicts: # app/src/main/java/one/mixin/android/ui/landing/MnemonicPhraseFragment.kt
8a33f79 to
4748203
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR migrates app storage and DI to a session/user-scoped database model (keyed by identityNumber) and updates a wide set of call sites to use the new scoped access patterns. It also refactors parts of the landing/login flow into a new LandingViewModel/LandingAccountRepository split, and adds logout UI wiring.
Changes:
- Introduce
CurrentUserScopeManagerto manage per-account scoped DB instances (Mixin/Wallet/Pending/FTS) and update services/jobs/repositories to use it. - Migrate database file layout to per-identity directories and add legacy-to-scoped file migration utilities; update backup/restore paths accordingly.
- Refactor landing/login flow (new
LandingViewModel, slimmerMobileViewModel) and add an Account “Log out” row + logic.
Reviewed changes
Copilot reviewed 58 out of 58 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| app/src/main/res/layout/fragment_account.xml | Adds “Log out” row to account settings UI. |
| app/src/main/java/one/mixin/android/websocket/ChatWebSocket.kt | Switches DB access to CurrentUserScopeManager. |
| app/src/main/java/one/mixin/android/webrtc/CallService.kt | Uses scoped DB via CurrentUserScopeManager. |
| app/src/main/java/one/mixin/android/util/database/DatabaseUtil.kt | Reworks DB file paths + legacy migration helpers; changes clearing logic to identity-scoped. |
| app/src/main/java/one/mixin/android/util/backup/Backup.kt | Backup/restore now resolves legacy vs scoped DB files. |
| app/src/main/java/one/mixin/android/util/AudioPlayer.kt | Uses identity-scoped MixinDatabase.getDatabase(...). |
| app/src/main/java/one/mixin/android/ui/wallet/fiatmoney/RouteAPI.kt | Writes participant session into identity-scoped DB. |
| app/src/main/java/one/mixin/android/ui/transfer/TransferActivity.kt | Uses identity-scoped DB for participant lookup. |
| app/src/main/java/one/mixin/android/ui/setting/ui/page/MnemonicPhraseBackupVerifyPage.kt | Injects WalletViewModel into compose page; passes TIP helpers through. |
| app/src/main/java/one/mixin/android/ui/setting/VerificationEmergencyFragment.kt | Ensures current user scope is entered after account store. |
| app/src/main/java/one/mixin/android/ui/setting/DatabaseDebugFragment.kt | Ensures scope from session before opening wallet DB. |
| app/src/main/java/one/mixin/android/ui/setting/AccountFragment.kt | Adds logout click handling and mnemonic-backup warning gating. |
| app/src/main/java/one/mixin/android/ui/search/holder/TipHolder.kt | Tweaks placeholder formatting/spacing. |
| app/src/main/java/one/mixin/android/ui/player/MusicService.kt | Uses scoped DB via CurrentUserScopeManager. |
| app/src/main/java/one/mixin/android/ui/oldwallet/AssetRepository.kt | Removes @Singleton (scope behavior change). |
| app/src/main/java/one/mixin/android/ui/landing/components/SetPinLoadingPage.kt | Displays detailed TIP step status during PIN setup. |
| app/src/main/java/one/mixin/android/ui/landing/components/MnemonicPhrasePage.kt | Migrates to LandingViewModel. |
| app/src/main/java/one/mixin/android/ui/landing/components/MnemonicPhraseInput.kt | Decouples TIP export from WalletViewModel by passing suspend lambdas. |
| app/src/main/java/one/mixin/android/ui/landing/VerificationFragment.kt | Switches to LandingViewModel; uses Provider<UserRepository> for session-aware usage. |
| app/src/main/java/one/mixin/android/ui/landing/UpgradeFragment.kt | Removes unused MobileViewModel binding. |
| app/src/main/java/one/mixin/android/ui/landing/SetupPinViewModel.kt | Adds tipStep LiveData and posts step changes. |
| app/src/main/java/one/mixin/android/ui/landing/RestoreFragment.kt | Resolves legacy vs scoped DB file for local data info. |
| app/src/main/java/one/mixin/android/ui/landing/MobileViewModel.kt | Slimmed; shifts responsibilities out to landing-specific view model/repositories. |
| app/src/main/java/one/mixin/android/ui/landing/MobileFragment.kt | Uses LandingViewModel for verification flow. |
| app/src/main/java/one/mixin/android/ui/landing/MnemonicPhraseFragment.kt | Uses LandingViewModel and new session initializer for session setup. |
| app/src/main/java/one/mixin/android/ui/landing/LocalRestoreFragment.kt | Adds more defensive error handling around restore operations. |
| app/src/main/java/one/mixin/android/ui/landing/LandingViewModel.kt | New view model for landing/login flows. |
| app/src/main/java/one/mixin/android/ui/home/MainActivity.kt | Triggers migration on start; converts multiple injected deps to Providers; version check uses scoped DB file. |
| app/src/main/java/one/mixin/android/ui/common/PinCodeFragment.kt | Replaces inline session setup with initializeAccountSession(...). |
| app/src/main/java/one/mixin/android/session/CurrentUserScopeManager.kt | New session-scope manager for DB instances. |
| app/src/main/java/one/mixin/android/session/AccountSessionInitializer.kt | New helper to initialize session and scope. |
| app/src/main/java/one/mixin/android/repository/Web3Repository.kt | Removes @Singleton (scope behavior change). |
| app/src/main/java/one/mixin/android/repository/UserRepository.kt | Removes @Singleton (scope behavior change). |
| app/src/main/java/one/mixin/android/repository/TokenRepository.kt | Moves SafeBox persistence to SafeBoxStoreManager. |
| app/src/main/java/one/mixin/android/repository/SafeBoxStoreManager.kt | New per-account DataStore manager for SafeBox. |
| app/src/main/java/one/mixin/android/repository/MemberRepository.kt | Removes @Singleton (scope behavior change). |
| app/src/main/java/one/mixin/android/repository/LandingAccountRepository.kt | New repository wrapper for landing flows (no DB dependency). |
| app/src/main/java/one/mixin/android/repository/ConversationRepository.kt | Updates conversation observation to use identity-scoped DB; removes unused create() overload. |
| app/src/main/java/one/mixin/android/repository/AccountRepository.kt | Removes @Singleton (scope behavior change). |
| app/src/main/java/one/mixin/android/messenger/HedwigImp.kt | Uses CurrentUserScopeManager and guards DB observers across scope changes. |
| app/src/main/java/one/mixin/android/job/RefreshAccountJob.kt | Uses identity-scoped DB for account updates. |
| app/src/main/java/one/mixin/android/job/NotificationGenerator.kt | Ensures session injection before generating notifications. |
| app/src/main/java/one/mixin/android/job/Injector.kt | Adds session re-injection mechanism keyed by scope version. |
| app/src/main/java/one/mixin/android/job/DecryptMessage.kt | Calls ensureSessionInjection() before DB operations. |
| app/src/main/java/one/mixin/android/job/DecryptCallMessage.kt | Calls ensureSessionInjection() before DB operations. |
| app/src/main/java/one/mixin/android/job/ConvertVideoJob.kt | Removes static DB reference; uses injected/scoped DB. |
| app/src/main/java/one/mixin/android/job/BlazeMessageService.kt | Refactors to resolve DBs via CurrentUserScopeManager; fixes observer removal across scope swaps. |
| app/src/main/java/one/mixin/android/fts/FtsDatabase.kt | Makes FTS DB identity-scoped and closable/resettable. |
| app/src/main/java/one/mixin/android/extension/UrlExtension.kt | Uses identity-scoped DB for deep-link lookups; adds fallback behavior when not logged in. |
| app/src/main/java/one/mixin/android/di/BaseDbModule.kt | Provides DBs via CurrentUserScopeManager (session-scoped). |
| app/src/main/java/one/mixin/android/di/AppModule.kt | Updates ChatWebSocket provider; removes SafeBox DataStore provider. |
| app/src/main/java/one/mixin/android/db/property/Web3PropertyHelper.kt | Uses identity-scoped wallet DB. |
| app/src/main/java/one/mixin/android/db/property/PropertyHelper.kt | Uses identity-scoped mixin DB for property ops/migrations. |
| app/src/main/java/one/mixin/android/db/pending/PendingDatabaseImp.kt | Makes pending DB identity-scoped; adjusts lifecycle handling. |
| app/src/main/java/one/mixin/android/db/WalletDatabase.kt | Makes wallet DB identity-scoped; removes temp migration path. |
| app/src/main/java/one/mixin/android/db/MixinDatabase.kt | Makes mixin DB identity-scoped; adds legacy file migration and better destroy/close semantics. |
| app/src/main/java/one/mixin/android/db/DatabaseMonitor.kt | Avoids enabling DB monitor when session not ready. |
| app/src/main/java/one/mixin/android/MixinApplication.kt | Splits logout into clearer steps; exits scope on logout; scoped participant session clearing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+24
to
+28
| private val stores = ConcurrentHashMap<String, DataStore<SafeBox>>() | ||
|
|
||
| fun current(): DataStore<SafeBox> { | ||
| val accountId = Session.getAccountId() ?: "temp" | ||
| return stores.getOrPut(accountId) { |
Comment on lines
+188
to
+202
| val scopeVersion = currentUserScopeManager.getScopeVersion() | ||
| if (scopeVersion == injectedScopeVersion) { | ||
| return | ||
| } | ||
| synchronized(this) { | ||
| val latestScopeVersion = currentUserScopeManager.getScopeVersion() | ||
| if (latestScopeVersion == injectedScopeVersion) { | ||
| return | ||
| } | ||
| injectSelf() | ||
| } | ||
| } | ||
|
|
||
| init { | ||
| injectSelf() |
Comment on lines
+25
to
+29
| fun provideRatchetSenderKeyDao(db: SignalDatabase) = db.ratchetSenderKeyDao() | ||
|
|
||
| @Singleton | ||
| @Provides | ||
| fun provideDb(app: Application) = MixinDatabase.getDatabase(app) | ||
|
|
||
| @Singleton | ||
| fun provideDb(scopeManager: CurrentUserScopeManager) = scopeManager.getMixinDatabase() | ||
| @Provides | ||
| fun providePendingDatabase( | ||
| app: Application, | ||
| mixinDatabase: MixinDatabase, | ||
| ): PendingDatabase = PendingDatabaseImp.getDatabase(app.applicationContext, mixinDatabase.floodMessageDao(), mixinDatabase.jobDao()) | ||
|
|
||
| @Singleton | ||
| fun providePendingDatabase(scopeManager: CurrentUserScopeManager): PendingDatabase = scopeManager.getPendingDatabase() |
Comment on lines
+25
to
+27
| withContext(Dispatchers.IO) { | ||
| clearJobsAndRawTransaction(context, account.identityNumber) | ||
| } |
| synchronized(lock) { | ||
| if (INSTANCE != null && currentIdentityNumber != scopedIdentity) { | ||
| INSTANCE?.close() | ||
| INSTANCE = null |
Comment on lines
+26
to
30
| val scopedDbFile = databaseFile(context, identityNumber) | ||
| val legacyDbFile = legacyDatabaseFile(context) | ||
| if (!scopedDbFile.exists() && !legacyDbFile.exists()) { | ||
| return | ||
| } |
Comment on lines
33
to
35
| // Init database | ||
| MixinDatabase.getDatabase(context) | ||
| MixinDatabase.getDatabase(context, identityNumber) | ||
| db = MixinDatabase.getWritableDatabase() ?: return |
Comment on lines
+190
to
+192
| super.close() | ||
| INSTANCE = null | ||
| currentIdentityNumber = null |
Comment on lines
37
to
39
| import one.mixin.android.extension.openUrl | ||
| import one.mixin.android.extension.toast | ||
| import one.mixin.android.ui.landing.SetupPinViewModel |
Comment on lines
55
to
58
| val setupState by viewModel.setupState.observeAsState(SetupState.Loading) | ||
| val tipStep by viewModel.tipStep.observeAsState(TryConnecting) | ||
| val errorMessage by viewModel.errorMessage.observeAsState("") | ||
| val context = LocalContext.current |
…pe-injection-migration # Conflicts: # app/src/main/java/one/mixin/android/ui/landing/LocalRestoreFragment.kt
Member
|
@claude[agent] review |
Contributor
* Initial plan * Fix session-scoped injection and database migration issues Address critical issues identified in PR review: - Fix SafeBoxStoreManager memory leak by tracking and cleaning up coroutine scopes - Fix PendingDatabaseImp to properly clear supportSQLiteDatabase on scope changes - Fix AccountSessionInitializer to migrate databases BEFORE clearing jobs/raw transactions - Fix BaseDbModule to use Provider for session-scoped DB bindings to defer resolution - Fix Injector to defer session-scoped injection until session is available - Fix AccountSessionInitializer to preserve settings on same-user re-login - Fix DatabaseUtil to avoid creating empty scoped DB files prematurely - Remove unused import and errorMessage observation in SetPinLoadingPage Co-authored-by: crossle <1675131+crossle@users.noreply.github.com> --------- Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com> Co-authored-by: crossle <1675131+crossle@users.noreply.github.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.
No description provided.