New Settings and Biometric Auth#137
Conversation
* Update project inspection profiles and build configuration * **IDE**: Extensively expanded `Project_Default.xml` with numerous Android Lint inspection tools, specifically covering Accessibility, Jetpack Compose, Fragments, and various Google Play policies. * **Build**: Updated `app/build.gradle.kts` to exclude dependency information from APKs while retaining it in App Bundles. * chore(deps): bump com.google.devtools.ksp in the maven group (#128) Bumps the maven group with 1 update: [com.google.devtools.ksp](https://github.com/google/ksp). Updates `com.google.devtools.ksp` from 2.3.5 to 2.3.6 - [Release notes](https://github.com/google/ksp/releases) - [Commits](google/ksp@2.3.5...2.3.6) --- updated-dependencies: - dependency-name: com.google.devtools.ksp dependency-version: 2.3.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: maven ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the maven group with 2 updates (#129) Bumps the maven group with 2 updates: com.android.application and com.android.test. Updates `com.android.application` from 9.1.0-alpha09 to 9.2.0-alpha01 Updates `com.android.test` from 9.1.0-alpha09 to 9.2.0-alpha01 Updates `com.android.test` from 9.1.0-alpha09 to 9.2.0-alpha01 --- updated-dependencies: - dependency-name: com.android.application dependency-version: 9.2.0-alpha01 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: maven - dependency-name: com.android.test dependency-version: 9.2.0-alpha01 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: maven - dependency-name: com.android.test dependency-version: 9.2.0-alpha01 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: maven ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Revise APK size details and add support options Updated download sizes and added support development section. * Add Ko-fi funding option to FUNDING.yml add ko-fi and patreon * Clean up project dependencies by removing benchmarking and profiling libraries * **Build**: Remove unused versions and library definitions for `annotationJvm`, `uiautomator`, `benchmarkMacroJunit4`, `baselineprofile`, and `profileinstaller` from `gradle/libs.versions.toml`. * Clean up project-level build configuration and plugin definitions * **Build**: Remove unused `kotlin-android` and `baselineprofile` plugin definitions from `gradle/libs.versions.toml`. * **Build**: Remove the commented-out `kotlin.android` plugin alias from the top-level `build.gradle.kts`. * Enhance Shizuku/Dhizuku installer stability and fallbacks * **Build**: Bump `versionCode` to 1715 and `versionName` to 1.71.5 in `gradle.properties`. * **Installer**: * Implement a silent fallback mechanism in `InstallerRepositoryImpl` that reverts to the system's default `PackageInstaller` if Shizuku or Dhizuku privileged installations fail. * Refactor `getDhizukuPackageInstaller` and `getShizukuPackageInstaller` to use `ShizukuPackageInstallerUtils` for better compatibility across API levels and ROMs, avoiding `NoSuchMethodError` on certain devices. * Ensure created installation sessions belong to the app's own package name to prevent UID mismatch errors. * Add `emitErrors` flag to `performPackageInstallerInstall` to allow internal retries without triggering error UI states prematurely. * **ShizukuReflector**: Add `createPackageInstallerFor(installerPackageName)` to allow creating privileged installers for specific package identities. * **IDE**: Clean up `Project_Default.xml` by removing numerous explicit Android Lint inspection rules. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Trinadh Thatakula <YOUR_EMAIL_HERE> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump io.coil-kt.coil3:coil-compose in the maven group (#132) Bumps the maven group with 1 update: [io.coil-kt.coil3:coil-compose](https://github.com/coil-kt/coil). Updates `io.coil-kt.coil3:coil-compose` from 3.3.0 to 3.4.0 - [Release notes](https://github.com/coil-kt/coil/releases) - [Changelog](https://github.com/coil-kt/coil/blob/main/CHANGELOG.md) - [Commits](coil-kt/coil@3.3.0...3.4.0) --- updated-dependencies: - dependency-name: io.coil-kt.coil3:coil-compose dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: maven ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the maven group across 1 directory with 3 updates (#134) Bumps the maven group with 3 updates in the / directory: androidx.compose.material3:material3, com.android.application and com.android.test. Updates `androidx.compose.material3:material3` from 1.5.0-alpha14 to 1.5.0-alpha15 Updates `com.android.application` from 9.2.0-alpha01 to 9.2.0-alpha02 Updates `com.android.test` from 9.2.0-alpha01 to 9.2.0-alpha02 Updates `com.android.test` from 9.2.0-alpha01 to 9.2.0-alpha02 --- updated-dependencies: - dependency-name: androidx.compose.material3:material3 dependency-version: 1.5.0-alpha15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: maven - dependency-name: com.android.application dependency-version: 9.2.0-alpha02 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: maven - dependency-name: com.android.test dependency-version: 9.2.0-alpha02 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: maven - dependency-name: com.android.test dependency-version: 9.2.0-alpha02 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: maven ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update Gradle wrapper to 9.4.0-rc-1 * Update `distributionUrl` to Gradle 9.4.0-rc-1 in `gradle-wrapper.properties`. * Add `distributionSha256Sum` for the new Gradle distribution. * Add AndroidX Biometric dependency * **Build**: Add `androidx.biometric:biometric-ktx` version `1.2.0-alpha05` to `gradle/libs.versions.toml`. * **App**: Include `libs.androidx.biometric` as an implementation dependency in `app/build.gradle.kts`. * Implement biometric authentication and expanded user preferences * **Core**: Add `BiometricHelper` utility to check for biometric hardware and authentication capabilities using `androidx.biometric`. * **Preferences**: * Expand `UserPreferences` and `PreferenceRepository` to support `ThemeMode`, `useDynamicColor`, and `biometricLockEnabled`. * Refactor `PreferenceRepositoryImpl` to use `runCatching` for safer enum parsing and organize keys into logical groups (App List, Theme, Security). * **Security UI**: * Implement `BiometricScreen` to handle the transition between the system biometric prompt and a custom `BiometricErrorScreen`. * Add `AuthState` sealed interface to manage the application's authentication lifecycle (NotRequired, Locked, Unlocked, Error). * Use `FragmentActivity` for hosting `BiometricPrompt` and provide a Material Expressive error UI with retry/exit actions. * Add SettingsViewModel and initial SettingsScreen with ThemeMode domain model * **Domain**: Add `ThemeMode` enum to represent Light, Dark, and System theme preferences with associated labels. * **Presentation**: * Implement `SettingsViewModel` to manage user preferences (theme mode, dynamic color, and biometric lock) and interface with `BiometricHelper` for hardware capability checks. * Create a placeholder `SettingsScreen` composable integrated with Koin for view model injection. * Add Settings screen and biometric authentication support * **Navigation**: Enable the `SETTINGS` destination in `AppDestinations.kt` and integrate `SettingsScreen` into the `MainScreen` navigation logic. * **Security**: * Implement `SecurityViewModel` to manage session-based authentication states (`Locked`, `Unlocked`, `Error`, `NotRequired`). * Add `BiometricHelper` to the dependency injection `coreModule`. * Update `HomeActivity` to conditionally display a `BiometricScreen` based on the current authentication state before granting access to the `MainScreen`. * **Preferences**: Expand `UserPreferences` to include settings for `themeMode`, `useDynamicColor`, and `biometricLockEnabled`. * **Dependency Injection**: Register `SettingsViewModel`, `SecurityViewModel`, and `BiometricHelper` in `Modules.kt`. * **Code Cleanup**: Remove redundant comments regarding Shizuku permission handling in `HomeActivity`. * Add UI components and building blocks for Settings screen * **UI Components**: Implement reusable Composable functions for the settings interface: * `SettingsHeader`: Displays a header with an icon and "Settings" title. * `SettingsSectionLabel` and `SettingsDivider`: Provides visual separation for setting groups. * `SettingsRow`: A base layout for setting items with an icon, title, and subtitle. * `SettingsSwitchRow`: A specialized row containing a toggle switch. * `SettingsInfoRow`: A row for displaying static key-value information. * `SettingsLinkRow`: A row with an action button for external links. * `EnrollBiometricRow`: A specific action row for directing users to system biometric settings. * Introduce `ConnectedButtonGroup` component and refactor UI selection controls * **Components**: Create `ConnectedButtonGroup`, a reusable selection component built on Material 3 Expressive APIs (`ButtonGroup` and `ToggleButton`) that supports animated width transitions and custom item types (Icon, Label, or both). * **UI Refactoring**: Replace `SingleChoiceSegmentedButtonRow` and `SegmentedButton` with the new `ConnectedButtonGroup` across multiple screens for a more consistent and animated experience: * `SettingsScreen`: Updated theme mode selection. * `AppListScreen` & `FreezerScreen`: Updated app type switcher (User/System). * `DashboardHeader`: Updated app type switcher. * `AppFilterSheet`: Updated tab selection (Filters/Sort). * **Security**: Wrap `BiometricScreen` content in a `Scaffold` and `Box` to ensure proper layout and padding. * **Navigation**: Fix a duplicate `SettingsScreen` entry in `MainScreen`'s destination logic. * **Activity**: Update `HomeActivity` to inherit from `FragmentActivity` instead of `ComponentActivity` to support fragment-based APIs (likely for biometric integration). * Update theme handling in HomeActivity and adjust versioning in gradle.properties * Update theme settings icon in SettingsScreen * **UI**: Update the `SettingsRow` for the "Theme" option in `SettingsScreen.kt` to use the new `theme_panel` icon instead of the shield icon. * **Resources**: Add `app/src/main/res/drawable/theme_panel.xml`, a new vector drawable representing a color palette/theme panel. * Add AMOLED mode support for pure black background in dark theme * **UI**: Add "AMOLED Mode" switch to `SettingsScreen` with a description for pure black backgrounds. * **Theme**: Update `ThorTheme` to override background and surface colors to pure black when `amoledMode` and `darkTheme` are enabled. * **Domain**: Add `useAmoled` property to `UserPreferences` and define `setUseAmoled` in `PreferenceRepository`. * **Data**: Implement `USE_AMOLED` DataStore key and persistence logic in `PreferenceRepositoryImpl`. * **Integration**: Update `SettingsViewModel` to handle AMOLED toggle and `HomeActivity` to pass the preference to the theme engine. * Update app/src/main/java/com/valhalla/thor/HomeActivity.kt Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update app/src/main/java/com/valhalla/thor/presentation/main/MainScreen.kt Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix review feedback: compilation errors, auth flicker, dead file, Gradle RC (#136) * Initial plan * Address all open review comments from Settings page PR Co-authored-by: trinadhthatakula <33689525+trinadhthatakula@users.noreply.github.com> * Revert Gradle wrapper back to 9.4.0-rc-1 (9.4 stable not yet released) Co-authored-by: trinadhthatakula <33689525+trinadhthatakula@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: trinadhthatakula <33689525+trinadhthatakula@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove distribution SHA-256 sum from Gradle wrapper * Remove the `distributionSha256Sum` property from `gradle/wrapper/gradle-wrapper.properties`. * Update app/src/main/java/com/valhalla/thor/presentation/security/BiometricPromptHandler.kt Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update app/src/main/java/com/valhalla/thor/presentation/common/components/ConnectedButtonGroup.kt Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Trinadh Thatakula <YOUR_EMAIL_HERE> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
* **UI**: Remove unused `Spacer`, `width`, and `animateWidth` imports from `ConnectedButtonGroup.kt`. * **UI**: Remove duplicate `@OptIn` and `@Composable` annotations from the `connectedShapesFor` function in `ConnectedButtonGroup.kt`. * **Security**: Remove a duplicate `BiometricPromptHandler` object declaration and its associated KDoc in `BiometricPromptHandler.kt`.
Removed Fingerprint Lock from upcoming features and added it to working features.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the user experience by introducing new personalization and security features. Users can now customize the app's appearance with detailed theming options and protect access using biometric authentication. Additionally, the underlying package installation logic has been made more resilient, and several UI components have been modernized for improved consistency and maintainability across the application. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces significant new features, including a comprehensive settings screen, theme customization with an AMOLED mode, and biometric authentication. The implementation is well-structured, introducing new ViewModels, state management for security, and reusable UI components like ConnectedButtonGroup. The installer logic has also been made more robust with a fallback mechanism. The code quality is generally high, but there are a few areas for improvement regarding code cleanup and best practices detailed in the comments.
app/src/main/java/com/valhalla/thor/data/repository/InstallerRepositoryImpl.kt
Outdated
Show resolved
Hide resolved
| fun createPackageInstallerFor(installerPackageName: String): PackageInstaller { | ||
| val iPackageInstaller = ShizukuPackageInstallerUtils.getPrivilegedPackageInstaller() | ||
| val root = try { rikka.shizuku.Shizuku.getUid() == 0 } catch (_: Exception) { false } | ||
| val userId = if (root) android.os.Process.myUserHandle().hashCode() else 0 | ||
|
|
||
| return ShizukuPackageInstallerUtils.createPackageInstaller( | ||
| iPackageInstaller, | ||
| installerPackageName, | ||
| userId | ||
| ) | ||
| } |
There was a problem hiding this comment.
The new function createPackageInstallerFor appears to be unused in the project. Furthermore, its logic is almost identical to the getShizukuPackageInstaller function in InstallerRepositoryImpl. This introduces code duplication and dead code. To improve maintainability, this unused function should be removed.
| SettingsHeader() | ||
|
|
||
| // ── APPEARANCE ────────────────────────────────────────────────────── | ||
| SettingsSectionLabel("Appearance") |
There was a problem hiding this comment.
The string "Appearance" is hardcoded. For better maintainability and to support localization in the future, it's recommended to extract UI strings into strings.xml resource files and reference them using stringResource(R.string.your_string_id). This applies to other hardcoded strings in this file as well.
| SettingsSectionLabel("Appearance") | |
| SettingsSectionLabel(stringResource(R.string.settings_appearance)) |
…epositoryImpl.kt Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new in-app Settings experience (theme + security) and introduces biometric authentication gating at app launch, along with UI component refactors and build/dependency updates.
Changes:
- Add Settings screen + persistence for theme mode, dynamic color, AMOLED mode, and biometric-lock preference (DataStore).
- Add biometric lock gate (auth state VM + biometric prompt/error UI) and wire it into
HomeActivity. - Introduce
ConnectedButtonGroupand replaceSegmentedButtonusage across multiple screens; update Gradle/versions and installer fallback logic.
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
gradle/wrapper/gradle-wrapper.properties |
Updates Gradle wrapper distribution URL. |
gradle/libs.versions.toml |
Updates version catalog (AGP/KSP/material3/coil) and adds Biometric dependency entry; removes some catalog entries. |
gradle.properties |
Disables ksp.use.k2 and bumps app version code/name. |
build.gradle.kts |
Adjusts top-level plugin aliases (comment removal). |
app/src/main/res/drawable/theme_panel.xml |
Adds a new theme-related vector drawable for Settings UI. |
app/src/main/java/com/valhalla/thor/presentation/widgets/AppList.kt |
Replaces segmented tabs in filter sheet with ConnectedButtonGroup. |
app/src/main/java/com/valhalla/thor/presentation/theme/Theme.kt |
Adds AMOLED theme override support in ThorTheme. |
app/src/main/java/com/valhalla/thor/presentation/settings/SettingsViewModel.kt |
New VM to expose preferences + update theme/security settings. |
app/src/main/java/com/valhalla/thor/presentation/settings/SettingsScreen.kt |
New Settings UI with theme controls, dynamic color, AMOLED, biometric lock, and about links. |
app/src/main/java/com/valhalla/thor/presentation/security/SecurityViewModel.kt |
New VM that derives AuthState from preferences/session/error. |
app/src/main/java/com/valhalla/thor/presentation/security/BiometricScreen.kt |
New biometric prompt + error UI and prompt orchestration. |
app/src/main/java/com/valhalla/thor/presentation/security/BiometricPromptHandler.kt |
Adds placeholder handler object for biometric interactions. |
app/src/main/java/com/valhalla/thor/presentation/security/AuthState.kt |
Defines auth gate state model for biometric lock flow. |
app/src/main/java/com/valhalla/thor/presentation/main/MainScreen.kt |
Adds Settings destination rendering. |
app/src/main/java/com/valhalla/thor/presentation/home/components/DashboardHeader.kt |
Replaces segmented app-type switcher with ConnectedButtonGroup. |
app/src/main/java/com/valhalla/thor/presentation/home/AppDestinations.kt |
Enables Settings destination in bottom navigation. |
app/src/main/java/com/valhalla/thor/presentation/freezer/FreezerScreen.kt |
Replaces segmented app-type switcher with ConnectedButtonGroup. |
app/src/main/java/com/valhalla/thor/presentation/common/components/ConnectedButtonGroup.kt |
Adds reusable connected toggle button group component. |
app/src/main/java/com/valhalla/thor/presentation/appList/AppListScreen.kt |
Replaces segmented app-type switcher with ConnectedButtonGroup. |
app/src/main/java/com/valhalla/thor/domain/repository/PreferenceRepository.kt |
Extends preferences API for theme + security settings. |
app/src/main/java/com/valhalla/thor/domain/model/UserPreferences.kt |
Adds theme/security fields to preferences domain model. |
app/src/main/java/com/valhalla/thor/domain/model/ThemeMode.kt |
Adds ThemeMode enum for theme selection. |
app/src/main/java/com/valhalla/thor/di/Modules.kt |
Wires new VMs and BiometricHelper into Koin modules. |
app/src/main/java/com/valhalla/thor/data/source/local/shizuku/ShizukuReflector.kt |
Adds privileged PackageInstaller creation helper; tweaks uninstall flow block. |
app/src/main/java/com/valhalla/thor/data/security/BiometricHelper.kt |
Adds biometric capability helper wrapper around BiometricManager. |
app/src/main/java/com/valhalla/thor/data/repository/PreferenceRepositoryImpl.kt |
Persists new theme/security preferences in DataStore and maps them to domain. |
app/src/main/java/com/valhalla/thor/data/repository/InstallerRepositoryImpl.kt |
Adds privileged-installer fallbacks and refactors Shizuku/Dhizuku install handling. |
app/src/main/java/com/valhalla/thor/HomeActivity.kt |
Applies theme preferences + gates app entry with biometric auth state. |
app/build.gradle.kts |
Adds Biometric dependency and configures dependenciesInfo. |
README.md |
Documents new features (fingerprint lock, themes) and adds support/donation section. |
.github/FUNDING.yml |
Updates funding links (Ko-fi + PayPal custom). |
Comments suppressed due to low confidence (1)
app/src/main/java/com/valhalla/thor/data/repository/InstallerRepositoryImpl.kt:37
shizukuReflectoris now injected but never used (only suppressed). This adds unnecessary DI wiring and can confuse future maintenance. Remove the constructor parameter and update the Koin module wiring accordingly, or start using it (e.g., viacreatePackageInstallerFor()if that’s the intent).
class InstallerRepositoryImpl(
private val context: Context,
private val eventBus: InstallerEventBus,
private val rootGateway: RootSystemGateway,
private val shizukuReflector: ShizukuReflector
) : InstallerRepository {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| distributionBase=GRADLE_USER_HOME | ||
| distributionPath=wrapper/dists | ||
| distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip | ||
| distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-rc-1-bin.zip |
There was a problem hiding this comment.
The wrapper is being bumped to a Gradle release-candidate (9.4.0-rc-1). RC tooling can be unstable and may break CI/reproducible builds unexpectedly. Prefer pinning the wrapper to the latest stable Gradle distribution unless there is a concrete requirement for the RC.
| checked = index == selectedIndex, | ||
| onCheckedChange = { checked -> if (checked) onItemSelected(index) }, | ||
| modifier = Modifier.animateWidth(interactionSource), | ||
| shapes = connectedShapesFor(index, lastIndex), | ||
| interactionSource = interactionSource, |
There was a problem hiding this comment.
Modifier.animateWidth(interactionSource) is used but there is no import or local definition for animateWidth, so this will be an unresolved reference at compile time. Add the correct import for the Material3 expressive animateWidth modifier (or replace this call with the intended animation modifier).
| // Create a PackageInstaller using Dhizuku's binder wrapper but make the installer package | ||
| // be this app's package name so created sessions belong to the app UID (avoids UID mismatch). | ||
| private fun getDhizukuPackageInstaller(): PackageInstaller { | ||
| val binder = SystemServiceHelper.getSystemService("package") | ||
| val wrappedBinder = DhizukuAPI.binderWrapper(binder) | ||
| val ipm = IPackageManager.Stub.asInterface(ShizukuBinderWrapper(wrappedBinder)) | ||
| val ipi = ipm.packageInstaller | ||
| val privilegedIpi = android.content.pm.IPackageInstaller.Stub.asInterface(ShizukuBinderWrapper(ipi.asBinder())) | ||
|
|
||
| // Prefer using the existing Shizuku helper which returns a privileged IPackageInstaller. | ||
| // This avoids calling IPackageManager.getPackageInstaller() directly (which may not exist | ||
| // on some ROMs / API versions and caused NoSuchMethodError). | ||
| try { | ||
| val iPackageInstaller = ShizukuPackageInstallerUtils.getPrivilegedPackageInstaller() | ||
| val root = try { rikka.shizuku.Shizuku.getUid() == 0 } catch (_: Exception) { false } | ||
| val userId = if (root) android.os.Process.myUserHandle().hashCode() else 0 | ||
| val installerPackageName = context.packageName | ||
|
|
||
| return ShizukuPackageInstallerUtils.createPackageInstaller( | ||
| iPackageInstaller, | ||
| installerPackageName, | ||
| userId | ||
| ) |
There was a problem hiding this comment.
getDhizukuPackageInstaller() is currently using ShizukuPackageInstallerUtils, which wraps the PackageManager binder using ShizukuBinderWrapper. That won’t work in Dhizuku mode and effectively disables/breaks the Dhizuku install path (it will always throw and fall back to the normal installer). Rework this to obtain an IPackageInstaller via Dhizuku’s binder wrapper/API (similar to the previous approach / DhizukuHelper) so InstallMode.DHIZUKU actually uses Dhizuku.
| // No credentials enrolled — fail open so user is never locked out. | ||
| onAuthenticated() |
There was a problem hiding this comment.
For BIOMETRIC_ERROR_NONE_ENROLLED, the code calls onAuthenticated() (fail-open). If the user enabled “Biometric Lock” and later removes biometrics/device credential, this bypasses the lock entirely, undermining the feature. Instead, treat this as a locked/error state (e.g., show an error with a link to enroll credentials, or disable the preference and require explicit user action).
| // No credentials enrolled — fail open so user is never locked out. | |
| onAuthenticated() | |
| // No biometrics or device credentials enrolled — keep locked and require user action. | |
| onError("No biometric or device credential is enrolled. Please enroll one in system settings to use biometric lock.") |
| // Check if package still has updates; value intentionally ignored here | ||
| (updatedPackageInfo.applicationInfo!!.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0 |
There was a problem hiding this comment.
This block computes whether the app is still an updated system app but discards the result, so it has no effect and is misleading. Either remove this check entirely or use the result (e.g., log it or return it / branch on it) to justify why it exists.
| // Check if package still has updates; value intentionally ignored here | |
| (updatedPackageInfo.applicationInfo!!.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0 | |
| // Check if package still has updates and log the result | |
| val stillUpdatedSystemApp = | |
| (updatedPackageInfo.applicationInfo!!.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0 | |
| Logger.d( | |
| "ShizukuReflector", | |
| "Package $packageName still updated system app after uninstall: $stillUpdatedSystemApp" | |
| ) |
Uh oh!
There was an error while loading. Please reload this page.