Eliminate any traces of Java in app
This commit is contained in:
parent
48395ba860
commit
f2494374f8
6
app/proguard-rules.pro
vendored
6
app/proguard-rules.pro
vendored
@ -17,9 +17,9 @@
|
||||
#}
|
||||
|
||||
# Snet
|
||||
-keepclassmembers class com.topjohnwu.magisk.utils.ISafetyNetHelper { *; }
|
||||
-keep,allowobfuscation interface com.topjohnwu.magisk.utils.ISafetyNetHelper$Callback
|
||||
-keepclassmembers class * implements com.topjohnwu.magisk.utils.ISafetyNetHelper$Callback {
|
||||
-keepclassmembers class com.topjohnwu.magisk.utils.SafetyNetHelper { *; }
|
||||
-keep,allowobfuscation interface com.topjohnwu.magisk.utils.SafetyNetHelper$Callback
|
||||
-keepclassmembers class * implements com.topjohnwu.magisk.utils.SafetyNetHelper$Callback {
|
||||
void onResponse(int);
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,14 @@ package a;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.topjohnwu.magisk.model.worker.DelegateWorker;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
import com.topjohnwu.magisk.model.worker.DelegateWorker;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
public abstract class w<T extends DelegateWorker> extends Worker {
|
||||
|
||||
/* Wrapper class to workaround Proguard -keep class * extends Worker */
|
||||
@ -22,7 +22,7 @@ public abstract class w<T extends DelegateWorker> extends Worker {
|
||||
try {
|
||||
base = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
|
||||
.getActualTypeArguments()[0]).newInstance();
|
||||
base.setActualWorker(this);
|
||||
base.attachWorker(this);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ object ClassMap {
|
||||
SuRequestActivity::class.java to a.m::class.java
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
operator fun <T : Class<*>>get(c: Class<*>): T {
|
||||
return map.getOrElse(c) { throw IllegalArgumentException() } as T
|
||||
}
|
||||
|
@ -113,7 +113,6 @@ object Config : PreferenceModel, DBConfig {
|
||||
var darkTheme by preference(Key.DARK_THEME, true)
|
||||
var suReAuth by preference(Key.SU_REAUTH, false)
|
||||
var checkUpdate by preference(Key.CHECK_UPDATES, true)
|
||||
@JvmStatic
|
||||
var magiskHide by preference(Key.MAGISKHIDE, true)
|
||||
var coreOnly by preference(Key.COREONLY, false)
|
||||
var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false)
|
||||
|
@ -1,31 +0,0 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.topjohnwu.magisk.model.entity.UpdateInfo;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
import com.topjohnwu.superuser.ShellUtils;
|
||||
|
||||
public final class Info {
|
||||
|
||||
public static int magiskVersionCode = -1;
|
||||
|
||||
@NonNull
|
||||
public static String magiskVersionString = "";
|
||||
|
||||
@NonNull
|
||||
public static UpdateInfo remote = new UpdateInfo();
|
||||
|
||||
public static boolean keepVerity = false;
|
||||
public static boolean keepEnc = false;
|
||||
public static boolean recovery = false;
|
||||
|
||||
public static void loadMagiskInfo() {
|
||||
try {
|
||||
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];
|
||||
magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V"));
|
||||
Config.setMagiskHide(Shell.su("magiskhide --status").exec().isSuccess());
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
26
app/src/main/java/com/topjohnwu/magisk/Info.kt
Normal file
26
app/src/main/java/com/topjohnwu/magisk/Info.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package com.topjohnwu.magisk
|
||||
|
||||
import com.topjohnwu.magisk.model.entity.UpdateInfo
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import com.topjohnwu.superuser.ShellUtils
|
||||
|
||||
object Info {
|
||||
|
||||
var magiskVersionCode = -1
|
||||
|
||||
var magiskVersionString = ""
|
||||
|
||||
var remote = UpdateInfo()
|
||||
|
||||
var keepVerity = false
|
||||
var keepEnc = false
|
||||
var recovery = false
|
||||
|
||||
fun loadMagiskInfo() {
|
||||
runCatching {
|
||||
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":".toRegex())[0]
|
||||
magiskVersionCode = ShellUtils.fastCmd("magisk -V").toInt()
|
||||
Config.magiskHide = Shell.su("magiskhide --status").exec().isSuccess
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package com.topjohnwu.magisk.model.worker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Network;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.ListenableWorker;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class DelegateWorker {
|
||||
|
||||
private ListenableWorker worker;
|
||||
|
||||
@NonNull
|
||||
public abstract ListenableWorker.Result doWork();
|
||||
|
||||
public void onStopped() {}
|
||||
|
||||
public void setActualWorker(ListenableWorker w) {
|
||||
worker = w;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Context getApplicationContext() {
|
||||
return worker.getApplicationContext();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public UUID getId() {
|
||||
return worker.getId();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Data getInputData() {
|
||||
return worker.getInputData();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Set<String> getTags() {
|
||||
return worker.getTags();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@RequiresApi(24)
|
||||
public List<Uri> getTriggeredContentUris() {
|
||||
return worker.getTriggeredContentUris();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@RequiresApi(24)
|
||||
public List<String> getTriggeredContentAuthorities() {
|
||||
return worker.getTriggeredContentAuthorities();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@RequiresApi(28)
|
||||
public Network getNetwork() {
|
||||
return worker.getNetwork();
|
||||
}
|
||||
|
||||
public int getRunAttemptCount() {
|
||||
return worker.getRunAttemptCount();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@MainThread
|
||||
public ListenableFuture<ListenableWorker.Result> startWork() {
|
||||
return worker.startWork();
|
||||
}
|
||||
|
||||
public boolean isStopped() {
|
||||
return worker.isStopped();
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.topjohnwu.magisk.model.worker
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Network
|
||||
import android.net.Uri
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.work.Data
|
||||
import androidx.work.ListenableWorker
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import java.util.*
|
||||
|
||||
abstract class DelegateWorker {
|
||||
|
||||
private lateinit var worker: ListenableWorker
|
||||
|
||||
val applicationContext: Context
|
||||
get() = worker.applicationContext
|
||||
|
||||
val id: UUID
|
||||
get() = worker.id
|
||||
|
||||
val inputData: Data
|
||||
get() = worker.inputData
|
||||
|
||||
val tags: Set<String>
|
||||
get() = worker.tags
|
||||
|
||||
val triggeredContentUris: List<Uri>
|
||||
@RequiresApi(24)
|
||||
get() = worker.triggeredContentUris
|
||||
|
||||
val triggeredContentAuthorities: List<String>
|
||||
@RequiresApi(24)
|
||||
get() = worker.triggeredContentAuthorities
|
||||
|
||||
val network: Network?
|
||||
@RequiresApi(28)
|
||||
get() = worker.network
|
||||
|
||||
val runAttemptCount: Int
|
||||
get() = worker.runAttemptCount
|
||||
|
||||
val isStopped: Boolean
|
||||
get() = worker.isStopped
|
||||
|
||||
abstract fun doWork(): ListenableWorker.Result
|
||||
|
||||
fun onStopped() {}
|
||||
|
||||
fun attachWorker(w: ListenableWorker) {
|
||||
worker = w
|
||||
}
|
||||
|
||||
@MainThread
|
||||
fun startWork(): ListenableFuture<ListenableWorker.Result> {
|
||||
return worker.startWork()
|
||||
}
|
||||
}
|
@ -17,8 +17,8 @@ import com.topjohnwu.magisk.extensions.writeTo
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.utils.ISafetyNetHelper
|
||||
import com.topjohnwu.magisk.utils.DynamicClassLoader
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
import com.topjohnwu.magisk.view.dialogs.*
|
||||
import com.topjohnwu.superuser.Shell
|
||||
@ -26,7 +26,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import java.io.File
|
||||
|
||||
class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
|
||||
ISafetyNetHelper.Callback {
|
||||
SafetyNetHelper.Callback {
|
||||
|
||||
override val layoutRes: Int = R.layout.fragment_magisk
|
||||
override val viewModel: HomeViewModel by viewModel()
|
||||
@ -101,8 +101,8 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
|
||||
val clazz = loader.loadClass("com.topjohnwu.snet.Snet")
|
||||
val helper = clazz.getMethod("newHelper",
|
||||
Class::class.java, String::class.java, Activity::class.java, Any::class.java)
|
||||
.invoke(null, ISafetyNetHelper::class.java, EXT_APK.path,
|
||||
requireActivity(), this) as ISafetyNetHelper
|
||||
.invoke(null, SafetyNetHelper::class.java, EXT_APK.path,
|
||||
activity, this) as SafetyNetHelper
|
||||
if (helper.version < Const.SNET_EXT_VER)
|
||||
throw Exception()
|
||||
helper.attest()
|
||||
|
@ -12,7 +12,7 @@ import com.topjohnwu.magisk.extensions.toggle
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.model.observer.Observer
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.ISafetyNetHelper
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
||||
enum class SafetyNetState {
|
||||
@ -142,8 +142,8 @@ class HomeViewModel(
|
||||
|
||||
fun finishSafetyNetCheck(response: Int) = when {
|
||||
response and 0x0F == 0 -> {
|
||||
val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0
|
||||
val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0
|
||||
val hasCtsPassed = response and SafetyNetHelper.CTS_PASS != 0
|
||||
val hasBasicIntegrityPassed = response and SafetyNetHelper.BASIC_PASS != 0
|
||||
safetyNetTitle.value = R.string.safetyNet_check_success
|
||||
ctsState.value = if (hasCtsPassed) {
|
||||
SafetyNetState.PASS
|
||||
@ -164,7 +164,7 @@ class HomeViewModel(
|
||||
ctsState.value = SafetyNetState.IDLE
|
||||
basicIntegrityState.value = SafetyNetState.IDLE
|
||||
safetyNetTitle.value = when (response) {
|
||||
ISafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid
|
||||
SafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid
|
||||
else -> R.string.safetyNet_api_error
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
package com.topjohnwu.magisk.utils;
|
||||
|
||||
public interface ISafetyNetHelper {
|
||||
|
||||
int RESPONSE_ERR = 0x01;
|
||||
int CONNECTION_FAIL = 0x02;
|
||||
|
||||
int BASIC_PASS = 0x10;
|
||||
int CTS_PASS = 0x20;
|
||||
|
||||
void attest();
|
||||
|
||||
int getVersion();
|
||||
|
||||
interface Callback {
|
||||
void onResponse(int responseCode);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
interface SafetyNetHelper {
|
||||
|
||||
val version: Int
|
||||
|
||||
fun attest()
|
||||
|
||||
interface Callback {
|
||||
fun onResponse(responseCode: Int)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val RESPONSE_ERR = 0x01
|
||||
val CONNECTION_FAIL = 0x02
|
||||
|
||||
val BASIC_PASS = 0x10
|
||||
val CTS_PASS = 0x20
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.topjohnwu.magisk.utils;
|
||||
|
||||
import android.net.LocalSocket;
|
||||
import android.net.LocalSocketAddress;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class SuConnector {
|
||||
|
||||
private LocalSocket socket;
|
||||
protected DataOutputStream out;
|
||||
protected DataInputStream in;
|
||||
|
||||
protected SuConnector(String name) throws IOException {
|
||||
socket = new LocalSocket();
|
||||
socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT));
|
||||
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
|
||||
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
|
||||
}
|
||||
|
||||
private String readString() throws IOException {
|
||||
int len = in.readInt();
|
||||
byte[] buf = new byte[len];
|
||||
in.readFully(buf);
|
||||
return new String(buf, "UTF-8");
|
||||
}
|
||||
|
||||
public Bundle readSocketInput() throws IOException {
|
||||
Bundle bundle = new Bundle();
|
||||
while (true) {
|
||||
String name = readString();
|
||||
if (TextUtils.equals(name, "eof"))
|
||||
break;
|
||||
bundle.putString(name, readString());
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public void response() {
|
||||
try {
|
||||
onResponse();
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
in.close();
|
||||
out.close();
|
||||
socket.close();
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
protected abstract void onResponse() throws IOException;
|
||||
|
||||
}
|
60
app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.kt
Normal file
60
app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.kt
Normal file
@ -0,0 +1,60 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.net.LocalSocket
|
||||
import android.net.LocalSocketAddress
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import timber.log.Timber
|
||||
import java.io.*
|
||||
import java.nio.charset.Charset
|
||||
|
||||
abstract class SuConnector @Throws(IOException::class)
|
||||
protected constructor(name: String) {
|
||||
|
||||
private val socket: LocalSocket = LocalSocket()
|
||||
protected var out: DataOutputStream
|
||||
protected var input: DataInputStream
|
||||
|
||||
init {
|
||||
socket.connect(LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT))
|
||||
out = DataOutputStream(BufferedOutputStream(socket.outputStream))
|
||||
input = DataInputStream(BufferedInputStream(socket.inputStream))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun readString(): String {
|
||||
val len = input.readInt()
|
||||
val buf = ByteArray(len)
|
||||
input.readFully(buf)
|
||||
return String(buf, Charset.forName("UTF-8"))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun readSocketInput(): Bundle {
|
||||
val bundle = Bundle()
|
||||
while (true) {
|
||||
val name = readString()
|
||||
if (TextUtils.equals(name, "eof"))
|
||||
break
|
||||
bundle.putString(name, readString())
|
||||
}
|
||||
return bundle
|
||||
}
|
||||
|
||||
fun response() {
|
||||
runCatching {
|
||||
onResponse()
|
||||
out.flush()
|
||||
}.onFailure { Timber.e(it) }
|
||||
|
||||
runCatching {
|
||||
input.close()
|
||||
out.close()
|
||||
socket.close()
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected abstract fun onResponse()
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user