├── .gitattributes
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.MD
├── app
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
├── shared
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ ├── a
│ │ └── p.java
│ │ └── com
│ │ └── topjohnwu
│ │ └── magisk
│ │ ├── DynAPK.java
│ │ ├── FileProvider.java
│ │ ├── ProviderCallHandler.java
│ │ ├── net
│ │ ├── BadRequest.java
│ │ ├── ErrorHandler.java
│ │ ├── Networking.java
│ │ ├── NoSSLv3SocketFactory.java
│ │ ├── Request.java
│ │ ├── ResponseListener.java
│ │ └── SSLSocketWrapper.java
│ │ └── utils
│ │ ├── APKInstall.java
│ │ ├── CompoundEnumeration.java
│ │ └── DynamicClassLoader.java
├── signing
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── topjohnwu
│ │ │ └── signing
│ │ │ ├── ApkSignerV2.java
│ │ │ ├── BootSigner.java
│ │ │ ├── ByteArrayStream.java
│ │ │ ├── CryptoUtils.java
│ │ │ ├── JarMap.java
│ │ │ ├── SignApk.java
│ │ │ ├── SignBoot.java
│ │ │ ├── ZipSigner.java
│ │ │ └── ZipUtils.java
│ │ └── resources
│ │ └── keys
│ │ ├── testkey.pk8
│ │ ├── testkey.x509.pem
│ │ ├── verity.pk8
│ │ └── verity.x509.pem
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── a
│ │ └── stubs.kt
│ └── com
│ │ └── topjohnwu
│ │ └── magisk
│ │ ├── arch
│ │ ├── BaseUIActivity.kt
│ │ ├── BaseUIComponent.kt
│ │ ├── BaseUIFragment.kt
│ │ ├── BaseViewModel.kt
│ │ ├── Helpers.kt
│ │ ├── Queryable.kt
│ │ └── ViewEvent.kt
│ │ ├── core
│ │ ├── App.kt
│ │ ├── Config.kt
│ │ ├── Const.kt
│ │ ├── GeneralReceiver.kt
│ │ ├── Hacks.kt
│ │ ├── Info.kt
│ │ ├── SplashActivity.kt
│ │ ├── UpdateCheckService.kt
│ │ ├── base
│ │ │ ├── BaseActivity.kt
│ │ │ ├── BaseReceiver.kt
│ │ │ ├── BaseService.kt
│ │ │ ├── BaseWorkerWrapper.kt
│ │ │ └── PermissionRequestBuilder.kt
│ │ ├── download
│ │ │ ├── Action.kt
│ │ │ ├── BaseDownloader.kt
│ │ │ ├── DownloadService.kt
│ │ │ ├── ManagerHandler.kt
│ │ │ ├── ModuleProcessor.kt
│ │ │ └── Subject.kt
│ │ ├── magiskdb
│ │ │ ├── BaseDao.kt
│ │ │ ├── PolicyDao.kt
│ │ │ ├── Query.kt
│ │ │ ├── SettingsDao.kt
│ │ │ └── StringDao.kt
│ │ ├── model
│ │ │ ├── UpdateInfo.kt
│ │ │ ├── module
│ │ │ │ ├── BaseModule.kt
│ │ │ │ ├── Module.kt
│ │ │ │ └── Repo.kt
│ │ │ └── su
│ │ │ │ ├── SuLog.kt
│ │ │ │ └── SuPolicy.kt
│ │ ├── su
│ │ │ ├── SuCallbackHandler.kt
│ │ │ └── SuRequestHandler.kt
│ │ ├── tasks
│ │ │ ├── FlashZip.kt
│ │ │ ├── MagiskInstaller.kt
│ │ │ ├── PatchAPK.kt
│ │ │ └── RepoUpdater.kt
│ │ └── utils
│ │ │ ├── AXML.kt
│ │ │ ├── BiometricHelper.kt
│ │ │ ├── IODispatcherExecutor.kt
│ │ │ ├── Keygen.kt
│ │ │ ├── Locales.kt
│ │ │ ├── MediaStoreUtils.kt
│ │ │ ├── ProgressInputStream.kt
│ │ │ ├── RootInit.kt
│ │ │ ├── ZipUtils.kt
│ │ │ └── net
│ │ │ ├── LollipopNetworkObserver.kt
│ │ │ ├── MarshmallowNetworkObserver.kt
│ │ │ ├── NetworkObserver.kt
│ │ │ └── PreLollipopNetworkObserver.kt
│ │ ├── data
│ │ ├── database
│ │ │ ├── Repo.kt
│ │ │ ├── RepoDao.kt
│ │ │ └── SuLogDao.kt
│ │ ├── network
│ │ │ └── NetworkServices.kt
│ │ ├── preference
│ │ │ ├── BooleanProperty.kt
│ │ │ ├── FloatProperty.kt
│ │ │ ├── IntProperty.kt
│ │ │ ├── LongProperty.kt
│ │ │ ├── PreferenceModel.kt
│ │ │ ├── Property.kt
│ │ │ ├── StringProperty.kt
│ │ │ └── StringSetProperty.kt
│ │ └── repository
│ │ │ ├── DBConfig.kt
│ │ │ ├── LogRepository.kt
│ │ │ └── NetworkService.kt
│ │ ├── databinding
│ │ ├── AdaptersRecycler.kt
│ │ ├── BindingBoundAdapter.kt
│ │ ├── DataBindingAdapters.kt
│ │ ├── RecyclerViewItems.kt
│ │ └── RvBindingAdapter.kt
│ │ ├── di
│ │ ├── ApplicationModule.kt
│ │ ├── DatabaseModule.kt
│ │ ├── Modules.kt
│ │ ├── NetworkingModule.kt
│ │ ├── RepositoryModule.kt
│ │ └── ViewModelsModule.kt
│ │ ├── events
│ │ ├── OpenInappLinkEvent.kt
│ │ ├── RebootEvent.kt
│ │ ├── SnackbarEvent.kt
│ │ ├── ViewEvents.kt
│ │ └── dialog
│ │ │ ├── BiometricEvent.kt
│ │ │ ├── DarkThemeDialog.kt
│ │ │ ├── DialogEvent.kt
│ │ │ ├── EnvFixDialog.kt
│ │ │ ├── ManagerInstallDialog.kt
│ │ │ ├── ModuleInstallDialog.kt
│ │ │ ├── SecondSlotWarningDialog.kt
│ │ │ ├── SuperuserRevokeDialog.kt
│ │ │ └── UninstallDialog.kt
│ │ ├── ktx
│ │ ├── Dimens.kt
│ │ ├── XAndroid.kt
│ │ ├── XBinding.kt
│ │ ├── XJava.kt
│ │ ├── XKoin.kt
│ │ ├── XSU.kt
│ │ ├── XString.kt
│ │ └── XTime.kt
│ │ ├── ui
│ │ ├── MainActivity.kt
│ │ ├── flash
│ │ │ ├── ConsoleItem.kt
│ │ │ ├── FlashFragment.kt
│ │ │ └── FlashViewModel.kt
│ │ ├── hide
│ │ │ ├── HideApp.kt
│ │ │ ├── HideFragment.kt
│ │ │ ├── HideRvItems.kt
│ │ │ └── HideViewModel.kt
│ │ ├── home
│ │ │ ├── DeveloperItem.kt
│ │ │ ├── HomeFragment.kt
│ │ │ └── HomeViewModel.kt
│ │ ├── install
│ │ │ ├── InstallFragment.kt
│ │ │ └── InstallViewModel.kt
│ │ ├── log
│ │ │ ├── LogFragment.kt
│ │ │ ├── LogRvItem.kt
│ │ │ └── LogViewModel.kt
│ │ ├── module
│ │ │ ├── ModuleFragment.kt
│ │ │ ├── ModuleRvItem.kt
│ │ │ └── ModuleViewModel.kt
│ │ ├── safetynet
│ │ │ ├── CheckSafetyNetEvent.kt
│ │ │ ├── SafetyNetHelper.kt
│ │ │ ├── SafetynetFragment.kt
│ │ │ └── SafetynetViewModel.kt
│ │ ├── settings
│ │ │ ├── BaseSettingsItem.kt
│ │ │ ├── SettingsFragment.kt
│ │ │ ├── SettingsItems.kt
│ │ │ └── SettingsViewModel.kt
│ │ ├── superuser
│ │ │ ├── PolicyRvItem.kt
│ │ │ ├── SpinnerRvItem.kt
│ │ │ ├── SuperuserFragment.kt
│ │ │ └── SuperuserViewModel.kt
│ │ ├── surequest
│ │ │ ├── SuRequestActivity.kt
│ │ │ └── SuRequestViewModel.kt
│ │ └── theme
│ │ │ ├── Theme.kt
│ │ │ ├── ThemeFragment.kt
│ │ │ └── ThemeViewModel.kt
│ │ ├── utils
│ │ ├── CachedValue.kt
│ │ ├── DiffObservableList.kt
│ │ ├── EndlessRecyclerScrollListener.kt
│ │ ├── FilterableDiffObservableList.kt
│ │ ├── HideBottomViewOnScrollBehavior.kt
│ │ ├── HideTopViewOnScrollBehavior.kt
│ │ ├── HideableBehavior.kt
│ │ ├── KItemDecoration.kt
│ │ ├── MarkwonImagePlugin.kt
│ │ ├── MotionRevealHelper.kt
│ │ ├── ObservableHost.kt
│ │ ├── TransitiveText.kt
│ │ └── Utils.kt
│ │ └── view
│ │ ├── MagiskDialog.kt
│ │ ├── MarkDownWindow.kt
│ │ ├── Notifications.kt
│ │ ├── Shortcuts.kt
│ │ ├── TappableHeadlineItem.kt
│ │ └── TextItem.kt
│ └── res
│ ├── anim
│ ├── fragment_enter.xml
│ ├── fragment_enter_pop.xml
│ ├── fragment_exit.xml
│ └── fragment_exit_pop.xml
│ ├── color
│ ├── color_error_transient.xml
│ ├── color_menu_tint.xml
│ ├── color_on_primary_transient.xml
│ ├── color_primary_error_transient.xml
│ ├── color_primary_transient.xml
│ ├── color_secondary_transient.xml
│ ├── color_state_primary_transient.xml
│ └── color_text_transient.xml
│ ├── drawable-anydpi-v21
│ └── ic_magisk_outline.xml
│ ├── drawable-anydpi-v23
│ └── ic_splash_activity.xml
│ ├── drawable-anydpi-v26
│ └── ic_launcher.xml
│ ├── drawable-hdpi
│ ├── ic_launcher.png
│ └── ic_magisk_outline.png
│ ├── drawable-mdpi
│ ├── ic_launcher.png
│ └── ic_magisk_outline.png
│ ├── drawable-nodpi
│ └── logo.png
│ ├── drawable-v26
│ ├── sc_extension.xml
│ ├── sc_magiskhide.xml
│ └── sc_superuser.xml
│ ├── drawable-xhdpi
│ ├── ic_launcher.png
│ └── ic_magisk_outline.png
│ ├── drawable-xxhdpi
│ ├── ic_launcher.png
│ └── ic_magisk_outline.png
│ ├── drawable-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_magisk_outline.png
│ ├── drawable
│ ├── avd_bug_from_filled.xml
│ ├── avd_bug_to_filled.xml
│ ├── avd_circle_check_from_filled.xml
│ ├── avd_circle_check_to_filled.xml
│ ├── avd_delete_magisk.xml
│ ├── avd_home_from_filled.xml
│ ├── avd_home_to_filled.xml
│ ├── avd_magisk_delete.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_checkbox.xml
│ ├── bg_divider_rounded_on_primary.xml
│ ├── bg_line_bottom_rounded.xml
│ ├── bg_line_top_rounded.xml
│ ├── bg_selection_circle_green.xml
│ ├── bg_shadow.xml
│ ├── divider_l1.xml
│ ├── divider_l_50.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_checkbox.xml
│ ├── ic_close_md2.xml
│ ├── ic_compound_checkbox.xml
│ ├── ic_day.xml
│ ├── ic_day_night.xml
│ ├── ic_delete_md2.xml
│ ├── ic_device.xml
│ ├── ic_download_md2.xml
│ ├── ic_extension.xml
│ ├── ic_fingerprint.xml
│ ├── ic_folder_list.xml
│ ├── ic_forth_md2.xml
│ ├── ic_github.xml
│ ├── ic_hide_md2.xml
│ ├── ic_hide_select_md2.xml
│ ├── ic_home_filled_md2.xml
│ ├── ic_home_md2.xml
│ ├── ic_home_outlined_md2.xml
│ ├── ic_info.xml
│ ├── ic_install.xml
│ ├── ic_logo.xml
│ ├── ic_magisk.xml
│ ├── ic_magisk_delete.xml
│ ├── ic_magisk_padded.xml
│ ├── ic_magiskhide.xml
│ ├── ic_manager.xml
│ ├── ic_module_filled_md2.xml
│ ├── ic_module_md2.xml
│ ├── ic_module_outlined_md2.xml
│ ├── ic_module_storage_md2.xml
│ ├── ic_more.xml
│ ├── ic_night.xml
│ ├── ic_notifications_md2.xml
│ ├── ic_order_date.xml
│ ├── ic_order_name.xml
│ ├── ic_paint.xml
│ ├── ic_patreon.xml
│ ├── ic_paypal.xml
│ ├── ic_refresh_data_md2.xml
│ ├── ic_refresh_safetynet_md2.xml
│ ├── ic_restart.xml
│ ├── ic_safetynet_md2.xml
│ ├── ic_save_md2.xml
│ ├── ic_search_md2.xml
│ ├── ic_settings_filled_md2.xml
│ ├── ic_settings_md2.xml
│ ├── ic_settings_outlined_md2.xml
│ ├── ic_show_md2.xml
│ ├── ic_splash_activity.xml
│ ├── ic_superuser.xml
│ ├── ic_superuser_filled_md2.xml
│ ├── ic_superuser_md2.xml
│ ├── ic_superuser_outlined_md2.xml
│ ├── ic_twitter.xml
│ ├── ic_up_md2.xml
│ ├── ic_update_md2.xml
│ ├── sc_extension.xml
│ ├── sc_magiskhide.xml
│ └── sc_superuser.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_flash_md2.xml
│ ├── fragment_hide_md2.xml
│ ├── fragment_home_md2.xml
│ ├── fragment_install_md2.xml
│ ├── fragment_log_md2.xml
│ ├── fragment_module_md2.xml
│ ├── fragment_safetynet_md2.xml
│ ├── fragment_settings_md2.xml
│ ├── fragment_superuser_md2.xml
│ ├── fragment_theme_md2.xml
│ ├── include_hide_filter.xml
│ ├── include_home_magisk.xml
│ ├── include_home_manager.xml
│ ├── include_log_magisk.xml
│ ├── include_log_superuser.xml
│ ├── include_module_filter.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_track_md2.xml
│ ├── item_module_download.xml
│ ├── item_module_md2.xml
│ ├── item_policy_md2.xml
│ ├── item_repo_md2.xml
│ ├── item_section_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_flash.xml
│ ├── menu_hide_md2.xml
│ ├── menu_home_md2.xml
│ ├── menu_log_md2.xml
│ ├── menu_module_md2.xml
│ └── menu_reboot.xml
│ ├── navigation
│ └── main.xml
│ ├── raw
│ ├── .gitignore
│ ├── changelog.md
│ └── manager.sh
│ ├── values-anydpi-v21
│ └── drawable.xml
│ ├── values-ar
│ └── 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-in
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-iw
│ └── strings.xml
│ ├── values-ja
│ └── strings.xml
│ ├── values-ka
│ └── strings.xml
│ ├── values-ko
│ └── strings.xml
│ ├── values-lt
│ └── strings.xml
│ ├── values-mk
│ └── strings.xml
│ ├── values-nb
│ └── strings.xml
│ ├── values-night
│ ├── colors.xml
│ └── themes_md2.xml
│ ├── values-nl
│ └── 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-sr
│ └── strings.xml
│ ├── values-sv
│ └── strings.xml
│ ├── values-th
│ └── strings.xml
│ ├── values-tr
│ └── strings.xml
│ ├── values-uk
│ └── strings.xml
│ ├── values-v19
│ └── styles_md2.xml
│ ├── values-v21
│ ├── styles_md2.xml
│ └── styles_md2_impl.xml
│ ├── values-vi
│ └── strings.xml
│ ├── values-zh-rCN
│ └── strings.xml
│ ├── values-zh-rTW
│ └── strings.xml
│ └── values
│ ├── arrays.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── default_color.xml
│ ├── dimens.xml
│ ├── ids.xml
│ ├── resources.xml
│ ├── strings.xml
│ ├── styles_md2.xml
│ ├── styles_md2_appearance.xml
│ ├── styles_md2_impl.xml
│ ├── styles_view_md2.xml
│ └── themes_md2.xml
├── build.gradle.kts
├── build.py
├── buildSrc
├── .gitignore
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── BuildSource.kt
├── config.prop.sample
├── docs
├── README.md
├── app_changes.md
├── boot.md
├── changes.md
├── deploy.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
├── procedures.html
├── 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
│ └── index.md
└── tools.md
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── native
├── .gitignore
├── build.gradle.kts
├── jni
│ ├── .gitignore
│ ├── Android.mk
│ ├── Application.mk
│ ├── core
│ │ ├── applet_stub.cpp
│ │ ├── applets.cpp
│ │ ├── bootstages.cpp
│ │ ├── daemon.cpp
│ │ ├── db.cpp
│ │ ├── magisk.cpp
│ │ ├── module.cpp
│ │ ├── restorecon.cpp
│ │ ├── scripting.cpp
│ │ └── socket.cpp
│ ├── 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
│ │ ├── daemon.hpp
│ │ ├── db.hpp
│ │ ├── flags.hpp
│ │ ├── magisk.hpp
│ │ ├── magiskpolicy.hpp
│ │ ├── resetprop.hpp
│ │ └── socket.hpp
│ ├── init
│ │ ├── getinfo.cpp
│ │ ├── init.cpp
│ │ ├── init.hpp
│ │ ├── magiskrc.inc
│ │ ├── mount.cpp
│ │ ├── rootdir.cpp
│ │ └── twostage.cpp
│ ├── magiskboot
│ │ ├── bootimg.cpp
│ │ ├── bootimg.hpp
│ │ ├── compress.cpp
│ │ ├── compress.hpp
│ │ ├── dtb.cpp
│ │ ├── dtb.hpp
│ │ ├── format.cpp
│ │ ├── format.hpp
│ │ ├── hexpatch.cpp
│ │ ├── magiskboot.hpp
│ │ ├── main.cpp
│ │ ├── pattern.cpp
│ │ └── ramdisk.cpp
│ ├── magiskhide
│ │ ├── hide_policy.cpp
│ │ ├── hide_utils.cpp
│ │ ├── magiskhide.cpp
│ │ ├── magiskhide.hpp
│ │ └── proc_monitor.cpp
│ ├── magiskpolicy
│ │ ├── magiskpolicy.cpp
│ │ ├── policydb.cpp
│ │ ├── rules.cpp
│ │ ├── sepolicy.cpp
│ │ ├── sepolicy.hpp
│ │ └── statement.cpp
│ ├── resetprop
│ │ ├── _resetprop.hpp
│ │ ├── persist_properties.cpp
│ │ └── resetprop.cpp
│ ├── su
│ │ ├── connect.cpp
│ │ ├── pts.cpp
│ │ ├── pts.hpp
│ │ ├── su.cpp
│ │ ├── su.hpp
│ │ └── su_daemon.cpp
│ ├── systemproperties
│ │ ├── Android.mk
│ │ ├── context_node.cpp
│ │ ├── contexts_serialized.cpp
│ │ ├── contexts_split.cpp
│ │ ├── include
│ │ │ ├── _system_properties.h
│ │ │ ├── async_safe
│ │ │ │ └── log.h
│ │ │ ├── private
│ │ │ │ ├── ErrnoRestorer.h
│ │ │ │ ├── bionic_defs.h
│ │ │ │ ├── bionic_futex.h
│ │ │ │ ├── bionic_lock.h
│ │ │ │ ├── bionic_macros.h
│ │ │ │ └── hacks.h
│ │ │ ├── property_info_parser
│ │ │ │ └── property_info_parser.h
│ │ │ ├── system_properties.h
│ │ │ └── system_properties
│ │ │ │ ├── context_node.h
│ │ │ │ ├── contexts.h
│ │ │ │ ├── contexts_pre_split.h
│ │ │ │ ├── contexts_serialized.h
│ │ │ │ ├── contexts_split.h
│ │ │ │ ├── prop_area.h
│ │ │ │ ├── prop_info.h
│ │ │ │ └── system_properties.h
│ │ ├── prop_area.cpp
│ │ ├── prop_info.cpp
│ │ ├── property_info_parser.cpp
│ │ ├── system_properties.cpp
│ │ ├── system_property_api.cpp
│ │ └── system_property_set.cpp
│ └── utils
│ │ ├── Android.mk
│ │ ├── cpio.cpp
│ │ ├── files.cpp
│ │ ├── files.hpp
│ │ ├── include
│ │ ├── cpio.hpp
│ │ ├── selinux.hpp
│ │ ├── stream.hpp
│ │ └── utils.hpp
│ │ ├── logging.cpp
│ │ ├── logging.hpp
│ │ ├── misc.cpp
│ │ ├── misc.hpp
│ │ ├── missing.cpp
│ │ ├── missing.hpp
│ │ ├── new.cpp
│ │ ├── selinux.cpp
│ │ ├── stream.cpp
│ │ ├── xwrap.cpp
│ │ └── xwrap.hpp
└── src
│ └── main
│ └── AndroidManifest.xml
├── scripts
├── addon.d.sh
├── boot_patch.sh
├── emulator.sh
├── flash_script.sh
├── magisk_uninstaller.sh
├── module_installer.sh
├── update_binary.sh
└── util_functions.sh
├── settings.gradle.kts
├── stub
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── a
│ │ └── a.java
│ └── com
│ │ └── topjohnwu
│ │ └── magisk
│ │ └── MainActivity.java
│ └── res
│ ├── values-ar
│ └── 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-in
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-iw
│ └── strings.xml
│ ├── values-ja
│ └── strings.xml
│ ├── values-ka
│ └── strings.xml
│ ├── values-ko
│ └── strings.xml
│ ├── values-lt
│ └── strings.xml
│ ├── values-mk
│ └── strings.xml
│ ├── values-nb
│ └── strings.xml
│ ├── values-nl
│ └── 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-sr
│ └── strings.xml
│ ├── values-sv
│ └── 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
└── tools
├── elf-cleaner.exe
├── futility
├── kernel.keyblock
├── kernel_data_key.vbprivk
└── ndk-bins
├── README.md
├── arm
├── crtbegin_dynamic.o
├── crtbegin_so.o
├── crtbegin_static.o
├── crtend_android.o
├── crtend_so.o
├── libc.a
├── libm.a
├── libm_hard.a
└── libstdc++.a
└── i686
├── crtbegin_dynamic.o
├── crtbegin_so.o
├── crtbegin_static.o
├── crtend_android.o
├── crtend_so.o
├── libc.a
├── libm.a
├── libstdc++.a
└── libz.a
/.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 | *.jar binary
16 | *.exe binary
17 | *.apk binary
18 | *.png binary
19 | *.jpg binary
20 | *.ttf binary
21 |
22 | # Help GitHub detect languages
23 | native/jni/external/** linguist-vendored
24 | native/jni/systemproperties/** linguist-language=C++
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | *.zip
3 | *.jks
4 | *.apk
5 | /config.prop
6 | /update.sh
7 |
8 | # Built binaries
9 | native/out
10 |
11 | # Android Studio / Gradle
12 | *.iml
13 | .gradle
14 | /local.properties
15 | /.idea
16 | /build
17 | /captures
18 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "selinux"]
2 | path = native/jni/external/selinux
3 | url = https://github.com/topjohnwu/selinux.git
4 | [submodule "busybox"]
5 | path = native/jni/external/busybox
6 | url = https://github.com/topjohnwu/ndk-busybox.git
7 | [submodule "dtc"]
8 | path = native/jni/external/dtc
9 | url = https://github.com/dgibson/dtc
10 | [submodule "lz4"]
11 | path = native/jni/external/lz4
12 | url = https://github.com/lz4/lz4.git
13 | [submodule "bzip2"]
14 | path = native/jni/external/bzip2
15 | url = https://github.com/nemequ/bzip2.git
16 | [submodule "xz"]
17 | path = native/jni/external/xz
18 | url = https://github.com/xz-mirror/xz.git
19 | [submodule "nanopb"]
20 | path = native/jni/external/nanopb
21 | url = https://github.com/nanopb/nanopb.git
22 | [submodule "mincrypt"]
23 | path = native/jni/external/mincrypt
24 | url = https://github.com/topjohnwu/mincrypt.git
25 | [submodule "pcre"]
26 | path = native/jni/external/pcre
27 | url = https://android.googlesource.com/platform/external/pcre
28 | [submodule "termux-elf-cleaner"]
29 | path = tools/termux-elf-cleaner
30 | url = https://github.com/termux/termux-elf-cleaner.git
31 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .idea/
5 | /build
6 | app/release
7 | *.hprof
8 | .externalNativeBuild/
9 | public.certificate.x509.pem
10 | private.key.pk8
11 | *.apk
12 |
--------------------------------------------------------------------------------
/app/shared/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/shared/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | }
4 |
5 | android {
6 | defaultConfig {
7 | vectorDrawables.useSupportLibrary = true
8 | consumerProguardFiles("proguard-rules.pro")
9 | }
10 | }
11 |
12 | dependencies {
13 | implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
14 | }
15 |
--------------------------------------------------------------------------------
/app/shared/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 | -keepclassmembers class * extends javax.net.ssl.SSLSocketFactory {
24 | ** delegate;
25 | }
26 |
--------------------------------------------------------------------------------
/app/shared/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
15 |
16 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/shared/src/main/java/a/p.java:
--------------------------------------------------------------------------------
1 | package a;
2 |
3 | import com.topjohnwu.magisk.FileProvider;
4 |
5 | public class p extends FileProvider {
6 | /* Stub */
7 | }
8 |
--------------------------------------------------------------------------------
/app/shared/src/main/java/com/topjohnwu/magisk/ProviderCallHandler.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 |
6 | public interface ProviderCallHandler {
7 | Bundle call(Context context, String method, String arg, Bundle extras);
8 | }
9 |
--------------------------------------------------------------------------------
/app/shared/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/shared/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/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.utils;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Build;
7 |
8 | import com.topjohnwu.magisk.FileProvider;
9 |
10 | import java.io.File;
11 |
12 | public class APKInstall {
13 | public static void install(Context c, File apk) {
14 | c.startActivity(installIntent(c, apk));
15 | }
16 |
17 | public static Intent installIntent(Context c, File apk) {
18 | Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE);
19 | install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
20 | install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
21 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
22 | install.setData(FileProvider.getUriForFile(c, c.getPackageName() + ".provider", apk));
23 | } else {
24 | apk.setReadable(true, false);
25 | install.setData(Uri.fromFile(apk));
26 | }
27 | return install;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/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/signing/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/signing/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2 |
3 | plugins {
4 | id("java-library")
5 | id("java")
6 | id("com.github.johnrengelman.shadow") version "6.0.0"
7 | }
8 |
9 | java {
10 | sourceCompatibility = JavaVersion.VERSION_1_8
11 | targetCompatibility = JavaVersion.VERSION_1_8
12 | }
13 |
14 | val jar by tasks.getting(Jar::class) {
15 | manifest {
16 | attributes["Main-Class"] = "com.topjohnwu.signing.ZipSigner"
17 | }
18 | }
19 |
20 | val shadowJar by tasks.getting(ShadowJar::class) {
21 | archiveBaseName.set("zipsigner")
22 | archiveClassifier.set(null as String?)
23 | archiveVersion.set("4.0")
24 | }
25 |
26 | repositories {
27 | jcenter()
28 | }
29 |
30 | dependencies {
31 | implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
32 |
33 | api("org.bouncycastle:bcprov-jdk15on:1.66")
34 | api("org.bouncycastle:bcpkix-jdk15on:1.66")
35 | }
36 |
--------------------------------------------------------------------------------
/app/signing/src/main/java/com/topjohnwu/signing/ByteArrayStream.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.signing;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | public class ByteArrayStream extends ByteArrayOutputStream {
9 |
10 | public synchronized void readFrom(InputStream is) {
11 | readFrom(is, Integer.MAX_VALUE);
12 | }
13 |
14 | public synchronized void readFrom(InputStream is, int len) {
15 | int read;
16 | byte buffer[] = new byte[4096];
17 | try {
18 | while ((read = is.read(buffer, 0, Math.min(len, buffer.length))) > 0) {
19 | write(buffer, 0, read);
20 | len -= read;
21 | }
22 | } catch (IOException e) {
23 | e.printStackTrace();
24 | }
25 | }
26 |
27 | public ByteArrayInputStream getInputStream() {
28 | return new ByteArrayInputStream(buf, 0, count);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/signing/src/main/resources/keys/testkey.pk8:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ianmacd/Magisk/3c0c7a45e7d6d4268fe837fff58357527dece787/app/signing/src/main/resources/keys/testkey.pk8
--------------------------------------------------------------------------------
/app/signing/src/main/resources/keys/verity.pk8:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ianmacd/Magisk/3c0c7a45e7d6d4268fe837fff58357527dece787/app/signing/src/main/resources/keys/verity.pk8
--------------------------------------------------------------------------------
/app/src/main/java/a/stubs.kt:
--------------------------------------------------------------------------------
1 | @file:JvmName("a")
2 | package a
3 |
4 | import com.topjohnwu.magisk.core.App
5 | import com.topjohnwu.magisk.core.GeneralReceiver
6 | import com.topjohnwu.magisk.core.SplashActivity
7 | import com.topjohnwu.magisk.core.download.DownloadService
8 | import com.topjohnwu.magisk.ui.MainActivity
9 | import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
10 | import com.topjohnwu.signing.BootSigner
11 |
12 | fun main(args: Array) {
13 | BootSigner.main(args)
14 | }
15 |
16 | class b : MainActivity()
17 |
18 | class c : SplashActivity()
19 |
20 | class e : App {
21 | constructor() : super()
22 | constructor(o: Any) : super(o)
23 | }
24 |
25 | class h : GeneralReceiver()
26 |
27 | class j : DownloadService()
28 |
29 | class m : SuRequestActivity()
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/arch/Queryable.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.arch
2 |
3 | import android.os.Handler
4 | import androidx.core.os.postDelayed
5 | import com.topjohnwu.superuser.internal.UiThreadHandler
6 |
7 | interface Queryable {
8 |
9 | val queryDelay: Long
10 | val queryHandler: Handler get() = UiThreadHandler.handler
11 |
12 | fun submitQuery() {
13 | queryHandler.postDelayed(queryDelay) { query() }
14 | }
15 |
16 | fun query()
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.arch
2 |
3 | import android.content.Context
4 | import kotlinx.coroutines.CoroutineScope
5 |
6 | /**
7 | * Class for passing events from ViewModels to Activities/Fragments
8 | * (see https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150)
9 | */
10 | abstract class ViewEvent
11 |
12 | abstract class ViewEventWithScope: ViewEvent() {
13 | lateinit var scope: CoroutineScope
14 | }
15 |
16 | interface ContextExecutor {
17 | operator fun invoke(context: Context)
18 | }
19 |
20 | interface ActivityExecutor {
21 | operator fun invoke(activity: BaseUIActivity<*, *>)
22 | }
23 |
24 | interface FragmentExecutor {
25 | operator fun invoke(fragment: BaseUIFragment<*, *>)
26 | }
27 |
--------------------------------------------------------------------------------
/app/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.ContextWrapper
6 | import android.content.Intent
7 | import com.topjohnwu.magisk.core.wrap
8 | import org.koin.core.KoinComponent
9 |
10 | abstract class BaseReceiver : BroadcastReceiver(), KoinComponent {
11 |
12 | final override fun onReceive(context: Context, intent: Intent?) {
13 | onReceive(context.wrap() as ContextWrapper, intent)
14 | }
15 |
16 | abstract fun onReceive(context: ContextWrapper, intent: Intent?)
17 | }
18 |
--------------------------------------------------------------------------------
/app/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 com.topjohnwu.magisk.core.wrap
6 | import org.koin.core.KoinComponent
7 |
8 | abstract class BaseService : Service(), KoinComponent {
9 | override fun attachBaseContext(base: Context) {
10 | super.attachBaseContext(base.wrap())
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/base/PermissionRequestBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | typealias SimpleCallback = () -> Unit
4 | typealias PermissionRationaleCallback = (List) -> Unit
5 |
6 | class PermissionRequestBuilder {
7 |
8 | private var onSuccessCallback: SimpleCallback = {}
9 | private var onFailureCallback: SimpleCallback = {}
10 | private var onShowRationaleCallback: PermissionRationaleCallback = {}
11 |
12 | fun onSuccess(callback: SimpleCallback) {
13 | onSuccessCallback = callback
14 | }
15 |
16 | fun onFailure(callback: SimpleCallback) {
17 | onFailureCallback = callback
18 | }
19 |
20 | fun onShowRationale(callback: PermissionRationaleCallback) {
21 | onShowRationaleCallback = callback
22 | }
23 |
24 | fun build(): PermissionRequest {
25 | return PermissionRequest(onSuccessCallback, onFailureCallback, onShowRationaleCallback)
26 | }
27 |
28 | }
29 |
30 | class PermissionRequest(
31 | private val onSuccessCallback: SimpleCallback,
32 | private val onFailureCallback: SimpleCallback,
33 | private val onShowRationaleCallback: PermissionRationaleCallback
34 | ) {
35 |
36 | fun onSuccess() = onSuccessCallback()
37 | fun onFailure() = onFailureCallback()
38 | fun onShowRationale(permissions: List) = onShowRationaleCallback(permissions)
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/download/Action.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.download
2 |
3 | import android.net.Uri
4 | import android.os.Parcelable
5 | import kotlinx.android.parcel.Parcelize
6 |
7 | sealed class Action : Parcelable {
8 |
9 | sealed class Flash : Action() {
10 |
11 | @Parcelize
12 | object Primary : Flash()
13 |
14 | @Parcelize
15 | object Secondary : Flash()
16 |
17 | }
18 |
19 | sealed class APK : Action() {
20 |
21 | @Parcelize
22 | object Upgrade : APK()
23 |
24 | @Parcelize
25 | object Restore : APK()
26 | }
27 |
28 | @Parcelize
29 | object Download : Action()
30 |
31 | @Parcelize
32 | object Uninstall : Action()
33 |
34 | @Parcelize
35 | object EnvFix : Action()
36 |
37 | @Parcelize
38 | data class Patch(val fileUri: Uri) : Action()
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/magiskdb/BaseDao.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.magiskdb
2 |
3 | import androidx.annotation.StringDef
4 |
5 | abstract class BaseDao {
6 |
7 | object Table {
8 | const val POLICY = "policies"
9 | const val LOG = "logs"
10 | const val SETTINGS = "settings"
11 | const val STRINGS = "strings"
12 | }
13 |
14 | @StringDef(Table.POLICY, Table.LOG, Table.SETTINGS, Table.STRINGS)
15 | @Retention(AnnotationRetention.SOURCE)
16 | annotation class TableStrict
17 |
18 | @TableStrict
19 | abstract val table: String
20 |
21 | inline fun buildQuery(builder: Builder.() -> Unit = {}) =
22 | Builder::class.java.newInstance()
23 | .apply { table = this@BaseDao.table }
24 | .apply(builder)
25 | .toString()
26 | .let { Query(it) }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/magiskdb/SettingsDao.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.magiskdb
2 |
3 | class SettingsDao : BaseDao() {
4 |
5 | override val table = Table.SETTINGS
6 |
7 | suspend fun delete(key: String) = buildQuery {
8 | condition { equals("key", key) }
9 | }.commit()
10 |
11 | suspend fun put(key: String, value: Int) = buildQuery {
12 | values("key" to key, "value" to value)
13 | }.commit()
14 |
15 | suspend fun fetch(key: String, default: Int = -1) = buildQuery