Compare commits

..

33 Commits

Author SHA1 Message Date
topjohnwu
070719db50 Release new canary build 2024-10-10 02:10:50 -07:00
topjohnwu
28cccdf7aa Release Magisk v28.0 2024-10-10 01:47:00 -07:00
topjohnwu
b7e0986a5c Add v28.0 changelog 2024-10-10 01:40:14 -07:00
topjohnwu
da709745dd Revert #8245 2024-10-09 15:40:23 -07:00
topjohnwu
8b6771d487 Update dependencies 2024-10-08 01:40:09 -07:00
topjohnwu
e1b847fbc5 Find boot image with MagiskInstaller
Fix #8211
2024-10-07 16:52:35 -07:00
topjohnwu
7188de1205 Support unaligned boot image file
Fix #7733
2024-10-06 03:01:08 -07:00
topjohnwu
44fb7dbcbe Update Busybox
Fix #8403
2024-10-06 01:47:13 -07:00
topjohnwu
8086b5933c Update crt0
Fix #8424
2024-10-02 16:37:07 -07:00
topjohnwu
7f675f4bf7 Update dependencies 2024-09-27 14:38:32 -07:00
vvb2060
5e6b53e0da AppMigration: put suManager after installation 2024-09-25 12:34:21 -07:00
残页
5b29fefc65 Replace LOGE with LOGW so the process don't abort
Co-authored-by: 南宫雪珊 <vvb2060@gmail.com>
2024-09-25 11:59:58 -07:00
残页
16a168535d Check sepolicy database version in add_xperm_rule
Fix #8344
2024-09-25 11:59:58 -07:00
Wang Han
33f70f8f6d Update zh-rCN strings 2024-09-17 15:01:10 -07:00
topjohnwu
4f18a66d73 Release new canary build 2024-09-17 01:46:04 -07:00
Wang Han
250dc16007 Fix post-fs-data blocking time in doc
f7d3d1eeaf.
2024-09-17 01:28:01 -07:00
Wang Han
7af273e047 Don't append "start logd" in post-fs-data
This was first done in b13eb3f because magiskd was started in
post-fs stage that time. Among all android versions, logd was all
started before post-fs-data.
2024-09-16 00:30:36 -07:00
Arbri çoçka
e381aebaa0 Update strings.xml Albania (sq) 2024-09-16 00:24:47 -07:00
LoveSy
45d91c9658 Upgrade Gradle 2024-09-15 00:14:15 -07:00
igor
4a9158f667 Update Portuguese translation 2024-09-14 23:08:40 -07:00
niels
0d9ee89e7f magiskboot: cleanup bootconfig and vendor ramdisk dir 2024-09-14 23:08:22 -07:00
topjohnwu
abaff72304 Enable core library desugaring
Fix #8343
2024-09-09 01:59:32 -07:00
topjohnwu
b828e2d0b2 Update dependencies 2024-09-08 03:02:09 -07:00
Wang Han
53d7cbc11b Clarify magiskboot requirements for repacking img 2024-09-08 01:13:46 -07:00
LoveSy
310be7ab47 Return exit value of action.sh 2024-09-08 01:12:30 -07:00
LoveSy
60894e458f Automatically close action fragment when action exits successfully 2024-09-08 01:12:30 -07:00
LoveSy
fbebb6ac10 Add action.sh for user to manually trigger modules' functionality from app 2024-09-08 01:12:30 -07:00
LoveSy
a9f8c20703 Upgrade AGP 2024-09-05 21:50:56 -07:00
vvb2060
ae0b15d197 deps: update gradle to 8.10 2024-09-05 21:50:46 -07:00
vvb2060
869aa62328 ci: fix build 2024-09-05 21:50:46 -07:00
vvb2060
dcd3bc58a3 app: target api 35 2024-09-05 21:50:46 -07:00
Salvo Giangreco
a82f17c594 Disable Samsung PROCA
Signed-off-by: Salvo Giangreco <giangrecosalvo9@gmail.com>
2024-09-04 01:49:02 -07:00
vvb2060
b38fd1ca5f init: support 2SI devices with skip_initramfs 2024-09-03 16:33:57 -07:00
48 changed files with 731 additions and 297 deletions

View File

@@ -10,7 +10,7 @@ runs:
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: "temurin" distribution: "temurin"
java-version: "17" java-version: "21"
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v5 uses: actions/setup-python@v5

View File

@@ -21,8 +21,8 @@ Some highlight features:
Click the icon below to download Magisk apk. Click the icon below to download Magisk apk.
[![](https://img.shields.io/badge/Magisk-v27.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v27.0) [![](https://img.shields.io/badge/Magisk-v27.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
[![](https://img.shields.io/badge/Magisk%20Beta-v27.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v27.0) [![](https://img.shields.io/badge/Magisk%20Beta-v28.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v28.0)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://github.com/topjohnwu/Magisk/releases/tag/canary-27007) [![](https://img.shields.io/badge/Magisk-Canary-red)](https://github.com/topjohnwu/Magisk/releases/tag/canary-28001)
## Useful Links ## Useful Links

View File

@@ -13,7 +13,7 @@ kapt {
useBuildCache = true useBuildCache = true
mapDiagnosticLocations = true mapDiagnosticLocations = true
javacOptions { javacOptions {
option("-Xmaxerrs", 1000) option("-Xmaxerrs", "1000")
} }
} }
@@ -42,10 +42,15 @@ android {
buildFeatures { buildFeatures {
dataBinding = true dataBinding = true
} }
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
} }
dependencies { dependencies {
implementation(project(":app:core")) implementation(project(":app:core"))
coreLibraryDesugaring(libs.jdk.libs)
implementation(libs.indeterminate.checkbox) implementation(libs.indeterminate.checkbox)
implementation(libs.rikka.layoutinflater) implementation(libs.rikka.layoutinflater)

View File

@@ -1,13 +1,18 @@
package com.topjohnwu.magisk.dialog package com.topjohnwu.magisk.dialog
import android.widget.Toast
import androidx.core.os.postDelayed
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.core.BuildConfig import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.ktx.reboot
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.MagiskInstaller import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.events.DialogBuilder import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.home.HomeViewModel import com.topjohnwu.magisk.ui.home.HomeViewModel
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.internal.UiThreadHandler
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : DialogBuilder { class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : DialogBuilder {
@@ -27,9 +32,15 @@ class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : Dialo
setCancelable(false) setCancelable(false)
} }
dialog.activity.lifecycleScope.launch { dialog.activity.lifecycleScope.launch {
MagiskInstaller.FixEnv { MagiskInstaller.FixEnv().exec { success ->
dialog.dismiss() dialog.dismiss()
}.exec() context.toast(
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
Toast.LENGTH_LONG
)
if (success)
UiThreadHandler.handler.postDelayed(5000) { reboot() }
}
} }
} }
} }

View File

@@ -1,15 +1,17 @@
package com.topjohnwu.magisk.dialog package com.topjohnwu.magisk.dialog
import android.app.ProgressDialog import android.app.ProgressDialog
import android.content.Context
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.arch.NavigationActivity import com.topjohnwu.magisk.arch.NavigationActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.events.DialogBuilder import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.flash.FlashFragment import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.Shell import kotlinx.coroutines.launch
class UninstallDialog : DialogBuilder { class UninstallDialog : DialogBuilder {
@@ -19,7 +21,7 @@ class UninstallDialog : DialogBuilder {
setMessage(R.string.uninstall_magisk_msg) setMessage(R.string.uninstall_magisk_msg)
setButton(MagiskDialog.ButtonType.POSITIVE) { setButton(MagiskDialog.ButtonType.POSITIVE) {
text = R.string.restore_img text = R.string.restore_img
onClick { restore(dialog.context) } onClick { restore(dialog.activity) }
} }
setButton(MagiskDialog.ButtonType.NEGATIVE) { setButton(MagiskDialog.ButtonType.NEGATIVE) {
text = R.string.complete_uninstall text = R.string.complete_uninstall
@@ -29,18 +31,20 @@ class UninstallDialog : DialogBuilder {
} }
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
private fun restore(context: Context) { private fun restore(activity: UIActivity<*>) {
val dialog = ProgressDialog(context).apply { val dialog = ProgressDialog(activity).apply {
setMessage(context.getString(R.string.restore_img_msg)) setMessage(activity.getString(R.string.restore_img_msg))
show() show()
} }
Shell.cmd("restore_imgs").submit { result -> activity.lifecycleScope.launch {
MagiskInstaller.Restore().exec { success ->
dialog.dismiss() dialog.dismiss()
if (result.isSuccess) { if (success) {
context.toast(R.string.restore_done, Toast.LENGTH_SHORT) activity.toast(R.string.restore_done, Toast.LENGTH_SHORT)
} else { } else {
context.toast(R.string.restore_fail, Toast.LENGTH_LONG) activity.toast(R.string.restore_fail, Toast.LENGTH_LONG)
}
} }
} }
} }

View File

@@ -0,0 +1,116 @@
package com.topjohnwu.magisk.ui.module
import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.databinding.FragmentActionMd2Binding
import com.topjohnwu.magisk.ui.flash.FlashViewModel
import timber.log.Timber
import com.topjohnwu.magisk.core.R as CoreR
class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
override val layoutRes = R.layout.fragment_action_md2
override val viewModel by viewModel<ActionViewModel>()
override val snackbarView: View get() = binding.snackbarContainer
private var defaultOrientation = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.args = ActionFragmentArgs.fromBundle(requireArguments())
}
override fun onStart() {
super.onStart()
activity?.setTitle(viewModel.args.name)
binding.closeBtn.setOnClickListener {
activity?.onBackPressed();
}
viewModel.state.observe(this) {
activity?.supportActionBar?.setSubtitle(
when (it) {
ActionViewModel.State.RUNNING -> CoreR.string.running
ActionViewModel.State.SUCCESS -> CoreR.string.done
ActionViewModel.State.FAILED -> CoreR.string.failure
}
)
when (it) {
ActionViewModel.State.SUCCESS -> {
activity?.apply {
toast(
getString(
com.topjohnwu.magisk.core.R.string.done_action,
this@ActionFragment.viewModel.args.name
), Toast.LENGTH_LONG
)
onBackPressed()
}
}
ActionViewModel.State.FAILED -> {
binding.closeBtn.apply {
if (!this.isVisible) this.show()
if (!this.isFocused) this.requestFocus()
}
}
else -> {}
}
}
}
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_flash, menu)
}
override fun onMenuItemSelected(item: MenuItem): Boolean {
return viewModel.onMenuItemClicked(item)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
defaultOrientation = activity?.requestedOrientation ?: -1
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
if (savedInstanceState == null) {
viewModel.startRunAction()
}
}
@SuppressLint("WrongConstant")
override fun onDestroyView() {
if (defaultOrientation != -1) {
activity?.requestedOrientation = defaultOrientation
}
super.onDestroyView()
}
override fun onKeyEvent(event: KeyEvent): Boolean {
return when (event.keyCode) {
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> true
else -> false
}
}
override fun onBackPressed(): Boolean {
if (viewModel.state.value == ActionViewModel.State.RUNNING) return true
return super.onBackPressed()
}
override fun onPreBind(binding: FragmentActionMd2Binding) = Unit
}

View File

@@ -0,0 +1,84 @@
package com.topjohnwu.magisk.ui.module
import android.view.MenuItem
import androidx.databinding.Bindable
import androidx.databinding.ObservableArrayList
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.map
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.ktx.synchronized
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.tasks.RunAction
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ui.flash.ConsoleItem
import com.topjohnwu.superuser.CallbackList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class ActionViewModel : BaseViewModel() {
enum class State {
RUNNING, SUCCESS, FAILED
}
private val _state = MutableLiveData(State.RUNNING)
val state: LiveData<State> get() = _state
val running = state.map { it == State.RUNNING }
val items = ObservableArrayList<ConsoleItem>()
lateinit var args: ActionFragmentArgs
private val logItems = mutableListOf<String>().synchronized()
private val outItems = object : CallbackList<String>() {
override fun onAddElement(e: String?) {
e ?: return
items.add(ConsoleItem(e))
logItems.add(e)
}
}
fun startRunAction() {
viewModelScope.launch {
onResult(RunAction(args.id, outItems, logItems).exec())
}
}
private fun onResult(success: Boolean) {
_state.value = if (success) State.SUCCESS else State.FAILED
}
fun onMenuItemClicked(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_save -> savePressed()
}
return true
}
private fun savePressed() = withExternalRW {
viewModelScope.launch(Dispatchers.IO) {
val name = "%s_action_log_%s.log".format(
args.name,
System.currentTimeMillis().toTime(timeFormatStandard)
)
val file = MediaStoreUtils.getFile(name)
file.uri.outputStream().bufferedWriter().use { writer ->
synchronized(logItems) {
logItems.forEach {
writer.write(it)
writer.newLine()
}
}
}
SnackbarEvent(file.toString()).publish()
}
}
}

View File

