├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── actions │ └── setup │ │ ├── action.yml │ │ └── sccache.sh ├── ci.prop └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.MD ├── app ├── .gitignore ├── apk │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── topjohnwu │ │ │ └── magisk │ │ │ ├── arch │ │ │ ├── AsyncLoadViewModel.kt │ │ │ ├── BaseFragment.kt │ │ │ ├── BaseViewModel.kt │ │ │ ├── NavigationActivity.kt │ │ │ ├── UIActivity.kt │ │ │ ├── ViewEvent.kt │ │ │ └── ViewModelHolder.kt │ │ │ ├── databinding │ │ │ ├── DataBindingAdapters.kt │ │ │ ├── DiffObservableList.kt │ │ │ ├── MergeObservableList.kt │ │ │ ├── ObservableHost.kt │ │ │ ├── RecyclerViewItems.kt │ │ │ └── RvItemAdapter.kt │ │ │ ├── dialog │ │ │ ├── DarkThemeDialog.kt │ │ │ ├── EnvFixDialog.kt │ │ │ ├── LocalModuleInstallDialog.kt │ │ │ ├── ManagerInstallDialog.kt │ │ │ ├── MarkDownDialog.kt │ │ │ ├── OnlineModuleInstallDialog.kt │ │ │ ├── SecondSlotWarningDialog.kt │ │ │ ├── SuperuserRevokeDialog.kt │ │ │ └── UninstallDialog.kt │ │ │ ├── events │ │ │ └── ViewEvents.kt │ │ │ ├── ui │ │ │ ├── MainActivity.kt │ │ │ ├── deny │ │ │ │ ├── AppProcessInfo.kt │ │ │ │ ├── DenyListFragment.kt │ │ │ │ ├── DenyListRvItem.kt │ │ │ │ └── DenyListViewModel.kt │ │ │ ├── flash │ │ │ │ ├── ConsoleItem.kt │ │ │ │ ├── FlashFragment.kt │ │ │ │ └── FlashViewModel.kt │ │ │ ├── home │ │ │ │ ├── DeveloperItem.kt │ │ │ │ ├── HomeFragment.kt │ │ │ │ ├── HomeViewModel.kt │ │ │ │ └── RebootMenu.kt │ │ │ ├── install │ │ │ │ ├── InstallFragment.kt │ │ │ │ └── InstallViewModel.kt │ │ │ ├── log │ │ │ │ ├── LogFragment.kt │ │ │ │ ├── LogRvItem.kt │ │ │ │ ├── LogViewModel.kt │ │ │ │ └── SuLogRvItem.kt │ │ │ ├── module │ │ │ │ ├── ActionFragment.kt │ │ │ │ ├── ActionViewModel.kt │ │ │ │ ├── ModuleFragment.kt │ │ │ │ ├── ModuleRvItem.kt │ │ │ │ └── ModuleViewModel.kt │ │ │ ├── settings │ │ │ │ ├── BaseSettingsItem.kt │ │ │ │ ├── SettingsFragment.kt │ │ │ │ ├── SettingsItems.kt │ │ │ │ └── SettingsViewModel.kt │ │ │ ├── superuser │ │ │ │ ├── PolicyRvItem.kt │ │ │ │ ├── SuperuserFragment.kt │ │ │ │ └── SuperuserViewModel.kt │ │ │ ├── surequest │ │ │ │ ├── SuRequestActivity.kt │ │ │ │ └── SuRequestViewModel.kt │ │ │ └── theme │ │ │ │ ├── Theme.kt │ │ │ │ ├── ThemeFragment.kt │ │ │ │ └── ThemeViewModel.kt │ │ │ ├── utils │ │ │ ├── AccessibilityUtils.kt │ │ │ ├── MotionRevealHelper.kt │ │ │ └── TextHolder.kt │ │ │ ├── view │ │ │ ├── MagiskDialog.kt │ │ │ ├── TappableHeadlineItem.kt │ │ │ └── TextItem.kt │ │ │ └── widget │ │ │ └── ConcealableBottomNavigationView.java │ │ └── res │ │ ├── anim │ │ ├── fragment_enter.xml │ │ ├── fragment_enter_pop.xml │ │ ├── fragment_exit.xml │ │ └── fragment_exit_pop.xml │ │ ├── color │ │ ├── color_card_background_color_selector.xml │ │ ├── color_error_transient.xml │ │ ├── color_menu_tint.xml │ │ ├── color_on_primary_transient.xml │ │ ├── color_primary_error_transient.xml │ │ ├── color_primary_transient.xml │ │ ├── color_state_primary_transient.xml │ │ └── color_text_transient.xml │ │ ├── drawable │ │ ├── avd_bug_from_filled.xml │ │ ├── avd_bug_to_filled.xml │ │ ├── avd_circle_check_from_filled.xml │ │ ├── avd_circle_check_to_filled.xml │ │ ├── avd_home_from_filled.xml │ │ ├── avd_home_to_filled.xml │ │ ├── avd_module_from_filled.xml │ │ ├── avd_module_to_filled.xml │ │ ├── avd_settings_from_filled.xml │ │ ├── avd_settings_to_filled.xml │ │ ├── avd_superuser_from_filled.xml │ │ ├── avd_superuser_to_filled.xml │ │ ├── bg_line_bottom_rounded.xml │ │ ├── bg_line_top_rounded.xml │ │ ├── bg_selection_circle_green.xml │ │ ├── ic_action_md2.xml │ │ ├── ic_back_md2.xml │ │ ├── ic_bug_filled_md2.xml │ │ ├── ic_bug_md2.xml │ │ ├── ic_bug_outlined_md2.xml │ │ ├── ic_check_circle_checked_md2.xml │ │ ├── ic_check_circle_md2.xml │ │ ├── ic_check_circle_unchecked_md2.xml │ │ ├── ic_check_md2.xml │ │ ├── ic_close_md2.xml │ │ ├── ic_day.xml │ │ ├── ic_day_night.xml │ │ ├── ic_delete_md2.xml │ │ ├── ic_download_md2.xml │ │ ├── ic_folder_list.xml │ │ ├── ic_forth_md2.xml │ │ ├── ic_home_filled_md2.xml │ │ ├── ic_home_md2.xml │ │ ├── ic_home_outlined_md2.xml │ │ ├── ic_install.xml │ │ ├── ic_manager.xml │ │ ├── ic_module_filled_md2.xml │ │ ├── ic_module_md2.xml │ │ ├── ic_module_outlined_md2.xml │ │ ├── ic_module_storage_md2.xml │ │ ├── ic_night.xml │ │ ├── ic_notifications_md2.xml │ │ ├── ic_paint.xml │ │ ├── ic_restart.xml │ │ ├── ic_save_md2.xml │ │ ├── ic_search_md2.xml │ │ ├── ic_settings_filled_md2.xml │ │ ├── ic_settings_md2.xml │ │ ├── ic_settings_outlined_md2.xml │ │ ├── ic_superuser_filled_md2.xml │ │ ├── ic_superuser_md2.xml │ │ ├── ic_superuser_outlined_md2.xml │ │ └── ic_update_md2.xml │ │ ├── layout │ │ ├── activity_main_md2.xml │ │ ├── activity_request.xml │ │ ├── dialog_magisk_base.xml │ │ ├── dialog_settings_app_name.xml │ │ ├── dialog_settings_download_path.xml │ │ ├── dialog_settings_update_channel.xml │ │ ├── fragment_action_md2.xml │ │ ├── fragment_deny_md2.xml │ │ ├── fragment_flash_md2.xml │ │ ├── fragment_home_md2.xml │ │ ├── fragment_install_md2.xml │ │ ├── fragment_log_md2.xml │ │ ├── fragment_module_md2.xml │ │ ├── fragment_settings_md2.xml │ │ ├── fragment_superuser_md2.xml │ │ ├── fragment_theme_md2.xml │ │ ├── include_home_magisk.xml │ │ ├── include_home_manager.xml │ │ ├── include_log_magisk.xml │ │ ├── include_log_superuser.xml │ │ ├── item_console_md2.xml │ │ ├── item_developer.xml │ │ ├── item_hide_md2.xml │ │ ├── item_hide_process_md2.xml │ │ ├── item_icon_link.xml │ │ ├── item_list_single_line.xml │ │ ├── item_log_access_md2.xml │ │ ├── item_log_textview.xml │ │ ├── item_log_track_md2.xml │ │ ├── item_module_download.xml │ │ ├── item_module_md2.xml │ │ ├── item_policy_md2.xml │ │ ├── item_settings.xml │ │ ├── item_settings_section.xml │ │ ├── item_spinner.xml │ │ ├── item_tappable_headline.xml │ │ ├── item_text.xml │ │ ├── item_theme.xml │ │ ├── item_theme_container.xml │ │ └── markdown_window_md2.xml │ │ ├── menu │ │ ├── menu_bottom_nav.xml │ │ ├── menu_deny_md2.xml │ │ ├── menu_flash.xml │ │ ├── menu_home_md2.xml │ │ ├── menu_log_md2.xml │ │ └── menu_reboot.xml │ │ ├── navigation │ │ └── main.xml │ │ ├── values-night │ │ ├── styles_md2.xml │ │ └── themes_md2.xml │ │ ├── values-v27 │ │ └── themes.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── styles_md2.xml │ │ ├── styles_md2_appearance.xml │ │ ├── styles_md2_impl.xml │ │ ├── styles_view_md2.xml │ │ ├── theme_overlay.xml │ │ ├── themes.xml │ │ ├── themes_md2.xml │ │ └── themes_override.xml ├── build.gradle.kts ├── buildSrc │ ├── .gitignore │ ├── build.gradle.kts │ ├── settings.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ ├── Codegen.kt │ │ ├── DesugarClassVisitorFactory.kt │ │ ├── Plugin.kt │ │ └── Setup.kt ├── core │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── aidl │ │ └── com │ │ │ └── topjohnwu │ │ │ └── magisk │ │ │ └── core │ │ │ └── utils │ │ │ └── IRootUtils.aidl │ │ ├── java │ │ └── com │ │ │ └── topjohnwu │ │ │ └── magisk │ │ │ ├── core │ │ │ ├── App.kt │ │ │ ├── AppContext.kt │ │ │ ├── Config.kt │ │ │ ├── Const.kt │ │ │ ├── Hacks.kt │ │ │ ├── Info.kt │ │ │ ├── JobService.kt │ │ │ ├── Provider.kt │ │ │ ├── Receiver.kt │ │ │ ├── Service.kt │ │ │ ├── base │ │ │ │ ├── BaseActivity.kt │ │ │ │ ├── BaseJobService.kt │ │ │ │ ├── BaseProvider.kt │ │ │ │ ├── BaseReceiver.kt │ │ │ │ ├── BaseService.kt │ │ │ │ └── SplashScreen.kt │ │ │ ├── data │ │ │ │ ├── NetworkServices.kt │ │ │ │ ├── SuLogDao.kt │ │ │ │ └── magiskdb │ │ │ │ │ ├── MagiskDB.kt │ │ │ │ │ ├── PolicyDao.kt │ │ │ │ │ ├── SettingsDao.kt │ │ │ │ │ └── StringDao.kt │ │ │ ├── di │ │ │ │ ├── Networking.kt │ │ │ │ └── ServiceLocator.kt │ │ │ ├── download │ │ │ │ ├── DownloadEngine.kt │ │ │ │ ├── DownloadProcessor.kt │ │ │ │ ├── Interfaces.kt │ │ │ │ └── Subject.kt │ │ │ ├── ktx │ │ │ │ ├── XAndroid.kt │ │ │ │ ├── XJVM.kt │ │ │ │ └── XSU.kt │ │ │ ├── model │ │ │ │ ├── UpdateInfo.kt │ │ │ │ ├── module │ │ │ │ │ ├── LocalModule.kt │ │ │ │ │ ├── Module.kt │ │ │ │ │ └── OnlineModule.kt │ │ │ │ └── su │ │ │ │ │ ├── SuLog.kt │ │ │ │ │ └── SuPolicy.kt │ │ │ ├── repository │ │ │ │ ├── DBConfig.kt │ │ │ │ ├── LogRepository.kt │ │ │ │ ├── NetworkService.kt │ │ │ │ └── PreferenceConfig.kt │ │ │ ├── signing │ │ │ │ ├── ApkSignerV2.java │ │ │ │ ├── ByteArrayStream.java │ │ │ │ ├── JarMap.java │ │ │ │ ├── SignApk.java │ │ │ │ └── ZipUtils.java │ │ │ ├── su │ │ │ │ ├── SuCallbackHandler.kt │ │ │ │ └── SuRequestHandler.kt │ │ │ ├── tasks │ │ │ │ ├── AppMigration.kt │ │ │ │ ├── FlashZip.kt │ │ │ │ └── MagiskInstaller.kt │ │ │ ├── utils │ │ │ │ ├── AXML.kt │ │ │ │ ├── Desugar.java │ │ │ │ ├── DummyList.kt │ │ │ │ ├── Keygen.kt │ │ │ │ ├── LocaleSetting.kt │ │ │ │ ├── MediaStoreUtils.kt │ │ │ │ ├── NetworkObserver.kt │ │ │ │ ├── ProgressInputStream.kt │ │ │ │ ├── RequestAuthentication.kt │ │ │ │ ├── RequestInstall.kt │ │ │ │ ├── RootUtils.kt │ │ │ │ └── ShellInit.kt │ │ │ └── view │ │ │ │ ├── Notifications.kt │ │ │ │ └── Shortcuts.kt │ │ │ └── test │ │ │ ├── AdditionalTest.kt │ │ │ ├── BaseTest.kt │ │ │ ├── Environment.kt │ │ │ └── MagiskAppTest.kt │ │ └── res │ │ ├── drawable-v26 │ │ ├── ic_launcher.xml │ │ ├── sc_extension.xml │ │ └── sc_superuser.xml │ │ ├── drawable │ │ ├── ic_extension.xml │ │ ├── ic_favorite.xml │ │ ├── ic_fingerprint.xml │ │ ├── ic_github.xml │ │ ├── ic_logo.xml │ │ ├── ic_magisk.xml │ │ ├── ic_magisk_outline.xml │ │ ├── ic_magisk_padded.xml │ │ ├── ic_more.xml │ │ ├── ic_patreon.xml │ │ ├── ic_paypal.xml │ │ ├── ic_superuser.xml │ │ ├── ic_twitter.xml │ │ ├── sc_extension.xml │ │ └── sc_superuser.xml │ │ ├── values-ar │ │ └── strings.xml │ │ ├── values-ast │ │ └── strings.xml │ │ ├── values-az │ │ └── strings.xml │ │ ├── values-be │ │ └── strings.xml │ │ ├── values-bg │ │ └── strings.xml │ │ ├── values-bn │ │ └── strings.xml │ │ ├── values-ca │ │ └── strings.xml │ │ ├── values-cs │ │ └── strings.xml │ │ ├── values-de │ │ └── strings.xml │ │ ├── values-el │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-et │ │ └── strings.xml │ │ ├── values-fa │ │ └── strings.xml │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-hi │ │ └── strings.xml │ │ ├── values-hr │ │ └── strings.xml │ │ ├── values-hu │ │ └── strings.xml │ │ ├── values-in │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-iw │ │ └── strings.xml │ │ ├── values-ja │ │ └── strings.xml │ │ ├── values-ka │ │ └── strings.xml │ │ ├── values-kk │ │ └── strings.xml │ │ ├── values-ko │ │ └── strings.xml │ │ ├── values-ku │ │ └── strings.xml │ │ ├── values-lt │ │ └── strings.xml │ │ ├── values-mk │ │ └── strings.xml │ │ ├── values-ml │ │ └── strings.xml │ │ ├── values-nb │ │ └── strings.xml │ │ ├── values-night │ │ └── colors.xml │ │ ├── values-nl │ │ └── strings.xml │ │ ├── values-pa │ │ └── strings.xml │ │ ├── values-pl │ │ └── strings.xml │ │ ├── values-pt-rBR │ │ └── strings.xml │ │ ├── values-pt-rPT │ │ └── strings.xml │ │ ├── values-ro │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-sk │ │ └── strings.xml │ │ ├── values-sq │ │ └── strings.xml │ │ ├── values-sr │ │ └── strings.xml │ │ ├── values-sv │ │ └── strings.xml │ │ ├── values-sw │ │ └── strings.xml │ │ ├── values-ta │ │ └── strings.xml │ │ ├── values-th │ │ └── strings.xml │ │ ├── values-tr │ │ └── strings.xml │ │ ├── values-uk │ │ └── strings.xml │ │ ├── values-v31 │ │ └── themes.xml │ │ ├── values-v34 │ │ └── resources.xml │ │ ├── values-vi │ │ └── strings.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ ├── values-zh-rTW │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── resources.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ └── locale_config.xml ├── gradle.properties ├── gradle │ ├── libs.versions.toml │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts ├── shared │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── topjohnwu │ │ └── magisk │ │ ├── ProviderInstaller.java │ │ ├── StubApk.java │ │ └── utils │ │ ├── APKInstall.java │ │ ├── CompoundEnumeration.java │ │ └── DynamicClassLoader.java ├── stub │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── topjohnwu │ │ │ └── magisk │ │ │ ├── ClassLoaders.java │ │ │ ├── DelegateComponentFactory.java │ │ │ ├── DownloadActivity.java │ │ │ ├── DynLoad.java │ │ │ ├── StubApplication.java │ │ │ ├── StubRootService.java │ │ │ ├── dummy │ │ │ ├── DummyProvider.java │ │ │ ├── DummyReceiver.java │ │ │ └── DummyService.java │ │ │ └── net │ │ │ ├── BadRequest.java │ │ │ ├── ErrorHandler.java │ │ │ ├── Networking.java │ │ │ ├── Request.java │ │ │ └── ResponseListener.java │ │ └── res │ │ ├── values-ar │ │ └── strings.xml │ │ ├── values-ast │ │ └── strings.xml │ │ ├── values-az │ │ └── strings.xml │ │ ├── values-be │ │ └── strings.xml │ │ ├── values-bg │ │ └── strings.xml │ │ ├── values-ca │ │ └── strings.xml │ │ ├── values-cs │ │ └── strings.xml │ │ ├── values-de │ │ └── strings.xml │ │ ├── values-el │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-et │ │ └── strings.xml │ │ ├── values-fa │ │ └── strings.xml │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-hi │ │ └── strings.xml │ │ ├── values-hr │ │ └── strings.xml │ │ ├── values-hu │ │ └── strings.xml │ │ ├── values-in │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-iw │ │ └── strings.xml │ │ ├── values-ja │ │ └── strings.xml │ │ ├── values-ka │ │ └── strings.xml │ │ ├── values-kk │ │ └── strings.xml │ │ ├── values-ko │ │ └── strings.xml │ │ ├── values-ku │ │ └── strings.xml │ │ ├── values-lt │ │ └── strings.xml │ │ ├── values-mk │ │ └── strings.xml │ │ ├── values-ml │ │ └── strings.xml │ │ ├── values-nb │ │ └── strings.xml │ │ ├── values-nl │ │ └── strings.xml │ │ ├── values-pa │ │ └── strings.xml │ │ ├── values-pl │ │ └── strings.xml │ │ ├── values-pt-rBR │ │ └── strings.xml │ │ ├── values-pt-rPT │ │ └── strings.xml │ │ ├── values-ro │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-sk │ │ └── strings.xml │ │ ├── values-sq │ │ └── strings.xml │ │ ├── values-sr │ │ └── strings.xml │ │ ├── values-sv │ │ └── strings.xml │ │ ├── values-sw │ │ └── strings.xml │ │ ├── values-ta │ │ └── strings.xml │ │ ├── values-th │ │ └── strings.xml │ │ ├── values-tr │ │ └── strings.xml │ │ ├── values-uk │ │ └── strings.xml │ │ ├── values-vi │ │ └── strings.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ ├── values-zh-rTW │ │ └── strings.xml │ │ └── values │ │ └── strings.xml └── test │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── topjohnwu │ └── magisk │ └── test │ ├── AppMigrationTest.kt │ └── Runners.kt ├── build.py ├── config.prop.sample ├── docs ├── README.md ├── app_changes.md ├── boot.md ├── build.md ├── changes.md ├── details.md ├── faq.md ├── guides.md ├── images │ ├── device_info.png │ ├── disable_auto_ota.png │ ├── install_inactive_slot.png │ ├── logo.png │ ├── manager_reboot.png │ ├── ota_done.png │ └── restore_img.png ├── install.md ├── ota.md ├── releases │ ├── 18000.md │ ├── 18100.md │ ├── 19000.md │ ├── 19100.md │ ├── 19200.md │ ├── 19300.md │ ├── 19400.md │ ├── 20000.md │ ├── 20100.md │ ├── 20200.md │ ├── 20300.md │ ├── 20400.md │ ├── 21000.md │ ├── 21100.md │ ├── 21200.md │ ├── 21400.md │ ├── 22000.md │ ├── 22100.md │ ├── 23000.md │ ├── 24000.md │ ├── 24100.md │ ├── 24200.md │ ├── 24300.md │ ├── 25000.md │ ├── 25100.md │ ├── 25200.md │ ├── 26000.md │ ├── 26100.md │ ├── 26200.md │ ├── 26300.md │ ├── 26400.md │ ├── 27000.md │ ├── 28000.md │ ├── 28100.md │ ├── 29000.md │ └── index.md └── tools.md ├── native ├── .gitignore ├── build.gradle.kts └── src │ ├── .cargo │ └── config.toml │ ├── Android-rs.mk │ ├── Android.mk │ ├── AndroidManifest.xml │ ├── Application.mk │ ├── Cargo.lock │ ├── Cargo.toml │ ├── base │ ├── Android.mk │ ├── Cargo.toml │ ├── build.rs │ ├── cstr.rs │ ├── cxx_extern.rs │ ├── dir.rs │ ├── files.cpp │ ├── files.hpp │ ├── files.rs │ ├── include │ │ ├── base.hpp │ │ └── stream.hpp │ ├── lib.rs │ ├── logging.cpp │ ├── logging.hpp │ ├── logging.rs │ ├── misc.cpp │ ├── misc.hpp │ ├── misc.rs │ ├── mount.rs │ ├── new.cpp │ ├── result.rs │ ├── stream.cpp │ ├── xwrap.hpp │ └── xwrap.rs │ ├── boot │ ├── .gitignore │ ├── Cargo.toml │ ├── bootimg.cpp │ ├── bootimg.hpp │ ├── build.rs │ ├── bzlib.h │ ├── compress.cpp │ ├── compress.hpp │ ├── cpio.rs │ ├── dtb.rs │ ├── format.cpp │ ├── format.hpp │ ├── lib.rs │ ├── magiskboot.hpp │ ├── main.cpp │ ├── patch.rs │ ├── payload.rs │ ├── proto │ │ └── update_metadata.proto │ └── sign.rs │ ├── core │ ├── Cargo.toml │ ├── applet_stub.cpp │ ├── applets.cpp │ ├── build.rs │ ├── daemon.cpp │ ├── daemon.rs │ ├── db.rs │ ├── deny │ │ ├── cli.cpp │ │ ├── deny.hpp │ │ ├── logcat.cpp │ │ └── utils.cpp │ ├── derive │ │ ├── Cargo.toml │ │ ├── decodable.rs │ │ └── lib.rs │ ├── include │ │ ├── core.hpp │ │ ├── resetprop.hpp │ │ └── sqlite.hpp │ ├── lib.rs │ ├── logging.rs │ ├── magisk.cpp │ ├── module.cpp │ ├── mount.rs │ ├── node.hpp │ ├── package.rs │ ├── resetprop.rs │ ├── resetprop │ │ ├── .gitignore │ │ ├── persist.rs │ │ ├── proto │ │ │ └── persistent_properties.proto │ │ └── resetprop.cpp │ ├── scripting.cpp │ ├── selinux.rs │ ├── socket.rs │ ├── sqlite.cpp │ ├── su │ │ ├── connect.cpp │ │ ├── daemon.rs │ │ ├── db.rs │ │ ├── mod.rs │ │ ├── pts.rs │ │ └── su.cpp │ ├── thread.cpp │ └── zygisk │ │ ├── api.hpp │ │ ├── daemon.rs │ │ ├── entry.cpp │ │ ├── gen_jni_hooks.py │ │ ├── hook.cpp │ │ ├── jni_hooks.hpp │ │ ├── mod.rs │ │ ├── module.cpp │ │ ├── module.hpp │ │ └── zygisk.hpp │ ├── exported_sym.txt │ ├── external │ ├── Android.mk │ ├── xz-embedded │ │ ├── xz.h │ │ ├── xz_config.h │ │ ├── xz_crc32.c │ │ ├── xz_dec_lzma2.c │ │ ├── xz_dec_stream.c │ │ ├── xz_lzma2.h │ │ ├── xz_private.h │ │ └── xz_stream.h │ └── xz_config │ │ └── config.h │ ├── include │ ├── codegen.rs │ ├── consts.hpp │ └── consts.rs │ ├── init │ ├── Cargo.toml │ ├── build.rs │ ├── getinfo.cpp │ ├── getinfo.rs │ ├── init.hpp │ ├── init.rs │ ├── lib.rs │ ├── logging.rs │ ├── mount.cpp │ ├── mount.rs │ ├── preload.c │ ├── rootdir.cpp │ ├── rootdir.rs │ ├── selinux.rs │ └── twostage.rs │ └── sepolicy │ ├── Cargo.toml │ ├── api.cpp │ ├── build.rs │ ├── cli.rs │ ├── include │ └── sepolicy.hpp │ ├── lib.rs │ ├── policy.hpp │ ├── policydb.cpp │ ├── rules.rs │ ├── sepolicy.cpp │ └── statement.rs ├── scripts ├── addon.d.sh ├── app_functions.sh ├── avd_magisk.sh ├── avd_patch.sh ├── avd_test.sh ├── boot_patch.sh ├── cuttlefish.sh ├── flash_script.sh ├── module_installer.sh ├── release.sh ├── test_common.sh ├── uninstaller.sh ├── update_binary.sh └── util_functions.sh └── tools ├── bootctl ├── bootctl.patch ├── elf-cleaner ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── futility ├── keys ├── kernel.keyblock ├── kernel_data_key.vbprivk ├── verity.pk8 └── verity.x509.pem └── rustup-wrapper ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src └── main.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text eol=lf 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | # *.c text 7 | # *.h text 8 | 9 | # Declare files that will always have CRLF line endings on checkout. 10 | *.cmd text eol=crlf 11 | *.bat text eol=crlf 12 | 13 | # Denote all files that are truly binary and should not be modified. 14 | tools/** binary 15 | tools/rustup-wrapper/** -binary 16 | tools/elf-cleaner/** -binary 17 | *.jar binary 18 | *.exe binary 19 | *.apk binary 20 | *.png binary 21 | *.jpg binary 22 | *.ttf binary 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | 32 | 33 | Device: 34 | Android version: 35 | Magisk version name: 36 | Magisk version code: 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: XDA Community Support 4 | url: https://forum.xda-developers.com/f/magisk.5903/ 5 | about: Please ask and answer questions here. 6 | 7 | -------------------------------------------------------------------------------- /.github/actions/setup/sccache.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Get latest sccache version 4 | get_sccache_ver() { 5 | curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name 6 | } 7 | 8 | # $1=variant 9 | # $2=install_dir 10 | # $3=exe 11 | install_from_gh() { 12 | local ver=$(curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name) 13 | local url="https://github.com/mozilla/sccache/releases/download/${ver}/sccache-${ver}-$1.tar.gz" 14 | local dest="$2/$3" 15 | curl -L "$url" | tar xz -O --wildcards "*/$3" > $dest 16 | chmod +x $dest 17 | } 18 | 19 | if [ $RUNNER_OS = "macOS" ]; then 20 | brew install sccache 21 | elif [ $RUNNER_OS = "Linux" ]; then 22 | install_from_gh x86_64-unknown-linux-musl /usr/local/bin sccache 23 | elif [ $RUNNER_OS = "Windows" ]; then 24 | install_from_gh x86_64-pc-windows-msvc $USERPROFILE/.cargo/bin sccache.exe 25 | fi 26 | -------------------------------------------------------------------------------- /.github/ci.prop: -------------------------------------------------------------------------------- 1 | abiList=arm64-v8a 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | *.zip 3 | *.jks 4 | *.apk 5 | *.log 6 | /config.prop 7 | /notes.md 8 | 9 | # Built binaries 10 | native/out 11 | 12 | # Android Studio 13 | *.iml 14 | .idea 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "selinux"] 2 | path = native/src/external/selinux 3 | url = https://github.com/topjohnwu/selinux.git 4 | [submodule "lz4"] 5 | path = native/src/external/lz4 6 | url = https://github.com/lz4/lz4.git 7 | [submodule "xz"] 8 | path = native/src/external/xz 9 | url = https://github.com/xz-mirror/xz.git 10 | [submodule "libcxx"] 11 | path = native/src/external/libcxx 12 | url = https://github.com/topjohnwu/libcxx.git 13 | [submodule "zopfli"] 14 | path = native/src/external/zopfli 15 | url = https://github.com/google/zopfli.git 16 | [submodule "cxx-rs"] 17 | path = native/src/external/cxx-rs 18 | url = https://github.com/topjohnwu/cxx.git 19 | [submodule "lsplt"] 20 | path = native/src/external/lsplt 21 | url = https://github.com/LSPosed/LSPlt.git 22 | [submodule "system_properties"] 23 | path = native/src/external/system_properties 24 | url = https://github.com/topjohnwu/system_properties.git 25 | [submodule "crt0"] 26 | path = native/src/external/crt0 27 | url = https://github.com/topjohnwu/crt0.git 28 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /dict.txt 2 | 3 | # Gradle 4 | .gradle 5 | .kotlin 6 | /local.properties 7 | /build 8 | -------------------------------------------------------------------------------- /app/apk/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/apk/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/arch/AsyncLoadViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.arch 2 | 3 | import androidx.annotation.MainThread 4 | import androidx.lifecycle.viewModelScope 5 | import kotlinx.coroutines.Job 6 | import kotlinx.coroutines.launch 7 | 8 | abstract class AsyncLoadViewModel : BaseViewModel() { 9 | 10 | private var loadingJob: Job? = null 11 | 12 | @MainThread 13 | fun startLoading() { 14 | if (loadingJob?.isActive == true) { 15 | // Prevent multiple jobs from running at the same time 16 | return 17 | } 18 | loadingJob = viewModelScope.launch { doLoadWork() } 19 | } 20 | 21 | protected abstract suspend fun doLoadWork() 22 | } 23 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.arch 2 | 3 | import android.content.Context 4 | 5 | /** 6 | * Class for passing events from ViewModels to Activities/Fragments 7 | * (see https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150) 8 | */ 9 | abstract class ViewEvent 10 | 11 | interface ContextExecutor { 12 | operator fun invoke(context: Context) 13 | } 14 | 15 | interface ActivityExecutor { 16 | operator fun invoke(activity: UIActivity<*>) 17 | } 18 | 19 | interface FragmentExecutor { 20 | operator fun invoke(fragment: BaseFragment<*>) 21 | } 22 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/databinding/RecyclerViewItems.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.databinding 2 | 3 | import androidx.databinding.PropertyChangeRegistry 4 | import androidx.databinding.ViewDataBinding 5 | import androidx.recyclerview.widget.RecyclerView 6 | 7 | abstract class RvItem { 8 | abstract val layoutRes: Int 9 | } 10 | 11 | abstract class ObservableRvItem : RvItem(), ObservableHost { 12 | override var callbacks: PropertyChangeRegistry? = null 13 | } 14 | 15 | interface ItemWrapper { 16 | val item: E 17 | } 18 | 19 | interface ViewAwareItem { 20 | fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) 21 | } 22 | 23 | interface DiffItem { 24 | 25 | fun itemSameAs(other: T): Boolean { 26 | if (this === other) return true 27 | return when (this) { 28 | is ItemWrapper<*> -> item == (other as ItemWrapper<*>).item 29 | is Comparable<*> -> compareValues(this, other as Comparable<*>) == 0 30 | else -> this == other 31 | } 32 | } 33 | 34 | fun contentSameAs(other: T) = true 35 | } 36 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/dialog/LocalModuleInstallDialog.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.dialog 2 | 3 | import android.net.Uri 4 | import com.topjohnwu.magisk.MainDirections 5 | import com.topjohnwu.magisk.core.Const 6 | import com.topjohnwu.magisk.core.R 7 | import com.topjohnwu.magisk.events.DialogBuilder 8 | import com.topjohnwu.magisk.ui.module.ModuleViewModel 9 | import com.topjohnwu.magisk.view.MagiskDialog 10 | 11 | class LocalModuleInstallDialog( 12 | private val viewModel: ModuleViewModel, 13 | private val uri: Uri, 14 | private val displayName: String 15 | ) : DialogBuilder { 16 | override fun build(dialog: MagiskDialog) { 17 | dialog.apply { 18 | setTitle(R.string.confirm_install_title) 19 | setMessage(context.getString(R.string.confirm_install, displayName)) 20 | setButton(MagiskDialog.ButtonType.POSITIVE) { 21 | text = android.R.string.ok 22 | onClick { 23 | viewModel.apply { 24 | MainDirections.actionFlashFragment(Const.Value.FLASH_ZIP, uri).navigate() 25 | } 26 | } 27 | } 28 | setButton(MagiskDialog.ButtonType.NEGATIVE) { 29 | text = android.R.string.cancel 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/dialog/MarkDownDialog.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.dialog 2 | 3 | import android.view.LayoutInflater 4 | import android.widget.TextView 5 | import androidx.annotation.CallSuper 6 | import androidx.lifecycle.lifecycleScope 7 | import com.topjohnwu.magisk.R 8 | import com.topjohnwu.magisk.core.di.ServiceLocator 9 | import com.topjohnwu.magisk.events.DialogBuilder 10 | import com.topjohnwu.magisk.view.MagiskDialog 11 | import kotlinx.coroutines.Dispatchers 12 | import kotlinx.coroutines.launch 13 | import kotlinx.coroutines.withContext 14 | import timber.log.Timber 15 | import java.io.IOException 16 | import com.topjohnwu.magisk.core.R as CoreR 17 | 18 | abstract class MarkDownDialog : DialogBuilder { 19 | 20 | abstract suspend fun getMarkdownText(): String 21 | 22 | @CallSuper 23 | override fun build(dialog: MagiskDialog) { 24 | with(dialog) { 25 | val view = LayoutInflater.from(context).inflate(R.layout.markdown_window_md2, null) 26 | setView(view) 27 | val tv = view.findViewById(R.id.md_txt) 28 | activity.lifecycleScope.launch { 29 | try { 30 | val text = withContext(Dispatchers.IO) { getMarkdownText() } 31 | ServiceLocator.markwon.setMarkdown(tv, text) 32 | } catch (e: IOException) { 33 | Timber.e(e) 34 | tv.setText(CoreR.string.download_file_error) 35 | } 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/dialog/SecondSlotWarningDialog.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.dialog 2 | 3 | import com.topjohnwu.magisk.core.R 4 | import com.topjohnwu.magisk.events.DialogBuilder 5 | import com.topjohnwu.magisk.view.MagiskDialog 6 | 7 | class SecondSlotWarningDialog : DialogBuilder { 8 | 9 | override fun build(dialog: MagiskDialog) { 10 | dialog.apply { 11 | setTitle(android.R.string.dialog_alert_title) 12 | setMessage(R.string.install_inactive_slot_msg) 13 | setButton(MagiskDialog.ButtonType.POSITIVE) { 14 | text = android.R.string.ok 15 | } 16 | setCancelable(true) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/dialog/SuperuserRevokeDialog.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.dialog 2 | 3 | import com.topjohnwu.magisk.core.R 4 | import com.topjohnwu.magisk.events.DialogBuilder 5 | import com.topjohnwu.magisk.view.MagiskDialog 6 | 7 | class SuperuserRevokeDialog( 8 | private val appName: String, 9 | private val onSuccess: () -> Unit 10 | ) : DialogBuilder { 11 | 12 | override fun build(dialog: MagiskDialog) { 13 | dialog.apply { 14 | setTitle(R.string.su_revoke_title) 15 | setMessage(R.string.su_revoke_msg, appName) 16 | setButton(MagiskDialog.ButtonType.POSITIVE) { 17 | text = android.R.string.ok 18 | onClick { onSuccess() } 19 | } 20 | setButton(MagiskDialog.ButtonType.NEGATIVE) { 21 | text = android.R.string.cancel 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/flash/ConsoleItem.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.flash 2 | 3 | import android.view.View 4 | import android.widget.TextView 5 | import androidx.core.view.updateLayoutParams 6 | import androidx.databinding.ViewDataBinding 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.topjohnwu.magisk.R 9 | import com.topjohnwu.magisk.databinding.DiffItem 10 | import com.topjohnwu.magisk.databinding.ItemWrapper 11 | import com.topjohnwu.magisk.databinding.RvItem 12 | import com.topjohnwu.magisk.databinding.ViewAwareItem 13 | import kotlin.math.max 14 | 15 | class ConsoleItem( 16 | override val item: String 17 | ) : RvItem(), ViewAwareItem, DiffItem, ItemWrapper { 18 | override val layoutRes = R.layout.item_console_md2 19 | 20 | private var parentWidth = -1 21 | 22 | override fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) { 23 | if (parentWidth < 0) 24 | parentWidth = (recyclerView.parent as View).width 25 | 26 | val view = binding.root as TextView 27 | view.measure(0, 0) 28 | 29 | // We want our recyclerView at least as wide as screen 30 | val desiredWidth = max(view.measuredWidth, parentWidth) 31 | 32 | view.updateLayoutParams { width = desiredWidth } 33 | 34 | if (recyclerView.width < desiredWidth) { 35 | recyclerView.requestLayout() 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/install/InstallFragment.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.install 2 | 3 | import com.topjohnwu.magisk.R 4 | import com.topjohnwu.magisk.arch.BaseFragment 5 | import com.topjohnwu.magisk.arch.viewModel 6 | import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding 7 | import com.topjohnwu.magisk.core.R as CoreR 8 | 9 | class InstallFragment : BaseFragment() { 10 | 11 | override val layoutRes = R.layout.fragment_install_md2 12 | override val viewModel by viewModel() 13 | 14 | override fun onStart() { 15 | super.onStart() 16 | requireActivity().setTitle(CoreR.string.install) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/log/LogRvItem.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.log 2 | 3 | import androidx.databinding.ViewDataBinding 4 | import androidx.recyclerview.widget.RecyclerView 5 | import com.google.android.material.textview.MaterialTextView 6 | import com.topjohnwu.magisk.R 7 | import com.topjohnwu.magisk.databinding.DiffItem 8 | import com.topjohnwu.magisk.databinding.ItemWrapper 9 | import com.topjohnwu.magisk.databinding.ObservableRvItem 10 | import com.topjohnwu.magisk.databinding.ViewAwareItem 11 | 12 | class LogRvItem( 13 | override val item: String 14 | ) : ObservableRvItem(), DiffItem, ItemWrapper, ViewAwareItem { 15 | 16 | override val layoutRes = R.layout.item_log_textview 17 | 18 | override fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) { 19 | val view = binding.root as MaterialTextView 20 | view.measure(0, 0) 21 | val desiredWidth = view.measuredWidth 22 | val layoutParams = view.layoutParams 23 | layoutParams.width = desiredWidth 24 | if (recyclerView.width < desiredWidth) { 25 | recyclerView.requestLayout() 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.settings 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import com.topjohnwu.magisk.R 6 | import com.topjohnwu.magisk.arch.BaseFragment 7 | import com.topjohnwu.magisk.arch.viewModel 8 | import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding 9 | import rikka.recyclerview.addEdgeSpacing 10 | import rikka.recyclerview.addItemSpacing 11 | import rikka.recyclerview.fixEdgeEffect 12 | import com.topjohnwu.magisk.core.R as CoreR 13 | 14 | class SettingsFragment : BaseFragment() { 15 | 16 | override val layoutRes = R.layout.fragment_settings_md2 17 | override val viewModel by viewModel() 18 | override val snackbarView: View get() = binding.snackbarContainer 19 | 20 | override fun onStart() { 21 | super.onStart() 22 | 23 | activity?.title = resources.getString(CoreR.string.settings) 24 | } 25 | 26 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 27 | super.onViewCreated(view, savedInstanceState) 28 | binding.settingsList.apply { 29 | addEdgeSpacing(bottom = R.dimen.l1) 30 | addItemSpacing(R.dimen.l1, R.dimen.l_50, R.dimen.l1) 31 | fixEdgeEffect() 32 | } 33 | } 34 | 35 | override fun onResume() { 36 | super.onResume() 37 | viewModel.items.forEach { it.refresh() } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserFragment.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.superuser 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import com.topjohnwu.magisk.R 6 | import com.topjohnwu.magisk.arch.BaseFragment 7 | import com.topjohnwu.magisk.arch.viewModel 8 | import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding 9 | import rikka.recyclerview.addEdgeSpacing 10 | import rikka.recyclerview.addItemSpacing 11 | import rikka.recyclerview.fixEdgeEffect 12 | import com.topjohnwu.magisk.core.R as CoreR 13 | 14 | class SuperuserFragment : BaseFragment() { 15 | 16 | override val layoutRes = R.layout.fragment_superuser_md2 17 | override val viewModel by viewModel() 18 | 19 | override fun onStart() { 20 | super.onStart() 21 | activity?.title = resources.getString(CoreR.string.superuser) 22 | } 23 | 24 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 25 | super.onViewCreated(view, savedInstanceState) 26 | 27 | binding.superuserList.apply { 28 | addEdgeSpacing(top = R.dimen.l_50, bottom = R.dimen.l1) 29 | addItemSpacing(R.dimen.l1, R.dimen.l_50, R.dimen.l1) 30 | fixEdgeEffect() 31 | } 32 | } 33 | 34 | override fun onPreBind(binding: FragmentSuperuserMd2Binding) {} 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.theme 2 | 3 | import com.topjohnwu.magisk.R 4 | import com.topjohnwu.magisk.core.Config 5 | 6 | enum class Theme( 7 | val themeName: String, 8 | val themeRes: Int 9 | ) { 10 | 11 | Piplup( 12 | themeName = "Piplup", 13 | themeRes = R.style.ThemeFoundationMD2_Piplup 14 | ), 15 | PiplupAmoled( 16 | themeName = "AMOLED", 17 | themeRes = R.style.ThemeFoundationMD2_Amoled 18 | ), 19 | Rayquaza( 20 | themeName = "Rayquaza", 21 | themeRes = R.style.ThemeFoundationMD2_Rayquaza 22 | ), 23 | Zapdos( 24 | themeName = "Zapdos", 25 | themeRes = R.style.ThemeFoundationMD2_Zapdos 26 | ), 27 | Charmeleon( 28 | themeName = "Charmeleon", 29 | themeRes = R.style.ThemeFoundationMD2_Charmeleon 30 | ), 31 | Mew( 32 | themeName = "Mew", 33 | themeRes = R.style.ThemeFoundationMD2_Mew 34 | ), 35 | Salamence( 36 | themeName = "Salamence", 37 | themeRes = R.style.ThemeFoundationMD2_Salamence 38 | ), 39 | Fraxure( 40 | themeName = "Fraxure (Legacy)", 41 | themeRes = R.style.ThemeFoundationMD2_Fraxure 42 | ); 43 | 44 | val isSelected get() = Config.themeOrdinal == ordinal 45 | 46 | fun select() { 47 | Config.themeOrdinal = ordinal 48 | } 49 | 50 | companion object { 51 | val selected get() = values().getOrNull(Config.themeOrdinal) ?: Piplup 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/ui/theme/ThemeViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.ui.theme 2 | 3 | import com.topjohnwu.magisk.arch.BaseViewModel 4 | import com.topjohnwu.magisk.core.Config 5 | import com.topjohnwu.magisk.dialog.DarkThemeDialog 6 | import com.topjohnwu.magisk.events.RecreateEvent 7 | import com.topjohnwu.magisk.view.TappableHeadlineItem 8 | 9 | class ThemeViewModel : BaseViewModel(), TappableHeadlineItem.Listener { 10 | 11 | val themeHeadline = TappableHeadlineItem.ThemeMode 12 | 13 | override fun onItemPressed(item: TappableHeadlineItem) = when (item) { 14 | is TappableHeadlineItem.ThemeMode -> DarkThemeDialog().show() 15 | } 16 | 17 | fun saveTheme(theme: Theme) { 18 | if (!theme.isSelected) { 19 | Config.themeOrdinal = theme.ordinal 20 | RecreateEvent().publish() 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/utils/AccessibilityUtils.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.utils 2 | 3 | import android.content.ContentResolver 4 | import android.provider.Settings 5 | 6 | class AccessibilityUtils { 7 | companion object { 8 | fun isAnimationEnabled(cr: ContentResolver): Boolean { 9 | return !(Settings.Global.getFloat(cr, Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f) == 0.0f 10 | && Settings.Global.getFloat(cr, Settings.Global.TRANSITION_ANIMATION_SCALE, 1.0f) == 0.0f 11 | && Settings.Global.getFloat(cr, Settings.Global.WINDOW_ANIMATION_SCALE, 1.0f) == 0.0f) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/utils/TextHolder.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.utils 2 | 3 | import android.content.res.Resources 4 | 5 | abstract class TextHolder { 6 | 7 | open val isEmpty: Boolean get() = false 8 | abstract fun getText(resources: Resources): CharSequence 9 | 10 | // --- 11 | 12 | class String( 13 | private val value: CharSequence 14 | ) : TextHolder() { 15 | override val isEmpty get() = value.isEmpty() 16 | override fun getText(resources: Resources) = value 17 | } 18 | 19 | open class Resource( 20 | protected val value: Int 21 | ) : TextHolder() { 22 | override val isEmpty get() = value == 0 23 | override fun getText(resources: Resources) = resources.getString(value) 24 | } 25 | 26 | class ResourceArgs( 27 | value: Int, 28 | private vararg val params: Any 29 | ) : Resource(value) { 30 | override fun getText(resources: Resources): kotlin.String { 31 | // Replace TextHolder with strings 32 | val args = params.map { if (it is TextHolder) it.getText(resources) else it } 33 | return resources.getString(value, *args.toTypedArray()) 34 | } 35 | } 36 | 37 | // --- 38 | 39 | companion object { 40 | val EMPTY = String("") 41 | } 42 | } 43 | 44 | fun Int.asText(): TextHolder = TextHolder.Resource(this) 45 | fun Int.asText(vararg params: Any): TextHolder = TextHolder.ResourceArgs(this, *params) 46 | fun CharSequence.asText(): TextHolder = TextHolder.String(this) 47 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/view/TappableHeadlineItem.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.view 2 | 3 | import com.topjohnwu.magisk.R 4 | import com.topjohnwu.magisk.databinding.DiffItem 5 | import com.topjohnwu.magisk.databinding.RvItem 6 | import com.topjohnwu.magisk.core.R as CoreR 7 | 8 | sealed class TappableHeadlineItem : RvItem(), DiffItem { 9 | 10 | abstract val title: Int 11 | abstract val icon: Int 12 | 13 | override val layoutRes = R.layout.item_tappable_headline 14 | 15 | // --- listener 16 | 17 | interface Listener { 18 | 19 | fun onItemPressed(item: TappableHeadlineItem) 20 | 21 | } 22 | 23 | // --- objects 24 | 25 | object ThemeMode : TappableHeadlineItem() { 26 | override val title = CoreR.string.settings_dark_mode_title 27 | override val icon = R.drawable.ic_day_night 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/apk/src/main/java/com/topjohnwu/magisk/view/TextItem.kt: -------------------------------------------------------------------------------- 1 | package com.topjohnwu.magisk.view 2 | 3 | import com.topjohnwu.magisk.R 4 | import com.topjohnwu.magisk.databinding.DiffItem 5 | import com.topjohnwu.magisk.databinding.ItemWrapper 6 | import com.topjohnwu.magisk.databinding.RvItem 7 | 8 | class TextItem(override val item: Int) : RvItem(), DiffItem, ItemWrapper { 9 | override val layoutRes = R.layout.item_text 10 | } 11 | -------------------------------------------------------------------------------- /app/apk/src/main/res/anim/fragment_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 15 | -------------------------------------------------------------------------------- /app/apk/src/main/res/anim/fragment_enter_pop.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 15 | -------------------------------------------------------------------------------- /app/apk/src/main/res/anim/fragment_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 15 | -------------------------------------------------------------------------------- /app/apk/src/main/res/anim/fragment_exit_pop.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 15 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_card_background_color_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_error_transient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_menu_tint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_on_primary_transient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_primary_error_transient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_primary_transient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_state_primary_transient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/apk/src/main/res/color/color_text_transient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/bg_line_bottom_rounded.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/bg_line_top_rounded.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/bg_selection_circle_green.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_action_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_back_md2.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_bug_filled_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_bug_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_bug_outlined_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_check_circle_checked_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_check_circle_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_check_circle_unchecked_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_check_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_close_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_day.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_day_night.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_delete_md2.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_download_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_folder_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_forth_md2.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_home_filled_md2.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_home_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 17 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_home_outlined_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_install.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_manager.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_module_filled_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_module_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 17 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_module_outlined_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_module_storage_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_night.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_notifications_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_paint.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_restart.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_save_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_search_md2.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_settings_filled_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_settings_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 17 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_superuser_filled_md2.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_superuser_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 17 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_superuser_outlined_md2.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/apk/src/main/res/drawable/ic_update_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/apk/src/main/res/layout/item_console_md2.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/apk/src/main/res/layout/item_icon_link.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 15 | 16 | 17 | 18 | 28 | 29 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/apk/src/main/res/layout/item_list_single_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 14 | 15 | 16 | 17 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/apk/src/main/res/layout/item_log_textview.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/apk/src/main/res/layout/item_module_download.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 14 | 15 | 16 | 17 |