Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 62fbba5

Browse files
authored
fixes android deeplink query paremeter null crashes (#24146)
1 parent f94cf14 commit 62fbba5

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ private String maybeGetInitialRouteFromIntent(Intent intent) {
400400
Uri data = intent.getData();
401401
if (data != null && !data.getPath().isEmpty()) {
402402
String pathAndQuery = data.getPath();
403-
if (!data.getQuery().isEmpty()) {
403+
if (data.getQuery() != null && !data.getQuery().isEmpty()) {
404404
pathAndQuery += "?" + data.getQuery();
405405
}
406406
return pathAndQuery;

shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,32 @@ public void itForwardsOnRequestPermissionsResultToFlutterEngine() {
456456
.setInitialRoute("/custom/route?query=test");
457457
}
458458

459+
@Test
460+
public void
461+
itSendsInitialRouteFromIntentOnStartIfNoInitialRouteFromActivityAndShouldHandleDeeplinkingNoQueryParameter() {
462+
Intent intent = FlutterActivity.createDefaultIntent(RuntimeEnvironment.application);
463+
intent.setData(Uri.parse("http://myApp/custom/route"));
464+
465+
ActivityController<FlutterActivity> activityController =
466+
Robolectric.buildActivity(FlutterActivity.class, intent);
467+
FlutterActivity flutterActivity = activityController.get();
468+
469+
when(mockHost.getActivity()).thenReturn(flutterActivity);
470+
when(mockHost.getInitialRoute()).thenReturn(null);
471+
when(mockHost.shouldHandleDeeplinking()).thenReturn(true);
472+
// Create the real object that we're testing.
473+
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
474+
475+
// --- Execute the behavior under test ---
476+
// The FlutterEngine is setup in onAttach().
477+
delegate.onAttach(RuntimeEnvironment.application);
478+
// Emulate app start.
479+
delegate.onStart();
480+
481+
// Verify that the navigation channel was given the initial route message.
482+
verify(mockFlutterEngine.getNavigationChannel(), times(1)).setInitialRoute("/custom/route");
483+
}
484+
459485
@Test
460486
public void itSendsdefaultInitialRouteOnStartIfNotDeepLinkingFromIntent() {
461487
// Creates an empty intent without launch uri.
@@ -501,6 +527,25 @@ public void itSendsPushRouteMessageWhenOnNewIntent() {
501527
.pushRoute("/custom/route?query=test");
502528
}
503529

530+
@Test
531+
public void itSendsPushRouteMessageWhenOnNewIntentNoQueryParameter() {
532+
when(mockHost.shouldHandleDeeplinking()).thenReturn(true);
533+
// Create the real object that we're testing.
534+
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
535+
536+
// --- Execute the behavior under test ---
537+
// The FlutterEngine is setup in onAttach().
538+
delegate.onAttach(RuntimeEnvironment.application);
539+
540+
Intent mockIntent = mock(Intent.class);
541+
when(mockIntent.getData()).thenReturn(Uri.parse("http://myApp/custom/route"));
542+
// Emulate the host and call the method that we expect to be forwarded.
543+
delegate.onNewIntent(mockIntent);
544+
545+
// Verify that the navigation channel was given the push route message.
546+
verify(mockFlutterEngine.getNavigationChannel(), times(1)).pushRoute("/custom/route");
547+
}
548+
504549
@Test
505550
public void itForwardsOnNewIntentToFlutterEngine() {
506551
// Create the real object that we're testing.

0 commit comments

Comments
 (0)