├── .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 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/layout/item_settings_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
19 |
20 |
28 |
29 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/layout/item_spinner.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/layout/item_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/layout/item_theme_container.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/layout/markdown_window_md2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/menu/menu_bottom_nav.xml:
--------------------------------------------------------------------------------
1 |
2 |
30 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/menu/menu_deny_md2.xml:
--------------------------------------------------------------------------------
1 |
2 |
21 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/menu/menu_flash.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/menu/menu_home_md2.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/menu/menu_log_md2.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/menu/menu_reboot.xml:
--------------------------------------------------------------------------------
1 |
2 |
35 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values-night/styles_md2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values-v27/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 |
6 | 2dp
7 | 4dp
8 | 8dp
9 | 12dp
10 | 16dp
11 | 32dp
12 | 48dp
13 |
14 | 8dp
15 |
16 | 56dp
17 |
18 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values/styles_md2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
23 |
24 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values/theme_overlay.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/apk/src/main/res/values/themes_override.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
14 |
18 |
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("MagiskPlugin")
3 | }
4 |
5 | tasks.register("clean", Delete::class) {
6 | delete(rootProject.layout.buildDirectory)
7 |
8 | subprojects.forEach {
9 | dependsOn(":${it.name}:clean")
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/buildSrc/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
2 |
3 | plugins {
4 | `kotlin-dsl`
5 | }
6 |
7 | repositories {
8 | google()
9 | mavenCentral()
10 | }
11 |
12 | gradlePlugin {
13 | plugins {
14 | register("MagiskPlugin") {
15 | id = "MagiskPlugin"
16 | implementationClass = "MagiskPlugin"
17 | }
18 | }
19 | }
20 |
21 | kotlin {
22 | compilerOptions {
23 | languageVersion = KotlinVersion.KOTLIN_2_0
24 | }
25 | }
26 |
27 | dependencies {
28 | implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
29 | implementation(libs.android.gradle.plugin)
30 | implementation(libs.ksp.plugin)
31 | implementation(libs.navigation.safe.args.plugin)
32 | implementation(libs.lsparanoid.plugin)
33 | implementation(libs.jgit)
34 | }
35 |
--------------------------------------------------------------------------------
/app/buildSrc/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | versionCatalogs {
3 | create("libs") {
4 | from(files("../gradle/libs.versions.toml"))
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/app/core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | src/*/assets
3 | src/*/jniLibs
4 | src/*/resources
5 |
--------------------------------------------------------------------------------
/app/core/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Parcelable
2 | -keepclassmembers class * implements android.os.Parcelable {
3 | public static final ** CREATOR;
4 | }
5 |
6 | # Kotlin
7 | -assumenosideeffects class kotlin.jvm.internal.Intrinsics {
8 | public static void check*(...);
9 | public static void throw*(...);
10 | }
11 | -assumenosideeffects class java.util.Objects {
12 | public static ** requireNonNull(...);
13 | }
14 | -assumenosideeffects public class kotlin.coroutines.jvm.internal.DebugMetadataKt {
15 | private static ** getDebugMetadataAnnotation(...) return null;
16 | }
17 |
18 | # Stub
19 | -keep class com.topjohnwu.magisk.core.App { (java.lang.Object); }
20 | -keepclassmembers class androidx.appcompat.app.AppCompatDelegateImpl {
21 | boolean mActivityHandlesConfigFlagsChecked;
22 | int mActivityHandlesConfigFlags;
23 | }
24 |
25 | # Strip Timber verbose and debug logging
26 | -assumenosideeffects class timber.log.Timber$Tree {
27 | public void v(**);
28 | public void d(**);
29 | }
30 |
31 | # With R8 full mode generic signatures are stripped for classes that are not
32 | # kept. Suspend functions are wrapped in continuations where the type argument
33 | # is used.
34 | -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
35 |
36 | # Excessive obfuscation
37 | -flattenpackagehierarchy
38 | -allowaccessmodification
39 |
40 | -dontwarn org.junit.**
41 |
--------------------------------------------------------------------------------
/app/core/src/main/aidl/com/topjohnwu/magisk/core/utils/IRootUtils.aidl:
--------------------------------------------------------------------------------
1 | // IRootUtils.aidl
2 | package com.topjohnwu.magisk.core.utils;
3 |
4 | // Declare any non-default types here with import statements
5 |
6 | interface IRootUtils {
7 | android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
8 | IBinder getFileSystem();
9 | }
10 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/App.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import com.topjohnwu.magisk.StubApk
6 | import com.topjohnwu.magisk.core.utils.RootUtils
7 |
8 | open class App() : Application() {
9 |
10 | constructor(o: Any) : this() {
11 | val data = StubApk.Data(o)
12 | // Add the root service name mapping
13 | data.classToComponent[RootUtils::class.java.name] = data.rootService.name
14 | // Send back the actual root service class
15 | data.rootService = RootUtils::class.java
16 | Info.stub = data
17 | }
18 |
19 | override fun attachBaseContext(context: Context) {
20 | if (context is Application) {
21 | AppContext.attachApplication(context)
22 | } else {
23 | super.attachBaseContext(context)
24 | AppContext.attachApplication(this)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/Provider.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core
2 |
3 | import android.os.Bundle
4 | import com.topjohnwu.magisk.core.base.BaseProvider
5 | import com.topjohnwu.magisk.core.su.SuCallbackHandler
6 |
7 | class Provider : BaseProvider() {
8 |
9 | override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
10 | return when (method) {
11 | SuCallbackHandler.LOG, SuCallbackHandler.NOTIFY -> {
12 | SuCallbackHandler.run(context!!, method, extras)
13 | Bundle.EMPTY
14 | }
15 | else -> Bundle.EMPTY
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseJobService.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | import android.app.job.JobService
4 | import android.content.Context
5 | import com.topjohnwu.magisk.core.patch
6 |
7 | abstract class BaseJobService : JobService() {
8 | override fun attachBaseContext(base: Context) {
9 | super.attachBaseContext(base.patch())
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseProvider.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | import android.content.ContentProvider
4 | import android.content.ContentValues
5 | import android.content.Context
6 | import android.content.pm.ProviderInfo
7 | import android.database.Cursor
8 | import android.net.Uri
9 | import com.topjohnwu.magisk.core.patch
10 |
11 | open class BaseProvider : ContentProvider() {
12 | override fun attachInfo(context: Context, info: ProviderInfo) {
13 | super.attachInfo(context.patch(), info)
14 | }
15 | override fun onCreate() = true
16 | override fun getType(uri: Uri): String? = null
17 | override fun insert(uri: Uri, values: ContentValues?): Uri? = null
18 | override fun delete(uri: Uri, selection: String?, selectionArgs: Array?) = 0
19 | override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array?) = 0
20 | override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? = null
21 | }
22 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import androidx.annotation.CallSuper
7 | import com.topjohnwu.magisk.core.patch
8 |
9 | abstract class BaseReceiver : BroadcastReceiver() {
10 | @CallSuper
11 | override fun onReceive(context: Context, intent: Intent?) {
12 | context.patch()
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseService.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | import android.app.Service
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.os.IBinder
7 | import com.topjohnwu.magisk.core.patch
8 |
9 | open class BaseService : Service() {
10 | override fun attachBaseContext(base: Context) {
11 | super.attachBaseContext(base.patch())
12 | }
13 | override fun onBind(intent: Intent?): IBinder? = null
14 | }
15 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/data/NetworkServices.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.data
2 |
3 | import com.topjohnwu.magisk.core.model.BranchInfo
4 | import com.topjohnwu.magisk.core.model.ModuleJson
5 | import com.topjohnwu.magisk.core.model.UpdateInfo
6 | import okhttp3.ResponseBody
7 | import retrofit2.http.GET
8 | import retrofit2.http.Headers
9 | import retrofit2.http.Path
10 | import retrofit2.http.Streaming
11 | import retrofit2.http.Url
12 |
13 | private const val BRANCH = "branch"
14 | private const val REPO = "repo"
15 | private const val FILE = "file"
16 |
17 | interface GithubPageServices {
18 |
19 | @GET
20 | suspend fun fetchUpdateJSON(@Url file: String): UpdateInfo
21 | }
22 |
23 | interface RawServices {
24 |
25 | @GET
26 | @Streaming
27 | suspend fun fetchFile(@Url url: String): ResponseBody
28 |
29 | @GET
30 | suspend fun fetchString(@Url url: String): String
31 |
32 | @GET
33 | suspend fun fetchModuleJson(@Url url: String): ModuleJson
34 |
35 | }
36 |
37 | interface GithubApiServices {
38 |
39 | @GET("repos/{$REPO}/branches/{$BRANCH}")
40 | @Headers("Accept: application/vnd.github.v3+json")
41 | suspend fun fetchBranch(
42 | @Path(REPO, encoded = true) repo: String,
43 | @Path(BRANCH) branch: String
44 | ): BranchInfo
45 | }
46 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/data/magiskdb/SettingsDao.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.data.magiskdb
2 |
3 | class SettingsDao : MagiskDB() {
4 |
5 | suspend fun delete(key: String) {
6 | val query = "DELETE FROM ${Table.SETTINGS} WHERE key=\"$key\""
7 | exec(query)
8 | }
9 |
10 | suspend fun put(key: String, value: Int) {
11 | val kv = mapOf("key" to key, "value" to value)
12 | val query = "REPLACE INTO ${Table.SETTINGS} ${kv.toQuery()}"
13 | exec(query)
14 | }
15 |
16 | suspend fun fetch(key: String, default: Int = -1): Int {
17 | val query = "SELECT value FROM ${Table.SETTINGS} WHERE key=\"$key\" LIMIT 1"
18 | return exec(query) { it["value"]?.toInt() }.firstOrNull() ?: default
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/data/magiskdb/StringDao.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.data.magiskdb
2 |
3 | class StringDao : MagiskDB() {
4 |
5 | suspend fun delete(key: String) {
6 | val query = "DELETE FROM ${Table.STRINGS} WHERE key=\"$key\""
7 | exec(query)
8 | }
9 |
10 | suspend fun put(key: String, value: String) {
11 | val kv = mapOf("key" to key, "value" to value)
12 | val query = "REPLACE INTO ${Table.STRINGS} ${kv.toQuery()}"
13 | exec(query)
14 | }
15 |
16 | suspend fun fetch(key: String, default: String = ""): String {
17 | val query = "SELECT value FROM ${Table.STRINGS} WHERE key=\"$key\" LIMIT 1"
18 | return exec(query) { it["value"] }.firstOrNull() ?: default
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/download/Interfaces.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.download
2 |
3 | import android.app.Notification
4 | import android.content.Context
5 |
6 | interface DownloadSession {
7 | val context: Context
8 | fun attachNotification(id: Int, builder: Notification.Builder)
9 | fun onDownloadComplete()
10 | }
11 |
12 | interface DownloadNotifier {
13 | val context: Context
14 | fun notifyUpdate(id: Int, editor: (Notification.Builder) -> Unit = {})
15 | }
16 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/ktx/XSU.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.ktx
2 |
3 | import com.topjohnwu.magisk.core.Config
4 | import com.topjohnwu.superuser.Shell
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.withContext
7 |
8 | fun reboot(reason: String = if (Config.recovery) "recovery" else "") {
9 | if (reason == "recovery") {
10 | // KEYCODE_POWER = 26, hide incorrect "Factory data reset" message
11 | Shell.cmd("/system/bin/input keyevent 26").submit()
12 | }
13 | Shell.cmd("/system/bin/svc power reboot $reason || /system/bin/reboot $reason").submit()
14 | }
15 |
16 | suspend fun Shell.Job.await() = withContext(Dispatchers.IO) { exec() }
17 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/model/UpdateInfo.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.model
2 |
3 | import android.os.Parcelable
4 | import com.squareup.moshi.JsonClass
5 | import kotlinx.parcelize.Parcelize
6 |
7 | @JsonClass(generateAdapter = true)
8 | data class UpdateInfo(
9 | val magisk: MagiskJson = MagiskJson(),
10 | )
11 |
12 | @Parcelize
13 | @JsonClass(generateAdapter = true)
14 | data class MagiskJson(
15 | val version: String = "",
16 | val versionCode: Int = -1,
17 | val link: String = "",
18 | val note: String = ""
19 | ) : Parcelable
20 |
21 | @JsonClass(generateAdapter = true)
22 | data class ModuleJson(
23 | val version: String,
24 | val versionCode: Int,
25 | val zipUrl: String,
26 | val changelog: String,
27 | )
28 |
29 | @JsonClass(generateAdapter = true)
30 | data class CommitInfo(
31 | val sha: String
32 | )
33 |
34 | @JsonClass(generateAdapter = true)
35 | data class BranchInfo(
36 | val commit: CommitInfo
37 | )
38 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/model/module/Module.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.model.module
2 |
3 | abstract class Module : Comparable {
4 | abstract var id: String
5 | protected set
6 | abstract var name: String
7 | protected set
8 | abstract var version: String
9 | protected set
10 | abstract var versionCode: Int
11 | protected set
12 |
13 | override operator fun compareTo(other: Module) = id.compareTo(other.id)
14 | }
15 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/model/module/OnlineModule.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.model.module
2 |
3 | import android.os.Parcelable
4 | import com.topjohnwu.magisk.core.model.ModuleJson
5 | import kotlinx.parcelize.Parcelize
6 |
7 | @Parcelize
8 | data class OnlineModule(
9 | override var id: String,
10 | override var name: String,
11 | override var version: String,
12 | override var versionCode: Int,
13 | val zipUrl: String,
14 | val changelog: String,
15 | ) : Module(), Parcelable {
16 | constructor(local: LocalModule, json: ModuleJson) :
17 | this(local.id, local.name, json.version, json.versionCode, json.zipUrl, json.changelog)
18 |
19 | val downloadFilename get() = "$name-$version($versionCode).zip".legalFilename()
20 |
21 | private fun String.legalFilename() = replace(" ", "_")
22 | .replace("'", "").replace("\"", "")
23 | .replace("$", "").replace("`", "")
24 | .replace("*", "").replace("/", "_")
25 | .replace("#", "").replace("@", "")
26 | .replace("\\", "_")
27 | }
28 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/model/su/SuPolicy.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.model.su
2 |
3 | import com.topjohnwu.magisk.core.data.magiskdb.MagiskDB
4 |
5 | class SuPolicy(
6 | val uid: Int,
7 | var policy: Int = INTERACTIVE,
8 | var remain: Long = -1L,
9 | var logging: Boolean = true,
10 | var notification: Boolean = true,
11 | ) {
12 | companion object {
13 | const val INTERACTIVE = 0
14 | const val DENY = 1
15 | const val ALLOW = 2
16 | }
17 |
18 | fun toMap(): MutableMap {
19 | val until = if (remain <= 0) {
20 | remain
21 | } else {
22 | MagiskDB.Literal("(strftime(\"%s\", \"now\") + $remain)")
23 | }
24 | return mutableMapOf(
25 | "uid" to uid,
26 | "policy" to policy,
27 | "until" to until,
28 | "logging" to logging,
29 | "notification" to notification
30 | )
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/signing/ByteArrayStream.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.signing;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.nio.ByteBuffer;
8 |
9 | public class ByteArrayStream extends ByteArrayOutputStream {
10 |
11 | public synchronized void readFrom(InputStream is) {
12 | readFrom(is, Integer.MAX_VALUE);
13 | }
14 |
15 | public synchronized void readFrom(InputStream is, int len) {
16 | int read;
17 | byte buffer[] = new byte[4096];
18 | try {
19 | while ((read = is.read(buffer, 0, Math.min(len, buffer.length))) > 0) {
20 | write(buffer, 0, read);
21 | len -= read;
22 | }
23 | } catch (IOException e) {
24 | e.printStackTrace();
25 | }
26 | }
27 |
28 | public ByteArrayInputStream getInputStream() {
29 | return new ByteArrayInputStream(buf, 0, count);
30 | }
31 |
32 | public ByteBuffer toByteBuffer() {
33 | return ByteBuffer.wrap(buf, 0, count);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/utils/DummyList.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.utils
2 |
3 | object DummyList : java.util.AbstractList() {
4 |
5 | override val size: Int get() = 0
6 |
7 | override fun get(index: Int): String {
8 | throw IndexOutOfBoundsException()
9 | }
10 |
11 | override fun add(element: String): Boolean = false
12 |
13 | override fun add(index: Int, element: String) {}
14 |
15 | override fun clear() {}
16 | }
17 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/utils/ProgressInputStream.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.utils
2 |
3 | import java.io.FilterInputStream
4 | import java.io.InputStream
5 |
6 | class ProgressInputStream(
7 | base: InputStream,
8 | val progressEmitter: (Long) -> Unit
9 | ) : FilterInputStream(base) {
10 |
11 | private var bytesRead = 0L
12 | private var lastUpdate = 0L
13 |
14 | private fun emitProgress() {
15 | val cur = System.currentTimeMillis()
16 | if (cur - lastUpdate > 1000) {
17 | lastUpdate = cur
18 | progressEmitter(bytesRead)
19 | }
20 | }
21 |
22 | override fun read(): Int {
23 | val b = read()
24 | if (b >= 0) {
25 | bytesRead++
26 | emitProgress()
27 | }
28 | return b
29 | }
30 |
31 | override fun read(b: ByteArray): Int {
32 | return read(b, 0, b.size)
33 | }
34 |
35 | override fun read(b: ByteArray, off: Int, len: Int): Int {
36 | val sz = super.read(b, off, len)
37 | if (sz > 0) {
38 | bytesRead += sz
39 | emitProgress()
40 | }
41 | return sz
42 | }
43 |
44 | override fun close() {
45 | super.close()
46 | progressEmitter(bytesRead)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/utils/RequestAuthentication.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.utils
2 |
3 | import android.app.Activity
4 | import android.app.KeyguardManager
5 | import android.content.Context
6 | import android.content.Intent
7 | import androidx.activity.result.contract.ActivityResultContract
8 |
9 | class RequestAuthentication: ActivityResultContract() {
10 |
11 | override fun createIntent(context: Context, input: Unit) =
12 | context.getSystemService(KeyguardManager::class.java)
13 | .createConfirmDeviceCredentialIntent(null, null)
14 |
15 | override fun parseResult(resultCode: Int, intent: Intent?) =
16 | resultCode == Activity.RESULT_OK
17 | }
18 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/core/utils/RequestInstall.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.utils
2 |
3 | import android.annotation.TargetApi
4 | import android.app.Activity
5 | import android.content.Context
6 | import android.content.Intent
7 | import android.net.Uri
8 | import android.os.Build
9 | import android.provider.Settings
10 | import androidx.activity.result.contract.ActivityResultContract
11 |
12 | class RequestInstall : ActivityResultContract() {
13 |
14 | @TargetApi(26)
15 | override fun createIntent(context: Context, input: Unit): Intent {
16 | // This will only be called on API 26+
17 | return Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
18 | .setData(Uri.parse("package:${context.packageName}"))
19 | }
20 |
21 | override fun parseResult(resultCode: Int, intent: Intent?) =
22 | resultCode == Activity.RESULT_OK
23 |
24 | override fun getSynchronousResult(
25 | context: Context,
26 | input: Unit
27 | ): SynchronousResult? {
28 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
29 | return SynchronousResult(true)
30 | if (context.packageManager.canRequestPackageInstalls())
31 | return SynchronousResult(true)
32 | return null
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/core/src/main/java/com/topjohnwu/magisk/test/BaseTest.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.test
2 |
3 | import android.app.Instrumentation
4 | import android.app.UiAutomation
5 | import android.content.Context
6 | import androidx.test.platform.app.InstrumentationRegistry
7 | import androidx.test.uiautomator.UiDevice
8 | import com.topjohnwu.magisk.core.utils.RootUtils
9 | import com.topjohnwu.superuser.Shell
10 | import org.junit.Assert.assertTrue
11 |
12 | interface BaseTest {
13 | val instrumentation: Instrumentation
14 | get() = InstrumentationRegistry.getInstrumentation()
15 | val appContext: Context get() = instrumentation.targetContext
16 | val testContext: Context get() = instrumentation.context
17 | val uiAutomation: UiAutomation get() = instrumentation.uiAutomation
18 | val device: UiDevice get() = UiDevice.getInstance(instrumentation)
19 |
20 | companion object {
21 | fun prerequisite() {
22 | assertTrue("Should have root access", Shell.getShell().isRoot)
23 | // Make sure the root service is running
24 | RootUtils.Connection.await()
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable-v26/sc_extension.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable-v26/sc_superuser.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_extension.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_favorite.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_github.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_logo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_more.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_patreon.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_paypal.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_superuser.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/ic_twitter.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/sc_extension.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/core/src/main/res/drawable/sc_superuser.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/core/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #0D0D0D
4 |
5 |
--------------------------------------------------------------------------------
/app/core/src/main/res/values-v31/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
--------------------------------------------------------------------------------
/app/core/src/main/res/values-v34/resources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 |
5 |
--------------------------------------------------------------------------------
/app/core/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #00AF9C
4 | #00796B
5 | #e0e0e0
6 | #e0e0e0
7 | @color/ic_launcher_background
8 |
9 |
--------------------------------------------------------------------------------
/app/core/src/main/res/values/resources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Magisk
6 | Zygisk
7 |
8 |
9 | PayPal
10 | Patreon
11 | Twitter
12 | GitHub
13 |
14 | @drawable/ic_logo
15 |
16 | true
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/core/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | org.gradle.jvmargs=-Xmx2560m -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | org.gradle.parallel=true
19 |
20 | # Enable build cache
21 | org.gradle.caching=true
22 |
23 | # Use K2 in kapt
24 | kapt.use.k2=true
25 |
26 | # Android
27 | android.useAndroidX=true
28 | android.injected.testOnly=false
29 | android.nonFinalResIds=false
30 |
31 | # Magisk
32 | magisk.stubVersion=40
33 | magisk.versionCode=29001
34 |
--------------------------------------------------------------------------------
/app/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/app/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/app/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | @Suppress("UnstableApiUsage")
2 | dependencyResolutionManagement {
3 | repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
4 | repositories {
5 | google()
6 | mavenCentral()
7 | maven("https://jitpack.io")
8 | }
9 | }
10 | rootProject.name = "Magisk"
11 | include(":apk", ":core", ":shared", ":stub", ":test")
12 |
--------------------------------------------------------------------------------
/app/shared/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/shared/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | }
4 |
5 | setupCommon()
6 |
7 | android {
8 | namespace = "com.topjohnwu.shared"
9 | }
10 |
--------------------------------------------------------------------------------
/app/shared/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/shared/src/main/java/com/topjohnwu/magisk/ProviderInstaller.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ApplicationInfo;
5 |
6 | public class ProviderInstaller {
7 |
8 | private static final String GMS_PACKAGE_NAME = "com.google.android.gms";
9 |
10 | public static void install(Context context) {
11 | try {
12 | // Check if gms is a system app
13 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(GMS_PACKAGE_NAME, 0);
14 | if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
15 | return;
16 | }
17 |
18 | // Try installing new SSL provider from Google Play Service
19 | Context gms = context.createPackageContext(GMS_PACKAGE_NAME,
20 | Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
21 | gms.getClassLoader()
22 | .loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
23 | .getMethod("insertProvider", Context.class)
24 | .invoke(null, gms);
25 | } catch (Exception ignored) {
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/shared/src/main/java/com/topjohnwu/magisk/utils/CompoundEnumeration.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.utils;
2 |
3 | import java.util.Enumeration;
4 | import java.util.NoSuchElementException;
5 |
6 | public class CompoundEnumeration implements Enumeration {
7 | private Enumeration[] enums;
8 | private int index = 0;
9 |
10 | @SafeVarargs
11 | public CompoundEnumeration(Enumeration ...enums) {
12 | this.enums = enums;
13 | }
14 |
15 | private boolean next() {
16 | while (index < enums.length) {
17 | if (enums[index] != null && enums[index].hasMoreElements()) {
18 | return true;
19 | }
20 | index++;
21 | }
22 | return false;
23 | }
24 |
25 | public boolean hasMoreElements() {
26 | return next();
27 | }
28 |
29 | public E nextElement() {
30 | if (!next()) {
31 | throw new NoSuchElementException();
32 | }
33 | return enums[index].nextElement();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/stub/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /src/release/AndroidManifest.xml
3 | /src/debug/AndroidManifest.xml
4 |
--------------------------------------------------------------------------------
/app/stub/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | id("org.lsposed.lsparanoid")
4 | }
5 |
6 | lsparanoid {
7 | seed = if (RAND_SEED != 0) RAND_SEED else null
8 | includeDependencies = true
9 | classFilter = { true }
10 | }
11 |
12 | android {
13 | namespace = "com.topjohnwu.magisk"
14 |
15 | val canary = !Config.version.contains(".")
16 |
17 | val url = if (canary) null
18 | else "https://github.com/topjohnwu/Magisk/releases/download/v${Config.version}/Magisk-v${Config.version}.apk"
19 |
20 | defaultConfig {
21 | applicationId = "com.topjohnwu.magisk"
22 | versionCode = 1
23 | versionName = "1.0"
24 | buildConfigField("String", "APK_URL", url?.let { "\"$it\"" } ?: "null" )
25 | buildConfigField("int", "STUB_VERSION", Config.stubVersion)
26 | }
27 |
28 | buildTypes {
29 | release {
30 | proguardFiles("proguard-rules.pro")
31 | isMinifyEnabled = true
32 | isShrinkResources = false
33 | }
34 | }
35 |
36 | buildFeatures {
37 | buildConfig = true
38 | }
39 | }
40 |
41 | setupStubApk()
42 |
43 | dependencies {
44 | implementation(project(":shared"))
45 | }
46 |
--------------------------------------------------------------------------------
/app/stub/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | -obfuscationdictionary ../dict.txt
24 | -classobfuscationdictionary ../dict.txt
25 | -packageobfuscationdictionary ../dict.txt
26 |
27 | # Excessive obfuscation
28 | -repackageclasses
29 | -allowaccessmodification
30 | -keepclassmembers class com.topjohnwu.magisk.dummy.* { (); }
31 | -keepclassmembers class com.topjohnwu.magisk.DownloadActivity { (); }
32 | -keepclassmembers class com.topjohnwu.magisk.StubRootService { (); }
33 |
--------------------------------------------------------------------------------
/app/stub/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/StubApplication.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | public class StubApplication extends Application {
7 | @Override
8 | protected void attachBaseContext(Context base) {
9 | super.attachBaseContext(base);
10 | DynLoad.loadAndInitializeApp(this);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyProvider.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.dummy;
2 |
3 | import android.content.ContentProvider;
4 | import android.content.ContentValues;
5 | import android.database.Cursor;
6 | import android.net.Uri;
7 |
8 | public class DummyProvider extends ContentProvider {
9 | @Override
10 | public boolean onCreate() {
11 | return false;
12 | }
13 |
14 | @Override
15 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
16 | return null;
17 | }
18 |
19 | @Override
20 | public String getType(Uri uri) {
21 | return null;
22 | }
23 |
24 | @Override
25 | public Uri insert(Uri uri, ContentValues values) {
26 | return null;
27 | }
28 |
29 | @Override
30 | public int delete(Uri uri, String selection, String[] selectionArgs) {
31 | return 0;
32 | }
33 |
34 | @Override
35 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
36 | return 0;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyReceiver.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.dummy;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | public class DummyReceiver extends BroadcastReceiver {
8 | @Override
9 | public void onReceive(Context context, Intent intent) {}
10 | }
11 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyService.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.dummy;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.IBinder;
6 |
7 | public class DummyService extends Service {
8 | @Override
9 | public IBinder onBind(Intent intent) {
10 | return null;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/net/BadRequest.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.net;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONObject;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 |
10 | class BadRequest extends Request {
11 |
12 | private final IOException ex;
13 |
14 | BadRequest(IOException e) { super(null); ex = e; }
15 |
16 | @Override
17 | public Request addHeaders(String key, String value) { return this; }
18 |
19 | @Override
20 | public Result execForInputStream() { fail(); return new Result<>(); }
21 |
22 | @Override
23 | public void getAsFile(File out, ResponseListener rs) { fail(); }
24 |
25 | @Override
26 | public void execForFile(File out) { fail(); }
27 |
28 | @Override
29 | public void getAsString(ResponseListener rs) { fail(); }
30 |
31 | @Override
32 | public Result execForString() { fail(); return new Result<>(); }
33 |
34 | @Override
35 | public void getAsJSONObject(ResponseListener rs) { fail(); }
36 |
37 | @Override
38 | public Result execForJSONObject() { fail(); return new Result<>(); }
39 |
40 | @Override
41 | public void getAsJSONArray(ResponseListener rs) { fail(); }
42 |
43 | @Override
44 | public Result execForJSONArray() { fail(); return new Result<>(); }
45 |
46 | private void fail() {
47 | if (err != null)
48 | err.onError(null, ex);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/net/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.net;
2 |
3 | import java.net.HttpURLConnection;
4 |
5 | public interface ErrorHandler {
6 | void onError(HttpURLConnection conn, Exception e);
7 | }
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/net/Networking.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.net;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 | import android.os.Handler;
7 | import android.os.Looper;
8 |
9 | import java.io.IOException;
10 | import java.net.HttpURLConnection;
11 | import java.net.URL;
12 |
13 | public class Networking {
14 |
15 | private static final int READ_TIMEOUT = 15000;
16 | private static final int CONNECT_TIMEOUT = 15000;
17 | static Handler mainHandler = new Handler(Looper.getMainLooper());
18 |
19 | private static Request request(String url, String method) {
20 | try {
21 | HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
22 | conn.setRequestMethod(method);
23 | conn.setReadTimeout(READ_TIMEOUT);
24 | conn.setConnectTimeout(CONNECT_TIMEOUT);
25 | return new Request(conn);
26 | } catch (IOException e) {
27 | return new BadRequest(e);
28 | }
29 | }
30 |
31 | public static Request get(String url) {
32 | return request(url, "GET");
33 | }
34 |
35 | public static boolean checkNetworkStatus(Context context) {
36 | ConnectivityManager manager = (ConnectivityManager)
37 | context.getSystemService(Context.CONNECTIVITY_SERVICE);
38 | NetworkInfo networkInfo = manager.getActiveNetworkInfo();
39 | return networkInfo != null && networkInfo.isConnected();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/stub/src/main/java/com/topjohnwu/magisk/net/ResponseListener.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.net;
2 |
3 | public interface ResponseListener {
4 | void onResponse(T response);
5 | }
6 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ar/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | عليك بتحديث ماجيسك لإكمال تهيئة التطبيق. هل تريد التنزيل والتثبيت؟
4 | يرجى الإتصال بالإنترنت! تحديث ماجيسك مطلوب.
5 | جارٍ التنزيل
6 | يرجى إعادة تشغيل التطبيق يدوياً
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ast/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Instala la versión completa de Magisk pa finar la configuración. ¿Quies facelo agora?
4 | ¡Conéctate a internet! Tienes d\'instalar la versión completa de Magisk.
5 | Baxando
6 | Volvi llanzar l\'aplicación manualmente
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-az/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Qurmanı sonlandırmaq üçün full Magisk Manager`ə yüksəldin. Yüklənib qurulsun?
3 | Lütfən internetə qoşulun! Full Magisk Manager\'ə yüksəltmə lazımidir.
4 |
5 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-be/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Абнавіце Magisk Manager для завяршэння ўсталёўкі. Спампаваць і ўсталяваць?
4 | Калі ласка, падлучыцеся да інтэрнэту! Патрабуецца абнаўленне Magisk Manager.
5 | Спампоўванне
6 | Калі ласка, уласнаручна перазапусціце праграму
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-bg/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Надградете до пълната версия на Magisk Manager, за да довършите първоначалната настройка. Изтегляне и инсталиране сега?
3 | Моля да се свържете към работеща интернет мрежа, защото надграждането до пълната версия на Magisk Manager е задължително.
4 |
5 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ca/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Fes una actualització total de Magisk Manager per finalitzar l\'instal·lació. Descarregar i instal·lar?
4 | Si us plau, connecta\'t a internet! Es necessari fer una actualització total de Magisk Manager.
5 | Baixant
6 | Torni a obrir l\'aplicació manualment, si us plau
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-cs/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Upgrade zum vollständigen Magisk Manager, um das Setup abzuschließen. Herunterladen und installieren?
3 | Bitte Internetverbindung herstellen! Das Upgrade zum vollständigen Magisk Manager ist erforderlich.
4 | Herunterladen...
5 | Bitte starte die App manuell neu!
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-el/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Actualiza a la versión completa de Magisk para finalizar la instalación. ¿Descargar e instalar?
3 | Sin conexión disponible
4 | Descargando...
5 | Por favor, relanza la app
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-et/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Täienda seadistuse lõpetamiseks Magiski täisversioonile. Kas laadid alla ja installid?
4 | Palun ühendu Internetti! Nõutud on Magiski täisversioonile täiendamine.
5 | Allalaadimine
6 | Palun käivita rakendus käsitsi uuesti
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-fa/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | برای به پایان رساندن تنظیمات ، به نسخه کامل Magisk Manager ارتقا دهید. دانلود و نصب بشه؟
4 | لطفاً به اینترنت متصل شوید! برای ارتقا به نسخه کامل Magisk Manager لازم است.
5 | درحال دانلود
6 | لطفاً به صورت دستی برنامه را دوباره راه اندازی کنید
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Une mise à niveau de Magisk Manager en version complète est nécessaire afin de terminer l’installation. Souhaitez‑vous procéder à son téléchargement et son installation ?
4 | Veuillez vous connecter à Internet ! Une mise à niveau complète de Magisk Manager est requise.
5 | Téléchargement en cours
6 | Veuillez relancer manuellement l’application
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-hi/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | सेटअप को पूरा करने के लिए पूर्ण मैजिस्क मैनेजर में अपग्रेड करें. डाउनलोड करके इंस्टॉल करें?
4 | कृपया इन्टरनेट से जुड़िये! पूर्ण मैजिस्क मैनेजर में अपग्रेड की आवश्यकता है।
5 | डाउनलोड हो रहा है
6 | कृपया ऐप को फिर से शुरू करें
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-hr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Nadogradite na full Magisk Manager da biste dovršili postavljanje. Preuzeti i instalirati?
4 | Povežite se na Internet! Potrebna je nadogradnja na full Magisk Manager.
5 | Preuzimanje
6 | Ručno ponovno pokrenite aplikaciju
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-hu/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | A telepítés befejezéséhez frissíts a teljes Magiskre. Letöltés és telepítés?
4 | Csatlakozz az internethez! Frissíteni kell a teljes Magiskre.
5 | Letöltés
6 | Kérjük manuálisan indítsd újra az alkalmazást
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-in/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tingkatkan Magisk Manager ke versi utuh untuk menyelesaikan penyiapan. Download dan instal?
4 | Harap sambungkan ke Internet! Peningkatan Magisk Manager versi utuh diperlukan.
5 | Mendownload
6 | Buka kembali aplikasi secara manual
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Aggiorna alla versione completa di Magisk per completare l\'installazione. Vuoi procedere con il download e l\'installazione?
3 | Controlla la connessione a Internet! È necessaria per l\'aggiornamento alla versione completa di Magisk.
4 | Download in corso
5 | Riavvia manualmente l\'app
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-iw/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | יש לעדכן לגירסה מלאה של מנהל Magisk בכדי לסיים את העדכון. להוריד ולהתקין?
4 | נא להתחבר לאינטרנט! עדכון לגירסה מלאה של מנהל Magisk נדרש.
5 | מוריד
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Magisk Manager のフルバージョンにアップグレードしてセットアップを完了します。ダウンロードしてインストールしますか?
3 | ダウンロード中
4 | インターネットに接続してください!フルバージョンの Magisk Manager が必要です。
5 |
6 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ka/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | განაახლეთ სრულ Magisk მენჯერის ვერსიამდე ინსტალაციის დასასრულებლად. გსურთ გადმოწერა და ინსტალირება?
4 | გთხოვთ დაუკავშირდით ინტერნეტს! საჭიროა Magisk მენეჯერის სრულ ვერსიამდე განახლება.
5 | მიმდინარეობს გადმოწერა
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-kk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Орнатуды аяқтау үшін Magisk қолданбасының толық нұсқасын жүктеп алу керек. Жалғастырасыз ба?
4 | Интернетке қосылыңызшы! Magisk қолданбасын жаңарту керек.
5 | Жүктеп алуда
6 | Қолданбаны қайта қосыңыз
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 완전한 Magisk Manager로 업데이트하여 설치를 마치십시오. 다운로드하고 설치하시겠습니까?
3 | 인터넷에 연결해 주시기 바랍니다! 완전한 Magisk Manager로 업데이트 해야 합니다.
4 | 다운로드중
5 | 앱을 수동으로 재시작 하세요
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ku/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ماجیسکەکەت بەرزبکەوە بۆ وەشانی تەواوەتی، دەتەوێت دایبگریت و ڕێکیبخەیت؟
4 | تکایە پەیوەست ببە بە ئینتەرنێتەوە، پێویستە ماجیسکەکەت ڕێک بخەیت.
5 | داگرتن
6 | تکایە دووبارە ئەپەکە بکەوە
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-lt/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Atsinaujinkite į pilną Magisk Manager versiją, kad baigtumėte pasiruošimą. Atsisiųsti ir instaliuoti?
3 | Prašome prisijungti prie interneto! Atsinaujinimas į pilną Magisk Manager versiją yra privalomas.
4 |
5 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-mk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Надградете до целосната верзија на Magisk Manager за да го завршите поставувањето. Преземете и инсталирајте?
3 | Ве молиме поврзете се на интернет бидејќи е потребна надградба на целосната верзија на Magisk Manager.
4 |
5 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ml/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | സജ്ജീകരണം പൂർത്തിയാക്കാൻ പൂർണ്ണ മജിസ്കിലേക്ക് അപ്ഗ്രേഡ് ചെയ്യുക. ഡൗൺലോഡ് ചെയ്ത് ഇൻസ്റ്റാൾ ചെയ്യണോ?
4 | ദയവായി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റുചെയ്യുക! പൂർണ്ണ മജിസ്കിലേക്ക് അപ്ഗ്രേഡ് ചെയ്യേണ്ടതുണ്ട്.
5 | ഡൗൺലോഡ് ചെയ്യുന്നു
6 | ആപ്പ് സ്വമേധയാ വീണ്ടും തുറക്കുക
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-nb/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Oppgrader til den komplette versjonen av Magisk Manager for å fullføre oppsettet. Vil du laste ned og installere?
4 | Vennligst koble deg på internettet! Å oppgradere til den komplette versjonen av Magisk Manager er påkrevd.
5 |
6 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-nl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Installeer de volledige Magisk Manager om de installatie af te ronden. Wil je dit nu doen?
4 | Maak verbinding met het internet! Het installeren van de volledige Magisk Manager is vereist.
5 | Bezig met downloaden...
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-pa/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ਸੈਟਅਪ ਨੂੰ ਪੂਰਾ ਕਰਨ ਲਈ ਪੂਰੇ ਮੈਜਿਕਸ ਮੈਨੇਜਰ ਵਿਚ ਅਪਗ੍ਰੇਡ ਕਰੋ. ਡਾਉਨਲੋਡ ਅਤੇ ਇੰਸਟੌਲ ਕਰੋ?
4 | ਕਿਰਪਾ ਕਰਕੇ ਇੰਟਰਨੈਟ ਨਾਲ ਜੁੜੋ! ਪੂਰਾ ਮੈਜਿਕਸ ਮੈਨੇਜਰ ਅਪਗ੍ਰੇਡ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।
5 | ਡਾਊਨਲੋਡ ਹੋ ਰਿਹਾ ਹੈ
6 | ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰੋ
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-pl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Zaktualizuj Magisk do pełnej wersji aby ukończyć instalację. Pobrać i zainstalować?
4 | Połącz się z Internetem! Wymagane jest uaktualnienie Magisk do pełnej wersji.
5 | Pobieranie
6 | Proszę ręcznie uruchomić aplikację ponownie.
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Atualize para o Magisk completo para finalizar a configuração. Deseja baixar e instalar?
4 | Por favor, conecte-se à internet! É necessário atualizar para o Magisk completo.
5 | Baixando
6 | Por favor, reinicie o app manualmente.
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-pt-rPT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Atualize para o Magisk completo para finalizar a configuração. Deseja baixar e instalar?
4 | Por favor, conecte-se à internet! É necessário atualizar para o Magisk completo.
5 | Baixando
6 | Por favor, reinicie o app manualmente.
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ro/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Treci la versiunea completă Magisk pentru a finaliza configurarea. Descarci și instalezi?
4 | Te rugăm să te conectezi la internet! Este necesară actualizarea la versiunea completă Magisk.
5 | Se descarcă
6 | Te rugăm să relansezi manual aplicația
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Обновите Magisk для завершения установки. Продолжить?
3 | Пожалуйста, подключитесь к Интернету! Требуется обновление Magisk.
4 | Загрузка
5 | Пожалуйста, перезапустите приложение
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-sk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pre dokončenie inštalácie sa vyžaduje upgrade Magisk Managera. Stiahnuť a nainštalovať?
4 | Pripojte sa na internet! Upgrade Magisk Managera je potrebný.
5 | Sťahuje sa
6 | Zavrite a spustite apku manuálne
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-sq/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Përditësoni Magisk në versionin e plotë për të përfunduar konfigurimin. Shkarkoni dhe instaloni?
4 | Ju lutemi lidhuni me internetin! Kërkohet internet për të shkarkuar Magisk në versionin e plotë.
5 | Duke shkarkuar
6 | Ju lutemi, ri-hapni aplikacionin manualisht
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-sr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ажурирајте Magisk да бисте завршили постављање. Преузми и инсталирај?
4 | Молимо повежите се на интернет! Неопходно је ажурирање Magisk-а.
5 | Преузимање
6 | Молимо покрените апликацију поново
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-sv/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-sw/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pata toleo jipya la Magisk kamili ili kumaliza usanidi. Pakua na usakinishe?
4 | Tafadhali unganisha kwenye Mtandao! Kusasisha hadi Magisk kamili inahitajika.
5 | Inapakua
6 | Tafadhali zindua upya programu wewe mwenyewe
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-ta/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | அமைப்பை முடிக்க முழு மேகிஸ்க்கு மேம்படுத்தவும். பதிவிறக்கி நிறுவவா?
4 | இணையத்துடன் இணைக்கவும்! முழு மேகிஸ்க்கு மேம்படுத்தல் தேவை.
5 | பதிவிறக்குகிறது
6 | பயன்பாட்டை கைமுறையாக மீண்டும் தொடங்கவும்
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-th/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-tr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Kurulumu tamamlamak için tam Magisk Manager\'a yükseltin. İndirip yüklensin mi?
4 | Lütfen internete bağlanın! Magisk Manager\'ın tam sürümüne yükseltmek gerekiyor.
5 | İndiriliyor
6 | Lütfen uygulamayı el ile yeniden açınız.
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-uk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Оновіть додаток Magisk для завершення встановлення. Завантажити і встановити?
4 | Будь ласка, підключіться до Інтернету! Потрібно оновити додаток Magisk.
5 | Завантаження
6 |
7 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-vi/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 需要下载完整版 Magisk 才能正常运行。开始下载?
4 | 下载需要网络,请检查网络连接。
5 | 正在下载
6 | 请重新打开本应用
7 |
8 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 需要升級到完整版 Magisk Manager。是否下載並安裝?
3 | 請連上網路!升級到完整版 Magisk Manager 是必須的。
4 | 正在下載
5 |
6 |
--------------------------------------------------------------------------------
/app/stub/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Upgrade to full Magisk to finish the setup. Download and install?
4 | Please connect to the Internet! Upgrading to full Magisk is required.
5 | Downloading
6 | Please manually re-launch the app
7 |
8 |
--------------------------------------------------------------------------------
/app/test/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | kotlin("android")
4 | }
5 |
6 | android {
7 | namespace = "com.topjohnwu.magisk.test"
8 |
9 | defaultConfig {
10 | applicationId = "com.topjohnwu.magisk.test"
11 | versionCode = 1
12 | versionName = "1.0"
13 | proguardFile("proguard-rules.pro")
14 | }
15 |
16 | buildTypes {
17 | release {
18 | isMinifyEnabled = true
19 | }
20 | }
21 | }
22 |
23 | setupTestApk()
24 |
25 | dependencies {
26 | implementation(libs.test.runner)
27 | implementation(libs.test.rules)
28 | implementation(libs.test.junit)
29 | implementation(libs.test.uiautomator)
30 | }
31 |
--------------------------------------------------------------------------------
/app/test/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Keep all test dependencies
2 | -keep class org.junit.** { *; }
3 | -keep class androidx.test.** { *; }
4 |
5 | # Make sure the classloader constructor is kept
6 | -keepclassmembers class com.topjohnwu.magisk.test.TestClassLoader { (); }
7 |
8 | # Repackage dependencies
9 | -repackageclasses 'deps'
10 | -allowaccessmodification
11 |
12 | # Keep attributes for stacktrace
13 | -keepattributes *
14 |
--------------------------------------------------------------------------------
/app/test/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/test/src/main/java/com/topjohnwu/magisk/test/Runners.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.test
2 |
3 | import android.os.Bundle
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import androidx.test.runner.AndroidJUnitRunner
6 |
7 | open class TestRunner : AndroidJUnitRunner() {
8 | override fun onCreate(arguments: Bundle) {
9 | // Support short-hand ".ClassName"
10 | arguments.getString("class")?.let {
11 | val classArg = it.split(",").joinToString(separator = ",") { clz ->
12 | if (clz.startsWith(".")) {
13 | "com.topjohnwu.magisk.test$clz"
14 | } else {
15 | clz
16 | }
17 | }
18 | arguments.putString("class", classArg)
19 | }
20 | super.onCreate(arguments)
21 | }
22 | }
23 |
24 | class AppTestRunner : TestRunner() {
25 | override fun onCreate(arguments: Bundle) {
26 | // Force using the target context's classloader to run tests
27 | arguments.putString("classLoader", TestClassLoader::class.java.name)
28 | super.onCreate(arguments)
29 | }
30 | }
31 |
32 | private val targetClassLoader inline get() =
33 | InstrumentationRegistry.getInstrumentation().targetContext.classLoader
34 |
35 | class TestClassLoader : ClassLoader(targetClassLoader)
36 |
--------------------------------------------------------------------------------
/config.prop.sample:
--------------------------------------------------------------------------------
1 | ##########################################################
2 | # All variables in config.prop are optional
3 | # Removing or leaving them blank will keep default values
4 | ##########################################################
5 |
6 | # The version name of Magisk. Default: git HEAD short SHA1
7 | version=string
8 |
9 | # Output path. Default: out
10 | outdir=string
11 |
12 | # List of ABIs to build, separated with ','
13 | # Default: armeabi-v7a,x86,arm64-v8a,x86_64
14 | abiList=[string]
15 |
16 | #####################################################
17 | # Signing configs for signing zips and APKs
18 | # These 4 variables has to be either all set or not
19 | #####################################################
20 |
21 | # Path to keystore file
22 | keyStore=string
23 | # Keystore password
24 | keyStorePass=string
25 | # The desired key alias in the keystore
26 | keyAlias=string
27 | # Password of specified key alias
28 | keyPass=string
29 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Magisk Documentation
2 |
3 | - [Installation Instructions](install.md)
4 | - [Frequently Asked Questions](faq.md)
5 | - [Release Notes](releases/index.md)
6 | - [Magisk Changelog](changes.md)
7 |
8 | The following sections are for developers
9 |
10 | - [Building and Developing Magisk](build.md) (for developing Magisk itself)
11 | - [Developer Guides](guides.md) (for developers **using** Magisk)
12 | - [Magisk Tools](tools.md)
13 | - [Internal Details](details.md)
14 | - [Android Booting Shenanigans](boot.md)
15 |
--------------------------------------------------------------------------------
/docs/images/device_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/device_info.png
--------------------------------------------------------------------------------
/docs/images/disable_auto_ota.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/disable_auto_ota.png
--------------------------------------------------------------------------------
/docs/images/install_inactive_slot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/install_inactive_slot.png
--------------------------------------------------------------------------------
/docs/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/logo.png
--------------------------------------------------------------------------------
/docs/images/manager_reboot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/manager_reboot.png
--------------------------------------------------------------------------------
/docs/images/ota_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/ota_done.png
--------------------------------------------------------------------------------
/docs/images/restore_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvb2060/Magisk/b1dc47a047f134f87943eb424309356d22091db5/docs/images/restore_img.png
--------------------------------------------------------------------------------
/docs/releases/19100.md:
--------------------------------------------------------------------------------
1 | # 2019.5.1 Magisk v19.1
2 | Finally, a lovely stable release!
3 |
4 | For those that were using v18.1, here are some quick highlights of v19.0
5 |
6 | - Imageless Magisk: Although module migration was tested, there are still chances that your modules will get lost in the process. Be prepared to reinstall your existing modules in that case.
7 | - Native 64-bit support
8 | - Zygote Ptrace Based MagiskHide
9 |
10 | Other than adding support for Samsung system-as-root devices, this release is mostly bug fixes from v19.0. Enjoy :)
11 |
12 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
13 |
--------------------------------------------------------------------------------
/docs/releases/19200.md:
--------------------------------------------------------------------------------
1 | # TODO
2 |
--------------------------------------------------------------------------------
/docs/releases/19300.md:
--------------------------------------------------------------------------------
1 | # TODO
2 |
--------------------------------------------------------------------------------
/docs/releases/20300.md:
--------------------------------------------------------------------------------
1 | # 2020.1.10 Magisk v20.3
2 |
3 | ### Magisk
4 | - Fix `magiskboot` crashing when dealing with `lz4_legacy` format
5 |
6 | ### Magisk Manager
7 | - Fix MagiskHide app component toggles
8 |
9 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
10 |
--------------------------------------------------------------------------------
/docs/releases/21100.md:
--------------------------------------------------------------------------------
1 | ## 2020.11.13 Magisk v21.1
2 |
3 | v21.1 is a maintenance update from v21.0, mostly addressing bugs, refining some details, and adding new boot image format support (for Pixel 5 and 4a 5G). Checkout the full [v21.0 release notes](https://topjohnwu.github.io/Magisk/releases/21000.html) if coming from older releases.
4 |
5 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
6 |
--------------------------------------------------------------------------------
/docs/releases/21200.md:
--------------------------------------------------------------------------------
1 | ## 2020.12.28 Magisk v21.2
2 |
3 | v21.2 is a maintenance update, mostly addressing bugs, and expanding device compatibility. Checkout the full [v21.0 release notes](https://topjohnwu.github.io/Magisk/releases/21000.html) if coming from older releases.
4 |
5 | ### v21.2
6 |
7 | - [MagiskInit] Detect 2SI after mounting `system_root` on legacy SAR devices
8 | - [General] Make sure `post-fs-data` scripts cannot block more than 35 seconds
9 | - [General] Fix the `magisk --install-module` command
10 | - [General] Trim Windows newline when reading files
11 | - [General] Directly log to file to prevent `logcat` weirdness
12 | - [MagiskBoot] Fix header dump/load for header v3 images
13 |
14 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
15 |
--------------------------------------------------------------------------------
/docs/releases/21400.md:
--------------------------------------------------------------------------------
1 | ## 2021.1.17 Magisk v21.4
2 |
3 | **Update**: v21.4 adds more regression hot fixes.
4 |
5 | Happy 2021! v21.3 adds a workaround for devices with buggy F2FS Linux kernel drivers. This F2FS bug may cause bootloops on many devices. Checkout the full [v21.0 release notes](https://topjohnwu.github.io/Magisk/releases/21000.html) if coming from older releases.
6 |
7 | ### v21.4
8 |
9 | - [MagiskSU] Fix `su -c` behavior that broke many root apps
10 | - [General] Properly handle read/write over sockets (the `broken pipe` issue)
11 |
12 | ### v21.3
13 |
14 | - [MagiskInit] Avoid mounting `f2fs` userdata as it may result in kernel crashes. This shall fix a lot of bootloops
15 | - [MagiskBoot] Fix a minor header checksum bug for `DHTB` header and ASUS `blob` image formats
16 | - [MagiskHide] Allowing hiding isolated processes if the mount namespace is separated
17 |
18 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
19 |
--------------------------------------------------------------------------------
/docs/releases/22100.md:
--------------------------------------------------------------------------------
1 | ## 2021.4.9 Magisk v22.1
2 |
3 | This release is focused on fixing regressions and bugs. Check the [v22.0 release notes](https://topjohnwu.github.io/Magisk/releases/22000.html) if coming from older releases.
4 |
5 | Note: Magisk v22 is the last major version to support Jellybean and Kitkat. Magisk v23 will only support Android 5.0 and higher.
6 |
7 | ### Bug Fixes
8 |
9 | - [App] Prevent multiple installation sessions running in parallel
10 | - [App] Prevent OutOfMemory crashes when checking boot signature on PXA boot images
11 | - [General] Proper cgroup migration implementation
12 | - [General] Rewrite log writer from scratch, should resolve any crashes and deadlocks
13 | - [General] Many scripts updates fixing regressions
14 | - [MagiskHide] Prevent possible deadlock when signal arrives
15 | - [MagiskHide] Partial match process names if necessary
16 | - [MagiskBoot] Preserve and patch AVB 2.0 structures/headers in boot images
17 | - [MagiskBoot] Properly strip out data encryption flags
18 | - [MagiskBoot] Prevent possible integer overflow
19 | - [MagiskInit] Fix `sepolicy.rule` mounting strategy
20 | - [resetprop] Always delete existing `ro.` props before updating. This will fix bootloops that could be caused by modifying device fingerprint properties.
21 |
22 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
23 |
--------------------------------------------------------------------------------
/docs/releases/23000.md:
--------------------------------------------------------------------------------
1 | ## 2021.5.12 Magisk v23.0
2 |
3 | This release is focused on fixing regressions and bugs.
4 |
5 | Note: Magisk v22 is the last major version to support Jellybean and Kitkat. Magisk v23 only supports Android 5.0 and higher.
6 |
7 | ### Bug Fixes
8 |
9 | - [App] Update snet extension. This fixes SafetyNet API errors.
10 | - [App] Fix a bug in the stub app that causes APK installation to fail
11 | - [App] Hide annoying errors in logs when hidden as stub
12 | - [App] Fix issues when patching ODIN tar files when the app is hidden
13 | - [General] Remove all pre Android 5.0 support
14 | - [General] Update BusyBox to use proper libc
15 | - [General] Fix C++ undefined behaviors
16 | - [General] Several `sepolicy.rule` copy/installation fixes
17 | - [MagiskPolicy] Remove unnecessary sepolicy rules
18 | - [MagiskHide] Update package and process name validation logic
19 | - [MagiskHide] Some changes that prevents zygote deadlock
20 |
21 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
22 |
--------------------------------------------------------------------------------
/docs/releases/24200.md:
--------------------------------------------------------------------------------
1 | ## 2022.3.1 Magisk v24.2
2 |
3 | Maintenance release fixing various issues.
4 |
5 | - [MagiskSU] Fix buffer overflow
6 | - [MagiskSU] Fix owner managed multiuser superuser settings
7 | - [MagiskSU] Fix command logging when using `su -c `
8 | - [MagiskSU] Prevent su request indefinite blocking
9 | - [MagiskBoot] Support `lz4_legacy` archive with multiple magic
10 | - [MagiskBoot] Fix `lz4_lg` compression
11 | - [DenyList] Allow targeting processes running as system UID
12 | - [Zygisk] Workaround Samsung's "early zygote"
13 | - [Zygisk] Improved Zygisk loading mechanism
14 | - [Zygisk] Fix application UID tracking
15 | - [Zygisk] Fix improper `umask` being set in zygote
16 | - [App] Fix BusyBox execution test
17 | - [App] Improve stub loading mechanism
18 | - [App] Major app upgrade flow improvements
19 | - [General] Improve commandline error handling and messaging
20 |
21 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
22 |
--------------------------------------------------------------------------------
/docs/releases/24300.md:
--------------------------------------------------------------------------------
1 | ## 2022.3.10 Magisk v24.3
2 |
3 | For those coming from v24.1, check the full changelog for changes introduced in v24.2.
4 |
5 | - [General] Stop using `getrandom` syscall
6 | - [Zygisk] Update API to v3, adding new fields to `AppSpecializeArgs`
7 | - [App] Improve app repackaging installation workflow
8 |
9 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
10 |
--------------------------------------------------------------------------------
/docs/releases/25200.md:
--------------------------------------------------------------------------------
1 | ## 2022.7.20 Magisk v25.2
2 |
3 | Maintenance release fixing various issues.
4 |
5 | - [MagiskInit] Fix a potential issue when stub cpio is used
6 | - [MagiskInit] Fix reboot to recovery when stub cpio is used
7 | - [MagiskInit] Fix sepolicy.rules symlink for rootfs devices
8 | - [General] Better data encryption detection
9 | - [General] Move the whole logging infrastructure into Rust
10 |
11 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
12 |
--------------------------------------------------------------------------------
/docs/releases/26200.md:
--------------------------------------------------------------------------------
1 | ## 2023.8.27 Magisk v26.2
2 |
3 | - [MagiskBoot] Support extracting boot image from `payload.bin`
4 | - [MagiskBoot] Support cpio files containing character files
5 | - [MagiskBoot] Support listing cpio content
6 | - [MagiskBoot] Directly handle AVB 1.0 signing and verification without going through Java implementation
7 | - [Daemon] Make daemon socket a fixed path in MAGISKTMP
8 | - [resetprop] Support printing property context
9 | - [resetprop] Support only printing persistent properties from storage
10 | - [resetprop] Properly support setting persistent properties bypassing property_service
11 | - [MagiskSU] Support `-g` and `-G` options
12 | - [MagiskSU] Support switching mount namespace to PID with `-t`
13 | - [MagiskPolicy] Fix patching extended permissions
14 | - [MagiskPolicy] Support more syntax for extended permissions
15 | - [MagiskPolicy] Support printing out the loaded sepolicy rules
16 | - [App] Support patching boot image from ROM zips
17 | - [App] Properly preserve `boot.img` when patching Samsung firmware with `init_boot.img`
18 |
19 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
20 |
--------------------------------------------------------------------------------
/docs/releases/26300.md:
--------------------------------------------------------------------------------
1 | ## 2023.9.4 Magisk v26.3
2 |
3 | ### v26.3
4 |
5 | - [General] Fix device information detection script
6 | - [General] Update BusyBox to 1.36.1
7 | - [General] Update toolchain that produces broken arm32 executables
8 | - [App] Fix root service unable to bind on OnePlus devices
9 |
10 | ### v26.2
11 |
12 | - [MagiskBoot] Support extracting boot image from `payload.bin`
13 | - [MagiskBoot] Support cpio files containing character files
14 | - [MagiskBoot] Support listing cpio content
15 | - [MagiskBoot] Directly handle AVB 1.0 signing and verification without going through Java implementation
16 | - [Daemon] Make daemon socket a fixed path in MAGISKTMP
17 | - [resetprop] Support printing property context
18 | - [resetprop] Support only printing persistent properties from storage
19 | - [resetprop] Properly support setting persistent properties bypassing property_service
20 | - [MagiskSU] Support `-g` and `-G` options
21 | - [MagiskSU] Support switching mount namespace to PID with `-t`
22 | - [MagiskPolicy] Fix patching extended permissions
23 | - [MagiskPolicy] Support more syntax for extended permissions
24 | - [MagiskPolicy] Support printing out the loaded sepolicy rules
25 | - [App] Support patching boot image from ROM zips
26 | - [App] Properly preserve `boot.img` when patching Samsung firmware with `init_boot.img`
27 |
28 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
29 |
--------------------------------------------------------------------------------
/docs/releases/26400.md:
--------------------------------------------------------------------------------
1 | ## 2023.11.5 Magisk v26.4
2 |
3 | - [MagiskBoot] Don't pad zeros if signed boot image is larger
4 | - [MagiskPolicy] Fix `genfscon` and `filename_trans`
5 | - [MagiskPolicy] Fix bug in `libsepol`
6 | - [Zygisk] Fix and simplify file descriptor sanitization logic
7 | - [App] Prevent OOM when patching AP tarfiles
8 | - [App] Fix bug in device configuration detection
9 | - [Daemon] Fix certificate parsing of APKs
10 | - [General] Fix logging errors from C++ code being ignored
11 |
12 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
13 |
--------------------------------------------------------------------------------
/docs/releases/27000.md:
--------------------------------------------------------------------------------
1 | ## 2024.2.3 Magisk v27.0
2 |
3 | - [Zygisk] Introduce new code injection mechanism
4 | - [Zygisk] Support new signature introduced in U QPR2
5 | - [SEPolicy] Update libsepol to properly set some policy config bits
6 | - [MagiskBoot] Support compressing `init` so Magisk is installable on devices with small boot partitions
7 | - [ResetProp] Add new wait for property feature `resetprop -w`
8 |
9 | ### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
10 |
--------------------------------------------------------------------------------
/docs/releases/index.md:
--------------------------------------------------------------------------------
1 | # Release Notes
2 |
3 | - [v29.0](29000.md)
4 | - [v28.1](28100.md)
5 | - [v28.0](28000.md)
6 | - [v27.0](27000.md)
7 | - [v26.4](26400.md)
8 | - [v26.3](26300.md)
9 | - [v26.2](26200.md)
10 | - [v26.1](26100.md)
11 | - [v26.0](26000.md)
12 | - [v25.2](25200.md)
13 | - [v25.1](25100.md)
14 | - [v25.0](25000.md)
15 | - [v24.3](24300.md)
16 | - [v24.2](24200.md)
17 | - [v24.1](24100.md)
18 | - [v24.0](24000.md)
19 | - [v23.0](23000.md)
20 | - [v22.1](22100.md)
21 | - [v22.0](22000.md)
22 | - [v21.4](21400.md)
23 | - [v21.2](21200.md)
24 | - [v21.1](21100.md)
25 | - [v21.0](21000.md)
26 | - [v20.4](20400.md)
27 | - [v20.3](20300.md)
28 | - [v20.2](20200.md)
29 | - [v20.1](20100.md)
30 | - [v20.0](20000.md)
31 | - [v19.4](19400.md)
32 | - [v19.3](19300.md)
33 | - [v19.2](19200.md)
34 | - [v19.1](19100.md)
35 | - [v19.0](19000.md)
36 | - [v18.1](18100.md)
37 | - [v18.0](18000.md)
38 |
--------------------------------------------------------------------------------
/native/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | obj
3 | libs
4 | /.externalNativeBuild
5 | /.cxx
6 | *-rs.cpp
7 | *-rs.hpp
8 | /compile_commands.json
9 |
--------------------------------------------------------------------------------
/native/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | }
4 |
5 | setupCommon()
6 |
7 | android {
8 | namespace = "com.topjohnwu.magisk.binary"
9 |
10 | externalNativeBuild {
11 | ndkBuild {
12 | path("src/Android.mk")
13 | }
14 | }
15 |
16 | sourceSets.getByName("main") {
17 | manifest.srcFile("src/AndroidManifest.xml")
18 | }
19 |
20 | defaultConfig {
21 | externalNativeBuild {
22 | ndkBuild {
23 | // Pass arguments to ndk-build.
24 | arguments(
25 | "B_MAGISK=1", "B_INIT=1", "B_BOOT=1", "B_POLICY=1",
26 | "B_PRELOAD=1", "B_PROP=1", "B_CRT0=1"
27 | )
28 | abiFilters("armeabi-v7a", "arm64-v8a", "x86", "x86_64", "riscv64")
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/native/src/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | # Set arm64 as the default target
3 | # The actual compilation will have the target overriden by command-line.
4 | target = "aarch64-linux-android"
5 | # Enable cross language LTO, and explicitly set dwarf-version for ThinLTO
6 | rustflags = ["-Z", "dwarf-version=4", "-C", "linker-plugin-lto"]
7 | target-dir = "../out/rust"
8 |
9 | [unstable]
10 | build-std = ["std", "panic_abort"]
11 | build-std-features = ["panic_immediate_abort", "optimize_for_size"]
12 | profile-rustflags = true
13 |
--------------------------------------------------------------------------------
/native/src/Android-rs.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | ###########################
4 | # Rust compilation outputs
5 | ###########################
6 |
7 | include $(CLEAR_VARS)
8 | LOCAL_MODULE := magisk-rs
9 | LOCAL_EXPORT_C_INCLUDES := src/core/include
10 | LOCAL_LIB = ../out/$(TARGET_ARCH_ABI)/libmagisk-rs.a
11 | ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_LIB)))
12 | LOCAL_SRC_FILES := $(LOCAL_LIB)
13 | include $(PREBUILT_STATIC_LIBRARY)
14 | else
15 | include $(BUILD_STATIC_LIBRARY)
16 | endif
17 |
18 | include $(CLEAR_VARS)
19 | LOCAL_MODULE := boot-rs
20 | LOCAL_LIB = ../out/$(TARGET_ARCH_ABI)/libmagiskboot-rs.a
21 | ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_LIB)))
22 | LOCAL_SRC_FILES := $(LOCAL_LIB)
23 | include $(PREBUILT_STATIC_LIBRARY)
24 | else
25 | include $(BUILD_STATIC_LIBRARY)
26 | endif
27 |
28 | include $(CLEAR_VARS)
29 | LOCAL_MODULE := init-rs
30 | LOCAL_LIB = ../out/$(TARGET_ARCH_ABI)/libmagiskinit-rs.a
31 | ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_LIB)))
32 | LOCAL_SRC_FILES := $(LOCAL_LIB)
33 | include $(PREBUILT_STATIC_LIBRARY)
34 | else
35 | include $(BUILD_STATIC_LIBRARY)
36 | endif
37 |
38 | include $(CLEAR_VARS)
39 | LOCAL_MODULE := policy-rs
40 | LOCAL_LIB = ../out/$(TARGET_ARCH_ABI)/libmagiskpolicy-rs.a
41 | ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_LIB)))
42 | LOCAL_SRC_FILES := $(LOCAL_LIB)
43 | include $(PREBUILT_STATIC_LIBRARY)
44 | else
45 | include $(BUILD_STATIC_LIBRARY)
46 | endif
47 |
--------------------------------------------------------------------------------
/native/src/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/native/src/Application.mk:
--------------------------------------------------------------------------------
1 | APP_BUILD_SCRIPT := src/Android.mk
2 | APP_CFLAGS := -Wall -Oz -fomit-frame-pointer
3 | APP_CPPFLAGS := -std=c++23
4 | APP_STL := none
5 | APP_PLATFORM := android-23
6 | APP_THIN_ARCHIVE := true
7 | APP_STRIP_MODE := none
8 |
9 | ifdef MAGISK_DEBUG
10 |
11 | NDK_APP_OUT := ./obj/debug
12 | APP_CFLAGS += -flto=thin -gdwarf-4
13 | APP_LDFLAGS += -flto=thin
14 |
15 | else
16 |
17 | NDK_APP_OUT := ./obj/release
18 | APP_CFLAGS += -flto
19 | APP_LDFLAGS += -flto -Wl,--icf=all
20 |
21 | endif
22 |
23 | ifdef B_CRT0
24 |
25 | # Disable all security and debugging features
26 | APP_CFLAGS += -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-protector -fno-threadsafe-statics -U_FORTIFY_SOURCE
27 | # Override output folder to make sure all dependencies are rebuilt with new CFLAGS
28 | NDK_APP_OUT := $(NDK_APP_OUT)-nolibc
29 |
30 | endif
31 |
--------------------------------------------------------------------------------
/native/src/base/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | # Magisk project-wide common code
4 |
5 | include $(CLEAR_VARS)
6 | LOCAL_MODULE := libbase
7 | LOCAL_C_INCLUDES := \
8 | src/include \
9 | $(LOCAL_PATH)/include \
10 | src/external/cxx-rs/include \
11 | out/generated
12 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
13 | LOCAL_EXPORT_STATIC_LIBRARIES := libcxx
14 | LOCAL_STATIC_LIBRARIES := libcxx
15 | LOCAL_CFLAGS := -DRUST_CXX_NO_EXCEPTIONS
16 | LOCAL_SRC_FILES := \
17 | new.cpp \
18 | files.cpp \
19 | misc.cpp \
20 | logging.cpp \
21 | stream.cpp \
22 | base-rs.cpp \
23 | ../external/cxx-rs/src/cxx.cc
24 | include $(BUILD_STATIC_LIBRARY)
25 |
--------------------------------------------------------------------------------
/native/src/base/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "base"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [lib]
7 | path = "lib.rs"
8 |
9 | [features]
10 | selinux = []
11 | dyn_selinux = []
12 |
13 | [build-dependencies]
14 | cxx-gen = { workspace = true }
15 |
16 | [dependencies]
17 | cxx = { workspace = true }
18 | libc = { workspace = true }
19 | cfg-if = { workspace = true }
20 | thiserror = { workspace = true }
21 | argh = { workspace = true }
22 | bytemuck = { workspace = true }
23 | num-traits = { workspace = true }
24 | num-derive = { workspace = true }
25 | const_format = { workspace = true }
26 |
--------------------------------------------------------------------------------
/native/src/base/build.rs:
--------------------------------------------------------------------------------
1 | use crate::codegen::gen_cxx_binding;
2 |
3 | #[path = "../include/codegen.rs"]
4 | mod codegen;
5 |
6 | fn main() {
7 | gen_cxx_binding("base-rs");
8 | }
9 |
--------------------------------------------------------------------------------
/native/src/base/include/base.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../xwrap.hpp"
4 | #include "../files.hpp"
5 | #include "../misc.hpp"
6 | #include "../logging.hpp"
7 | #include "../base-rs.hpp"
8 |
9 | using rust::xpipe2;
10 | using rust::fd_path;
11 | using kv_pairs = std::vector>;
12 |
--------------------------------------------------------------------------------
/native/src/base/logging.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | void LOGD(const char *fmt, ...) __printflike(1, 2);
7 | void LOGI(const char *fmt, ...) __printflike(1, 2);
8 | void LOGW(const char *fmt, ...) __printflike(1, 2);
9 | void LOGE(const char *fmt, ...) __printflike(1, 2);
10 | #define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s\n", ##args, errno, std::strerror(errno))
11 |
--------------------------------------------------------------------------------
/native/src/base/new.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | /* Override libc++ new implementation
5 | * to optimize final build size */
6 |
7 | void* operator new(std::size_t s) { return std::malloc(s); }
8 | void* operator new[](std::size_t s) { return std::malloc(s); }
9 | void operator delete(void *p) { std::free(p); }
10 | void operator delete[](void *p) { std::free(p); }
11 | void* operator new(std::size_t s, const std::nothrow_t&) noexcept { return std::malloc(s); }
12 | void* operator new[](std::size_t s, const std::nothrow_t&) noexcept { return std::malloc(s); }
13 | void operator delete(void *p, const std::nothrow_t&) noexcept { std::free(p); }
14 | void operator delete[](void *p, const std::nothrow_t&) noexcept { std::free(p); }
15 |
--------------------------------------------------------------------------------
/native/src/boot/.gitignore:
--------------------------------------------------------------------------------
1 | proto/update_metadata.rs
2 | proto/mod.rs
3 |
--------------------------------------------------------------------------------
/native/src/boot/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "magiskboot"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [lib]
7 | crate-type = ["staticlib"]
8 | path = "lib.rs"
9 |
10 | [build-dependencies]
11 | cxx-gen = { workspace = true }
12 | pb-rs = { workspace = true }
13 |
14 | [dependencies]
15 | base = { path = "../base" }
16 | cxx = { workspace = true }
17 | byteorder = { workspace = true }
18 | size = { workspace = true }
19 | quick-protobuf = { workspace = true }
20 | argh = { workspace = true }
21 | sha1 = { workspace = true }
22 | sha2 = { workspace = true }
23 | digest = { workspace = true }
24 | p256 = { workspace = true }
25 | p384 = { workspace = true }
26 | p521 = { workspace = true }
27 | rsa = { workspace = true, features = ["sha2"] }
28 | x509-cert = { workspace = true }
29 | der = { workspace = true, features = ["derive", "pem"] }
30 | fdt = { workspace = true }
31 | bytemuck = { workspace = true, features = ["derive", "min_const_generics"] }
32 | num-traits = { workspace = true }
33 | libz-rs-sys = { workspace = true }
34 | libbz2-rs-sys = { workspace = true }
35 |
36 | # Pin version to prevent cargo update break builds
37 | block-buffer = { workspace = true }
38 | sec1 = { workspace = true }
39 |
--------------------------------------------------------------------------------
/native/src/boot/build.rs:
--------------------------------------------------------------------------------
1 | use pb_rs::{ConfigBuilder, types::FileDescriptor};
2 |
3 | use crate::codegen::gen_cxx_binding;
4 |
5 | #[path = "../include/codegen.rs"]
6 | mod codegen;
7 |
8 | fn main() {
9 | println!("cargo:rerun-if-changed=proto/update_metadata.proto");
10 |
11 | gen_cxx_binding("boot-rs");
12 |
13 | let cb = ConfigBuilder::new(
14 | &["proto/update_metadata.proto"],
15 | None,
16 | Some(&"proto"),
17 | &["."],
18 | )
19 | .unwrap();
20 | FileDescriptor::run(
21 | &cb.single_module(true)
22 | .dont_use_cow(true)
23 | .generate_getters(true)
24 | .build(),
25 | )
26 | .unwrap();
27 | }
28 |
--------------------------------------------------------------------------------
/native/src/boot/compress.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "format.hpp"
7 |
8 | out_strm_ptr get_encoder(format_t type, out_strm_ptr &&base);
9 | out_strm_ptr get_decoder(format_t type, out_strm_ptr &&base);
10 | void compress(const char *method, const char *infile, const char *outfile);
11 | void decompress(char *infile, const char *outfile);
12 | bool decompress(rust::Slice buf, int fd);
13 | bool xz(rust::Slice buf, rust::Vec &out);
14 | bool unxz(rust::Slice buf, rust::Vec &out);
15 |
--------------------------------------------------------------------------------
/native/src/boot/magiskboot.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 |
7 | #define HEADER_FILE "header"
8 | #define KERNEL_FILE "kernel"
9 | #define RAMDISK_FILE "ramdisk.cpio"
10 | #define VND_RAMDISK_DIR "vendor_ramdisk"
11 | #define SECOND_FILE "second"
12 | #define EXTRA_FILE "extra"
13 | #define KER_DTB_FILE "kernel_dtb"
14 | #define RECV_DTBO_FILE "recovery_dtbo"
15 | #define DTB_FILE "dtb"
16 | #define BOOTCONFIG_FILE "bootconfig"
17 | #define NEW_BOOT "new-boot.img"
18 |
19 | int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
20 | void repack(const char *src_img, const char *out_img, bool skip_comp = false);
21 | int verify(const char *image, const char *cert);
22 | int sign(const char *image, const char *name, const char *cert, const char *key);
23 | int split_image_dtb(const char *filename, bool skip_decomp = false);
24 | int dtb_commands(int argc, char *argv[]);
25 |
26 | static inline bool check_env(const char *name) {
27 | using namespace std::string_view_literals;
28 | const char *val = getenv(name);
29 | return val != nullptr && val == "true"sv;
30 | }
31 |
--------------------------------------------------------------------------------
/native/src/core/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "magisk"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [lib]
7 | crate-type = ["staticlib"]
8 | path = "lib.rs"
9 |
10 | [features]
11 | default = ["check-signature"]
12 | check-signature = []
13 |
14 | [build-dependencies]
15 | cxx-gen = { workspace = true }
16 | pb-rs = { workspace = true }
17 |
18 | [dependencies]
19 | base = { path = "../base", features = ["selinux"] }
20 | derive = { path = "derive" }
21 | cxx = { workspace = true }
22 | num-traits = { workspace = true }
23 | num-derive = { workspace = true }
24 | quick-protobuf = { workspace = true }
25 | bytemuck = { workspace = true, features = ["derive"] }
26 | thiserror = { workspace = true }
27 | bit-set = { workspace = true }
28 |
--------------------------------------------------------------------------------
/native/src/core/applet_stub.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 |
6 | int main(int argc, char *argv[]) {
7 | if (argc < 1)
8 | return 1;
9 | cmdline_logging();
10 | init_argv0(argc, argv);
11 | umask(0);
12 | return APPLET_STUB_MAIN(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/native/src/core/build.rs:
--------------------------------------------------------------------------------
1 | use pb_rs::{ConfigBuilder, types::FileDescriptor};
2 |
3 | use crate::codegen::gen_cxx_binding;
4 |
5 | #[path = "../include/codegen.rs"]
6 | mod codegen;
7 |
8 | fn main() {
9 | println!("cargo:rerun-if-changed=resetprop/proto/persistent_properties.proto");
10 |
11 | gen_cxx_binding("core-rs");
12 |
13 | let cb = ConfigBuilder::new(
14 | &["resetprop/proto/persistent_properties.proto"],
15 | None,
16 | Some(&"resetprop/proto"),
17 | &["."],
18 | )
19 | .unwrap();
20 | FileDescriptor::run(
21 | &cb.single_module(true)
22 | .dont_use_cow(true)
23 | .generate_getters(true)
24 | .build(),
25 | )
26 | .unwrap();
27 | }
28 |
--------------------------------------------------------------------------------
/native/src/core/deny/deny.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include