Compare commits

...

15 Commits
v24.0 ... v24.1

Author SHA1 Message Date
topjohnwu
32fc34f922 Release Magisk v24.1 2022-01-28 03:43:42 -08:00
topjohnwu
b82a393692 Add v24.1 release notes 2022-01-28 03:37:00 -08:00
LoveSy
3c7e792167 Catch PendingIntent.CanceledException thrown from send 2022-01-27 05:29:32 -08:00
LoveSy
0ad66875ab Fix crash when zip is malformat
Co-authored-by: 南宫雪珊 <vvb2060@gmail.com>
Co-authored-by: 残页 <31466456+canyie@users.noreply.github.com>
2022-01-27 05:26:31 -08:00
Arbri çoçka
1191ac2671 update Albania translation 2022-01-27 05:25:13 -08:00
topjohnwu
928b3425e3 Embed module installer in APK 2022-01-27 05:24:05 -08:00
topjohnwu
0726a00e3b Fix download notifications 2022-01-27 05:17:52 -08:00
LoveSy
5a88984d34 Guard synchronizedList's iteration
It's needed to guard a synchronizedList when iterating it
2022-01-27 02:01:30 -08:00
LoveSy
18de60f68c Fix NPE of SuRequestViewModel
countdown timer may have not initialized when backpressed
2022-01-27 02:01:04 -08:00
LoveSy
1893359142 Fix crash when fragment is detached from activity 2022-01-27 01:54:24 -08:00
topjohnwu
f5e5ab2436 Update Android Studio 2022-01-27 01:46:00 -08:00
topjohnwu
ff5ea1a70d Clarify what 64-bit only means 2022-01-26 04:39:14 -08:00
topjohnwu
54ee63a409 Minor install guide changes 2022-01-26 02:55:25 -08:00
topjohnwu
f095606b50 Release new canary build 2022-01-26 02:41:46 -08:00
topjohnwu
e8f31c78d7 Update README 2022-01-26 02:33:22 -08:00
32 changed files with 119 additions and 96 deletions

View File

