From 10804dfa7fd72fe3cdeeeb77a27a2dd372a7af1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=97=E5=AE=AB=E9=9B=AA=E7=8F=8A?= Date: Mon, 16 Jan 2023 22:04:00 +0800 Subject: [PATCH] Clean code (#2335) --- .../lspd/util/ClassPathURLStreamHandler.java | 3 +- .../java/org/lsposed/lspd/util/Handler.java | 192 ------------------ .../lsposed/lspd/util/InstallerVerifier.java | 40 ---- .../lspd/util/LspModuleClassLoader.java | 21 +- hiddenapi/stubs/build.gradle.kts | 5 + .../android/content/pm/IShortcutService.java | 24 --- .../java/android/content/pm/ShortcutInfo.java | 28 --- .../main/java/android/os/ShellCallback.java | 2 +- .../java/sun/misc}/CompoundEnumeration.java | 2 +- .../sun/net/www/protocol/jar/Handler.java | 4 + .../lspd/util/ParasiticManagerHooker.java | 14 +- 11 files changed, 35 insertions(+), 300 deletions(-) delete mode 100644 core/src/main/java/org/lsposed/lspd/util/Handler.java delete mode 100644 core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java delete mode 100644 hiddenapi/stubs/src/main/java/android/content/pm/IShortcutService.java delete mode 100644 hiddenapi/stubs/src/main/java/android/content/pm/ShortcutInfo.java rename {core/src/main/java/org/lsposed/lspd/util => hiddenapi/stubs/src/main/java/sun/misc}/CompoundEnumeration.java (96%) create mode 100644 hiddenapi/stubs/src/main/java/sun/net/www/protocol/jar/Handler.java diff --git a/core/src/main/java/org/lsposed/lspd/util/ClassPathURLStreamHandler.java b/core/src/main/java/org/lsposed/lspd/util/ClassPathURLStreamHandler.java index a1ccf8b4b86..9e43461379d 100644 --- a/core/src/main/java/org/lsposed/lspd/util/ClassPathURLStreamHandler.java +++ b/core/src/main/java/org/lsposed/lspd/util/ClassPathURLStreamHandler.java @@ -13,6 +13,7 @@ import java.util.zip.ZipEntry; import sun.net.www.ParseUtil; +import sun.net.www.protocol.jar.Handler; final class ClassPathURLStreamHandler extends Handler { private final String fileUri; @@ -41,7 +42,7 @@ protected URLConnection openConnection(URL url) throws IOException { } @Override - protected void finalize() throws Throwable { + protected void finalize() throws IOException { jarFile.close(); } diff --git a/core/src/main/java/org/lsposed/lspd/util/Handler.java b/core/src/main/java/org/lsposed/lspd/util/Handler.java deleted file mode 100644 index f5fec90033a..00000000000 --- a/core/src/main/java/org/lsposed/lspd/util/Handler.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.lsposed.lspd.util; - -import java.net.MalformedURLException; -import java.net.URL; - -public abstract class Handler extends java.net.URLStreamHandler { - - private static final String separator = "!/"; - - private static int indexOfBangSlash(String spec) { - int indexOfBang = spec.length(); - while ((indexOfBang = spec.lastIndexOf('!', indexOfBang)) != -1) { - if ((indexOfBang != (spec.length() - 1)) && - (spec.charAt(indexOfBang + 1) == '/')) { - return indexOfBang + 1; - } else { - indexOfBang--; - } - } - return -1; - } - - @Override - protected boolean sameFile(URL u1, URL u2) { - if (!u1.getProtocol().equals("jar") || !u2.getProtocol().equals("jar")) - return false; - - String file1 = u1.getFile(); - String file2 = u2.getFile(); - int sep1 = file1.indexOf(separator); - int sep2 = file2.indexOf(separator); - - if (sep1 == -1 || sep2 == -1) { - return super.sameFile(u1, u2); - } - - String entry1 = file1.substring(sep1 + 2); - String entry2 = file2.substring(sep2 + 2); - - if (!entry1.equals(entry2)) - return false; - - URL enclosedURL1, enclosedURL2; - try { - enclosedURL1 = new URL(file1.substring(0, sep1)); - enclosedURL2 = new URL(file2.substring(0, sep2)); - } catch (MalformedURLException unused) { - return super.sameFile(u1, u2); - } - - return super.sameFile(enclosedURL1, enclosedURL2); - } - - @Override - protected int hashCode(URL u) { - int h = 0; - - String protocol = u.getProtocol(); - if (protocol != null) - h += protocol.hashCode(); - - String file = u.getFile(); - int sep = file.indexOf(separator); - - if (sep == -1) - return h + file.hashCode(); - - URL enclosedURL; - String fileWithoutEntry = file.substring(0, sep); - try { - enclosedURL = new URL(fileWithoutEntry); - h += enclosedURL.hashCode(); - } catch (MalformedURLException unused) { - h += fileWithoutEntry.hashCode(); - } - - String entry = file.substring(sep + 2); - h += entry.hashCode(); - - return h; - } - - - @Override - @SuppressWarnings("deprecation") - protected void parseURL(URL url, String spec, int start, int limit) { - String file = null; - String ref = null; - // first figure out if there is an anchor - int refPos = spec.indexOf('#', limit); - boolean refOnly = refPos == start; - if (refPos > -1) { - ref = spec.substring(refPos + 1); - if (refOnly) { - file = url.getFile(); - } - } - // then figure out if the spec is - // 1. absolute (jar:) - // 2. relative (i.e. url + foo/bar/baz.ext) - // 3. anchor-only (i.e. url + #foo), which we already did (refOnly) - boolean absoluteSpec = false; - if (spec.length() >= 4) { - absoluteSpec = spec.substring(0, 4).equalsIgnoreCase("jar:"); - } - spec = spec.substring(start, limit); - - if (absoluteSpec) { - file = parseAbsoluteSpec(spec); - } else if (!refOnly) { - file = parseContextSpec(url, spec); - - // Canonize the result after the bangslash - int bangSlash = indexOfBangSlash(file); - String toBangSlash = file.substring(0, bangSlash); - String afterBangSlash = file.substring(bangSlash); - afterBangSlash = canonizeString(afterBangSlash); - file = toBangSlash + afterBangSlash; - } - setURL(url, "jar", "", -1, file, ref); - } - - private String canonizeString(String file) { - int i; - int lim; - - // Remove embedded /../ - while ((i = file.indexOf("/../")) >= 0) { - if ((lim = file.lastIndexOf('/', i - 1)) >= 0) { - file = file.substring(0, lim) + file.substring(i + 3); - } else { - file = file.substring(i + 3); - } - } - // Remove embedded /./ - while ((i = file.indexOf("/./")) >= 0) { - file = file.substring(0, i) + file.substring(i + 2); - } - // Remove trailing .. - while (file.endsWith("/..")) { - i = file.indexOf("/.."); - if ((lim = file.lastIndexOf('/', i - 1)) >= 0) { - file = file.substring(0, lim + 1); - } else { - file = file.substring(0, i); - } - } - // Remove trailing . - if (file.endsWith("/.")) - file = file.substring(0, file.length() - 1); - - return file; - } - - private String parseAbsoluteSpec(String spec) { - int index; - // check for !/ - if ((index = indexOfBangSlash(spec)) == -1) { - throw new NullPointerException("no !/ in spec"); - } - // test the inner URL - try { - String innerSpec = spec.substring(0, index - 1); - new URL(innerSpec); - } catch (MalformedURLException e) { - throw new NullPointerException("invalid url: " + - spec + " (" + e + ")"); - } - return spec; - } - - private String parseContextSpec(URL url, String spec) { - String ctxFile = url.getFile(); - // if the spec begins with /, chop up the jar back !/ - if (spec.startsWith("/")) { - int bangSlash = indexOfBangSlash(ctxFile); - if (bangSlash == -1) { - throw new NullPointerException("malformed " + "context url:" + url + ": no !/"); - } - ctxFile = ctxFile.substring(0, bangSlash); - } - if (!ctxFile.endsWith("/") && (!spec.startsWith("/"))) { - // chop up the last component - int lastSlash = ctxFile.lastIndexOf('/'); - if (lastSlash == -1) { - throw new NullPointerException("malformed " + "context url:" + url); - } - ctxFile = ctxFile.substring(0, lastSlash + 1); - } - return (ctxFile + spec); - } -} diff --git a/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java b/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java deleted file mode 100644 index 507e2d893d1..00000000000 --- a/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -package org.lsposed.lspd.util; - -import android.os.IBinder; - -import de.robv.android.xposed.XposedHelpers; - -public class InstallerVerifier { - - public static void sendBinderToManager(final ClassLoader classLoader, IBinder binder) { - try { - var clazz = XposedHelpers.findClass("org.lsposed.manager.Constants", classLoader); - var ok = (boolean) XposedHelpers.callStaticMethod(clazz, "setBinder", - new Class[]{IBinder.class}, binder); - if (ok) return; - throw new RuntimeException("setBinder: " + false); - } catch (Throwable t) { - Utils.logW("Could not send binder to LSPosed Manager", t); - } - } -} diff --git a/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java b/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java index 3dd5b3ed54a..49def72b85c 100644 --- a/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java +++ b/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java @@ -23,10 +23,10 @@ import java.util.List; import java.util.Objects; import java.util.jar.JarFile; -import java.util.stream.Collectors; import java.util.zip.ZipEntry; import hidden.ByteBufferDexClassLoader; +import sun.misc.CompoundEnumeration; @SuppressWarnings("ConstantConditions") public final class LspModuleClassLoader extends ByteBufferDexClassLoader { @@ -135,7 +135,12 @@ public String getLdLibraryPath() { protected URL findResource(String name) { try { var urlHandler = new ClassPathURLStreamHandler(apk); - return urlHandler.getEntryUrlOrNull(name); + var url = urlHandler.getEntryUrlOrNull(name); + if (url == null) { + // noinspection FinalizeCalledExplicitly + urlHandler.finalize(); + } + return url; } catch (IOException e) { return null; } @@ -171,16 +176,8 @@ public Enumeration getResources(String name) throws IOException { @NonNull @Override public String toString() { - if (apk == null) { - return "LspModuleClassLoader[instantiating]"; - } - var nativeLibraryDirsString = nativeLibraryDirs.stream() - .map(File::getPath) - .collect(Collectors.joining(", ")); - return "LspModuleClassLoader[" + - "module=" + apk + ", " + - "nativeLibraryDirs=" + nativeLibraryDirsString + ", " + - super.toString() + "]"; + if (apk == null) return "LspModuleClassLoader[instantiating]"; + return "LspModuleClassLoader[module=" + apk + ", " + super.toString() + "]"; } public static ClassLoader loadApk(String apk, diff --git a/hiddenapi/stubs/build.gradle.kts b/hiddenapi/stubs/build.gradle.kts index 87c6345370c..384caffcf91 100644 --- a/hiddenapi/stubs/build.gradle.kts +++ b/hiddenapi/stubs/build.gradle.kts @@ -20,3 +20,8 @@ plugins { `java-library` } + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/IShortcutService.java b/hiddenapi/stubs/src/main/java/android/content/pm/IShortcutService.java deleted file mode 100644 index 75d351fd68e..00000000000 --- a/hiddenapi/stubs/src/main/java/android/content/pm/IShortcutService.java +++ /dev/null @@ -1,24 +0,0 @@ -package android.content.pm; - -import android.content.IntentSender; -import android.os.Binder; -import android.os.IBinder; -import android.os.IInterface; -import android.os.RemoteException; - -public interface IShortcutService extends IInterface { - boolean isRequestPinItemSupported(int user, int requestType) throws RemoteException; - ParceledListSlice getShortcuts(String packageName, int matchFlags, int userId) throws RemoteException; - ParceledListSlice getPinnedShortcuts(String packageName, int userId) throws RemoteException; - boolean requestPinShortcut(String packageName, ShortcutInfo shortcut, - IntentSender resultIntent, int userId) throws RemoteException; - - boolean updateShortcuts(String packageName, ParceledListSlice shortcuts, int userId) throws RemoteException; - - abstract class Stub extends Binder implements IShortcutService { - - public static IShortcutService asInterface(IBinder obj) { - throw new RuntimeException("STUB"); - } - } -} diff --git a/hiddenapi/stubs/src/main/java/android/content/pm/ShortcutInfo.java b/hiddenapi/stubs/src/main/java/android/content/pm/ShortcutInfo.java deleted file mode 100644 index 24b8b062f84..00000000000 --- a/hiddenapi/stubs/src/main/java/android/content/pm/ShortcutInfo.java +++ /dev/null @@ -1,28 +0,0 @@ -package android.content.pm; - -import android.os.Parcel; -import android.os.Parcelable; - -public class ShortcutInfo implements Parcelable { - public static final Creator CREATOR = new Creator<>() { - @Override - public ShortcutInfo createFromParcel(Parcel in) { - throw new IllegalArgumentException("STUB"); - } - - @Override - public ShortcutInfo[] newArray(int size) { - throw new IllegalArgumentException("STUB"); - } - }; - - @Override - public void writeToParcel(Parcel dest, int flags) { - throw new IllegalArgumentException("STUB"); - } - - @Override - public int describeContents() { - throw new IllegalArgumentException("STUB"); - } -} diff --git a/hiddenapi/stubs/src/main/java/android/os/ShellCallback.java b/hiddenapi/stubs/src/main/java/android/os/ShellCallback.java index b8a5771fdaf..fe342213a3f 100644 --- a/hiddenapi/stubs/src/main/java/android/os/ShellCallback.java +++ b/hiddenapi/stubs/src/main/java/android/os/ShellCallback.java @@ -1,7 +1,7 @@ package android.os; public class ShellCallback implements Parcelable { - public static final Parcelable.Creator CREATOR = new Creator<>() { + public static final Parcelable.Creator CREATOR = new Creator() { @Override public ShellCallback createFromParcel(Parcel source) { throw new IllegalArgumentException("STUB"); diff --git a/core/src/main/java/org/lsposed/lspd/util/CompoundEnumeration.java b/hiddenapi/stubs/src/main/java/sun/misc/CompoundEnumeration.java similarity index 96% rename from core/src/main/java/org/lsposed/lspd/util/CompoundEnumeration.java rename to hiddenapi/stubs/src/main/java/sun/misc/CompoundEnumeration.java index 1f2d6cd9376..26eeedc1012 100644 --- a/core/src/main/java/org/lsposed/lspd/util/CompoundEnumeration.java +++ b/hiddenapi/stubs/src/main/java/sun/misc/CompoundEnumeration.java @@ -1,4 +1,4 @@ -package org.lsposed.lspd.util; +package sun.misc; import java.util.Enumeration; import java.util.NoSuchElementException; diff --git a/hiddenapi/stubs/src/main/java/sun/net/www/protocol/jar/Handler.java b/hiddenapi/stubs/src/main/java/sun/net/www/protocol/jar/Handler.java new file mode 100644 index 00000000000..838a47e559a --- /dev/null +++ b/hiddenapi/stubs/src/main/java/sun/net/www/protocol/jar/Handler.java @@ -0,0 +1,4 @@ +package sun.net.www.protocol.jar; + +public abstract class Handler extends java.net.URLStreamHandler { +} diff --git a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java index e2d6fa93521..560382d1236 100644 --- a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java +++ b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java @@ -89,6 +89,18 @@ private synchronized static PackageInfo getManagerPkgInfo(ApplicationInfo appInf return managerPkgInfo; } + private static void sendBinderToManager(final ClassLoader classLoader, IBinder binder) { + try { + var clazz = XposedHelpers.findClass("org.lsposed.manager.Constants", classLoader); + var ok = (boolean) XposedHelpers.callStaticMethod(clazz, "setBinder", + new Class[]{IBinder.class}, binder); + if (ok) return; + throw new RuntimeException("setBinder: " + false); + } catch (Throwable t) { + Utils.logW("Could not send binder to LSPosed Manager", t); + } + } + private static void hookForManager(ILSPManagerService managerService) { var managerApkHooker = new XC_MethodHook() { @Override @@ -111,7 +123,7 @@ protected void beforeHookedMethod(MethodHookParam param) { protected void afterHookedMethod(MethodHookParam param) { var pkgInfo = getManagerPkgInfo(null); if (pkgInfo != null && XposedHelpers.getObjectField(param.thisObject, "mApplicationInfo") == pkgInfo.applicationInfo) { - InstallerVerifier.sendBinderToManager((ClassLoader) param.getResult(), managerService.asBinder()); + sendBinderToManager((ClassLoader) param.getResult(), managerService.asBinder()); unhooks[0].unhook(); } }