Add LSPatch manager
|
|
@ -1,6 +1,7 @@
|
|||
package org.lsposed.lspatch.loader;
|
||||
|
||||
import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE;
|
||||
import static org.lsposed.lspd.service.ConfigFileManager.loadModule;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.app.Application;
|
||||
|
|
@ -15,10 +16,7 @@ import android.os.Environment;
|
|||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SharedMemory;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.OsConstants;
|
||||
import android.util.Log;
|
||||
|
||||
import org.lsposed.lspatch.loader.util.FileUtils;
|
||||
|
|
@ -27,19 +25,15 @@ import org.lsposed.lspatch.share.Constants;
|
|||
import org.lsposed.lspd.config.ApplicationServiceClient;
|
||||
import org.lsposed.lspd.core.Main;
|
||||
import org.lsposed.lspd.models.Module;
|
||||
import org.lsposed.lspd.models.PreLoadedApk;
|
||||
import org.lsposed.lspd.nativebridge.SigBypass;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
|
|
@ -176,7 +170,8 @@ public class LSPApplication extends ApplicationServiceClient {
|
|||
public static void loadModules(Context context) {
|
||||
if (useManager) {
|
||||
try {
|
||||
LSPApplication.modules.addAll(managerResolver.getModules());
|
||||
modules.addAll(managerResolver.getModules());
|
||||
modules.forEach(m -> Log.i(TAG, "Load module " + m.packageName + " from manager"));
|
||||
} catch (NullPointerException | RemoteException e) {
|
||||
Log.e(TAG, "Failed to get modules from manager", e);
|
||||
}
|
||||
|
|
@ -202,7 +197,8 @@ public class LSPApplication extends ApplicationServiceClient {
|
|||
var module = new Module();
|
||||
module.apkPath = cacheApkPath;
|
||||
module.packageName = packageName;
|
||||
module.file = loadModule(context, cacheApkPath);
|
||||
module.file = loadModule(cacheApkPath);
|
||||
if (module.file != null) module.file.hostApk = context.getApplicationInfo().sourceDir;
|
||||
modules.add(module);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
|
|
@ -210,61 +206,6 @@ public class LSPApplication extends ApplicationServiceClient {
|
|||
}
|
||||
}
|
||||
|
||||
private static void readDexes(ZipFile apkFile, List<SharedMemory> preLoadedDexes) {
|
||||
int secondary = 2;
|
||||
for (var dexFile = apkFile.getEntry("classes.dex"); dexFile != null;
|
||||
dexFile = apkFile.getEntry("classes" + secondary + ".dex"), secondary++) {
|
||||
try (var in = apkFile.getInputStream(dexFile)) {
|
||||
var memory = SharedMemory.create(null, in.available());
|
||||
var byteBuffer = memory.mapReadWrite();
|
||||
Channels.newChannel(in).read(byteBuffer);
|
||||
SharedMemory.unmap(byteBuffer);
|
||||
memory.setProtect(OsConstants.PROT_READ);
|
||||
preLoadedDexes.add(memory);
|
||||
} catch (IOException | ErrnoException e) {
|
||||
Log.w(TAG, "Can not load " + dexFile + " in " + apkFile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void readName(ZipFile apkFile, String initName, List<String> names) {
|
||||
var initEntry = apkFile.getEntry(initName);
|
||||
if (initEntry == null) return;
|
||||
try (var in = apkFile.getInputStream(initEntry)) {
|
||||
var reader = new BufferedReader(new InputStreamReader(in));
|
||||
String name;
|
||||
while ((name = reader.readLine()) != null) {
|
||||
name = name.trim();
|
||||
if (name.isEmpty() || name.startsWith("#")) continue;
|
||||
names.add(name);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Can not open " + initEntry, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static PreLoadedApk loadModule(Context context, String path) {
|
||||
var file = new PreLoadedApk();
|
||||
var preLoadedDexes = new ArrayList<SharedMemory>();
|
||||
var moduleClassNames = new ArrayList<String>(1);
|
||||
var moduleLibraryNames = new ArrayList<String>(1);
|
||||
try (var apkFile = new ZipFile(path)) {
|
||||
readDexes(apkFile, preLoadedDexes);
|
||||
readName(apkFile, "assets/xposed_init", moduleClassNames);
|
||||
readName(apkFile, "assets/native_init", moduleLibraryNames);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Can not open " + path, e);
|
||||
return null;
|
||||
}
|
||||
if (preLoadedDexes.isEmpty()) return null;
|
||||
if (moduleClassNames.isEmpty()) return null;
|
||||
file.hostApk = context.getApplicationInfo().sourceDir;
|
||||
file.preLoadedDexes = preLoadedDexes;
|
||||
file.moduleClassNames = moduleClassNames;
|
||||
file.moduleLibraryNames = moduleLibraryNames;
|
||||
return file;
|
||||
}
|
||||
|
||||
public LSPApplication() {
|
||||
super();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.lsposed.lspatch.loader;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import static org.lsposed.lspatch.share.Constants.MANAGER_PACKAGE_NAME;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -11,19 +12,19 @@ import org.lsposed.lspd.models.Module;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public class ManagerResolver extends ContentResolver {
|
||||
private static final String MANAGER_PACKAGE_NAME = "org.lsposed.lspatch";
|
||||
private static final Uri BINDER_URI = Uri.parse("content://" + MANAGER_PACKAGE_NAME + "/binder");
|
||||
public class ManagerResolver {
|
||||
private static final Uri PROVIDER = Uri.parse("content://" + MANAGER_PACKAGE_NAME + ".provider");
|
||||
|
||||
private final IManagerService service;
|
||||
|
||||
public ManagerResolver(Context context) throws RemoteException {
|
||||
super(context);
|
||||
try {
|
||||
Bundle back = call(BINDER_URI, "getBinder", null, null);
|
||||
Bundle back = context.getContentResolver().call(PROVIDER, "getBinder", null, null);
|
||||
service = IManagerService.Stub.asInterface(back.getBinder("binder"));
|
||||
if (service == null) throw new RemoteException("Binder is null");
|
||||
} catch (Throwable t) {
|
||||
var e = new RemoteException("Failed to get manager binder");
|
||||
e.setStackTrace(new StackTraceElement[0]);
|
||||
e.addSuppressed(t);
|
||||
throw e;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ buildscript {
|
|||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.0-alpha11'
|
||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
2
core
|
|
@ -1 +1 @@
|
|||
Subproject commit f955755ac40134f1b0a858f4e7df3b4a4eec78a8
|
||||
Subproject commit 6b4c519cf1b0d1ada03c9f39e27c3a0971b47f9e
|
||||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.lsposed.lspatch"
|
||||
minSdk 27
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(":imanager")
|
||||
implementation project(path: ':lspcore')
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.6.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="org.lsposed.lspatch">
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.LSPatch">
|
||||
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name=".ModuleProvider"
|
||||
android:authorities="org.lsposed.lspatch.provider"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.lsposed.lspatch
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
|
||||
class LSPApplication : Application() {
|
||||
companion object {
|
||||
const val TAG = "LSPatch Manager"
|
||||
lateinit var appContext: Context
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
appContext = applicationContext
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package org.lsposed.lspatch
|
||||
|
||||
import org.lsposed.lspatch.manager.IManagerService
|
||||
import org.lsposed.lspd.models.Module
|
||||
|
||||
class ManagerServiceImpl : IManagerService.Stub() {
|
||||
override fun getModules(): List<Module> {
|
||||
return ModuleProvider.allModules
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package org.lsposed.lspatch
|
||||
|
||||
import android.content.ContentProvider
|
||||
import android.content.ContentValues
|
||||
import android.content.pm.PackageManager
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.Binder
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import org.lsposed.lspatch.LSPApplication.Companion.TAG
|
||||
import org.lsposed.lspd.models.Module
|
||||
import org.lsposed.lspd.service.ConfigFileManager.loadModule
|
||||
|
||||
class ModuleProvider : ContentProvider() {
|
||||
companion object {
|
||||
lateinit var allModules: List<Module>
|
||||
}
|
||||
|
||||
override fun onCreate(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun call(method: String, arg: String?, extras: Bundle?): Bundle {
|
||||
val app = context!!.packageManager.getNameForUid(Binder.getCallingUid())
|
||||
Log.d(TAG, "$app calls binder")
|
||||
when (method) {
|
||||
"getBinder" -> {
|
||||
loadAllModules()
|
||||
return Bundle().apply {
|
||||
putBinder("binder", ManagerServiceImpl())
|
||||
}
|
||||
}
|
||||
else -> throw IllegalArgumentException("Invalid method name")
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAllModules() {
|
||||
val list = mutableListOf<Module>()
|
||||
for (pkg in context!!.packageManager.getInstalledPackages(PackageManager.GET_META_DATA)) {
|
||||
val app = pkg.applicationInfo ?: continue
|
||||
if (app.metaData != null && app.metaData.containsKey("xposedminversion")) {
|
||||
Module().apply {
|
||||
apkPath = app.publicSourceDir
|
||||
packageName = app.packageName
|
||||
file = loadModule(apkPath)
|
||||
}.also { list.add(it) }
|
||||
Log.d(TAG, "send module ${app.packageName}")
|
||||
}
|
||||
}
|
||||
allModules = list
|
||||
}
|
||||
|
||||
override fun query(p0: Uri, p1: Array<out String>?, p2: String?, p3: Array<out String>?, p4: String?): Cursor? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getType(p0: Uri): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun insert(p0: Uri, p1: ContentValues?): Uri? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun delete(p0: Uri, p1: String?, p2: Array<out String>?): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun update(p0: Uri, p1: ContentValues?, p2: String?, p3: Array<out String>?): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package org.lsposed.lspatch.ui
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import org.lsposed.lspatch.databinding.ActivityMainBinding
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
lateinit var binding: ActivityMainBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Stub!"
|
||||
android:textSize="50sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
|
@ -0,0 +1,16 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.LSPatch" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">LSPatch</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.LSPatch" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -16,3 +16,4 @@ include ':share'
|
|||
include ':appstub'
|
||||
include ':apkzlib'
|
||||
include ':imanager'
|
||||
include ':manager'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.lsposed.lspatch.share;
|
||||
|
||||
public class Constants {
|
||||
final static public String MANAGER_PACKAGE_NAME = "org.lsposed.lspatch";
|
||||
final static public String CONFIG_NAME_SIGBYPASSLV = "lspatch_sigbypasslv";
|
||||
final static public int SIGBYPASS_LV_DISABLE = 0;
|
||||
final static public int SIGBYPASS_LV_PM = 1;
|
||||
|
|
|
|||