Merge "Add aapt support for generating proguard rules for onClick methods." into jb-dev

This commit is contained in:
Dianne Hackborn
2012-05-18 19:39:09 -07:00
committed by Android (Google) Code Review
3 changed files with 50 additions and 8 deletions

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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;
}