@@ -12,19 +12,19 @@ Some highlight features:
- **MagiskSU**: Provide root access for applications
- **Magisk Modules**: Modify read-only partitions by installing modules
- **MagiskBoot**: The most complete tool for unpacking and repacking Android boot images
- **Zygisk**: Run code in every Android applications' processes
## Downloads
[Github](https://github.com/topjohnwu/Magisk/) is the only source where you can get official Magisk information and downloads.
[![](https://img.shields.io/badge/Magisk-v23.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v23.0)
[![](https://img.shields.io/badge/Magisk%20Beta-v23.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v23.0)
[![](https://img.shields.io/badge/Magisk%20Beta-v24.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v24.0)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk)
## Useful Links
- [Installation Instruction](https://topjohnwu.github.io/Magisk/install.html)
- [Frequently Asked Questions](https://topjohnwu.github.io/Magisk/faq.html)
- [Magisk Documentation](https://topjohnwu.github.io/Magisk/)
- [Magisk Troubleshoot Wiki](https://www.didgeridoohan.com/magisk/HomePage) (by [@Didgeridoohan](https://github.com/Didgeridoohan))
@@ -41,15 +41,15 @@ For Magisk app crashes, record and upload the logcat when the crash occurs.
- Magisk builds on any OS Android Studio supports. Install Android Studio and do the initial setups.
- Clone sources: `git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git`
- Install Python 3.6+ \
(Windows only: select **'Add Python to PATH'** in installer, and run `pip install colorama` after install)
(Windows only: select **'Add Python to PATH'** in installer, and run `pip install colorama` after install)
- Configure to use the JDK bundled in Android Studio:
- macOS: `export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/Contents/Home"`
- Linux: `export PATH="/path/to/androidstudio/jre/bin:$PATH"`
- Windows: Add `C:\Path\To\Android Studio\jre\bin` to environment variable `PATH`
- macOS: `export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/Contents/Home"`
- Linux: `export PATH="/path/to/androidstudio/jre/bin:$PATH"`
- Windows: Add `C:\Path\To\Android Studio\jre\bin` to environment variable `PATH`
- Set environment variable `ANDROID_SDK_ROOT` to the Android SDK folder (can be found in Android Studio settings)
- Run `./build.py ndk` to let the script download and install NDK for you
- To start building, run `build.py` to see your options. \
For each action, use `-h` to access help (e.g. `./build.py all -h`)
For each action, use `-h` to access help (e.g. `./build.py all -h`)
- To start development, open the project with Android Studio. The IDE can be used for both app (Kotlin/Java) and native (C++/C) sources.
- Optionally, set custom configs with `config.prop`. A sample `config.prop.sample` is provided.
- To sign APKs and zips with your own private keys, set signing configs in `config.prop`. For more info, check [Google's Documentation](https://developer.android.com/studio/publish/app-signing.html#generate-key).

View File

@@ -57,6 +57,7 @@ android {
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs = listOf("-Xjvm-default=enable")
}
}
@@ -109,19 +110,19 @@ dependencies {
implementation("androidx.room:room-ktx:${vRoom}")
kapt("androidx.room:room-compiler:${vRoom}")
val vNav = "2.4.0-rc01"
val vNav = "2.5.0-alpha01"
implementation("androidx.navigation:navigation-fragment-ktx:${vNav}")
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")
implementation("androidx.biometric:biometric:1.1.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.2")
implementation("androidx.constraintlayout:constraintlayout:2.1.3")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.appcompat:appcompat:1.4.1")
implementation("androidx.preference:preference:1.1.1")
implementation("androidx.preference:preference:1.2.0")
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.fragment:fragment-ktx:1.4.0")
implementation("androidx.fragment:fragment-ktx:1.4.1")
implementation("androidx.transition:transition:1.4.1")
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.core:core-splashscreen:1.0.0-beta01")
implementation("com.google.android.material:material:1.4.0")
implementation("com.google.android.material:material:1.5.0")
}

View File

@@ -15,11 +15,11 @@ import com.topjohnwu.magisk.ktx.startAnimations
abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHolder {
val activity get() = requireActivity() as NavigationActivity<*>
val activity get() = getActivity() as? NavigationActivity<*>
protected lateinit var binding: Binding
protected abstract val layoutRes: Int
private val navigation get() = activity.navigation
private val navigation get() = activity?.navigation
open val snackbarAnchorView: View? get() = null
override fun onCreate(savedInstanceState: Bundle?) {
@@ -41,12 +41,12 @@ abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHo
override fun onStart() {
super.onStart()
activity.supportActionBar?.subtitle = null
activity?.supportActionBar?.subtitle = null
}
override fun onEventDispatched(event: ViewEvent) = when(event) {
is ContextExecutor -> event(requireContext())
is ActivityExecutor -> event(activity)
is ActivityExecutor -> activity?.let { event(it) } ?: Unit
is FragmentExecutor -> event(this)
else -> Unit
}

View File

@@ -64,7 +64,7 @@ open class App() : Application() {
}
base.resources.patch()
app.registerActivityLifecycleCallbacks(ForegroundTracker)
app.registerActivityLifecycleCallbacks(ActivityTracker)
}
override fun onCreate() {
@@ -86,7 +86,7 @@ open class App() : Application() {
}
@SuppressLint("StaticFieldLeak")
object ForegroundTracker : Application.ActivityLifecycleCallbacks {
object ActivityTracker : Application.ActivityLifecycleCallbacks {
@Volatile
var foreground: Activity? = null

View File

@@ -11,7 +11,7 @@ import android.os.IBinder
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.ForegroundTracker
import com.topjohnwu.magisk.core.ActivityTracker
import com.topjohnwu.magisk.core.base.BaseService
import com.topjohnwu.magisk.core.intent
import com.topjohnwu.magisk.core.utils.ProgressInputStream
@@ -25,7 +25,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import okhttp3.ResponseBody
import timber.log.Timber
import java.io.IOException
import java.io.InputStream
class DownloadService : BaseService() {
@@ -66,17 +65,18 @@ class DownloadService : BaseService() {
val stream = service.fetchFile(subject.url).toProgressStream(subject)
when (subject) {
is Subject.Manager -> handleAPK(subject, stream)
else -> stream.toModule(subject.file, service.fetchInstaller().byteStream())
is Subject.Module -> stream.toModule(subject.file, assets.open("module_installer.sh"))
}
if (ForegroundTracker.hasForeground) {
val activity = ActivityTracker.foreground
if (activity != null && subject.autoStart) {
remove(subject.notifyId)
subject.pendingIntent(this@DownloadService)?.send()
subject.pendingIntent(activity).send()
} else {
notifyFinish(subject)
}
if (!hasNotifications)
stopSelf()
} catch (e: IOException) {
} catch (e: Exception) {
Timber.e(e)
notifyFail(subject)
}

View File

@@ -7,7 +7,7 @@ import androidx.core.content.getSystemService
import androidx.core.net.toFile
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.ForegroundTracker
import com.topjohnwu.magisk.core.ActivityTracker
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.tasks.HideAPK
@@ -64,7 +64,7 @@ suspend fun DownloadService.handleAPK(subject: Subject.Manager, stream: InputStr
//noinspection InlinedApi
val flag = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
val pending = PendingIntent.getActivity(this, id, intent, flag)
if (ForegroundTracker.hasForeground) {
if (ActivityTracker.hasForeground) {
val alarm = getSystemService<AlarmManager>()
alarm!!.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pending)
}

View File

@@ -34,8 +34,9 @@ sealed class Subject : Parcelable {
abstract val file: Uri
abstract val title: String
abstract val notifyId: Int
open val autoStart: Boolean get() = true
abstract fun pendingIntent(context: Context): PendingIntent?
abstract fun pendingIntent(context: Context): PendingIntent
@Parcelize
class Module(
@@ -45,16 +46,15 @@ sealed class Subject : Parcelable {
) : Subject() {
override val url: String get() = module.zipUrl
override val title: String get() = module.downloadFilename
override val autoStart: Boolean get() = action == Action.Flash
@IgnoredOnParcel
override val file by lazy {
MediaStoreUtils.getFile(title).uri
}
override fun pendingIntent(context: Context) = when (action) {
Action.Flash -> FlashFragment.installIntent(context, file)
else -> null
}
override fun pendingIntent(context: Context) =
FlashFragment.installIntent(context, file)
}
@Parcelize

View File

@@ -38,8 +38,7 @@ fun InputStream.unzip(folder: File, path: String, junkPath: Boolean) {
}
SuFileOutputStream.open(dest).use { out -> zin.copyTo(out) }
}
} catch (e: IOException) {
e.printStackTrace()
throw e
} catch (e: IllegalArgumentException) {
throw IOException(e)
}
}

View File

@@ -6,26 +6,16 @@ import com.topjohnwu.magisk.core.model.UpdateInfo
import okhttp3.ResponseBody
import retrofit2.http.*
private const val REVISION = "revision"
private const val BRANCH = "branch"
private const val REPO = "repo"
private const val FILE = "file"
const val MAGISK_MAIN = "topjohnwu/Magisk"
interface GithubPageServices {
@GET("{$FILE}")
suspend fun fetchUpdateJSON(@Path(FILE) file: String): UpdateInfo
}
interface JSDelivrServices {
@GET("$MAGISK_MAIN@{$REVISION}/scripts/module_installer.sh")
@Streaming
suspend fun fetchInstaller(@Path(REVISION) revision: String): ResponseBody
}
interface RawServices {
@GET

View File

@@ -7,7 +7,9 @@ import com.topjohnwu.magisk.core.Config.Value.CUSTOM_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.DEFAULT_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.STABLE_CHANNEL
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.data.network.*
import com.topjohnwu.magisk.data.network.GithubApiServices
import com.topjohnwu.magisk.data.network.GithubPageServices
import com.topjohnwu.magisk.data.network.RawServices
import retrofit2.HttpException
import timber.log.Timber
import java.io.IOException
@@ -15,7 +17,6 @@ import java.io.IOException
class NetworkService(
private val pages: GithubPageServices,
private val raw: RawServices,
private val jsd: JSDelivrServices,
private val api: GithubApiServices
) {
suspend fun fetchUpdate() = safe {
@@ -59,13 +60,7 @@ class NetworkService(
}
// Fetch files
suspend fun fetchInstaller() = wrap {
val sha = fetchMainVersion()
jsd.fetchInstaller(sha)
}
suspend fun fetchFile(url: String) = wrap { raw.fetchFile(url) }
suspend fun fetchString(url: String) = wrap { raw.fetchString(url) }
suspend fun fetchModuleJson(url: String) = wrap { raw.fetchModuleJson(url) }
private suspend fun fetchMainVersion() = api.fetchBranch(MAGISK_MAIN, "master").commit.sha
}

View File

@@ -47,21 +47,20 @@ object ServiceLocator {
NetworkService(
createApiService(retrofit, Const.Url.GITHUB_PAGE_URL),
createApiService(retrofit, Const.Url.GITHUB_RAW_URL),
createApiService(retrofit, Const.Url.JS_DELIVR_URL),
createApiService(retrofit, Const.Url.GITHUB_API_URL)
)
}
object VMFactory : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(clz: Class<T>): T {
return when (clz) {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return when (modelClass) {
HomeViewModel::class.java -> HomeViewModel(networkService)
LogViewModel::class.java -> LogViewModel(logRepo)
SuperuserViewModel::class.java -> SuperuserViewModel(policyDB)
InstallViewModel::class.java -> InstallViewModel(networkService)
SuRequestViewModel::class.java -> SuRequestViewModel(policyDB, timeoutPrefs)
else -> clz.newInstance()
else -> modelClass.newInstance()
} as T
}
}
@@ -69,7 +68,7 @@ object ServiceLocator {
inline fun <reified VM : ViewModel> ViewModelStoreOwner.viewModel() =
lazy(LazyThreadSafetyMode.NONE) {
ViewModelProvider(this, ServiceLocator.VMFactory).get(VM::class.java)
ViewModelProvider(this, ServiceLocator.VMFactory)[VM::class.java]
}
private fun createSuLogDatabase(context: Context) =

View File

@@ -83,7 +83,7 @@ class SelectModuleEvent : ViewEvent(), FragmentExecutor {
override fun invoke(fragment: BaseFragment<*>) {
try {
fragment.apply {
activity.getContent("application/zip") {
activity?.getContent("application/zip") {
MainDirections.actionFlashFragment(Const.Value.FLASH_ZIP, it).navigate()
}
}

View File

@@ -26,7 +26,7 @@ class DenyListFragment : BaseFragment<FragmentDenyMd2Binding>() {
override fun onAttach(context: Context) {
super.onAttach(context)
activity.setTitle(R.string.denylist)
activity?.setTitle(R.string.denylist)
setHasOptionsMenu(true)
}

View File

@@ -31,10 +31,10 @@ class FlashFragment : BaseFragment<FragmentFlashMd2Binding>() {
override fun onStart() {
super.onStart()
setHasOptionsMenu(true)
activity.setTitle(R.string.flash_screen_title)
activity?.setTitle(R.string.flash_screen_title)
viewModel.subtitle.observe(this) {
activity.supportActionBar?.setSubtitle(it)
activity?.supportActionBar?.setSubtitle(it)
}
}
@@ -49,15 +49,15 @@ class FlashFragment : BaseFragment<FragmentFlashMd2Binding>() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
defaultOrientation = activity.requestedOrientation
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
defaultOrientation = activity?.requestedOrientation ?: -1
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
viewModel.startFlashing()
}
@SuppressLint("WrongConstant")
override fun onDestroyView() {
if (defaultOrientation != -1) {
activity.requestedOrientation = defaultOrientation
activity?.requestedOrientation = defaultOrientation
}
super.onDestroyView()
}

View File

@@ -103,9 +103,11 @@ class FlashViewModel : BaseViewModel() {
val name = "magisk_install_log_%s.log".format(now.toTime(timeFormatStandard))
val file = MediaStoreUtils.getFile(name, true)
file.uri.outputStream().bufferedWriter().use { writer ->
logItems.forEach {
writer.write(it)
writer.newLine()
synchronized(logItems) {
logItems.forEach {
writer.write(it)
writer.newLine()
}
}
}
SnackbarEvent(file.toString()).publish()

View File

@@ -19,7 +19,7 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
override fun onStart() {
super.onStart()
activity.title = resources.getString(R.string.section_home)
activity?.title = resources.getString(R.string.section_home)
setHasOptionsMenu(true)
DownloadService.observeProgress(this, viewModel::onProgressUpdate)
}
@@ -64,7 +64,7 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
when (item.itemId) {
R.id.action_settings ->
HomeFragmentDirections.actionHomeFragmentToSettingsFragment().navigate()
R.id.action_reboot -> RebootEvent.inflateMenu(activity).show()
R.id.action_reboot -> activity?.let { RebootEvent.inflateMenu(it).show() }
else -> return super.onOptionsItemSelected(item)
}
return true

View File

@@ -38,7 +38,7 @@ class LogFragment : BaseFragment<FragmentLogMd2Binding>() {
override fun onStart() {
super.onStart()
setHasOptionsMenu(true)
activity.title = resources.getString(R.string.logs)
activity?.title = resources.getString(R.string.logs)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@@ -19,7 +19,7 @@ class ModuleFragment : BaseFragment<FragmentModuleMd2Binding>() {
override fun onStart() {
super.onStart()
setHasOptionsMenu(true)
activity.title = resources.getString(R.string.modules)
activity?.title = resources.getString(R.string.modules)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@@ -18,7 +18,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsMd2Binding>() {
override fun onStart() {
super.onStart()
activity.title = resources.getString(R.string.settings)
activity?.title = resources.getString(R.string.settings)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@@ -17,7 +17,7 @@ class SuperuserFragment : BaseFragment<FragmentSuperuserMd2Binding>() {
override fun onStart() {
super.onStart()
activity.title = resources.getString(R.string.superuser)
activity?.title = resources.getString(R.string.superuser)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@@ -73,7 +73,7 @@ class SuRequestViewModel(
val itemBinding = ItemBinding.of<String>(BR.item, R.layout.item_spinner)
private val handler = SuRequestHandler(AppContext.packageManager, policyDB)
private lateinit var timer: CountDownTimer
private var timer: CountDownTimer? = null
fun grantPressed() {
cancelTimer()
@@ -121,7 +121,7 @@ class SuRequestViewModel(
}
private fun respond(action: Int) {
timer.cancel()
timer?.cancel()
val pos = selectedItemPosition
timeoutPrefs.edit().putInt(handler.policy.packageName, pos).apply()
@@ -132,7 +132,7 @@ class SuRequestViewModel(
}
private fun cancelTimer() {
timer.cancel()
timer?.cancel()
denyText.seconds = 0
}

View File

@@ -61,7 +61,7 @@ class ThemeFragment : BaseFragment<FragmentThemeMd2Binding>() {
override fun onStart() {
super.onStart()
activity.title = getString(R.string.section_theme)
activity?.title = getString(R.string.section_theme)
}
}

View File

@@ -121,15 +121,15 @@ class MagiskDialog(
super.onCreate(savedInstanceState)
super.setContentView(binding.root)
val default = MaterialColors.getColor(context, R.attr.colorSurface, javaClass.canonicalName)
val default = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, javaClass.canonicalName)
val surfaceColor = MaterialColors.getColor(context, R.attr.colorSurfaceSurfaceVariant, default)
val materialShapeDrawable = MaterialShapeDrawable(context, null, R.attr.alertDialogStyle, R.style.MaterialAlertDialog_MaterialComponents)
val materialShapeDrawable = MaterialShapeDrawable(context, null, androidx.appcompat.R.attr.alertDialogStyle, com.google.android.material.R.style.MaterialAlertDialog_MaterialComponents)
materialShapeDrawable.initializeElevationOverlay(context)
materialShapeDrawable.fillColor = ColorStateList.valueOf(surfaceColor)
materialShapeDrawable.elevation = context.resources.getDimension(R.dimen.margin_generic)
materialShapeDrawable.setCornerSize(context.resources.getDimension(R.dimen.l_50))
val inset = context.resources.getDimensionPixelSize(R.dimen.appcompat_dialog_background_inset)
val inset = context.resources.getDimensionPixelSize(com.google.android.material.R.dimen.appcompat_dialog_background_inset)
window?.apply {
setBackgroundDrawable(InsetDrawable(materialShapeDrawable, inset, inset, inset, inset))
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

View File

@@ -29,11 +29,11 @@ public class ConcealableBottomNavigationView extends BottomNavigationView {
}
public ConcealableBottomNavigationView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, R.attr.bottomNavigationStyle);
this(context, attrs, com.google.android.material.R.attr.bottomNavigationStyle);
}
public ConcealableBottomNavigationView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, R.style.Widget_Design_BottomNavigationView);
this(context, attrs, defStyleAttr, com.google.android.material.R.style.Widget_Design_BottomNavigationView);
}
public ConcealableBottomNavigationView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {

View File

@@ -106,7 +106,7 @@
<string name="module_version_author">%1$s nga %2$s</string>
<string name="module_state_remove">Hiqe</string>
<string name="module_state_restore">Rikëthe</string>
<string name="module_action_install_external">Instaloni nga ruajtja</string>
<string name="module_action_install_external">Instaloni nga sdcard</string>
<string name="update_available">Përditësimi në dispozicion</string>
<string name="suspend_text_riru">Moduli u pezullua sepse %1$s është aktivizuar</string>
<string name="suspend_text_zygisk">Moduli është pezulluar sepse %1$s nuk është i aktivizuar</string>
@@ -157,7 +157,7 @@
<string name="settings_su_request_60">60 Sekonda</string>
<string name="superuser_access">Aksesi i Super-përdorues</string>
<string name="auto_response">Përgjigje automatike</string>
<string name="request_timeout">Kërkesës i mbaroi koha</string>
<string name="request_timeout">Koha për mbarimit të Kërkesës</string>
<string name="superuser_notification">Njoftimi i Super-përdoruesit</string>
<string name="settings_su_reauth_title">Ri-vërtetimi pas azhurnimit</string>
<string name="settings_su_reauth_summary">Ri-vërtetoni lejet e super-përdoruesit pas azhurnimit të aplikacionit</string>

View File

@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
`kotlin-dsl`
}
@@ -15,10 +17,16 @@ gradlePlugin {
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
jvmTarget = "11"
}
}
dependencies {
implementation(kotlin("gradle-plugin", "1.6.10"))
implementation("com.android.tools.build:gradle:7.0.4")
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.4.0-rc01")
implementation("com.android.tools.build:gradle:7.1.0")
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.5.0-alpha01")
implementation("io.michaelrocks:paranoid-gradle-plugin:0.3.7")
implementation("org.eclipse.jgit:org.eclipse.jgit:5.12.0.202106070339-r")
}

View File

@@ -29,7 +29,7 @@ fun Project.setupCommon() {
androidBase {
compileSdkVersion(31)
buildToolsVersion = "31.0.0"
ndkPath = "${System.getenv("ANDROID_SDK_ROOT")}/ndk/magisk"
ndkPath = "$sdkDirectory/ndk/magisk"
defaultConfig {
minSdk = 21
@@ -123,7 +123,8 @@ fun Project.setupApp() {
inputs.property("versionCode", Config.versionCode)
into("src/main/assets")
from(rootProject.file("scripts")) {
include("util_functions.sh", "boot_patch.sh", "uninstaller.sh", "addon.d.sh")
include("util_functions.sh", "boot_patch.sh", "addon.d.sh")
include("uninstaller.sh", "module_installer.sh")
}
from(rootProject.file("tools/bootctl"))
into("chromeos") {

View File

@@ -1,10 +1,14 @@
# Magisk Changelog
### v24.1
- [App] Stability improvements
### v24.0
- [General] MagiskHide is removed from Magisk
- [General] Support 64-bit only systems
- [General] Support Android 12
- [General] Support devices that do not support 32-bit and only runs 64-bit code
- [General] Update BusyBox to 1.34.1
- [Zygisk] Introduce new feature: Zygisk
- [Zygisk] Introduce DenyList feature to revert Magisk features in user selected processes

View File

@@ -34,11 +34,11 @@ Next, we need to know whether your device has a separate `vbmeta` partition.
- If you find `vbmeta`, `vbmeta_a`, or `vbmeta_b`, then yes, your device **has** a separate `vbmeta` partition
- Otherwise, your device **does not** have a separate `vbmeta` partition.
Quick recap, at this point, you should know and prepared:
Quick recap, at this point, you should have known and prepared:
1. Whether your device has boot ramdisk
2. Whether your device has a separate `vbmeta` partition
3. A `boot.img` or `recovery.img` based on the result of (1)
3. A `boot.img` or `recovery.img` based on (1)
Let's continue to [Patching Images](#patching-images).
@@ -103,16 +103,15 @@ Unlocking the bootloader on modern Samsung devices have some caveats. The newly
- Use either [samfirm.js](https://github.com/jesec/samfirm.js), [Frija](https://forum.xda-developers.com/s10-plus/how-to/tool-frija-samsung-firmware-downloader-t3910594), or [Samloader](https://forum.xda-developers.com/s10-plus/how-to/tool-samloader-samfirm-frija-replacement-t4105929) to download the latest firmware zip of your device directly from Samsung servers.
- Unzip the firmware and copy the `AP` tar file to your device. It is normally named as `AP_[device_model_sw_ver].tar.md5`
- Press the **Install** button in the Magisk card
- If you are patching a recovery image, check the **"Recovery Mode"** option
- If your device does **NOT** have boot ramdisk, check the **"Recovery Mode"** option
- Choose **"Select and Patch a File"** in method, and select the `AP` tar file
- The Magisk app will patch the whole firmware file to `[Internal Storage]/Download/magisk_patched_[random_strings].tar`
- Start the installation, and copy the patched tar file to your PC using ADB:<br>
`adb pull /sdcard/Download/magisk_patched_[random_strings].tar`<br>
**DO NOT USE MTP** as it is known to corrupt large files.
- Reboot to download mode. Open Odin on your PC, and flash `magisk_patched.tar` as `AP`, together with `BL`, `CP`, and `CSC` (**NOT** `HOME_CSC` because we want to **wipe data**) from the original firmware.
- Your device should reboot automatically once Odin finished flashing. Agree to do a factory reset if asked.
- If your device does **NOT** have boot ramdisk, reboot to recovery now to enable Magisk (reason stated in [Magisk in Recovery](#magisk-in-recovery)).
- Install the Magisk app you've downloaded and launch the app. It should show a dialog asking for additional setup.
- Install the Magisk app you've already downloaded and launch the app. It should show a dialog asking for additional setup.
- Let the app do its job and automatically reboot the device. Voila!
### Upgrading the OS

23
docs/releases/24100.md Normal file
View File

@@ -0,0 +1,23 @@
## 2022.1.28 Magisk v24.1
> For those coming from v24.0, v24.1 only has some minor app improvements. The following are copied from v24.0 release notes.
It has been a while since the last public release, long time no see! A personal update for those unaware: I am now working at Google on the Android Platform Security team. Without further ado, let's jump right into it!
### MagiskHide Removal
I have lost interest in fighting this battle for quite a while; plus, the existing MagiskHide implementation is flawed in so many ways. Decoupling Magisk from root hiding is, in my opinion, beneficial to the community. Ever since my announcement on Twitter months ago, highly effective "root hiding" modules (much **MUCH** better than MagiskHide) has been flourishing, which again shows that people are way more capable than I am on this subject. So why not give those determined their time to shine, and let me focus on improving Magisk instead of drowning in the everlasting cat-and-mouse game 😉.
### Sunsetting Magisk-Modules-Repo
Due to lack of time and maintenance, the centralized Magisk-Modules-Repo was frozen, and the functionality to download modules from the repo is removed in v24.0. As a supplement, module developers can now specify an `updateJson` URL in their modules. The Magisk app will use that to check, download, and install module updates.
### Introducing Zygisk
Zygisk is **Magisk in Zygote**, the next big thing for Magisk! When this feature is enabled, a part of Magisk will run in the `Zygote` daemon process, allowing module developers to run code directly in every Android apps' processes. If you've heard of [Riru](https://github.com/RikkaApps/Riru), then Zygisk is inspired by that project and is functionally similar, though the implementation is quite different internally. I cannot wait to see what module developers can achieve using Zygisk!
### Documentation
For developers, details about `updateJson` and building Zygisk modules can all be found in the updated [documentation](https://topjohnwu.github.io/Magisk/guides.html#magisk-modules).
### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)

View File

@@ -1,5 +1,6 @@
# Release Notes
- [v24.1](24100.md)
- [v24.0](24000.md)
- [v23.0](23000.md)
- [v22.1](22100.md)

View File

@@ -24,9 +24,10 @@ org.gradle.caching=true
android.useAndroidX=true
android.databinding.incremental=true
android.injected.testOnly=false
android.nonTransitiveRClass=true
# Magisk
magisk.stubVersion=23
magisk.versionCode=24000
magisk.stubVersion=24
magisk.versionCode=24100
magisk.ndkVersion=21e
magisk.fullNdkVersion=21.4.7075529