@@ -25,6 +25,7 @@ class LocalModuleRvItem(
override val layoutRes = R.layout.item_module_md2 override val layoutRes = R.layout.item_module_md2
val showNotice: Boolean val showNotice: Boolean
val showAction: Boolean
val noticeText: TextHolder val noticeText: TextHolder
init { init {
@@ -35,6 +36,7 @@ class LocalModuleRvItem(
showNotice = zygiskUnloaded || showNotice = zygiskUnloaded ||
(Info.isZygiskEnabled && isRiru) || (Info.isZygiskEnabled && isRiru) ||
(!Info.isZygiskEnabled && isZygisk) (!Info.isZygiskEnabled && isZygisk)
showAction = item.hasAction && !showNotice
noticeText = noticeText =
when { when {
zygiskUnloaded -> CoreR.string.zygisk_module_unloaded.asText() zygiskUnloaded -> CoreR.string.zygisk_module_unloaded.asText()

View File

@@ -4,8 +4,10 @@ import android.net.Uri
import androidx.databinding.Bindable import androidx.databinding.Bindable
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.MainDirections
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.AsyncLoadViewModel import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.ContentResultCallback import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.model.module.LocalModule import com.topjohnwu.magisk.core.model.module.LocalModule
@@ -96,6 +98,10 @@ class ModuleViewModel : AsyncLoadViewModel() {
} }
} }
fun runAction(id: String, name: String) {
MainDirections.actionActionFragment(id, name).navigate()
}
companion object { companion object {
private val uri = MutableLiveData<Uri?>() private val uri = MutableLiveData<Uri?>()
} }

View File

@@ -78,8 +78,8 @@ class SuperuserViewModel(
this@SuperuserViewModel, policy, this@SuperuserViewModel, policy,
info.packageName, info.packageName,
info.sharedUserId != null, info.sharedUserId != null,
info.applicationInfo.loadIcon(pm), info.applicationInfo?.loadIcon(pm) ?: pm.defaultActivityIcon,
info.applicationInfo.getLabel(pm) info.applicationInfo?.getLabel(pm) ?: info.packageName
) )
} catch (e: PackageManager.NameNotFoundException) { } catch (e: PackageManager.NameNotFoundException) {
null null

View File

@@ -111,7 +111,7 @@ class SuRequestViewModel(
// shared UID. We have no way to know where this request comes from. // shared UID. We have no way to know where this request comes from.
icon = pm.defaultActivityIcon icon = pm.defaultActivityIcon
title = "[SharedUID] ${info.sharedUserId}" title = "[SharedUID] ${info.sharedUserId}"
packageName = info.sharedUserId packageName = info.sharedUserId.toString()
} else { } else {
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] " val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
icon = app.loadIcon(pm) icon = app.loadIcon(pm)

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
</vector>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.topjohnwu.magisk.ui.module.ActionViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/internal_action_bar_size"
app:layout_fitsSystemWindowsInsets="top"
tools:layout_marginTop="@dimen/internal_action_bar_size">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/flash_content"
scrollToLast="@{true}"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical"
app:fitsSystemWindowsInsets="start|end|bottom"
app:items="@{viewModel.items}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:listitem="@layout/item_console_md2" />
</HorizontalScrollView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/close_btn"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/l1"
android:layout_marginBottom="@dimen/l1"
android:clickable="true"
android:enabled="true"
android:focusable="true"
android:text="@string/close"
android:textAllCaps="false"
android:textColor="?colorOnPrimary"
android:textStyle="bold"
app:backgroundTint="?colorPrimary"
app:icon="@drawable/ic_close_md2"
app:iconTint="?colorOnPrimary"
app:layout_fitsSystemWindowsInsets="bottom" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/snackbar_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:fitsSystemWindowsInsets="top|bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

View File

@@ -189,12 +189,32 @@
android:textColor="?colorError" android:textColor="?colorError"
app:layout_constraintBottom_toBottomOf="@+id/module_remove" app:layout_constraintBottom_toBottomOf="@+id/module_remove"
app:layout_constraintEnd_toStartOf="@+id/bottom_bar_barrier" app:layout_constraintEnd_toStartOf="@+id/bottom_bar_barrier"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toEndOf="@id/module_config"
app:layout_constraintTop_toTopOf="@+id/module_remove" app:layout_constraintTop_toTopOf="@+id/module_remove"
tools:lines="2" tools:lines="2"
tools:text="@tools:sample/lorem/random" tools:text="@tools:sample/lorem/random"
tools:visibility="visible" /> tools:visibility="visible" />
<Button
android:id="@+id/module_config"
style="@style/WidgetFoundation.Button.Text"
goneUnless="@{item.showAction}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:enabled="@{item.enabled}"
android:focusable="true"
android:onClick="@{() -> viewModel.runAction(item.item.id, item.item.name)}"
android:text="@string/module_action"
android:textAllCaps="false"
android:visibility="gone"
app:icon="@drawable/ic_action_md2"
app:iconGravity="textStart"
app:layout_constraintBottom_toBottomOf="@+id/module_remove"
app:layout_constraintTop_toTopOf="@+id/module_remove"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/ic_download_md2" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>

View File

@@ -53,6 +53,21 @@
</fragment> </fragment>
<fragment
android:id="@+id/actionFragment"
android:name="com.topjohnwu.magisk.ui.module.ActionFragment"
android:label="ActionFragment"
tools:layout="@layout/fragment_action_md2" >
<argument
android:name="id"
app:argType="string" />
<argument
android:name="name"
app:argType="string" />
</fragment>
<fragment <fragment
android:id="@+id/installFragment" android:id="@+id/installFragment"
android:name="com.topjohnwu.magisk.ui.install.InstallFragment" android:name="com.topjohnwu.magisk.ui.install.InstallFragment"
@@ -152,4 +167,12 @@
app:popEnterAnim="@anim/fragment_enter_pop" app:popEnterAnim="@anim/fragment_enter_pop"
app:popExitAnim="@anim/fragment_exit_pop" /> app:popExitAnim="@anim/fragment_exit_pop" />
<action
android:id="@+id/action_actionFragment"
app:destination="@id/actionFragment"
app:enterAnim="@anim/fragment_enter"
app:exitAnim="@anim/fragment_exit"
app:popEnterAnim="@anim/fragment_enter_pop"
app:popExitAnim="@anim/fragment_exit_pop" />
</navigation> </navigation>

View File

@@ -37,6 +37,7 @@ data class LocalModule(
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists() val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
val isZygisk: Boolean get() = zygiskFolder.exists() val isZygisk: Boolean get() = zygiskFolder.exists()
val zygiskUnloaded: Boolean get() = unloaded.exists() val zygiskUnloaded: Boolean get() = unloaded.exists()
val hasAction: Boolean;
var enable: Boolean var enable: Boolean
get() = !disableFile.exists() get() = !disableFile.exists()
@@ -100,6 +101,8 @@ data class LocalModule(
if (name.isEmpty()) { if (name.isEmpty()) {
name = id name = id
} }
hasAction = RootUtils.fs.getFile(path, "action.sh").exists()
} }
suspend fun fetch(): Boolean { suspend fun fetch(): Boolean {

View File

@@ -1,6 +1,6 @@
package com.topjohnwu.magisk.core.model.su package com.topjohnwu.magisk.core.model.su
import android.content.pm.PackageInfo import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@@ -24,7 +24,7 @@ class SuLog(
} }
fun PackageManager.createSuLog( fun PackageManager.createSuLog(
info: PackageInfo, info: ApplicationInfo,
toUid: Int, toUid: Int,
fromPid: Int, fromPid: Int,
command: String, command: String,
@@ -33,13 +33,12 @@ fun PackageManager.createSuLog(
context: String, context: String,
gids: String, gids: String,
): SuLog { ): SuLog {
val appInfo = info.applicationInfo
return SuLog( return SuLog(
fromUid = appInfo.uid, fromUid = info.uid,
toUid = toUid, toUid = toUid,
fromPid = fromPid, fromPid = fromPid,
packageName = getNameForUid(appInfo.uid)!!, packageName = getNameForUid(info.uid)!!,
appName = appInfo.getLabel(this), appName = info.getLabel(this),
command = command, command = command,
action = policy, action = policy,
target = target, target = target,

View File

@@ -64,7 +64,7 @@ object SuCallbackHandler {
val pm = context.packageManager val pm = context.packageManager
val log = runCatching { val log = runCatching {
pm.getPackageInfo(fromUid, pid)?.let { pm.getPackageInfo(fromUid, pid)?.applicationInfo?.let {
pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids) pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids)
} }
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids) }.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)

View File

@@ -125,8 +125,9 @@ object AppMigration {
apk: File, out: OutputStream, apk: File, out: OutputStream,
pkg: String, label: CharSequence pkg: String, label: CharSequence
): Boolean { ): Boolean {
val info = context.packageManager.getPackageArchiveInfo(apk.path, 0) ?: return false val pm = context.packageManager
val origLabel = info.applicationInfo.nonLocalizedLabel.toString() val info = pm.getPackageArchiveInfo(apk.path, 0)?.applicationInfo ?: return false
val origLabel = info.nonLocalizedLabel.toString()
try { try {
JarMap.open(apk, true).use { jar -> JarMap.open(apk, true).use { jar ->
val je = jar.getJarEntry(ANDROID_MANIFEST) val je = jar.getJarEntry(ANDROID_MANIFEST)
@@ -190,11 +191,12 @@ object AppMigration {
// Install and auto launch app // Install and auto launch app
val session = APKInstall.startSession(activity, pkg, onFailure) { val session = APKInstall.startSession(activity, pkg, onFailure) {
Config.suManager = pkg
Shell.cmd("touch $AppApkPath").exec()
launchApp(activity, pkg) launchApp(activity, pkg)
} }
Config.suManager = pkg val cmd = "adb_pm_install $repack $pkg"
val cmd = "touch $AppApkPath; adb_pm_install $repack $pkg"
if (Shell.cmd(cmd).exec().isSuccess) return true if (Shell.cmd(cmd).exec().isSuccess) return true
try { try {
@@ -239,11 +241,12 @@ object AppMigration {
} }
val apk = StubApk.current(activity) val apk = StubApk.current(activity)
val session = APKInstall.startSession(activity, APP_PACKAGE_NAME, onFailure) { val session = APKInstall.startSession(activity, APP_PACKAGE_NAME, onFailure) {
Config.suManager = ""
Shell.cmd("touch $AppApkPath").exec()
launchApp(activity, APP_PACKAGE_NAME) launchApp(activity, APP_PACKAGE_NAME)
dialog.dismiss() dialog.dismiss()
} }
Config.suManager = "" val cmd = "adb_pm_install $apk $APP_PACKAGE_NAME"
val cmd = "touch $AppApkPath; adb_pm_install $apk $APP_PACKAGE_NAME"
if (Shell.cmd(cmd).await().isSuccess) return if (Shell.cmd(cmd).await().isSuccess) return
val success = withContext(Dispatchers.IO) { val success = withContext(Dispatchers.IO) {
try { try {

View File

@@ -6,7 +6,6 @@ import android.system.ErrnoException
import android.system.Os import android.system.Os
import android.system.OsConstants import android.system.OsConstants
import android.system.OsConstants.O_WRONLY import android.system.OsConstants.O_WRONLY
import android.widget.Toast
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.core.os.postDelayed import androidx.core.os.postDelayed
import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.StubApk
@@ -15,13 +14,10 @@ import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.isRunningAsStub import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.copyAll import com.topjohnwu.magisk.core.ktx.copyAll
import com.topjohnwu.magisk.core.ktx.copyAndClose import com.topjohnwu.magisk.core.ktx.copyAndClose
import com.topjohnwu.magisk.core.ktx.reboot
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.DummyList import com.topjohnwu.magisk.core.utils.DummyList
import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils
@@ -585,6 +581,8 @@ abstract class MagiskInstallImpl protected constructor(
protected suspend fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess protected suspend fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
protected fun restore() = findImage() && "restore_imgs $srcBoot".sh().isSuccess
protected fun uninstall() = "run_uninstaller $AppApkPath".sh().isSuccess protected fun uninstall() = "run_uninstaller $AppApkPath".sh().isSuccess
@WorkerThread @WorkerThread
@@ -608,11 +606,10 @@ abstract class MagiskInstallImpl protected constructor(
} }
} }
abstract class MagiskInstaller( abstract class ConsoleInstaller(
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstallImpl(console, logs) { ) : MagiskInstallImpl(console, logs) {
override suspend fun exec(): Boolean { override suspend fun exec(): Boolean {
val success = super.exec() val success = super.exec()
if (success) { if (success) {
@@ -622,40 +619,51 @@ abstract class MagiskInstaller(
} }
return success return success
} }
}
abstract class CallBackInstaller : MagiskInstallImpl(DummyList, DummyList) {
suspend fun exec(callback: (Boolean) -> Unit): Boolean {
val success = exec()
callback(success)
return success
}
}
class MagiskInstaller {
class Patch( class Patch(
private val uri: Uri, private val uri: Uri,
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(console, logs) { ) : ConsoleInstaller(console, logs) {
override suspend fun operations() = patchFile(uri) override suspend fun operations() = patchFile(uri)
} }
class SecondSlot( class SecondSlot(
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(console, logs) { ) : ConsoleInstaller(console, logs) {
override suspend fun operations() = secondSlot() override suspend fun operations() = secondSlot()
} }
class Direct( class Direct(
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(console, logs) { ) : ConsoleInstaller(console, logs) {
override suspend fun operations() = direct() override suspend fun operations() = direct()
} }
class Emulator( class Emulator(
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(console, logs) { ) : ConsoleInstaller(console, logs) {
override suspend fun operations() = fixEnv() override suspend fun operations() = fixEnv()
} }
class Uninstall( class Uninstall(
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstallImpl(console, logs) { ) : ConsoleInstaller(console, logs) {
override suspend fun operations() = uninstall() override suspend fun operations() = uninstall()
override suspend fun exec(): Boolean { override suspend fun exec(): Boolean {
@@ -669,19 +677,11 @@ abstract class MagiskInstaller(
} }
} }
class FixEnv(private val callback: () -> Unit) : MagiskInstallImpl(DummyList, DummyList) { class Restore : CallBackInstaller() {
override suspend fun operations() = fixEnv() override suspend fun operations() = restore()
override suspend fun exec(): Boolean {
val success = super.exec()
callback()
context.toast(
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
Toast.LENGTH_LONG
)
if (success)
UiThreadHandler.handler.postDelayed(5000) { reboot() }
return success
} }
class FixEnv : CallBackInstaller() {
override suspend fun operations() = fixEnv()
} }
} }

View File

@@ -0,0 +1,42 @@
package com.topjohnwu.magisk.core.tasks
import android.net.Uri
import androidx.core.net.toFile
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.unzip
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
open class RunAction(
private val module: String,
private val console: MutableList<String>,
private val logs: MutableList<String>
) {
@Throws(IOException::class)
private suspend fun run(): Boolean {
return Shell.cmd("run_action \'$module\'").to(console, logs).exec().isSuccess
}
open suspend fun exec() = withContext(Dispatchers.IO) {
try {
if (!run()) {
console.add("! Run action failed")
false
} else {
true
}
} catch (e: IOException) {
Timber.e(e)
false
}
}
}

View File

@@ -2,154 +2,130 @@
<!--Sections--> <!--Sections-->
<string name="modules">الإضافات</string> <string name="modules">الإضافات</string>
<string name="superuser">المستخدم الخارق</string> <string name="superuser">صلاحية الروت</string>
<string name="logs">السجلات</string> <string name="logs">السجلات</string>
<string name="settings">الإعدادات</string> <string name="settings">الإعدادات</string>
<string name="install">التثبيت</string> <string name="install">تثبيت</string>
<string name="section_home">الرئيسية</string> <string name="section_home">الأساسي</string>
<string name="section_theme">المظهر</string> <string name="section_theme">السِمات</string>
<string name="denylist">القائمة السوداء</string>
<!--Home--> <!--Home-->
<string name="no_connection">لا يوجد اتصال متاح</string> <string name="no_connection">لا يوجد إتصال</string>
<string name="app_changelog">سجل التغييرات</string> <string name="app_changelog">تفاصيل التحديث</string>
<string name="loading">جارٍ التحميل...</string> <string name="loading">جارٍ التحميل...</string>
<string name="update">تحديث</string> <string name="update">تحديث</string>
<string name="not_available">غير متاح</string> <string name="not_available">غير/متوفر</string>
<string name="hide">إخفاء</string> <string name="hide">إخفاء</string>
<string name="home_package">الحزمة</string> <string name="home_package">الحزمة</string>
<string name="home_app_title">التطبيق</string>
<string name="home_notice_content">قم بتحميل Magisk فقط من صفحة GitHub الرسمية. الملفات من مصادر غير معروفة قد تكون ضارة!</string> <string name="home_support_title">تبرع لنا</string>
<string name="home_support_title">ادعمنا</string> <string name="home_item_source">الكود المصدري للتطبيق</string>
<string name="home_follow_title">تابعنا</string> <string name="home_support_content">مـاجـيسك هي، وستظل دوماً، مجانيةً و مفتوحة المصدر، اظهر اهتمامك لنا لكي نبقيها هكذا بدعم مالي صغير</string>
<string name="home_item_source">المصدر</string> <string name="home_installed_version">تم التثبيت</string>
<string name="home_support_content">Magisk مجاني ومفتوح المصدر وسيظل كذلك دائمًا. يمكنك إظهار دعمك لنا من خلال التبرع.</string> <string name="home_latest_version">آخر إصدار</string>
<string name="home_installed_version">المثبتة</string> <string name="invalid_update_channel">مصدر التحديث غير صالح</string>
<string name="home_latest_version">الأحدث</string>
<string name="invalid_update_channel">قناة التحديث غير صالحة</string>
<string name="uninstall_magisk_title">إلغاء تثبيت Magisk</string> <string name="uninstall_magisk_title">إلغاء تثبيت Magisk</string>
<string name="uninstall_magisk_msg">ستتم إزالة جميع الوحدات / تعطيلها!\nسيتم إزالة الروت!\nأي تخزين داخلي تم فك تشفيره باستخدام Magisk سيتم إعادة تشفيره!</string> <string name="uninstall_magisk_msg">ستُعطل/ستُحذف جميع الإضافات. سيُحذف الروت، وربما ستشفر بياناتك إذا لم تكن غير مشفرة حالياً.</string>
<!--Install--> <!--Install-->
<string name="keep_force_encryption">الحفاظ على التشفير الإجباري</string> <string name="keep_force_encryption">فرض التشفير الإجباري</string>
<string name="keep_dm_verity">الحفاظ على AVB 2.0/dm-verity</string> <string name="keep_dm_verity">فرض تشفيرات AVB2.0/dm-verity</string>
<string name="recovery_mode">وضع الاسترداد</string> <string name="recovery_mode">وضـع الريكفري</string>
<string name="install_options_title">الخيارات</string> <string name="install_options_title">الخيارات</string>
<string name="install_method_title">الطريقة</string> <string name="install_method_title">الطريقة</string>
<string name="install_next">التالي</string> <string name="install_next">التالي</string>
<string name="install_start">هيا بنا</string> <string name="install_start">هيا، بنا</string>
<string name="manager_download_install">اضغط للتنزيل والتثبيت</string> <string name="manager_download_install">اضغط للتنزيل و التثبيت</string>
<string name="direct_install">التثبيت المباشر (موصى به)</string> <string name="direct_install">تثبيت مباشر (موصى بها)</string>
<string name="install_inactive_slot">التثبيت على الشريحة غير النشطة (بعد OTA)</string> <string name="install_inactive_slot">التثبيت على المنطقة الغير نشطة (بعد OTA)</string>
<string name="install_inactive_slot_msg">سيتم إجبار جهازك على التمهيد إلى الشريحة غير النشطة الحالية بعد إعادة التشغيل!\nاستخدم هذا الخيار فقط بعد الانتهاء من OTA.\nهل تود المتابعة؟</string> <string name="install_inactive_slot_msg">سيُجبر جهازك للاقلاع على المنطقة الغير النشطة بعد إعادة التشغيل!\n استخدم هذا الخيار فقط بعد الانتهاء من OTA. استمرار؟</string>
<string name="setup_title">إعداد إضافي</string> <string name="setup_title">إعدادات إضافية</string>
<string name="select_patch_file">اختر وقم بعمل باتش ملف</string> <string name="select_patch_file">حدد و عدل ملفاً</string>
<string name="patch_file_msg">اختر صورة خام (*.img) أو ملف ODIN tarfile (*.tar) أو payload.bin (*.bin)</string> <string name="patch_file_msg">اختر ملف (*.img) أو ملف odin (*.tar)</string>
<string name="reboot_delay_toast">سيتم إعادة التشغيل في 5 ثوانٍ...</string> <string name="reboot_delay_toast">إعادة التشغيل بعد ٥ ثواني…</string>
<string name="flash_screen_title">التثبيت</string> <string name="flash_screen_title">التثبيت</string>
<!--Superuser--> <!--Superuser-->
<string name="su_request_title">طلب المستخدم الخارق</string> <string name="su_request_title">طلبات صلاحية الروت</string>
<string name="touch_filtered_warning">نظرًا لأن تطبيقًا ما يحجب طلب المستخدم الخارق، لا يمكن لـ Magisk التحقق من استجابتك</string>
<string name="deny">رفض</string> <string name="deny">رفض</string>
<string name="prompt">إشعار</string> <string name="prompt">طلب</string>
<string name="grant">منح</string> <string name="grant">سماح</string>
<string name="su_warning">يمنح حق الوصول الكامل لجهازك.\nارفض إذا لم تكن متأكدًا!</string> <string name="su_warning">يمنح حق الوصول الكامل إلى جهازك. ارفض إذا كنت غير متأكد!</string>
<string name="forever">دائمًا</string> <string name="forever">للأبد</string>
<string name="once">مرة واحدة</string> <string name="once">مرة واحدة</string>
<string name="tenmin">جار0 دقائق</string> <string name="tenmin">10 دقائق</string>
<string name="twentymin">20 دقيقة</string> <string name="twentymin">20 دقيقة</string>
<string name="thirtymin">30 دقيقة</string> <string name="thirtymin">30 دقيقة</string>
<string name="sixtymin">60 دقيقة</string> <string name="sixtymin">60 دقيقة</string>
<string name="su_allow_toast">%جار$s تم منحه حقوق المستخدم الخارق</string> <string name="su_allow_toast">تم منح صلاحيات الروت لـ%1$s</string>
<string name="su_deny_toast">%جار$s تم رفض حقوق المستخدم الخارق</string> <string name="su_deny_toast">تم رفض صلاحيات الروت لـ%1$s </string>
<string name="su_snack_grant">تم منح حقوق المستخدم الخارق لـ %جار$s</string> <string name="su_snack_grant">تم منح صلاحيات الروت لـ%1$s</string>
<string name="su_snack_deny">تم رفض حقوق المستخدم الخارق لـ %جار$s</string> <string name="su_snack_deny">تم رفض صلاحيات الروت لـ%1$s</string>
<string name="su_snack_notif_on">تم تفعيل الإشعارات لـ %جار$s</string> <string name="su_snack_notif_on">تم تفعيل الإشعارات لـ%1$s</string>
<string name="su_snack_notif_off">تم تعطيل الإشعارات لـ %جار$s</string> <string name="su_snack_notif_off">تم تعطيل الإشعارات لـ%1$s</string>
<string name="su_snack_log_on">تم تفعيل السجلات لـ %جار$s</string> <string name="su_snack_log_on">تم تفعيل السجلات لـ%1$s</string>
<string name="su_snack_log_off">تم تعطيل السجلات لـ %جار$s</string> <string name="su_snack_log_off">تم تعطيل السجلات لـ%1$s</string>
<string name="su_revoke_title">إلغاء؟</string> <string name="su_revoke_title">منع؟</string>
<string name="su_revoke_msg">تأكيد لإلغاء حقوق المستخدم الخارق لـ %جار$s</string> <string name="su_revoke_msg">هل تريد منع صلاحية %1$s?</string>
<string name="toast">إشعار</string> <string name="toast">اشعار</string>
<string name="none">لا شيء</string> <string name="none">بدون</string>
<string name="superuser_toggle_notification">الإشعارات</string> <string name="superuser_toggle_notification">الإشعارات</string>
<string name="superuser_toggle_revoke">إلغاء</string> <string name="superuser_toggle_revoke">منع</string>
<string name="superuser_policy_none">لم يطلب أي تطبيق بعد إذن المستخدم الخارق.</string> <string name="superuser_policy_none">لم يسأل آية تطبيق لصلاحيات الروت</string>
<!--Logs--> <!--Logs-->
<string name="log_data_none">أنت خالٍ من السجلات، جرب استخدام تطبيقات الروت الخاصة بك أكثر</string> <string name="log_data_none">لا يوجد أية سجلات هنا :-:، حاول استعمال تطبيقات روت اكثر</string>
<string name="log_data_magisk_none">سجلات Magisk فارغة، هذا غريب</string> <string name="log_data_magisk_none">لا توجد أيةَ سجلات ⊙_⊙</string>
<string name="menuSaveLog">حفظ السجل</string> <string name="menuSaveLog">حفظ السجلات</string>
<string name="menuClearLog">مسح السجل الآن</string> <string name="menuClearLog">حذف السجلات</string>
<string name="logs_cleared">تم مسح السجل بنجاح</string> <string name="logs_cleared">تم الحذف بنجاح</string>
<string name="pid">PID: %جار$d</string> <string name="pid">PID: %1$d</string>
<string name="target_uid">UID الهدف: %جار$d</string> <string name="target_uid">UID: %1$d</string>
<string name="target_pid">PID هدف النطاق المركب: %s</string>
<string name="selinux_context">سياق SELinux: %s</string>
<string name="supp_group">المجموعة التكميلية: %s</string>
<!--SafetyNet--> <!--SafetyNet-->
<!--MagiskHide--> <!-- MagiskHide -->
<string name="show_system_app">عرض تطبيقات النظام</string> <string name="show_system_app">إظهار برامج النظام</string>
<string name="show_os_app">عرض تطبيقات نظام التشغيل</string> <string name="hide_filter_hint">البحث بالإسم</string>
<string name="hide_filter_hint">التصفية بالاسم</string> <string name="hide_search">ابحث</string>
<string name="hide_search">بحث</string>
<!--Module--> <!--Module Fragment-->
<string name="no_info_provided">(لم يتم تقديم معلومات)</string> <string name="no_info_provided">(لم توفر معلومات)</string>
<string name="reboot_userspace">إعادة تشغيل ناعمة</string> <string name="reboot_recovery">إعادة التشغيل إلى Recovery</string>
<string name="reboot_recovery">إعادة التشغيل إلى وضع الاسترداد</string> <string name="reboot_bootloader">إعادة التشغيل إلى Bootloader</string>
<string name="reboot_bootloader">إعادة التشغيل إلى محمل الإقلاع</string> <string name="reboot_download">إعادة التشغيل إلى وضـع Odin</string>
<string name="reboot_download">إعادة التشغيل إلى وضع التنزيل</string> <string name="reboot_edl">إعادة التشغيل إلى وضـعية EDL</string>
<string name="reboot_edl">إعادة التشغيل إلى وضع EDL</string> <string name="module_version_author">%1$sبواسطة%2$s</string>
<string name="reboot_safe_mode">وضع الآمن</string> <string name="module_state_remove">إزالة </string>
<string name="module_state_remove">إزالة</string> <string name="module_state_restore">إسترجاع</string>
<string name="module_state_restore">استعادة</string> <string name="module_action_install_external">اختر من الذاكرة الداخلية</string>
<string name="module_action_install_external">التثبيت من التخزين</string> <string name="update_available">التحديث متوفر</string>
<string name="update_available">تحديث متاح</string> <string name="external_rw_permission_denied">امنحني إذن الولوج للذاكرة الداخلية</string>
<string name="suspend_text_riru">تم تعليق الإضافةة لأن %جار$s مفعّل</string>
<string name="suspend_text_zygisk">تم تعليق الإضافةة لأن %جار$s غير مفعّل</string>
<string name="zygisk_module_unloaded">لم يتم تحميل إضافة Zygisk بسبب عدم التوافق</string>
<string name="module_empty">لم يتم تثبيت أي إضافة</string>
<string name="confirm_install">هل تريد تثبيت الإضافة %جار$s؟</string>
<string name="confirm_install_title">تأكيد التثبيت</string>
<!--Settings--> <!--Settings -->
<string name="settings_dark_mode_title">وضع الثيم</string> <string name="settings_dark_mode_title">وضـعية الِسمات</string>
<string name="settings_dark_mode_message">اختر الوضع الذي يناسب نمطك!</string> <string name="settings_dark_mode_message">حدد الوضـع الذي يناسب ذوقك</string>
<string name="settings_dark_mode_light">دائمًا فاتح</string> <string name="settings_dark_mode_light">الوضـع المضيء</string>
<string name="settings_dark_mode_system">تابع النظام</string> <string name="settings_dark_mode_system">اتبّع النظام</string>
<string name="settings_dark_mode_dark">دائمًا داكن</string> <string name="settings_dark_mode_dark">وضـع الظلام</string>
<string name="settings_download_path_title">مسار التنزيل</string> <string name="settings_download_path_title">مسار التحميل</string>
<string name="settings_download_path_message">سيتم حفظ الملفات في %جار$s</string> <string name="settings_download_path_message">ستحمل الملفات إلى %1$s</string>
<string name="settings_hide_app_title">إخفاء تطبيق Magisk</string>
<string name="settings_hide_app_summary">تثبيت تطبيق وكيل بمعرف حزمة عشوائي واسم تطبيق مخصص</string>
<string name="settings_restore_app_title">استعادة تطبيق Magisk</string>
<string name="settings_restore_app_summary">إظهار التطبيق واستعادة APK الأصلي</string>
<string name="language">اللغة</string> <string name="language">اللغة</string>
<string name="system_default">(افتراضي النظام)</string> <string name="system_default">(الأفتراضي)</string>
<string name="settings_check_update_title">تحقق من التحديثات</string> <string name="settings_check_update_title">تحقق من التحديثات</string>
<string name="settings_check_update_summary">التحقق دوريًا من التحديثات في الخلفية</string> <string name="settings_check_update_summary">التحقق من التحديثات في الخلفية بشكل دوري</string>
<string name="settings_update_channel_title">قناة التحديث</string> <string name="settings_update_channel_title">مصدر التحديثات</string>
<string name="settings_update_stable">مستقر</string> <string name="settings_update_stable">مستقر</string>
<string name="settings_update_beta">بيتا</string> <string name="settings_update_beta">تجريبي</string>
<string name="settings_update_custom">مخصص</string> <string name="settings_update_custom">مخصص</string>
<string name="settings_update_custom_msg">أدخل عنوان URL لقناة مخصصة</string> <string name="settings_update_custom_msg">أدخل الرابط لمصدرك المخصص</string>
<string name="settings_zygisk_summary">تشغيل أجزاء من Magisk في خدمة zygote</string> <string name="settings_hosts_title">موانع الاعلانات</string>
<string name="settings_denylist_title">تفعيل القائمة السوداء</string> <string name="settings_hosts_summary">حجب الاعلانات دون تعديل النظام</string>
<string name="settings_denylist_summary">سيتم إرجاع جميع تعديلات Magisk للعمليات الموجودة في القائمة السوداء</string> <string name="settings_hosts_toast">تم تمكين خاصية حجب الاعلانات</string>
<string name="settings_denylist_config_title">تكوين القائمة السوداء</string> <string name="settings_app_name_hint">الإسم الجديد</string>
<string name="settings_denylist_config_summary">اختر العمليات التي سيتم تضمينها في القائمة السوداء</string> <string name="settings_app_name_helper">التطبيق الجديد سوف يملك هذا الإسم</string>
<string name="settings_hosts_title">مضيفين بدون نظام</string> <string name="settings_app_name_error">الصيغة غير مقبولة</string>
<string name="settings_hosts_summary">دعم المضيفين بدون نظام لتطبيقات حظر الإعلانات</string>
<string name="settings_hosts_toast">تم إضافة إضافة المضيفين بدون نظام</string>
<string name="settings_app_name_hint">اسم جديد</string>
<string name="settings_app_name_helper">سيتم إعادة تغليف التطبيق بهذا الاسم</string>
<string name="settings_app_name_error">تنسيق غير صالح</string>
<string name="settings_su_app_adb">التطبيقات و ADB</string> <string name="settings_su_app_adb">التطبيقات و ADB</string>
<string name="settings_su_app">التطبيقات فقط</string> <string name="settings_su_app">التطبيقات فقط</string>
<string name="settings_su_adb">ADB فقط</string> <string name="settings_su_adb">ADB فقط</string>
@@ -160,86 +136,55 @@
<string name="settings_su_request_30">30 ثانية</string> <string name="settings_su_request_30">30 ثانية</string>
<string name="settings_su_request_45">45 ثانية</string> <string name="settings_su_request_45">45 ثانية</string>
<string name="settings_su_request_60">60 ثانية</string> <string name="settings_su_request_60">60 ثانية</string>
<string name="superuser_access">وصول المستخدم الخارق</string> <string name="superuser_access">صلاحيات الروت</string>
<string name="auto_response">استجابة تلقائية</string> <string name="auto_response">الفعل التلقائي</string>
<string name="request_timeout">انتهاء مهلة الطلب</string> <string name="request_timeout">المهلة قبل الفعل التلقائي</string>
<string name="superuser_notification">إشعار المستخدم الخارق</string> <string name="superuser_notification">إشعارات طلبات الروت</string>
<string name="settings_su_reauth_title">إعادة التوثيق بعد الترقية</string> <string name="settings_su_reauth_title">إعادة المصادقة بعد الترقية</string>
<string name="settings_su_reauth_summary">طلب أذونات المستخدم الخارق مرة أخرى بعد ترقية التطبيقات</string> <string name="settings_su_reauth_summary">أعد مصادقة صلاحيات الروت بعد إجراء ترقيات للتطبيق</string>
<string name="settings_su_tapjack_title">حماية من اختراق النقرات</string> <string name="settings_customization">تخصيص</string>
<string name="settings_su_tapjack_summary">لن يستجيب مربع حوار طلب المستخدم الخارق لأي إدخال أثناء تغطيته بواسطة أي نافذة أو تراكب آخر</string>
<string name="settings_su_auth_title">توثيق المستخدم</string>
<string name="settings_su_auth_summary">طلب توثيق المستخدم أثناء طلبات المستخدم الخارق</string>
<string name="settings_su_auth_insecure">لا توجد طريقة توثيق مهيأة على الجهاز</string>
<string name="settings_customization">التخصيص</string>
<string name="setting_add_shortcut_summary">إضافة اختصار جميل إلى الشاشة الرئيسية في حالة كان الاسم والأيقونة صعب التعرف عليهما بعد إخفاء التطبيق</string>
<string name="settings_doh_title">DNS عبر HTTPS</string>
<string name="settings_doh_description">الحل لمشكلة تسميم DNS في بعض الدول</string>
<string name="settings_random_name_title">تغيير الاسم عشوائيًا</string>
<string name="settings_random_name_description">تغيير اسم ملف الخرج عشوائيًا لصور وملفات tar المصححة لمنع الاكتشاف</string>
<string name="multiuser_mode">وضع المستخدمين المتعددين</string> <string name="multiuser_mode">نمط مستخدمين متعددين</string>
<string name="settings_owner_only">مالك الجهاز فقط</string> <string name="settings_owner_only">مالك الجهاز فقط</string>
<string name="settings_owner_manage">يديرها مالك الجهاز</string> <string name="settings_owner_manage">المالك هو من يحدد</string>
<string name="settings_user_independent">مستقل عن المستخدم</string> <string name="settings_user_independent">مستقل </string>
<string name="owner_only_summary">فقط المالك له وصول روت</string> <string name="owner_only_summary">للمالك فقط له صلاحيات الروت</string>
<string name="owner_manage_summary">فقط المالك يمكنه إدارة وصول الروت وتلقي طلبات الإذن</string> <string name="owner_manage_summary">فقط المالك من يرفض و يمنح صلاحيات الروت</string>
<string name="user_independent_summary">كل مستخدم لديه قواعد الروت الخاصة به</string> <string name="user_independent_summary">كل مستخدم له قواعد روت خاصة به</string>
<string name="mount_namespace_mode">وضع مساحة التثبيت</string> <string name="mount_namespace_mode">نمط Mount Namespace</string>
<string name="settings_ns_global">مساحة أسماء عامة</string> <string name="settings_ns_global">نمط Namespace العام</string>
<string name="settings_ns_requester">وراثة مساحة الأسماء</string> <string name="settings_ns_requester">نمط NameSpace المتوارث</string>
<string name="settings_ns_isolate">مساحة أسماء معزولة</string> <string name="settings_ns_isolate">نمط NameSpace المعزول</string>
<string name="global_summary">جميع جلسات الروت تستخدم مساحة التثبيت العامة</string> <string name="global_summary">جميع الجلسات الروت تستخدم NameSpace العام</string>
<string name="requester_summary">جلسات الروت سترث مساحة الأسماء من طالب الروت</string> <string name="requester_summary">جميع الجلسات الروت تستخدم NameSpace المتوارث</string>
<string name="isolate_summary">كل جلسة روت سيكون لها مساحة أسماء معزولة خاصة بها</string> <string name="isolate_summary">جميع الجلسات الروت تستخدم NameSpace المعزول</string>
<!--Notifications--> <!--Notifications-->
<string name="update_channel">تحديثات Magisk</string> <string name="update_channel">تحديثات Magisk</string>
<string name="progress_channel">إشعارات التقدم</string> <string name="progress_channel">إشعارات التقدم</string>
<string name="updated_channel">اكتمل التحديث</string>
<string name="download_complete">اكتمل التنزيل</string> <string name="download_complete">اكتمل التنزيل</string>
<string name="download_file_error">خطأ في تنزيل الملف</string> <string name="download_file_error">فشل تنزيل الملف</string>
<string name="magisk_update_title">تحديث Magisk متاح!</string> <string name="magisk_update_title">تحديث مـاجـيسك متوفر!</string>
<string name="updated_title">تم تحديث Magisk</string>
<string name="updated_text">اضغط لفتح التطبيق</string>
<!--Toasts, Dialogs--> <!--Toasts, Dialogs-->
<string name="yes">نعم</string> <string name="yes">نعم</string>
<string name="no">لا</string> <string name="no">لا</string>
<string name="download">تنزيل</string> <string name="download">تنزيل</string>
<string name="reboot">إعادة التشغيل</string> <string name="reboot">إعادة التشغيل</string>
<string name="release_notes">ملاحظات الإصدار</string> <string name="release_notes">معلومات الأصدار الجديد</string>
<string name="flashing">جارٍ التثبيت...</string> <string name="flashing">يتم الحرق...</string>
<string name="done">تم!</string> <string name="done">تم!</string>
<string name="failure">فشل!</string> <string name="failure">فشل!</string>
<string name="hide_app_title">جارٍ إخفاء تطبيق Magisk...</string> <string name="open_link_failed_toast">لم يُعثر على تطبيق لفتح الرابط …</string>
<string name="open_link_failed_toast">لم يتم العثور على تطبيق لفتح الرابط</string> <string name="complete_uninstall">إلغاء التثبيت بالكامل</string>
<string name="complete_uninstall">إلغاء التثبيت الكامل</string>
<string name="restore_img">استعادة الصور</string> <string name="restore_img">استعادة الصور</string>
<string name="restore_img_msg">جارٍ الاستعادة...</string> <string name="restore_img_msg">جار الأستعادة</string>
<string name="restore_done">اكتملت الاستعادة!</string> <string name="restore_done">تم الأستعادة</string>
<string name="restore_fail">لا يوجد نسخة احتياطية أصلية!</string> <string name="restore_fail">النسخة الاحتياطية الأصلية غير موجودة!</string>
<string name="setup_fail">فشل الإعداد</string> <string name="setup_fail">فشل التضبيط</string>
<string name="env_fix_title">يتطلب إعداد إضافي</string> <string name="env_fix_title"> الإعداد الأضافي مطلوب</string>
<string name="env_fix_msg">يحتاج جهازك إلى إعداد إضافي ليعمل Magisk بشكل صحيح. هل تريد المتابعة وإعادة التشغيل؟</string> <string name="setup_msg">جار تضبيت البيئة</string>
<string name="env_full_fix_msg">يحتاج جهازك إلى إعادة تثبيت Magisk ليعمل بشكل صحيح. يرجى إعادة تثبيت Magisk من داخل التطبيق، لا يمكن لوضع الاسترداد الحصول على معلومات الجهاز الصحيحة.</string> <string name="unsupport_magisk_title">إصدار مـاجـيسك غير مدعوم</string>
<string name="setup_msg">جارٍ تشغيل إعداد البيئة...</string>
<string name="unsupport_magisk_title">إصدار Magisk غير مدعوم</string>
<string name="unsupport_magisk_msg">هذا الإصدار من التطبيق لا يدعم إصدارات Magisk الأقل من %جار$s.\n\nسيعمل التطبيق كما لو أن Magisk غير مثبت، يرجى ترقية Magisk في أقرب وقت ممكن.</string>
<string name="unsupport_general_title">حالة غير طبيعية</string>
<string name="unsupport_system_app_msg">تشغيل هذا التطبيق كتطبيق نظام غير مدعوم. يرجى إعادة التطبيق إلى تطبيق مستخدم.</string>
<string name="unsupport_other_su_msg">تم اكتشاف "su" ثنائي ليس من Magisk. يرجى إزالة أي حل روت منافس و/أو إعادة تثبيت Magisk.</string>
<string name="unsupport_external_storage_msg">تم تثبيت Magisk في التخزين الخارجي. يرجى نقل التطبيق إلى التخزين الداخلي.</string>
<string name="unsupport_nonroot_stub_msg">لا يمكن للتطبيق المخفي Magisk الاستمرار في العمل لأن الروت قد فقد. يرجى استعادة APK الأصلي.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">امنح إذن التخزين لتمكين هذه الوظيفة</string>
<string name="post_notifications_denied">امنح إذن الإشعارات لتمكين هذه الوظيفة</string>
<string name="install_unknown_denied">اسمح بتثبيت "التطبيقات غير المعروفة" لتمكين هذه الوظيفة</string>
<string name="add_shortcut_title">إضافة اختصار إلى الشاشة الرئيسية</string>
<string name="add_shortcut_msg">بعد إخفاء هذا التطبيق، قد يصبح من الصعب التعرف على اسمه ورمزه. هل تريد إضافة اختصار جميل إلى الشاشة الرئيسية؟</string>
<string name="app_not_found">لم يتم العثور على تطبيق لمعالجة هذا الإجراء</string>
<string name="reboot_apply_change">إعادة التشغيل لتطبيق التغييرات</string>
<string name="restore_app_confirmation">سيؤدي هذا إلى استعادة التطبيق المخفي إلى التطبيق الأصلي. هل تريد حقًا القيام بذلك؟</string>
</resources> </resources>

View File

@@ -105,6 +105,7 @@
<string name="reboot_safe_mode">Modo de segurança</string> <string name="reboot_safe_mode">Modo de segurança</string>
<string name="module_version_author">%1$s por %2$s</string> <string name="module_version_author">%1$s por %2$s</string>
<string name="module_state_remove">Remover</string> <string name="module_state_remove">Remover</string>
<string name="module_action">Ação</string>
<string name="module_state_restore">Restaurar</string> <string name="module_state_restore">Restaurar</string>
<string name="module_action_install_external">Instalar a partir do armazenamento</string> <string name="module_action_install_external">Instalar a partir do armazenamento</string>
<string name="update_available">Atualização disponível</string> <string name="update_available">Atualização disponível</string>
@@ -173,7 +174,7 @@
<string name="settings_doh_title">DNS sobre HTTPS</string> <string name="settings_doh_title">DNS sobre HTTPS</string>
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string> <string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
<string name="settings_random_name_title">Randomizar nome de saída</string> <string name="settings_random_name_title">Randomizar nome de saída</string>
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar para evitar a detecção</string> <string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
<string name="multiuser_mode">Modo multiusuário</string> <string name="multiuser_mode">Modo multiusuário</string>
<string name="settings_owner_only">Somente proprietário do dispositivo</string> <string name="settings_owner_only">Somente proprietário do dispositivo</string>
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string> <string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
@@ -205,9 +206,12 @@
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string> <string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
<string name="download">Baixar</string> <string name="download">Baixar</string>
<string name="reboot">Reiniciar</string> <string name="reboot">Reiniciar</string>
<string name="close">Fechar</string>
<string name="release_notes">Notas da atualização</string> <string name="release_notes">Notas da atualização</string>
<string name="flashing">Flashando…</string> <string name="flashing">Flashando…</string>
<string name="running">Executando…</string>
<string name="done">Concluído!</string> <string name="done">Concluído!</string>
<string name="done_action">Ação de execução de %1$s concluída</string>
<string name="failure">Falhou!</string> <string name="failure">Falhou!</string>
<string name="hide_app_title">Ocultando o app do Magisk…</string> <string name="hide_app_title">Ocultando o app do Magisk…</string>
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string> <string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>

View File

@@ -105,6 +105,7 @@
<string name="reboot_safe_mode">Modo de segurança</string> <string name="reboot_safe_mode">Modo de segurança</string>
<string name="module_version_author">%1$s por %2$s</string> <string name="module_version_author">%1$s por %2$s</string>
<string name="module_state_remove">Remover</string> <string name="module_state_remove">Remover</string>
<string name="module_action">Ação</string>
<string name="module_state_restore">Restaurar</string> <string name="module_state_restore">Restaurar</string>
<string name="module_action_install_external">Instalar a partir do armazenamento</string> <string name="module_action_install_external">Instalar a partir do armazenamento</string>
<string name="update_available">Atualização disponível</string> <string name="update_available">Atualização disponível</string>
@@ -173,7 +174,7 @@
<string name="settings_doh_title">DNS sobre HTTPS</string> <string name="settings_doh_title">DNS sobre HTTPS</string>
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string> <string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
<string name="settings_random_name_title">Randomizar nome de saída</string> <string name="settings_random_name_title">Randomizar nome de saída</string>
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar para evitar a detecção</string> <string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
<string name="multiuser_mode">Modo multiusuário</string> <string name="multiuser_mode">Modo multiusuário</string>
<string name="settings_owner_only">Somente proprietário do dispositivo</string> <string name="settings_owner_only">Somente proprietário do dispositivo</string>
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string> <string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
@@ -205,9 +206,12 @@
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string> <string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
<string name="download">Baixar</string> <string name="download">Baixar</string>
<string name="reboot">Reiniciar</string> <string name="reboot">Reiniciar</string>
<string name="close">Fechar</string>
<string name="release_notes">Notas da atualização</string> <string name="release_notes">Notas da atualização</string>
<string name="flashing">Flashando…</string> <string name="flashing">Flashando…</string>
<string name="running">Executando…</string>
<string name="done">Concluído!</string> <string name="done">Concluído!</string>
<string name="done_action">Ação de execução de %1$s concluída</string>
<string name="failure">Falhou!</string> <string name="failure">Falhou!</string>
<string name="hide_app_title">Ocultando o app do Magisk…</string> <string name="hide_app_title">Ocultando o app do Magisk…</string>
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string> <string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>

View File

@@ -74,7 +74,6 @@
<string name="su_revoke_msg">Konfirmo për të hequr të drejtat e %1$s?</string> <string name="su_revoke_msg">Konfirmo për të hequr të drejtat e %1$s?</string>
<string name="toast">Dolli</string> <string name="toast">Dolli</string>
<string name="none">Asnjë</string> <string name="none">Asnjë</string>
<string name="superuser_toggle_notification">Njoftimet</string> <string name="superuser_toggle_notification">Njoftimet</string>
<string name="superuser_toggle_revoke">Të drejtat</string> <string name="superuser_toggle_revoke">Të drejtat</string>
<string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar akoma akses për super-përdoruesin.</string> <string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar akoma akses për super-përdoruesin.</string>
@@ -91,8 +90,6 @@
<string name="selinux_context">Konteksti SELinux: %s</string> <string name="selinux_context">Konteksti SELinux: %s</string>
<string name="supp_group">Grupi suplementar: %s</string> <string name="supp_group">Grupi suplementar: %s</string>
<!--SafetyNet-->
<!--MagiskHide--> <!--MagiskHide-->
<string name="show_system_app">Shfaq aplikacionet e sistemit</string> <string name="show_system_app">Shfaq aplikacionet e sistemit</string>
<string name="show_os_app">Shfaq aplikacionet e sistemit operativ</string> <string name="show_os_app">Shfaq aplikacionet e sistemit operativ</string>
@@ -109,6 +106,7 @@
<string name="reboot_safe_mode">Rinis në safe mode</string> <string name="reboot_safe_mode">Rinis në safe mode</string>
<string name="module_version_author">%1$s nga %2$s</string> <string name="module_version_author">%1$s nga %2$s</string>
<string name="module_state_remove">Hiqe</string> <string name="module_state_remove">Hiqe</string>
<string name="module_action">Veprim</string>
<string name="module_state_restore">Rikëthe</string> <string name="module_state_restore">Rikëthe</string>
<string name="module_action_install_external">Instaloni nga sdcard</string> <string name="module_action_install_external">Instaloni nga sdcard</string>
<string name="update_available">Përditësimi në dispozicion</string> <string name="update_available">Përditësimi në dispozicion</string>
@@ -207,9 +205,12 @@
<string name="repo_install_title">Instalo %1$s %2$s(%3$d)</string> <string name="repo_install_title">Instalo %1$s %2$s(%3$d)</string>
<string name="download">Shkarko</string> <string name="download">Shkarko</string>
<string name="reboot">Rinis</string> <string name="reboot">Rinis</string>
<string name="close">Mbylle</string>
<string name="release_notes">Shënimet e lëshimit</string> <string name="release_notes">Shënimet e lëshimit</string>
<string name="flashing">Duke flashuar…</string> <string name="flashing">Duke flashuar…</string>
<string name="running">Duke vepruar...</string>
<string name="done">U krye!</string> <string name="done">U krye!</string>
<string name="done_action">Veprimi i ekzekutimit të %1$s u krye</string>
<string name="failure">Dështoi!</string> <string name="failure">Dështoi!</string>
<string name="hide_app_title">Fshehja e aplikacionit Magisk…</string> <string name="hide_app_title">Fshehja e aplikacionit Magisk…</string>
<string name="open_link_failed_toast">Nuk u gjet asnjë aplikacion për të hapur lidhjen</string> <string name="open_link_failed_toast">Nuk u gjet asnjë aplikacion për të hapur lidhjen</string>

View File

@@ -109,6 +109,7 @@
<string name="reboot_safe_mode">安全模式</string> <string name="reboot_safe_mode">安全模式</string>
<string name="module_version_author">%1$s作者 %2$s</string> <string name="module_version_author">%1$s作者 %2$s</string>
<string name="module_state_remove">移除</string> <string name="module_state_remove">移除</string>
<string name="module_action">操作</string>
<string name="module_state_restore">还原</string> <string name="module_state_restore">还原</string>
<string name="module_action_install_external">从本地安装</string> <string name="module_action_install_external">从本地安装</string>
<string name="update_available">可更新</string> <string name="update_available">可更新</string>
@@ -211,9 +212,12 @@
<string name="repo_install_title">安装 %1$s %2$s(%3$d)</string> <string name="repo_install_title">安装 %1$s %2$s(%3$d)</string>
<string name="download">下载</string> <string name="download">下载</string>
<string name="reboot">重启</string> <string name="reboot">重启</string>
<string name="close">关闭</string>
<string name="release_notes">发布说明</string> <string name="release_notes">发布说明</string>
<string name="flashing">正在刷入</string> <string name="flashing">正在刷入</string>
<string name="running">运行中……</string>
<string name="done">完成!</string> <string name="done">完成!</string>
<string name="done_action">%1$s 操作运行完成</string>
<string name="failure">失败</string> <string name="failure">失败</string>
<string name="hide_app_title">正在隐藏 Magisk 应用</string> <string name="hide_app_title">正在隐藏 Magisk 应用</string>
<string name="open_link_failed_toast">找不到能打开此链接的应用</string> <string name="open_link_failed_toast">找不到能打开此链接的应用</string>

View File

@@ -109,6 +109,7 @@
<string name="reboot_safe_mode">Safe mode</string> <string name="reboot_safe_mode">Safe mode</string>
<string name="module_version_author">%1$s by %2$s</string> <string name="module_version_author">%1$s by %2$s</string>
<string name="module_state_remove">Remove</string> <string name="module_state_remove">Remove</string>
<string name="module_action">Action</string>
<string name="module_state_restore">Restore</string> <string name="module_state_restore">Restore</string>
<string name="module_action_install_external">Install from storage</string> <string name="module_action_install_external">Install from storage</string>
<string name="update_available">Update Available</string> <string name="update_available">Update Available</string>
@@ -211,9 +212,12 @@
<string name="repo_install_title">Install %1$s %2$s(%3$d)</string> <string name="repo_install_title">Install %1$s %2$s(%3$d)</string>
<string name="download">Download</string> <string name="download">Download</string>
<string name="reboot">Reboot</string> <string name="reboot">Reboot</string>
<string name="close">Close</string>
<string name="release_notes">Release notes</string> <string name="release_notes">Release notes</string>
<string name="flashing">Flashing…</string> <string name="flashing">Flashing…</string>
<string name="running">Running…</string>
<string name="done">Done!</string> <string name="done">Done!</string>
<string name="done_action">Done running action of %1$s</string>
<string name="failure">Failed!</string> <string name="failure">Failed!</string>
<string name="hide_app_title">Hiding the Magisk app…</string> <string name="hide_app_title">Hiding the Magisk app…</string>
<string name="open_link_failed_toast">No app found to open the link</string> <string name="open_link_failed_toast">No app found to open the link</string>

View File

@@ -69,7 +69,7 @@ private val Project.androidComponents
fun Project.setupCommon() { fun Project.setupCommon() {
androidBase { androidBase {
compileSdkVersion(34) compileSdkVersion(35)
buildToolsVersion = "34.0.0" buildToolsVersion = "34.0.0"
ndkPath = "$sdkDirectory/ndk/magisk" ndkPath = "$sdkDirectory/ndk/magisk"
ndkVersion = "27.0.12077973" ndkVersion = "27.0.12077973"
@@ -79,8 +79,8 @@ fun Project.setupCommon() {
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_21
} }
packagingOptions { packagingOptions {
@@ -108,15 +108,15 @@ fun Project.setupCommon() {
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
compilerOptions { compilerOptions {
jvmTarget = JvmTarget.JVM_17 jvmTarget = JvmTarget.JVM_21
} }
} }
} }
const val BUSYBOX_DOWNLOAD_URL = const val BUSYBOX_DOWNLOAD_URL =
"https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.0.zip" "https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.1.zip"
const val BUSYBOX_ZIP_CHECKSUM = const val BUSYBOX_ZIP_CHECKSUM =
"ea4f3019b0087dcb68130b32ab59dc2db0ee0af11d8396124a94c4231c5ea441" "b4d0551feabaf314e53c79316c980e8f66432e9fb91a69dbbf10a93564b40951"
fun Project.setupCoreLib() { fun Project.setupCoreLib() {
setupCommon() setupCommon()
@@ -296,7 +296,7 @@ fun Project.setupAppCommon() {
} }
defaultConfig { defaultConfig {
targetSdk = 34 targetSdk = 35
} }
buildTypes { buildTypes {
@@ -375,8 +375,8 @@ fun Project.setupStub() {
val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile
val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile
val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2") val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2")
val apk = layout.buildDirectory.file("intermediates/processed_res/" + val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
"${variantLowered}/process${variantCapped}Resources/out/resources-${variantLowered}.ap_").get().asFile "${variantLowered}/process${variantCapped}Resources/linked-resources-binary-format-${variantLowered}.ap_").get().asFile
val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") { val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") {
inputs.property("seed", RAND_SEED) inputs.property("seed", RAND_SEED)
@@ -417,8 +417,8 @@ fun Project.setupStub() {
registerJavaGeneratingTask(processResourcesTask, outResDir) registerJavaGeneratingTask(processResourcesTask, outResDir)
} }
// Override optimizeReleaseResources task // Override optimizeReleaseResources task
val apk = layout.buildDirectory.file("intermediates/processed_res/" + val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
"release/processReleaseResources/out/resources-release.ap_").get().asFile "release/processReleaseResources/linked-resources-binary-format-release.ap_").get().asFile
val optRes = layout.buildDirectory.file("intermediates/optimized_processed_res/" + val optRes = layout.buildDirectory.file("intermediates/optimized_processed_res/" +
"release/optimizeReleaseResources/resources-release-optimize.ap_").get().asFile "release/optimizeReleaseResources/resources-release-optimize.ap_").get().asFile
afterEvaluate { afterEvaluate {

View File

@@ -1,5 +1,29 @@
# Magisk Changelog # Magisk Changelog
### v28.0
- [General] Support 16k page size
- [General] Add basic support for RISC-V (not built in releases)
- [General] Use a minimal libc to build static executables (`magiskinit` and `magiskboot`) for smaller sizes
- [Core] Remove unnecessary mirror for magic mount
- [Core] Update boot image detection logic to support more devices
- [MagiskInit] Rewrite 2SI logic for injecting `magiskinit` as `init`
- [MagiskInit] Update preinit partition detection
- [Zygisk] Update internal JNI hooking implementation
- [MagiskPolicy] Preserve sepolicy config flag after patching
- [MagiskPolicy] Optimize patching rules to reduce the amount of new rules being injected
- [DenyList] Support enforcing denylist when Zygisk is disabled
- [Resetprop] Improve implementation to workaround several property modification detections
- [Resetprop] Update to properly work with property overlays
- [App] Major internal code refactoring
- [App] Support patching Samsung firmware with images larger than 8GiB
- [App] Use user-initiated job instead of foreground services on Android 14
- [App] Support Android 13+ built-in per-app language preferences
- [App] Add `action.sh` support to allow modules to define an action triggered from UI
- [MagiskBoot] Support spliting kernel images without decompression
- [MagiskBoot] Properly support vendor boot images
- [MagiskBoot] Disable Samsung PROCA from kernel image
### v27.0 ### v27.0
- [Zygisk] Introduce new code injection mechanism - [Zygisk] Introduce new code injection mechanism

View File

@@ -54,6 +54,7 @@ A Magisk module is a folder placed in `/data/adb/modules` with the structure bel
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data │ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
│ ├── service.sh <--- This script will be executed in late_start service │ ├── service.sh <--- This script will be executed in late_start service
| ├── uninstall.sh <--- This script will be executed when Magisk removes your module | ├── uninstall.sh <--- This script will be executed when Magisk removes your module
| ├── action.sh <--- This script will be executed when user click the action button in Magisk app
│ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop │ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
│ ├── sepolicy.rule <--- Additional custom sepolicy rules │ ├── sepolicy.rule <--- Additional custom sepolicy rules
│ │ │ │
@@ -231,7 +232,7 @@ The list above will result in the following files being created: `$MODPATH/syste
In Magisk, you can run boot scripts in 2 different modes: **post-fs-data** and **late_start service** mode. In Magisk, you can run boot scripts in 2 different modes: **post-fs-data** and **late_start service** mode.
- post-fs-data mode - post-fs-data mode
- This stage is BLOCKING. The boot process is paused before execution is done, or 10 seconds have passed. - This stage is BLOCKING. The boot process is paused before execution is done, or 40 seconds have passed.
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted. - Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
- This stage happens before Zygote is started, which pretty much means everything in Android - This stage happens before Zygote is started, which pretty much means everything in Android
- **WARNING:** using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead. - **WARNING:** using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead.

25
docs/releases/28000.md Normal file
View File

@@ -0,0 +1,25 @@
## 2024.10.10 Magisk v28.0
- [General] Support 16k page size
- [General] Add basic support for RISC-V (not built in releases)
- [General] Use a minimal libc to build static executables (`magiskinit` and `magiskboot`) for smaller sizes
- [Core] Remove unnecessary mirror for magic mount
- [Core] Update boot image detection logic to support more devices
- [MagiskInit] Rewrite 2SI logic for injecting `magiskinit` as `init`
- [MagiskInit] Update preinit partition detection
- [Zygisk] Update internal JNI hooking implementation
- [MagiskPolicy] Preserve sepolicy config flag after patching
- [MagiskPolicy] Optimize patching rules to reduce the amount of new rules being injected
- [DenyList] Support enforcing denylist when Zygisk is disabled
- [Resetprop] Improve implementation to workaround several property modification detections
- [Resetprop] Update to properly work with property overlays
- [App] Major internal code refactoring
- [App] Support patching Samsung firmware with images larger than 8GiB
- [App] Use user-initiated job instead of foreground services on Android 14
- [App] Support Android 13+ built-in per-app language preferences
- [App] Add `action.sh` support to allow modules to define an action triggered from UI
- [MagiskBoot] Support spliting kernel images without decompression
- [MagiskBoot] Properly support vendor boot images
- [MagiskBoot] Disable Samsung PROCA from kernel image
### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)

View File

@@ -1,5 +1,6 @@
# Release Notes # Release Notes
- [v28.0](28000.md)
- [v27.0](27000.md) - [v27.0](27000.md)
- [v26.4](26400.md) - [v26.4](26400.md)
- [v26.3](26300.md) - [v26.3](26300.md)

View File

@@ -41,7 +41,9 @@ Supported actions:
repack [-n] <origbootimg> [outbootimg] repack [-n] <origbootimg> [outbootimg]
Repack boot image components using files from the current directory Repack boot image components using files from the current directory
to [outbootimg], or 'new-boot.img' if not specified. to [outbootimg], or 'new-boot.img' if not specified. Current directory
should only contain required files for [outbootimg], or incorrect
[outbootimg] may be produced.
<origbootimg> is the original boot image used to unpack the components. <origbootimg> is the original boot image used to unpack the components.
By default, each component will be automatically compressed using its By default, each component will be automatically compressed using its
corresponding format detected in <origbootimg>. If a component file corresponding format detected in <origbootimg>. If a component file

View File

@@ -30,5 +30,5 @@ android.nonFinalResIds=false
# Magisk # Magisk
magisk.stubVersion=40 magisk.stubVersion=40
magisk.versionCode=27007 magisk.versionCode=28001
magisk.ondkVersion=r27.4 magisk.ondkVersion=r27.4

View File

@@ -1,9 +1,9 @@
[versions] [versions]
kotlin = "2.0.10" kotlin = "2.0.20"
android = "8.5.2" android = "8.7.0"
ksp = "2.0.10-1.0.24" ksp = "2.0.20-1.0.25"
rikka = "1.3.0" rikka = "1.3.0"
navigation = "2.7.7" navigation = "2.8.2"
libsu = "6.0.0" libsu = "6.0.0"
moshi = "1.15.1" moshi = "1.15.1"
okhttp = "4.12.0" okhttp = "4.12.0"
@@ -12,7 +12,7 @@ room = "2.6.1"
[libraries] [libraries]
bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.78.1" } bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.78.1" }
commons-compress = { module = "org.apache.commons:commons-compress", version = "1.27.0" } commons-compress = { module = "org.apache.commons:commons-compress", version = "1.27.1" }
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" } retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
retrofit-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" } retrofit-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" }
@@ -26,24 +26,25 @@ timber = { module = "com.jakewharton.timber:timber", version = "5.0.1" }
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.10.0.202406032230-r" } jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.10.0.202406032230-r" }
# AndroidX # AndroidX
activity = { module = "androidx.activity:activity", version = "1.9.1" } activity = { module = "androidx.activity:activity", version = "1.9.2" }
appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.0" } appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.0" }
core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" } core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" }
core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" } core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" } constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" }
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.2" } fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.4" }
navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" } navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" }
navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigation" } navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigation" }
profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version = "1.3.1" } profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version = "1.4.1" }
recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.2" } recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.2" }
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" } swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
transition = { module = "androidx.transition:transition", version = "1.5.1" } transition = { module = "androidx.transition:transition", version = "1.5.1" }
collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.4.3" } collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.4.4" }
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version = "2.8.4" } lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version = "2.8.6" }
material = { module = "com.google.android.material:material", version = "1.12.0" } material = { module = "com.google.android.material:material", version = "1.12.0" }
jdk-libs = { module = "com.android.tools:desugar_jdk_libs_nio", version = "2.1.2" }
# topjohnwu # topjohnwu
indeterminate-checkbox = { module = "com.github.topjohnwu:indeterminate-checkbox", version = "1.0.7" } indeterminate-checkbox = { module = "com.github.topjohnwu:indeterminate-checkbox", version = "1.0.7" }

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -366,7 +366,7 @@ static const char *vendor_ramdisk_type(int type) {
} }
#define assert_off() \ #define assert_off() \
if ((base_addr + off) > (map.buf() + map.sz())) { \ if ((base_addr + off) > (map.buf() + map_end)) { \
fprintf(stderr, "Corrupted boot image!\n"); \ fprintf(stderr, "Corrupted boot image!\n"); \
return false; \ return false; \
} }
@@ -395,6 +395,7 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
hdr->print(); hdr->print();
size_t map_end = align_to(map.sz(), getpagesize());
size_t off = hdr->hdr_space(); size_t off = hdr->hdr_space();
get_block(kernel); get_block(kernel);
get_block(ramdisk); get_block(ramdisk);
@@ -408,7 +409,7 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
payload = byte_view(base_addr, off); payload = byte_view(base_addr, off);
auto tail_addr = base_addr + off; auto tail_addr = base_addr + off;
tail = byte_view(tail_addr, map.buf() + map.sz() - tail_addr); tail = byte_view(tail_addr, map.buf() + map_end - tail_addr);
if (auto size = hdr->kernel_size()) { if (auto size = hdr->kernel_size()) {
if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) { if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {

View File

@@ -8,10 +8,6 @@ using namespace std;
#ifdef USE_CRT0 #ifdef USE_CRT0
__BEGIN_DECLS __BEGIN_DECLS
int tfp_vsscanf(const char *s, const char *fmt, va_list args);
int vsscanf(const char *s, const char *fmt, va_list args) {
return tfp_vsscanf(s, fmt, args);
}
int musl_vfprintf(FILE *stream, const char *format, va_list arg); int musl_vfprintf(FILE *stream, const char *format, va_list arg);
int vfprintf(FILE *stream, const char *format, va_list arg) { int vfprintf(FILE *stream, const char *format, va_list arg) {
return musl_vfprintf(stream, format, arg); return musl_vfprintf(stream, format, arg);
@@ -48,7 +44,9 @@ Supported actions:
repack [-n] <origbootimg> [outbootimg] repack [-n] <origbootimg> [outbootimg]
Repack boot image components using files from the current directory Repack boot image components using files from the current directory
to [outbootimg], or 'new-boot.img' if not specified. to [outbootimg], or 'new-boot.img' if not specified. Current directory
should only contain required files for [outbootimg], or incorrect
[outbootimg] may be produced.
<origbootimg> is the original boot image used to unpack the components. <origbootimg> is the original boot image used to unpack the components.
By default, each component will be automatically compressed using its By default, each component will be automatically compressed using its
corresponding format detected in <origbootimg>. If a component file corresponding format detected in <origbootimg>. If a component file
@@ -150,6 +148,8 @@ int main(int argc, char *argv[]) {
unlink(EXTRA_FILE); unlink(EXTRA_FILE);
unlink(RECV_DTBO_FILE); unlink(RECV_DTBO_FILE);
unlink(DTB_FILE); unlink(DTB_FILE);
unlink(BOOTCONFIG_FILE);
rm_rf(VND_RAMDISK_DIR);
} else if (argc > 2 && action == "sha1") { } else if (argc > 2 && action == "sha1") {
uint8_t sha1[20]; uint8_t sha1[20];
{ {

View File

@@ -230,7 +230,9 @@ kv_pairs load_partition_map() {
} }
bool check_two_stage() { bool check_two_stage() {
if (access("/apex", F_OK) == 0) if (access("/first_stage_ramdisk", F_OK) == 0)
return true;
if (access("/second_stage_resources", F_OK) == 0)
return true; return true;
if (access("/system/bin/init", F_OK) == 0) if (access("/system/bin/init", F_OK) == 0)
return true; return true;

View File

@@ -13,9 +13,9 @@ using namespace std;
#ifdef USE_CRT0 #ifdef USE_CRT0
__BEGIN_DECLS __BEGIN_DECLS
int tfp_vfprintf(FILE *stream, const char *format, va_list arg); int tiny_vfprintf(FILE *stream, const char *format, va_list arg);
int vfprintf(FILE *stream, const char *format, va_list arg) { int vfprintf(FILE *stream, const char *format, va_list arg) {
return tfp_vfprintf(stream, format, arg); return tiny_vfprintf(stream, format, arg);
} }
__END_DECLS __END_DECLS
#endif #endif
@@ -90,15 +90,17 @@ int main(int argc, char *argv[]) {
} else { } else {
// This will also mount /sys and /proc // This will also mount /sys and /proc
load_kernel_info(&config); load_kernel_info(&config);
bool recovery = access("/sbin/recovery", F_OK) == 0 ||
access("/system/bin/recovery", F_OK) == 0;
if (config.skip_initramfs) if (config.force_normal_boot)
init = new FirstStageInit(argv, &config);
else if (!recovery && check_two_stage())
init = new FirstStageInit(argv, &config);
else if (config.skip_initramfs)
init = new LegacySARInit(argv, &config); init = new LegacySARInit(argv, &config);
else if (config.force_normal_boot) else if (recovery)
init = new FirstStageInit(argv, &config);
else if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
init = new RecoveryInit(argv, &config); init = new RecoveryInit(argv, &config);
else if (check_two_stage())
init = new FirstStageInit(argv, &config);
else else
init = new RootFSInit(argv, &config); init = new RootFSInit(argv, &config);
} }

View File

@@ -200,8 +200,7 @@ mount_root:
xmount("tmpfs", "/dev", "tmpfs", 0, "mode=755"); xmount("tmpfs", "/dev", "tmpfs", 0, "mode=755");
mount_list.emplace_back("/dev"); mount_list.emplace_back("/dev");
// Use the apex folder to determine whether 2SI (Android 10+) bool is_two_stage = access("/system/bin/init", F_OK) == 0;
bool is_two_stage = access("/apex", F_OK) == 0;
LOGD("is_two_stage: [%d]\n", is_two_stage); LOGD("is_two_stage: [%d]\n", is_two_stage);
// For API 28 AVD, it uses legacy SAR setup that requires // For API 28 AVD, it uses legacy SAR setup that requires

View File

@@ -14,7 +14,6 @@ pub fn inject_magisk_rc(fd: RawFd, tmp_dir: &Utf8CStr) {
file, file,
r#" r#"
on post-fs-data on post-fs-data
start logd
exec {0} 0 0 -- {1}/magisk --post-fs-data exec {0} 0 0 -- {1}/magisk --post-fs-data
on property:vold.decrypt=trigger_restart_framework on property:vold.decrypt=trigger_restart_framework

View File

@@ -271,6 +271,10 @@ bool sepol_impl::add_rule(const char *s, const char *t, const char *c, const cha
#define ioctl_func(x) (x & 0xFF) #define ioctl_func(x) (x & 0xFF)
void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect) { void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect) {
if (db->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) {
LOGW("policy version %u does not support ioctl extended permissions rules\n", db->policyvers);
return;
}
if (src == nullptr) { if (src == nullptr) {
for_each_attr(db->p_types.table, [&](type_datum_t *type) { for_each_attr(db->p_types.table, [&](type_datum_t *type) {
add_xperm_rule(type, tgt, cls, p, effect); add_xperm_rule(type, tgt, cls, p, effect);

View File

@@ -2,10 +2,14 @@
# Magisk app internal scripts # Magisk app internal scripts
################################## ##################################
# $1 = delay
# $2 = command
run_delay() { run_delay() {
(sleep $1; $2)& (sleep $1; $2)&
} }
# $1 = version string
# $2 = version code
env_check() { env_check() {
for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do
[ -f "$MAGISKBIN/$file" ] || return 1 [ -f "$MAGISKBIN/$file" ] || return 1
@@ -21,6 +25,8 @@ env_check() {
return 0 return 0
} }
# $1 = dir to copy
# $2 = destination (optional)
cp_readlink() { cp_readlink() {
if [ -z $2 ]; then if [ -z $2 ]; then
cd $1 cd $1
@@ -39,6 +45,7 @@ cp_readlink() {
cd / cd /
} }
# $1 = install dir
fix_env() { fix_env() {
# Cleanup and make dirs # Cleanup and make dirs
rm -rf $MAGISKBIN/* rm -rf $MAGISKBIN/*
@@ -49,6 +56,8 @@ fix_env() {
chown -R 0:0 $MAGISKBIN chown -R 0:0 $MAGISKBIN
} }
# $1 = install dir
# $2 = boot partition
direct_install() { direct_install() {
echo "- Flashing new boot image" echo "- Flashing new boot image"
flash_image $1/new-boot.img $2 flash_image $1/new-boot.img $2
@@ -70,6 +79,7 @@ direct_install() {
return 0 return 0
} }
# $1 = uninstaller zip
run_uninstaller() { run_uninstaller() {
rm -rf /dev/tmp rm -rf /dev/tmp
mkdir -p /dev/tmp/install mkdir -p /dev/tmp/install
@@ -77,24 +87,16 @@ run_uninstaller() {
INSTALLER=/dev/tmp/install sh /dev/tmp/install/assets/uninstaller.sh dummy 1 "$1" INSTALLER=/dev/tmp/install sh /dev/tmp/install/assets/uninstaller.sh dummy 1 "$1"
} }
# $1 = boot partition
restore_imgs() { restore_imgs() {
local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config) local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
local BACKUPDIR=/data/magisk_backup_$SHA1 local BACKUPDIR=/data/magisk_backup_$SHA1
[ -d $BACKUPDIR ] || return 1 [ -d $BACKUPDIR ] || return 1
get_flags
find_boot_image
for name in dtb dtbo; do
[ -f $BACKUPDIR/${name}.img.gz ] || continue
local IMAGE=$(find_block $name$SLOT)
[ -z $IMAGE ] && continue
flash_image $BACKUPDIR/${name}.img.gz $IMAGE
done
[ -f $BACKUPDIR/boot.img.gz ] || return 1 [ -f $BACKUPDIR/boot.img.gz ] || return 1
flash_image $BACKUPDIR/boot.img.gz $BOOTIMAGE flash_image $BACKUPDIR/boot.img.gz $1
} }
# $1 = path to bootctl executable
post_ota() { post_ota() {
cd /data/adb cd /data/adb
cp -f $1 bootctl cp -f $1 bootctl
@@ -131,6 +133,8 @@ EOF
cd / cd /
} }
# $1 = APK
# $2 = package name
adb_pm_install() { adb_pm_install() {
local tmp=/data/local/tmp/temp.apk local tmp=/data/local/tmp/temp.apk
cp -f "$1" $tmp cp -f "$1" $tmp
@@ -189,6 +193,15 @@ printvar() {
eval echo $1=\$$1 eval echo $1=\$$1
} }
run_action() {
local MODID="$1"
cd "/data/adb/modules/$MODID"
sh ./action.sh
local RES=$?
cd /
return $RES
}
########################## ##########################
# Non-root util_functions # Non-root util_functions
########################## ##########################

View File

@@ -206,7 +206,7 @@ fi
yes | "$sdk" --licenses > /dev/null yes | "$sdk" --licenses > /dev/null
curl -L $lsposed_url -o out/lsposed.zip curl -L $lsposed_url -o out/lsposed.zip
"$sdk" --channel=3 tools platform-tools emulator "$sdk" --channel=3 platform-tools emulator
if [ -n "$1" ]; then if [ -n "$1" ]; then
run_test $1 $2 run_test $1 $2

View File

@@ -220,6 +220,13 @@ if [ -f kernel ]; then
# After: [mov w2, #-32768] # After: [mov w2, #-32768]
./magiskboot hexpatch kernel 821B8012 E2FF8F12 && PATCHEDKERNEL=true ./magiskboot hexpatch kernel 821B8012 E2FF8F12 && PATCHEDKERNEL=true
# Disable Samsung PROCA
# proca_config -> proca_magisk
./magiskboot hexpatch kernel \
70726F63615F636F6E66696700 \
70726F63615F6D616769736B00 \
&& PATCHEDKERNEL=true
# Force kernel to load rootfs for legacy SAR devices # Force kernel to load rootfs for legacy SAR devices
# skip_initramfs -> want_initramfs # skip_initramfs -> want_initramfs
$LEGACYSAR && ./magiskboot hexpatch kernel \ $LEGACYSAR && ./magiskboot hexpatch kernel \