From 3bffd22510c046e166e565ccfc28f387a09317c2 Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Fri, 28 Jul 2023 10:41:58 -0400 Subject: [PATCH 1/9] Revert "Revert "[url_launcher] Set broadcast reciever visability as required by target api 34" (#4027)" This reverts commit baeca8868d8a7d978c79cc444935b9f59502ddb6. --- .../url_launcher/url_launcher_android/android/build.gradle | 3 +++ .../io/flutter/plugins/urllauncher/WebViewActivity.java | 7 ++++++- packages/url_launcher/url_launcher_android/pubspec.yaml | 1 - 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/android/build.gradle b/packages/url_launcher/url_launcher_android/android/build.gradle index cf504cb8afd..2ddd182523f 100644 --- a/packages/url_launcher/url_launcher_android/android/build.gradle +++ b/packages/url_launcher/url_launcher_android/android/build.gradle @@ -62,6 +62,9 @@ android { } dependencies { + + // Java language implementation + implementation "androidx.core:core:1.10.1" implementation 'androidx.annotation:annotation:1.6.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.1.1' diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 63b6b71552e..5b2498f0790 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -23,6 +23,7 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; +import androidx.core.content.ContextCompat; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -143,7 +144,11 @@ public void onCreate(@Nullable Bundle savedInstanceState) { webview.setWebChromeClient(new FlutterWebChromeClient()); // Register receiver that may finish this Activity. - registerReceiver(broadcastReceiver, closeIntentFilter); + ContextCompat.registerReceiver( + this.getApplication(), + broadcastReceiver, + closeIntentFilter, + ContextCompat.RECEIVER_EXPORTED); } @VisibleForTesting diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index 1ef09dbb97f..2d7c33efbf0 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -3,7 +3,6 @@ description: Android implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 version: 6.0.37 - environment: sdk: ">=2.18.0 <4.0.0" flutter: ">=3.3.0" From b9ba682a1ca741e6351eb895a77d9e7becc9477a Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Thu, 3 Aug 2023 10:18:37 -0400 Subject: [PATCH 2/9] Add comment --- .../io/flutter/plugins/urllauncher/WebViewActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 5b2498f0790..3a906a66963 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -167,6 +167,12 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @Override protected void onDestroy() { super.onDestroy(); + // TODO verify base case crash then uncomment and verify fix. + // BroadcastReceiver receiver = broadcastReceiver; + // if (receiver != null) { + // deviceCommandReceiver = null; + // context.unregisterReceiver(receiver); + // } unregisterReceiver(broadcastReceiver); } From 1bb7a9e0fe7c27d28be5ac6a8315e4ca0bdc0128 Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Mon, 7 Aug 2023 11:18:51 -0400 Subject: [PATCH 3/9] Register on the same context as re unregester --- .../io/flutter/plugins/urllauncher/WebViewActivity.java | 8 +------- .../example/integration_test/url_launcher_test.dart | 4 ++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 3a906a66963..821ca7e40ea 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -145,7 +145,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { // Register receiver that may finish this Activity. ContextCompat.registerReceiver( - this.getApplication(), + this, broadcastReceiver, closeIntentFilter, ContextCompat.RECEIVER_EXPORTED); @@ -167,12 +167,6 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @Override protected void onDestroy() { super.onDestroy(); - // TODO verify base case crash then uncomment and verify fix. - // BroadcastReceiver receiver = broadcastReceiver; - // if (receiver != null) { - // deviceCommandReceiver = null; - // context.unregisterReceiver(receiver); - // } unregisterReceiver(broadcastReceiver); } diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index 28dc79b7af3..a28f7323ab3 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -17,6 +17,10 @@ void main() { // Generally all devices should have some default browser. expect(await launcher.canLaunch('http://flutter.dev'), true); + // Launch a url then close. + expect(await launcher.launch('http://flutter.dev'), true); + await launcher.closeWebView(); + // sms:, tel:, and mailto: links may not be openable on every device, so // aren't tested here. }); From 8d31e6f92d4b28729654efe2e93483f76b89efc9 Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Mon, 7 Aug 2023 11:47:29 -0400 Subject: [PATCH 4/9] Add integration test for android url launch and close --- .../integration_test/url_launcher_test.dart | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index a28f7323ab3..b09f664e86e 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -17,9 +17,28 @@ void main() { // Generally all devices should have some default browser. expect(await launcher.canLaunch('http://flutter.dev'), true); + // sms:, tel:, and mailto: links may not be openable on every device, so + // aren't tested here. + }); + + testWidgets('launch and close', (WidgetTester _) async { + final UrlLauncherPlatform launcher = UrlLauncherPlatform.instance; + // Launch a url then close. - expect(await launcher.launch('http://flutter.dev'), true); + expect( + await launcher.launch('https://flutter.dev', + useSafariVC: true, + useWebView: true, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {'my_header_key': 'my_header_value'}), + true); + // Allow time for page to load. + await Future.delayed(Duration(seconds: 3)); await launcher.closeWebView(); + // Delay required to catch android side crashes in onDestroy + await Future.delayed(Duration(seconds: 3)); // sms:, tel:, and mailto: links may not be openable on every device, so // aren't tested here. From e56adf3d907473cfd0317589178dddbcb4ad6aea Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Mon, 7 Aug 2023 11:51:34 -0400 Subject: [PATCH 5/9] Changelog and version bump added --- packages/url_launcher/url_launcher_android/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher_android/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md index 331e7a61c2e..b534ddcb286 100644 --- a/packages/url_launcher/url_launcher_android/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.38 + +* Updates android implementation to support api 34 broadcast receiver requirements. + ## 6.0.37 * Sets android.defaults.buildfeatures.buildconfig to true for compatibility with AGP 8.0+. diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index 2d7c33efbf0..a80c010cc83 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher_android description: Android implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.0.37 +version: 6.0.38 environment: sdk: ">=2.18.0 <4.0.0" flutter: ">=3.3.0" From 78a37492ccce8caa32af5efc848dd298da60f37d Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Mon, 7 Aug 2023 12:00:37 -0400 Subject: [PATCH 6/9] dart analyze feedback --- .../example/integration_test/url_launcher_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index b09f664e86e..f1290377624 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -35,10 +35,10 @@ void main() { headers: {'my_header_key': 'my_header_value'}), true); // Allow time for page to load. - await Future.delayed(Duration(seconds: 3)); + await Future.delayed(const Duration(seconds: 3)); await launcher.closeWebView(); // Delay required to catch android side crashes in onDestroy - await Future.delayed(Duration(seconds: 3)); + await Future.delayed(const Duration(seconds: 3)); // sms:, tel:, and mailto: links may not be openable on every device, so // aren't tested here. From 1e190caf958ffb3d37abfb469b5924bb49af43cd Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Mon, 7 Aug 2023 13:32:38 -0400 Subject: [PATCH 7/9] java format --- .../java/io/flutter/plugins/urllauncher/WebViewActivity.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 821ca7e40ea..4bfe12986f0 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -145,10 +145,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { // Register receiver that may finish this Activity. ContextCompat.registerReceiver( - this, - broadcastReceiver, - closeIntentFilter, - ContextCompat.RECEIVER_EXPORTED); + this, broadcastReceiver, closeIntentFilter, ContextCompat.RECEIVER_EXPORTED); } @VisibleForTesting From 26853fd78c8869b4d86e19be9c8ca9dc7f494593 Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Wed, 9 Aug 2023 10:46:55 -0400 Subject: [PATCH 8/9] Bump wait time to 5s to more reliabily catch onDestroy crashes when testing on emulators, update documentation with an explination of why the delay --- .../integration_test/url_launcher_test.dart | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index f1290377624..495ba1edc16 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; +import 'dart:io'; + import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; @@ -24,9 +27,23 @@ void main() { testWidgets('launch and close', (WidgetTester _) async { final UrlLauncherPlatform launcher = UrlLauncherPlatform.instance; + // Setup fake http server. + final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); + unawaited(server.forEach((HttpRequest request) { + if (request.uri.path == '/hello.txt') { + request.response.writeln('Hello, world.'); + } else { + fail('unexpected request: ${request.method} ${request.uri}'); + } + request.response.close(); + })); + // Https to avoid cleartext warning on android. + final String prefixUrl = 'https://${server.address.address}:${server.port}'; + final String primaryUrl = '$prefixUrl/hello.txt'; + // Launch a url then close. expect( - await launcher.launch('https://flutter.dev', + await launcher.launch(primaryUrl, useSafariVC: true, useWebView: true, enableJavaScript: false, @@ -34,11 +51,14 @@ void main() { universalLinksOnly: false, headers: {'my_header_key': 'my_header_value'}), true); - // Allow time for page to load. - await Future.delayed(const Duration(seconds: 3)); await launcher.closeWebView(); - // Delay required to catch android side crashes in onDestroy - await Future.delayed(const Duration(seconds: 3)); + // Delay required to catch android side crashes in onDestroy. + // + // If this test flakes with an android crash during this delay the test + // should be considered failing because this integration test can have a + // false positive pass if the test closes before an onDestroy crash. + // See https://github.com/flutter/flutter/issues/126460 for more info. + await Future.delayed(const Duration(seconds: 5)); // sms:, tel:, and mailto: links may not be openable on every device, so // aren't tested here. From 7ec52013c5daa8742cf757cfde4d331ca2a829b8 Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Wed, 9 Aug 2023 10:57:45 -0400 Subject: [PATCH 9/9] remove headers since they are not used remove stray comment --- .../example/integration_test/url_launcher_test.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index 495ba1edc16..7aa221b3e1a 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -49,7 +49,7 @@ void main() { enableJavaScript: false, enableDomStorage: false, universalLinksOnly: false, - headers: {'my_header_key': 'my_header_value'}), + headers: {}), true); await launcher.closeWebView(); // Delay required to catch android side crashes in onDestroy. @@ -59,8 +59,5 @@ void main() { // false positive pass if the test closes before an onDestroy crash. // See https://github.com/flutter/flutter/issues/126460 for more info. await Future.delayed(const Duration(seconds: 5)); - - // sms:, tel:, and mailto: links may not be openable on every device, so - // aren't tested here. }); }