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

Commit 9275197d authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add aapt support for generating proguard rules for onClick methods.

Also fix Activity menu inflater when using the dark on light
theme wrapper to still be able to find onClick listeners.

Change-Id: Ie206db26d1df96041bc477804e476b02ad99dc9d
parent fb5c3dba
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3273,7 +3273,7 @@ public class Activity extends ContextThemeWrapper
        if (mMenuInflater == null) {
            initActionBar();
            if (mActionBar != null) {
                mMenuInflater = new MenuInflater(mActionBar.getThemedContext());
                mMenuInflater = new MenuInflater(mActionBar.getThemedContext(), this);
            } else {
                mMenuInflater = new MenuInflater(this);
            }
+22 −7
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ public class MenuInflater {
    private final Object[] mActionProviderConstructorArguments;

    private Context mContext;
    private Object mRealOwner;

    /**
     * Constructs a menu inflater.
@@ -73,6 +74,20 @@ public class MenuInflater {
     */
    public MenuInflater(Context context) {
        mContext = context;
        mRealOwner = context;
        mActionViewConstructorArguments = new Object[] {context};
        mActionProviderConstructorArguments = mActionViewConstructorArguments;
    }

    /**
     * Constructs a menu inflater.
     *
     * @see Activity#getMenuInflater()
     * @hide
     */
    public MenuInflater(Context context, Object realOwner) {
        mContext = context;
        mRealOwner = realOwner;
        mActionViewConstructorArguments = new Object[] {context};
        mActionProviderConstructorArguments = mActionViewConstructorArguments;
    }
@@ -190,12 +205,12 @@ public class MenuInflater {
            implements MenuItem.OnMenuItemClickListener {
        private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class };
        
        private Context mContext;
        private Object mRealOwner;
        private Method mMethod;
        
        public InflatedOnMenuItemClickListener(Context context, String methodName) {
            mContext = context;
            Class<?> c = context.getClass();
        public InflatedOnMenuItemClickListener(Object realOwner, String methodName) {
            mRealOwner = realOwner;
            Class<?> c = realOwner.getClass();
            try {
                mMethod = c.getMethod(methodName, PARAM_TYPES);
            } catch (Exception e) {
@@ -210,9 +225,9 @@ public class MenuInflater {
        public boolean onMenuItemClick(MenuItem item) {
            try {
                if (mMethod.getReturnType() == Boolean.TYPE) {
                    return (Boolean) mMethod.invoke(mContext, item);
                    return (Boolean) mMethod.invoke(mRealOwner, item);
                } else {
                    mMethod.invoke(mContext, item);
                    mMethod.invoke(mRealOwner, item);
                    return true;
                }
            } catch (Exception e) {
@@ -400,7 +415,7 @@ public class MenuInflater {
                            + "be used within a restricted context");
                }
                item.setOnMenuItemClickListener(
                        new InflatedOnMenuItemClickListener(mContext, itemListenerMethodName));
                        new InflatedOnMenuItemClickListener(mRealOwner, itemListenerMethodName));
            }

            if (item instanceof MenuItemImpl) {
+27 −0
Original line number Diff line number Diff line
@@ -2089,6 +2089,23 @@ addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,
    keep->add(rule, location);
}

void
addProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,
        const char* pkg, const String8& srcName, int line)
{
    String8 rule("-keepclassmembers class * { *** ");
    rule += memberName;
    rule += "(...); }";

    String8 location("onClick ");
    location += srcName;
    char lineno[20];
    sprintf(lineno, ":%d", line);
    location += lineno;

    keep->add(rule, location);
}

status_t
writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
{
@@ -2251,6 +2268,13 @@ writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,
                }
            }
        }
        ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick");
        if (attrIndex >= 0) {
            size_t len;
            addProguardKeepMethodRule(keep,
                                String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
                                layoutFile->getPrintableSource(), tree.getLineNumber());
        }
    }

    return NO_ERROR;
@@ -2289,6 +2313,9 @@ writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
        } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) {
            startTag = "PreferenceScreen";
            tagAttrPairs = &kXmlTagAttrPairs;
        } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) {
            startTag = "menu";
            tagAttrPairs = NULL;
        } else {
            continue;
        }