Enhance resources hook (#1524)

1. Fix missing `getFloat` overload for XResources
2. Fix missing `getFont` overload
3. Add `getValue` and `getValueForDensity` replacement for apps that
   obtain raw values
This commit is contained in:
LoveSy 2022-01-10 20:51:56 +08:00 committed by GitHub
parent e3fee7806e
commit d59cc6b784
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 117 additions and 0 deletions

View File

@ -23,6 +23,7 @@ package android.content.res;
import static org.lsposed.lspd.nativebridge.ResourcesHook.rewriteXmlReferencesNative;
import static de.robv.android.xposed.XposedHelpers.decrementMethodDepth;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.getBooleanField;
import static de.robv.android.xposed.XposedHelpers.getLongField;
import static de.robv.android.xposed.XposedHelpers.getObjectField;
import static de.robv.android.xposed.XposedHelpers.incrementMethodDepth;
@ -32,8 +33,10 @@ import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.graphics.Color;
import android.graphics.Movie;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.StrictMode;
import android.text.Html;
import android.util.AttributeSet;
@ -44,6 +47,8 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.RequiresApi;
import org.xmlpull.v1.XmlPullParser;
import java.io.File;
@ -860,6 +865,35 @@ public class XResources extends XResourcesSuperClass {
}
}
/** @hide */
@RequiresApi(Build.VERSION_CODES.Q)
@Override
public float getFloat(int id) {
Object replacement = getReplacement(id);
if (replacement instanceof Float) {
return (Float) replacement;
} else if (replacement instanceof XResForwarder) {
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
return repRes.getFloat(repId);
}
return super.getFloat(id);
}
/** @hide */
@Override
public Typeface getFont(int id) {
Object replacement = getReplacement(id);
if (replacement instanceof Typeface) {
return (Typeface) replacement;
} else if (replacement instanceof XResForwarder) {
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
return repRes.getFont(repId);
}
return super.getFont(id);
}
/** @hide */
@Override
public float getFraction(int id, int base, int pbase) {
@ -1055,6 +1089,38 @@ public class XResources extends XResourcesSuperClass {
return super.getTextArray(id);
}
/** @hide */
@Override
public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException {
Object replacement = getReplacement(id);
if (replacement instanceof XResForwarder) {
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
repRes.getValue(repId, outValue, resolveRefs);
} else {
if (replacement != null) {
XposedBridge.log("Replacement of resource ID #0x" + Integer.toHexString(id) + " escaped because of deprecated replacement. Please use XResForwarder instead.");
}
super.getValue(id, outValue, resolveRefs);
}
}
/** @hide */
@Override
public void getValueForDensity(int id, int density, TypedValue outValue, boolean resolveRefs) throws NotFoundException {
Object replacement = getReplacement(id);
if (replacement instanceof XResForwarder) {
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
repRes.getValueForDensity(repId, density, outValue, resolveRefs);
} else {
if (replacement != null) {
XposedBridge.log("Replacement of resource ID #0x" + Integer.toHexString(id) + " escaped because of deprecated replacement. Please use XResForwarder instead.");
}
super.getValueForDensity(id, density, outValue, resolveRefs);
}
}
/** @hide */
@Override
public XmlResourceParser getXml(int id) throws NotFoundException {
@ -1337,6 +1403,19 @@ public class XResources extends XResourcesSuperClass {
return super.getFloat(index, defValue);
}
@Override
public Typeface getFont(int index) {
Object replacement = ((XResources) getResources()).getReplacement(getResourceId(index, 0));
if (replacement instanceof Typeface) {
return (Typeface) replacement;
} else if (replacement instanceof XResForwarder) {
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
return repRes.getFont(repId);
}
return super.getFont(index);
}
@Override
public float getFraction(int index, int base, int pbase, float defValue) {
Object replacement = ((XResources) getResources()).getReplacement(getResourceId(index, 0));
@ -1435,6 +1514,44 @@ public class XResources extends XResourcesSuperClass {
}
return super.getTextArray(index);
}
@Override
public boolean getValue(int index, TypedValue outValue) {
var id = getResourceId(index, 0);
Object replacement = ((XResources) getResources()).getReplacement(id);
if (replacement instanceof XResForwarder) {
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
repRes.getValue(repId, outValue, true);
return outValue.type != TypedValue.TYPE_NULL;
} else {
if (replacement != null) {
XposedBridge.log("Replacement of resource ID #0x" + Integer.toHexString(id) + " escaped because of deprecated replacement. Please use XResForwarder instead.");
}
return super.getValue(index, outValue);
}
}
@Override
public TypedValue peekValue(int index) {
var id = getResourceId(index, 0);
Object replacement = ((XResources) getResources()).getReplacement(id);
if (replacement instanceof XResForwarder) {
if (getBooleanField(this, "mRecycled")) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
final TypedValue value = (TypedValue) getObjectField(this, "mValue");
Resources repRes = ((XResForwarder) replacement).getResources();
int repId = ((XResForwarder) replacement).getId();
repRes.getValue(repId, value, true);
return value;
} else {
if (replacement != null) {
XposedBridge.log("Replacement of resource ID #0x" + Integer.toHexString(id) + " escaped because of deprecated replacement. Please use XResForwarder instead.");
}
return super.peekValue(index);
}
}
}