X Tutup
Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@
public @interface ReceiverAction {

/**
* Define the action's name. If this field isn't set the annotated method
* name will be used.
* Define a set of actions this method should handle. If this field isn't
* set the annotated method name will be used.
*
* @return the action's name
* @return the actions
*/
String value() default "";
String[] value() default {};

/**
* Define a set of data schemes to filter the Intent. If this field isn't
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,41 +79,40 @@ public void process(Element element, EReceiverHolder holder) throws Exception {

ReceiverAction annotation = element.getAnnotation(ReceiverAction.class);
String[] dataSchemes = annotation.dataSchemes();
String extraKey = annotation.value();
if (extraKey.isEmpty()) {
extraKey = methodName;
String[] actions = annotation.value();
if (actions.length == 0) {
actions = new String[] { methodName };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think it is a good idea to catch intents with action as the method name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, you are right, but that was the old behaviour. changing this might break existing apps.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooops, i see. We missed that in the initial review of this feature...
It should stay, then, but we will change the behavior in 4.0.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall i open an issue and prepare a PR (based on this one)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically a PR should not depend on other PRs, but we can make an exception here. Thanks!

}

JFieldVar actionKeyField = createStaticActionField(holder, extraKey, methodName);
JFieldVar dataSchemesField = createStaticDataSchemesField(holder, dataSchemes, methodName);
JFieldVar actionKeyField = createStaticField(holder, "actions", methodName, actions);
JFieldVar dataSchemesField = createStaticField(holder, "dataSchemes", methodName, dataSchemes);
addActionInOnReceive(holder, executableElement, methodName, actionKeyField, dataSchemesField);
}

private JFieldVar createStaticActionField(EReceiverHolder holder, String extraKey, String methodName) {
String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase("action", methodName, null);
return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, classes().STRING, staticFieldName, lit(extraKey));
}
private JFieldVar createStaticField(EReceiverHolder holder, String prefix, String methodName, String[] values) {
String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase(prefix, methodName, null);

private JFieldVar createStaticDataSchemesField(EReceiverHolder holder, String[] dataSchemes, String methodName) {
if (dataSchemes == null || dataSchemes.length == 0) {
if (values == null || values.length == 0) {
return null;
} else if (values.length == 1) {
return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, classes().STRING, staticFieldName, lit(values[0]));

}
JClass listOfStrings = classes().LIST.narrow(classes().STRING);
String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase("dataSchemes", methodName, null);

JInvocation asListInvoke = classes().ARRAYS.staticInvoke("asList");
for (String scheme : dataSchemes) {
for (String scheme : values) {
asListInvoke.arg(scheme);
}

JClass listOfStrings = classes().LIST.narrow(classes().STRING);
return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, listOfStrings, staticFieldName, asListInvoke);
}

private void addActionInOnReceive(EReceiverHolder holder, ExecutableElement executableElement, String methodName, JFieldVar actionKeyField, JFieldVar dataSchemesField) {
// If action match, call the method
JExpression filterCondition = actionKeyField.invoke("equals").arg(holder.getOnReceiveIntentAction());
private void addActionInOnReceive(EReceiverHolder holder, ExecutableElement executableElement, String methodName, JFieldVar actionsField, JFieldVar dataSchemesField) {
String actionsInvoke = getInvocationName(actionsField);
JExpression filterCondition = actionsField.invoke(actionsInvoke).arg(holder.getOnReceiveIntentAction());
if (dataSchemesField != null) {
filterCondition = filterCondition.cand(dataSchemesField.invoke("contains").arg(holder.getOnReceiveIntentDataScheme()));
String dataSchemesInvoke = getInvocationName(dataSchemesField);
filterCondition = filterCondition.cand(dataSchemesField.invoke(dataSchemesInvoke).arg(holder.getOnReceiveIntentDataScheme()));
}

JBlock callActionBlock = holder.getOnReceiveBody()._if(filterCondition)._then();
Expand Down Expand Up @@ -142,6 +141,14 @@ private void addActionInOnReceive(EReceiverHolder holder, ExecutableElement exec
callActionBlock._return();
}

private String getInvocationName(JFieldVar field) {
JClass listOfStrings = classes().LIST.narrow(classes().STRING);
if (field.type().fullName().equals(listOfStrings.fullName())) {
return "contains";
}
return "equals";
}

private static class ExtraHandler extends ExtraParameterHandler {

public ExtraHandler(ProcessingEnvironment processingEnvironment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public class EReceiverHolder extends EComponentHolder {

private JFieldVar contextField;
private JBlock onReceiveBody;
private JVar onReceiveIntentAction;
private JVar onReceiveIntentDataScheme;
Expand All @@ -45,13 +43,15 @@ public EReceiverHolder(ProcessHolder processHolder, TypeElement annotatedElement

@Override
protected void setContextRef() {
contextField = generatedClass.field(PRIVATE, classes().CONTEXT, "context_");
contextRef = contextField;
if (init == null) {
setInit();
}
}

@Override
protected void setInit() {
init = generatedClass.method(PRIVATE, codeModel().VOID, "init_");
contextRef = init.param(classes().CONTEXT, "context");
if (onReceiveMethod == null) {
createOnReceive();
}
Expand All @@ -63,14 +63,18 @@ private void createOnReceive() {
onReceiveIntent = onReceiveMethod.param(classes().INTENT, "intent");
onReceiveMethod.annotate(Override.class);
onReceiveBody = onReceiveMethod.body();
onReceiveBody.assign(getContextField(), onReceiveContext);
onReceiveBody.invoke(getInit());
onReceiveBody.invoke(getInit()).arg(onReceiveContext);
onReceiveBody.invoke(JExpr._super(), onReceiveMethod).arg(onReceiveContext).arg(onReceiveIntent);
}

JInvocation getActionInvocation = JExpr.invoke(onReceiveIntent, "getAction");
JInvocation getDataSchemeInvocation = JExpr.invoke(onReceiveIntent, "getScheme");
onReceiveIntentAction = onReceiveBody.decl(classes().STRING, "action", getActionInvocation);
onReceiveIntentDataScheme = onReceiveBody.decl(classes().STRING, "dataScheme", getDataSchemeInvocation);
private void setOnReceiveIntentAction() {
JInvocation getActionInvocation = JExpr.invoke(getOnReceiveIntent(), "getAction");
onReceiveIntentAction = getOnReceiveBody().decl(classes().STRING, "action", getActionInvocation);
}

private void setOnReceiveIntentDataScheme() {
JInvocation getDataSchemeInvocation = JExpr.invoke(getOnReceiveIntent(), "getScheme");
onReceiveIntentDataScheme = getOnReceiveBody().decl(classes().STRING, "dataScheme", getDataSchemeInvocation);
}

public JMethod getOnReceiveMethod() {
Expand Down Expand Up @@ -103,22 +107,15 @@ public JVar getOnReceiveContext() {

public JVar getOnReceiveIntentAction() {
if (onReceiveIntentAction == null) {
createOnReceive();
setOnReceiveIntentAction();
}
return onReceiveIntentAction;
}

public JVar getOnReceiveIntentDataScheme() {
if (onReceiveIntentDataScheme == null) {
createOnReceive();
setOnReceiveIntentDataScheme();
}
return onReceiveIntentDataScheme;
}

public JFieldVar getContextField() {
if (contextField == null) {
setContextRef();
}
return contextField;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@
@EReceiver
public class ReceiverWithActions extends BroadcastReceiver {

public static final String ACTION_SIMPLE_TEST = "ACTION_SIMPLE_TEST";
public static final String ACTION_SCHEME_TEST = "ACTION_SCHEME_TEST";
public static final String ACTION_PARAMETER_TEST = "ACTION_PARAMETER_TEST";
public static final String ACTION_MULTIPLE_TEST_1 = "ACTION_MULTIPLE_TEST_1";
public static final String ACTION_MULTIPLE_TEST_2 = "ACTION_MULTIPLE_TEST_2";
public static final String ACTION_EXTRA_PARAMETER_TEST = "ACTION_EXTRA_PARAMETER_TEST";
public static final String EXTRA_ARG_NAME1 = "thisExtraHasAnotherName";
public static final String EXTRA_ARG_NAME2 = "thisIsMyParameter";
public static final String DATA_SCHEME = "http";

public boolean simpleActionReceived = false;
public boolean actionWithSchemeReceived = false;

Expand All @@ -34,29 +44,36 @@ public class ReceiverWithActions extends BroadcastReceiver {
public boolean extraParameterActionReceived = false;
public String extraParameterActionValue = null;

public int multipleActionCall = 0;

@Override
public void onReceive(Context context, Intent intent) {
}

@ReceiverAction("ACTION_SIMPLE_TEST")
@ReceiverAction(ACTION_SIMPLE_TEST)
public void onSimpleAction() {
simpleActionReceived = true;
}

@ReceiverAction(value = "ACTION_SCHEME_TEST", dataSchemes = "http")
@ReceiverAction(value = ACTION_SCHEME_TEST, dataSchemes = DATA_SCHEME)
public void onActionWithReceiver() {
actionWithSchemeReceived = true;
}

@ReceiverAction("ACTION_PARAMETER_TEST")
@ReceiverAction(ACTION_PARAMETER_TEST)
public void onParameterAction(@ReceiverAction.Extra String thisIsMyParameter) {
parameterActionReceived = true;
parameterActionValue = thisIsMyParameter;
}

@ReceiverAction("ACTION_EXTRA_PARAMETER_TEST")
public void onExtraParameterAction(@ReceiverAction.Extra("thisExtraHasAnotherName") String thisIsAParameter) {
@ReceiverAction(ACTION_EXTRA_PARAMETER_TEST)
public void onExtraParameterAction(@ReceiverAction.Extra(EXTRA_ARG_NAME1) String thisIsAParameter) {
extraParameterActionReceived = true;
extraParameterActionValue = thisIsAParameter;
}

@ReceiverAction({ ACTION_MULTIPLE_TEST_1, ACTION_MULTIPLE_TEST_2 })
public void onMultipleActions() {
multipleActionCall++;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

@RunWith(RobolectricTestRunner.class)
public class ReceiverWithActionsTest {
private static final String EXTRA_PARAMETER_VALUE = "string value";

private ReceiverWithActions receiver;

@Before
Expand All @@ -38,36 +40,49 @@ public void setup() {

@Test
public void onSimpleActionTest() {
receiver.onReceive(Robolectric.application, new Intent("ACTION_SIMPLE_TEST"));
receiver.onReceive(Robolectric.application, new Intent(ReceiverWithActions.ACTION_SIMPLE_TEST));

assertTrue(receiver.simpleActionReceived);
}

@Test
public void onActionWithReceiverTest() {
Intent intent = new Intent("ACTION_SCHEME_TEST", Uri.parse("http://androidannotations.org"));
Intent intent = new Intent(ReceiverWithActions.ACTION_SCHEME_TEST, Uri.parse(ReceiverWithActions.DATA_SCHEME + "://androidannotations.org"));
receiver.onReceive(Robolectric.application, intent);

assertTrue(receiver.actionWithSchemeReceived);
}

@Test
public void onParameterActionTest() {
Intent intent = new Intent("ACTION_PARAMETER_TEST");
intent.putExtra("thisIsMyParameter", "string value");
Intent intent = new Intent(ReceiverWithActions.ACTION_PARAMETER_TEST);
intent.putExtra(ReceiverWithActions.EXTRA_ARG_NAME2, EXTRA_PARAMETER_VALUE);
receiver.onReceive(Robolectric.application, intent);

assertTrue(receiver.parameterActionReceived);
assertEquals("string value", receiver.parameterActionValue);
assertEquals(EXTRA_PARAMETER_VALUE, receiver.parameterActionValue);
}

@Test
public void onExtraParameterActionTest() {
Intent intent = new Intent("ACTION_EXTRA_PARAMETER_TEST");
intent.putExtra("thisExtraHasAnotherName", "string value");
Intent intent = new Intent(ReceiverWithActions.ACTION_EXTRA_PARAMETER_TEST);
intent.putExtra(ReceiverWithActions.EXTRA_ARG_NAME1, EXTRA_PARAMETER_VALUE);
receiver.onReceive(Robolectric.application, intent);

assertTrue(receiver.extraParameterActionReceived);
assertEquals("string value", receiver.extraParameterActionValue);
assertEquals(EXTRA_PARAMETER_VALUE, receiver.extraParameterActionValue);
}

@Test
public void onMultipleActionsTest() {
assertEquals(0, receiver.multipleActionCall);

Intent intent = new Intent(ReceiverWithActions.ACTION_MULTIPLE_TEST_1);
receiver.onReceive(Robolectric.application, intent);
assertEquals(1, receiver.multipleActionCall);

intent = new Intent(ReceiverWithActions.ACTION_MULTIPLE_TEST_2);
receiver.onReceive(Robolectric.application, intent);
assertEquals(2, receiver.multipleActionCall);
}
}
X Tutup