Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8ea7504 authored by Deepanshu Gupta's avatar Deepanshu Gupta
Browse files

Make Context.getClassLoader() work.

Context.getClassLoader() is used by the LayoutInflater and can be used
by custom views. However, when called from the LayoutInflater, this
needs to return only the Framework classes. This is so that the IDE gets
a chance to instantiate the custom views, which helps in better error
reporting and better fallback in case of exceptions, like MockView.

To workaround this need of the same method returning different results
based on where it's called from, the method call in LayoutInflater is
renamed to getFrameworkClassLoader() and the new method is injected in
Context. The implementation of getFrameworkClassLoader() maintains the
existing behaviour of getClassLoader().

Context.getClassLoader() is now modified to return classes from both
Framework and the app namespace.

Also, update the list of packages to search for Framework views.

Change-Id: I1a6be4aa1fc5c1c5520b5440a348a52f10b6eb3b
parent 21b56457
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -53,9 +53,14 @@ public final class BridgeInflater extends LayoutInflater {
     */
    private static final String[] sClassPrefixList = {
        "android.widget.",
        "android.webkit."
        "android.webkit.",
        "android.app."
    };

    public static String[] getClassPrefixList() {
        return sClassPrefixList;
    }

    protected BridgeInflater(LayoutInflater original, Context newContext) {
        super(original, newContext);
        newContext = getBaseContext(newContext);
+17 −2
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ public final class BridgeContext extends Context {

    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
    private SharedPreferences mSharedPreferences;
    private ClassLoader mClassLoader;

    /**
     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
@@ -462,7 +463,21 @@ public final class BridgeContext extends Context {

    @Override
    public ClassLoader getClassLoader() {
        return this.getClass().getClassLoader();
        if (mClassLoader == null) {
            mClassLoader = new ClassLoader(getClass().getClassLoader()) {
                @Override
                protected Class<?> findClass(String name) throws ClassNotFoundException {
                    for (String prefix : BridgeInflater.getClassPrefixList()) {
                        if (name.startsWith(prefix)) {
                            // These are framework classes and should not be loaded from the app.
                            throw new ClassNotFoundException(name + " not found");
                        }
                    }
                    return BridgeContext.this.mLayoutlibCallback.findClass(name);
                }
            };
        }
        return mClassLoader;
    }

    @Override
+0 −1
Original line number Diff line number Diff line
@@ -275,7 +275,6 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
            mContext.getRenderResources().setLogger(null);
        }
        ParserFactory.setParserFactory(null);

    }

    public static BridgeContext getCurrentContext() {
+1 −1
Original line number Diff line number Diff line
@@ -728,7 +728,7 @@ public class AsmAnalyzer {


                // Check if method needs to replaced by a call to a different method.
                if (ReplaceMethodCallsAdapter.isReplacementNeeded(owner, name, desc)) {
                if (ReplaceMethodCallsAdapter.isReplacementNeeded(owner, name, desc, mOwnerClass)) {
                    mReplaceMethodCallClasses.add(mOwnerClass);
                }
            }
+10 −1
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ public class AsmGenerator {
    /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN.
     * map old-FQCN => new-FQCN */
    private final HashMap<String, String> mRefactorClasses;
    /** Methods to inject. FQCN of class in which method should be injected => runnable that does
     * the injection. */
    private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;

    /**
     * Creates a new generator that can generate the output JAR with the stubbed classes.
@@ -165,6 +168,8 @@ public class AsmGenerator {
            }
            returnTypes.add(binaryToInternalClassName(className));
        }

        mInjectedMethodsMap = createInfo.getInjectedMethodsMap();
    }

    /**
@@ -337,7 +342,7 @@ public class AsmGenerator {
        ClassVisitor cv = cw;

        if (mReplaceMethodCallsClasses.contains(className)) {
            cv = new ReplaceMethodCallsAdapter(cv);
            cv = new ReplaceMethodCallsAdapter(cv, className);
        }

        cv = new RefactorClassAdapter(cv, mRefactorClasses);
@@ -345,6 +350,10 @@ public class AsmGenerator {
            cv = new RenameClassAdapter(cv, className, newName);
        }

        String binaryNewName = newName.replace('/', '.');
        if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
            cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
        }
        cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className),
                newName, cv, stubNativesOnly);

Loading