-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[in_app_purchase] Android: fix potential crash when casting in v1 embedding. (Trivial) #2585
Conversation
| if (registrar.context().getApplicationContext() != null | ||
| && registrar.context().getApplicationContext() instanceof Application) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it bad if it's null or not an Application? Does that need to be handled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if either of those situations happens, we are not able to get the application, which makes us no way to register life cycle callbacks. We kind of just bailing here.
I'm not sure if there would be a way to handle that situation in V1 embedding, but we definitely don't want to crash here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know how people are getting in this state?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not entirely sure. @mklim or @matthew-carroll might have more ideas on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that you can just say registrar.context().getApplicationContext(). I don't think that context() can return null, and I don't think that getApplicationContext() can return null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, do you know why you need an Application? What are the Application methods that are being called that are not defined on a Context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. I just did some search and it seems to be the case. I'll update the fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe .registerActivityLifecycleCallbacks is only in Application?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To explain this a little more, there is a difference between an ApplicationContext (can be cast to Application) and an ActivityContext (can be cast to Activity) even though they're both Contexts. Generally it's hard to tell the difference but occasionally it's critical. The Activity Context is tied to the Activity lifecycle so can be invalidated much easier. registrar.context() returns an activity context if an activity has been registered with the Engine and an application context otherwise. getApplicationContext() should always be castable to an application like @matthew-carroll mentioned.
jmagman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WorkspaceSettings.xcsettings looks right. Defer to @matthew-carroll for the java change.
| } | ||
|
|
||
| @Test | ||
| public void registerWith_doNotCrashWhenApplicationContextIsTypeApplication() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this test necessary? We should probably avoid testing situations that can't happen, because it might indicate to readers that it can happen...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't context.getApplicationContext() always going to return an application? This looks like the standard case to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though on a second look, maybe a more meaningful test here would be to return an Activity from registrar.context() and make sure that that doesn't crash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mklim Sounds good, I will update the test.
mklim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| } | ||
|
|
||
| @Test | ||
| public void registerWith_doNotCrashWhenApplicationContextIsTypeApplication() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't context.getApplicationContext() always going to return an application? This looks like the standard case to me.
| public static void registerWith(Registrar registrar) { | ||
| InAppPurchasePlugin plugin = new InAppPurchasePlugin(); | ||
| plugin.setupMethodChannel(registrar.activity(), registrar.messenger(), registrar.context()); | ||
| ((Application) registrar.context()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for a little more info in case this doesn't make sense, the bug here is that sometimes registrar.context() will return an Activity context instead of an Application context if it's available and this case will fail. My understanding is that it's the typical for it to do this so I'm actually surprised that this was routinely working before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was newly added in my new patch so it might be that my patch broke it. However, when I tested locally, it was working. I wonder why activity was not available when i was testing it.
|
Updated the tests based on discussion. Will merge on green. |
|
Landing on tree red as it is going to fix a ci error. |
Description
Fix a potential crash when we cast context() to Application in the v1 embedding code.
Related Issues
flutter/flutter#50861
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.///).flutter analyze) does not report any problems on my PR.Breaking Change
Does your PR require plugin users to manually update their apps to accommodate your change?