Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,3 @@ native/out
.idea
.cursor
ramdisk.img
app/core/src/debug
app/core/src/release
1 change: 0 additions & 1 deletion app/apk-ng/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ fun InstallBottomSheet(

SettingsArrow(
title = stringResource(CoreR.string.select_patch_file),
summary = stringResource(CoreR.string.select_patch_file_summary),
onClick = {
show.value = false
installVm.selectMethod(InstallViewModel.Method.PATCH)
Expand All @@ -133,7 +132,6 @@ fun InstallBottomSheet(
if (installVm.isRooted) {
SettingsArrow(
title = stringResource(CoreR.string.direct_install),
summary = stringResource(CoreR.string.direct_install_summary),
onClick = {
show.value = false
installVm.selectMethod(InstallViewModel.Method.DIRECT)
Expand All @@ -145,7 +143,6 @@ fun InstallBottomSheet(
if (!installVm.noSecondSlot) {
SettingsArrow(
title = stringResource(CoreR.string.install_inactive_slot),
summary = stringResource(CoreR.string.install_inactive_slot_summary),
onClick = {
show.value = false
installVm.selectMethod(InstallViewModel.Method.INACTIVE_SLOT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fun LogScreen(viewModel: LogViewModel) {
IconButton(onClick = { viewModel.saveMagiskLog() }) {
Icon(
imageVector = Icons.Default.Download,
contentDescription = stringResource(CoreR.string.save_log),
contentDescription = stringResource(CoreR.string.menuSaveLog),
)
}
}
Expand All @@ -97,7 +97,7 @@ fun LogScreen(viewModel: LogViewModel) {
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = stringResource(CoreR.string.clear_log),
contentDescription = stringResource(CoreR.string.menuClearLog),
)
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fun SuperuserDetailScreen(
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(CoreR.string.superuser_setting)) },
title = { Text(stringResource(CoreR.string.settings)) },
navigationIcon = {
IconButton(
modifier = Modifier.padding(start = 16.dp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fun SuRequestScreen(viewModel: SuRequestViewModel) {
Spacer(Modifier.height(16.dp))

Text(
text = stringResource(CoreR.string.su_request_title),
text = stringResource(CoreR.string.su_warning),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Bold,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.topjohnwu.magisk.core.su
import android.content.Context
import android.os.Bundle
import android.widget.Toast
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.R
Expand Down Expand Up @@ -71,12 +70,11 @@ object SuCallbackHandler {
}
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)

runBlocking { ServiceLocator.logRepo.insert(log) }

if (notify || Config.suNotification == Config.Value.NOTIFICATION_STATUS_BAR)
if (notify)
notify(context, log.action >= SuPolicy.ALLOW, log.appName)

runBlocking { ServiceLocator.logRepo.insert(log) }
SuEvents.notifyLogUpdated()
SuEvents.notifyPolicyChanged()
}

private fun handleNotify(context: Context, data: Bundle) {
Expand All @@ -91,19 +89,6 @@ object SuCallbackHandler {
}.getOrNull() ?: "[UID] $uid"

notify(context, policy >= SuPolicy.ALLOW, appName)
SuEvents.notifyPolicyChanged()
}

fun notify(granted: Boolean, appName: String) {
when (Config.suNotification) {
Config.Value.NOTIFICATION_TOAST -> {
val resId = if (granted) R.string.su_allow_toast else R.string.su_deny_toast
AppContext.toast(AppContext.getString(resId, appName), Toast.LENGTH_SHORT)
}
Config.Value.NOTIFICATION_STATUS_BAR -> {
Notifications.suNotification(granted, appName)
}
}
}

private fun notify(context: Context, granted: Boolean, appName: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class SuRequestHandler(

private lateinit var output: File
private lateinit var policy: SuPolicy
private var pid: Int = -1
lateinit var pkgInfo: PackageInfo
private set

Expand Down Expand Up @@ -60,7 +59,7 @@ class SuRequestHandler(

private suspend fun init(intent: Intent): Boolean {
val uid = intent.getIntExtra("uid", -1)
pid = intent.getIntExtra("pid", -1)
val pid = intent.getIntExtra("pid", -1)
val fifo = intent.getStringExtra("fifo")
if (uid <= 0 || pid <= 0 || fifo == null) {
Timber.e("Unexpected extras: uid=[${uid}], pid=[${pid}], fifo=[${fifo}]")
Expand Down Expand Up @@ -109,32 +108,7 @@ class SuRequestHandler(
}
if (time >= 0) {
policyDB.update(policy)

val appInfo = pkgInfo.applicationInfo
val appName = appInfo?.getLabel(pm)
?: pkgInfo.sharedUserId ?: "[UID] ${policy.uid}"
val packageName = appInfo?.let { pm.getNameForUid(it.uid) }
?: pkgInfo.sharedUserId ?: "[UID] ${policy.uid}"

val log = SuLog(
fromUid = policy.uid,
toUid = 0,
fromPid = pid,
packageName = packageName,
appName = appName,
command = "",
action = policy.policy,
target = -1,
context = "",
gids = "",
)
ServiceLocator.logRepo.insert(log)

val granted = policy.policy >= SuPolicy.ALLOW
SuCallbackHandler.notify(granted, appName)

SuEvents.notifyPolicyChanged()
SuEvents.notifyLogUpdated()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class ExtractImage(
}
}
zipFile.getRawInputStream(payload)
extractFromOTAPackage(payload, channel, outFile)
extractFromOTAPackage(payload, channel)
} else {
extractFromFactoryImage(zipFile, channel, outFile)
extractFromFactoryImage(zipFile, channel)
}
}
}
Expand All @@ -52,27 +52,25 @@ class ExtractImage(
private fun extractFromOTAPackage(
payload: ZipArchiveEntry,
channel: DataSourceChannel,
outFile: File,
) {
if (payload.method != ZipMethod.STORED.code) {
throw IOException("payload.bin is compressed, expected STORED method")
}

channel.slice(payload.dataOffset, payload.size).use { payloadChannel ->
Payload(payloadChannel).extract(outFile, { console.add(it) }, { logs.add(it) })
Payload(payloadChannel).extract(outFile, console, logs)
}
}

@Throws(IOException::class)
private fun extractFromFactoryImage(
zipFile: ZipFile,
channel: DataSourceChannel,
outFile: File
) {
console.add("- Processing as factory image package")

findBootImageZipEntry(zipFile)?.let { entry ->
return extractImageFile(zipFile, entry, channel, outFile)
return extractImageFile(zipFile, entry, channel)
}

val imageZipEntry = zipFile.entries.asSequence().find { entry ->
Expand All @@ -81,7 +79,7 @@ class ExtractImage(
}
if (imageZipEntry != null) {
zipFile.getRawInputStream(imageZipEntry)
return extractFromInnerImageZip(imageZipEntry, channel, outFile)
return extractFromInnerImageZip(imageZipEntry, channel)
}

throw IOException("inner image ZIP not found in factory image package")
Expand All @@ -99,7 +97,6 @@ class ExtractImage(
private fun extractFromInnerImageZip(
entry: ZipArchiveEntry,
channel: DataSourceChannel,
outFile: File
) {
logs.add("Found inner image ZIP: ${entry.name}")

Expand All @@ -114,7 +111,7 @@ class ExtractImage(
.get().use { innerZipFile ->
val targetEntry = findBootImageZipEntry(innerZipFile)
?: throw IOException("boot image not found in inner image ZIP")
return extractImageFile(innerZipFile, targetEntry, innerZipChannel, outFile)
return extractImageFile(innerZipFile, targetEntry, innerZipChannel)
}
}
}
Expand All @@ -124,7 +121,6 @@ class ExtractImage(
zipFile: ZipFile,
entry: ZipArchiveEntry,
channel: DataSourceChannel,
outFile: File,
) {
console.add("- Found boot image entry: ${entry.name} (${entry.size} bytes)")
console.add("- Downloading")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ abstract class MagiskInstallImpl protected constructor(
try {
if (magic.contentEquals("CrAU".toByteArray())) {
DataSourceChannel(channel).use { source ->
Payload(source).extract(boot, { console.add(it) }, { logs.add(it) })
Payload(source).extract(boot, console, logs)
}
} else if (magic.contentEquals("PK\u0003\u0004".toByteArray())) {
ExtractImage(boot, console, logs).consume(DataSourceChannel(channel))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ class Payload(private val channel: DataSourceChannel) {
}

@Throws(IOException::class)
fun extract(outputFile: File, console: (String) -> Unit, logger: (String) -> Unit) {
fun extract(outputFile: File, console: MutableList<String>, logger: MutableList<String>) {
val partition = findPartition()
console("- Found partition ${partition.partition_name}")
console.add("- Found partition ${partition.partition_name}")

val actualHash = extractPartition(outputFile, partition, console)

val newPartitionInfo = partition.new_partition_info
if (newPartitionInfo?.hash == null) {
logger("Hash verification skipped")
logger.add("Hash verification skipped")
return
}

Expand All @@ -43,7 +43,7 @@ class Payload(private val channel: DataSourceChannel) {
"Hash mismatch, expected ${toHex(expectedHash)}, but got ${toHex(actualHash)}"
)
}
logger("Hash verification passed")
logger.add("Hash verification passed")
}

@Throws(IOException::class)
Expand Down Expand Up @@ -109,7 +109,7 @@ class Payload(private val channel: DataSourceChannel) {
private fun extractPartition(
outputFile: File,
partition: PartitionUpdate,
console: (String) -> Unit,
console: MutableList<String>,
): ByteArray {
FileChannel.open(
outputFile.toPath(),
Expand All @@ -124,7 +124,7 @@ class Payload(private val channel: DataSourceChannel) {
val count = partition.operations.size
partition.operations.forEachIndexed { index, operation ->
if (index % 5 == 0 || index == count - 1) {
console("- Downloading ${index + 1}/$count")
console.add("- Downloading ${index + 1}/$count")
}
processOperation(outChannel, operation)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public class DataSourceChannel implements SeekableByteChannel {
private final OkHttpClient client;
private final String url;
private final FileChannel fileChannel;
private final boolean ownership;
private final long startOffset;
private final long size;
private long size;

private long position = 0;
private boolean open = true;
Expand All @@ -33,54 +34,54 @@ public class DataSourceChannel implements SeekableByteChannel {
private long cacheStart = -1;

private DataSourceChannel(OkHttpClient client, String url, FileChannel fileChannel,
long startOffset, long size) {
boolean ownership, long startOffset, long size) {
this.client = client;
this.url = url;
this.fileChannel = fileChannel;
this.ownership = ownership;
this.startOffset = startOffset;
this.size = size;
}

public DataSourceChannel(FileChannel fileChannel) throws IOException {
this(null, null, fileChannel, 0, fileChannel.size());
this(null, null, fileChannel, true, 0, fileChannel.size());
}

public DataSourceChannel(OkHttpClient client, String url) throws IOException {
this(client, url, null, 0, fetchTotalSize(client, url));
}

private static long fetchTotalSize(OkHttpClient client, String url) throws IOException {
var request = new Request.Builder().url(url).head().build();
this(client, url, null, false, 0, 0);
var request = new Request.Builder()
.url(url)
.header("Range", "bytes=" + "-" + RANDOM_READ_CACHE_SIZE)
.build();
try (var response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Failed to connect to URL: " + response);
if (response.code() != 206) {
throw new IOException("Unexpected response code " + response.code());
}
var contentLength = response.header("Content-Length");
if (contentLength == null) {
var contentRange = response.header("Content-Range");
if (contentRange == null) {
throw new IOException("Could not determine file size.");
}
var acceptRanges = response.header("Accept-Ranges");
if (acceptRanges == null || !acceptRanges.equalsIgnoreCase("bytes")) {
throw new IOException("Server does not support byte ranges: " + response);
}
return Long.parseLong(contentLength);
var contentLength = contentRange.substring(contentRange.lastIndexOf('/') + 1);
size = Long.parseLong(contentLength);
cache = response.body().bytes();
cacheStart = size - cache.length;
}
}

public DataSourceChannel slice(long offset, long sliceSize) {
if (offset == 0 && sliceSize == size) {
return this;
}
if (offset < 0 || sliceSize <= 0 || offset + sliceSize >= size) {
if (offset < 0 || sliceSize <= 0 || offset + sliceSize > size) {
throw new IllegalArgumentException("Invalid slice parameters");
}
return new DataSourceChannel(client, url, fileChannel, startOffset + offset, sliceSize);
return new DataSourceChannel(client, url, fileChannel, false,
startOffset + offset, sliceSize);
}

@Override
public int read(ByteBuffer dst) throws IOException {
var bytesRead = read(dst, position);
position += bytesRead;
if (bytesRead > 0) {
position += bytesRead;
}
return bytesRead;
}

Expand Down Expand Up @@ -250,7 +251,7 @@ public boolean isOpen() {
public void close() throws IOException {
open = false;
cache = null;
if (fileChannel != null) {
if (ownership) {
fileChannel.close();
}
}
Expand Down
Loading