Call setIntent when starting a Component.

Before the Intent would only have been set by calling .attach (if
doBootSequence is enabled). Attach is only called when the modell is
filled with instructions.

This new variant calls setIntent when creating the wrapper for the model
(getMethodAs). This is much better!
This commit is contained in:
Tobias Blaschke 2014-03-02 11:43:54 +01:00 committed by Juergen Graf
parent eb4e3e4b58
commit cbfca1df4e
2 changed files with 44 additions and 1 deletions

View File

@ -720,6 +720,7 @@ public class AndroidModel /* makes SummarizedMethod */
defaults.add(unpackedIntent);
}
}
final SSAValue intent = acc.firstExtends(AndroidTypes.Intent, cha);
final AndroidStartComponentTool tool = new AndroidStartComponentTool(getClassHierarchy(), asMethod, flags, caller, instructionFactory,
acc, pm, redirect, self, info, callerNd);
@ -734,9 +735,13 @@ public class AndroidModel /* makes SummarizedMethod */
// TODO: Check, that caller is an activity where necessary!
// TODO: Call Activity.setIntent
//final SSAValue iBinder = tool.fetchIBinder(androidContext);
//tool.assignIBinder(iBinder, allActivities);
if (intent != null) {
tool.setIntent(intent, allActivities);
} else if (! info.isSystemService()) { // it's normal for SystemServices
logger.warn("Got no Intent in call to: {} as {}", this.name, asMethod);
}
// Call the model
{

View File

@ -255,6 +255,8 @@ public class AndroidStartComponentTool {
final IClass iCaller = cha.lookupClass(caller);
final IClass iActivity = cha.lookupClass(AndroidTypes.Activity);
final IClass iApp = cha.lookupClass(AndroidTypes.Application);
final IClass iService = cha.lookupClass(AndroidTypes.Service);
logger.debug("Fetching caller context...");
final SSAValue androidContext;
@ -297,6 +299,16 @@ public class AndroidStartComponentTool {
this.callerContext = AndroidTypes.AndroidContextType.CONTEXT_BRIDGE;
logger.info("Caller has android-context type: BridgeContext");
return androidContext;
} else if (cha.isAssignableFrom(iApp, iCaller)) {
androidContext = self;
this.callerContext = AndroidTypes.AndroidContextType.APPLICATION;
logger.info("Caller has android-context type: Application");
return androidContext;
} else if (cha.isAssignableFrom(iService, iCaller)) {
androidContext = self;
this.callerContext = AndroidTypes.AndroidContextType.SERVICE;
logger.info("Caller has android-context type: Service");
return androidContext;
} else {
throw new UnsupportedOperationException("Can not handle the callers android-context of " + caller);
}
@ -439,6 +451,32 @@ public class AndroidStartComponentTool {
}
}
/**
* Call Activity.setIntent.
*/
public void setIntent(SSAValue intent, List<? extends SSAValue> allActivities) {
if (intent == null) {
throw new IllegalArgumentException("Null-Intent");
}
logger.info("Assigning the intent");
// TODO: Use Phi?
for (SSAValue activity : allActivities) {
logger.debug("\tto: {}", activity);
final int callPC = redirect.getNextProgramCounter();
final Selector mSel = Selector.make("setIntent(Landroid/content/Intent;)V");
final MethodReference mRef = MethodReference.findOrCreate(AndroidTypes.Activity, mSel);
final CallSiteReference site = CallSiteReference.make(callPC, mRef, IInvokeInstruction.Dispatch.VIRTUAL);
final SSAValue exception = pm.getException();
final List<SSAValue> params = new ArrayList<SSAValue>(1);
params.add(activity);
params.add(intent);
final SSAInstruction invokation = instructionFactory.InvokeInstruction(callPC, params, exception, site);
redirect.addStatement(invokation);
}
}
/**
* Grab mResultCode and mResultData.