From 608ac110e745f183684f9ba87365604dba5827af Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 15 Feb 2024 12:25:33 -0500 Subject: [PATCH 1/5] [url_launcher] Remove `renderView` usage Removes calls to the deprecated `renderView` method, replacing them with best-effort lookup of the implicit view. This only affects an API that has been deprecated for almost two years, and only when using a specific optional parameter on that method, so the potential impact here is minimal, and this avoids the need for a breaking change. In the future, when we remove this deprecated API, the workaround will go away as well. Fixes https://github.com/flutter/flutter/issues/143449 --- .../url_launcher/lib/src/legacy_api.dart | 49 ++++++++++++------- .../test/src/legacy_api_test.dart | 22 ++++----- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/packages/url_launcher/url_launcher/lib/src/legacy_api.dart b/packages/url_launcher/url_launcher/lib/src/legacy_api.dart index 9f6d2dca001..c682c7feb8e 100644 --- a/packages/url_launcher/url_launcher/lib/src/legacy_api.dart +++ b/packages/url_launcher/url_launcher/lib/src/legacy_api.dart @@ -3,8 +3,10 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:ui'; import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; @@ -85,15 +87,14 @@ Future launch( /// [true] so that ui is automatically computed if [statusBarBrightness] is set. bool previousAutomaticSystemUiAdjustment = true; - if (statusBarBrightness != null && - defaultTargetPlatform == TargetPlatform.iOS && - _ambiguate(WidgetsBinding.instance) != null) { - previousAutomaticSystemUiAdjustment = _ambiguate(WidgetsBinding.instance)! - .renderView - .automaticSystemUiAdjustment; - _ambiguate(WidgetsBinding.instance)! - .renderView - .automaticSystemUiAdjustment = false; + final RenderView? renderViewToAdjust = + statusBarBrightness != null && defaultTargetPlatform == TargetPlatform.iOS + ? _findImplicitRenderView() + : null; + if (renderViewToAdjust != null) { + previousAutomaticSystemUiAdjustment = + renderViewToAdjust.automaticSystemUiAdjustment; + renderViewToAdjust.automaticSystemUiAdjustment = false; SystemChrome.setSystemUIOverlayStyle(statusBarBrightness == Brightness.light ? SystemUiOverlayStyle.dark : SystemUiOverlayStyle.light); @@ -110,11 +111,9 @@ Future launch( webOnlyWindowName: webOnlyWindowName, ); - if (statusBarBrightness != null && - _ambiguate(WidgetsBinding.instance) != null) { - _ambiguate(WidgetsBinding.instance)! - .renderView - .automaticSystemUiAdjustment = previousAutomaticSystemUiAdjustment; + if (renderViewToAdjust != null) { + renderViewToAdjust.automaticSystemUiAdjustment = + previousAutomaticSystemUiAdjustment; } return result; @@ -146,8 +145,22 @@ Future closeWebView() async { return UrlLauncherPlatform.instance.closeWebView(); } -/// This allows a value of type T or T? to be treated as a value of type T?. +/// Returns the [RenderView] associated with the implicit [FlutterView], if any. /// -/// We use this so that APIs that have become non-nullable can still be used -/// with `!` and `?` on the stable branch. -T? _ambiguate(T? value) => value; +/// [launch] predates multi-window support, and it doesn't have enough context +/// to get the right render view, so this assumes anyone still trying to use +/// the deprecated API with `statusBarBrightness` is in a single-view scenario. +/// This allows a best-effort implementation of the deprecated API for as long +/// as it continues to exist, without depending on deprecated Flutter APIs (and +/// therefore keeping url_launcher forward-compatible with future versions of +/// Flutter for longer). +RenderView? _findImplicitRenderView() { + final FlutterView? implicitFlutteView = + WidgetsBinding.instance.platformDispatcher.implicitView; + if (implicitFlutteView == null) { + return null; + } + return WidgetsBinding.instance.renderViews + .where((RenderView v) => v.flutterView == implicitFlutteView) + .firstOrNull; +} diff --git a/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart b/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart index 8a694546397..091f9b7c8fd 100644 --- a/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart +++ b/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart @@ -235,10 +235,11 @@ void main() { ..setResponse(true); final TestWidgetsFlutterBinding binding = - _anonymize(TestWidgetsFlutterBinding.ensureInitialized())! - as TestWidgetsFlutterBinding; + TestWidgetsFlutterBinding.ensureInitialized(); debugDefaultTargetPlatformOverride = TargetPlatform.iOS; - final RenderView renderView = binding.renderView; + final RenderView renderView = + RenderView(view: binding.platformDispatcher.implicitView!); + binding.addRenderView(renderView); renderView.automaticSystemUiAdjustment = true; final Future launchResult = launch('http://flutter.dev/', statusBarBrightness: Brightness.dark); @@ -248,6 +249,7 @@ void main() { expect(renderView.automaticSystemUiAdjustment, isFalse); await launchResult; expect(renderView.automaticSystemUiAdjustment, isTrue); + binding.removeRenderView(renderView); }); test('sets automaticSystemUiAdjustment to not be null', () async { @@ -265,10 +267,11 @@ void main() { ..setResponse(true); final TestWidgetsFlutterBinding binding = - _anonymize(TestWidgetsFlutterBinding.ensureInitialized())! - as TestWidgetsFlutterBinding; + TestWidgetsFlutterBinding.ensureInitialized(); debugDefaultTargetPlatformOverride = TargetPlatform.android; - final RenderView renderView = binding.renderView; + final RenderView renderView = + RenderView(view: binding.platformDispatcher.implicitView!); + binding.addRenderView(renderView); expect(renderView.automaticSystemUiAdjustment, true); final Future launchResult = launch('http://flutter.dev/', statusBarBrightness: Brightness.dark); @@ -278,6 +281,7 @@ void main() { expect(renderView.automaticSystemUiAdjustment, true); await launchResult; expect(renderView.automaticSystemUiAdjustment, true); + binding.removeRenderView(renderView); }); test('open non-parseable url', () async { @@ -317,9 +321,3 @@ void main() { }); }); } - -/// This removes the type information from a value so that it can be cast -/// to another type even if that cast is redundant. -/// We use this so that APIs whose type have become more descriptive can still -/// be used on the stable branch where they require a cast. -Object? _anonymize(T? value) => value; From 2c6997c9c66c9f8b9ca6ba4f74ca073c6b3f73a0 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 15 Feb 2024 12:29:52 -0500 Subject: [PATCH 2/5] Version bump --- analysis_options.yaml | 2 +- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 364fc12db89..bc9e549e47f 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -14,7 +14,7 @@ analyzer: # allow deprecated members (we do this because otherwise we have to annotate # every member in every test, assert, etc, when we or the Dart SDK deprecates # something (https://github.com/flutter/flutter/issues/143312) - deprecated_member_use: ignore + #deprecated_member_use: ignore deprecated_member_use_from_same_package: ignore exclude: # DIFFERENT FROM FLUTTER/FLUTTER # Ignore generated files diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 61a568c9aa1..3659a50c0a6 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.2.5 + +* Removes use of deprecated `renderView` API. + ## 6.2.4 * Updates support matrix in README to indicate that iOS 11 is no longer supported. diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index fe3f2990d08..c7589f48cd0 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.2.4 +version: 6.2.5 environment: sdk: ">=3.1.0 <4.0.0" From 75b7c4e451f9f9273fedf9ceecbcdce9ff5150d5 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 15 Feb 2024 13:03:25 -0500 Subject: [PATCH 3/5] Revert change intended to be local-only --- analysis_options.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index bc9e549e47f..364fc12db89 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -14,7 +14,7 @@ analyzer: # allow deprecated members (we do this because otherwise we have to annotate # every member in every test, assert, etc, when we or the Dart SDK deprecates # something (https://github.com/flutter/flutter/issues/143312) - #deprecated_member_use: ignore + deprecated_member_use: ignore deprecated_member_use_from_same_package: ignore exclude: # DIFFERENT FROM FLUTTER/FLUTTER # Ignore generated files From 7ae176f8b7bb66add0a1bbb5e1a5639218e9e8af Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 15 Feb 2024 13:09:53 -0500 Subject: [PATCH 4/5] Fix typo --- packages/url_launcher/url_launcher/lib/src/legacy_api.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/url_launcher/url_launcher/lib/src/legacy_api.dart b/packages/url_launcher/url_launcher/lib/src/legacy_api.dart index c682c7feb8e..f709a75f758 100644 --- a/packages/url_launcher/url_launcher/lib/src/legacy_api.dart +++ b/packages/url_launcher/url_launcher/lib/src/legacy_api.dart @@ -155,12 +155,12 @@ Future closeWebView() async { /// therefore keeping url_launcher forward-compatible with future versions of /// Flutter for longer). RenderView? _findImplicitRenderView() { - final FlutterView? implicitFlutteView = + final FlutterView? implicitFlutterView = WidgetsBinding.instance.platformDispatcher.implicitView; - if (implicitFlutteView == null) { + if (implicitFlutterView == null) { return null; } return WidgetsBinding.instance.renderViews - .where((RenderView v) => v.flutterView == implicitFlutteView) + .where((RenderView v) => v.flutterView == implicitFlutterView) .firstOrNull; } From 4c325c05a1827d4dfd47671d8c5e314e3409584c Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 21 Feb 2024 12:57:00 -0500 Subject: [PATCH 5/5] Bump Flutter requirement --- packages/url_launcher/url_launcher/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index c7589f48cd0..e59afe4690d 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 6.2.5 environment: - sdk: ">=3.1.0 <4.0.0" - flutter: ">=3.13.0" + sdk: ">=3.2.0 <4.0.0" + flutter: ">=3.16.0" flutter: plugin: