Skip to content

Commit 5f44e3d

Browse files
[url_launcher] Remove renderView usage (#6137)
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. Also opportunistically removes `_ambiguate` and `_anonymize` as they were only needed for versions of Flutter we no longer support. Fixes flutter/flutter#143449
1 parent e88ca69 commit 5f44e3d

File tree

4 files changed

+48
-33
lines changed

4 files changed

+48
-33
lines changed

packages/url_launcher/url_launcher/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 6.2.5
2+
3+
* Removes use of deprecated `renderView` API.
4+
15
## 6.2.4
26

37
* Updates support matrix in README to indicate that iOS 11 is no longer supported.

packages/url_launcher/url_launcher/lib/src/legacy_api.dart

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// found in the LICENSE file.
44

55
import 'dart:async';
6+
import 'dart:ui';
67

78
import 'package:flutter/foundation.dart';
9+
import 'package:flutter/rendering.dart';
810
import 'package:flutter/services.dart';
911
import 'package:flutter/widgets.dart';
1012
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
@@ -85,15 +87,14 @@ Future<bool> launch(
8587

8688
/// [true] so that ui is automatically computed if [statusBarBrightness] is set.
8789
bool previousAutomaticSystemUiAdjustment = true;
88-
if (statusBarBrightness != null &&
89-
defaultTargetPlatform == TargetPlatform.iOS &&
90-
_ambiguate(WidgetsBinding.instance) != null) {
91-
previousAutomaticSystemUiAdjustment = _ambiguate(WidgetsBinding.instance)!
92-
.renderView
93-
.automaticSystemUiAdjustment;
94-
_ambiguate(WidgetsBinding.instance)!
95-
.renderView
96-
.automaticSystemUiAdjustment = false;
90+
final RenderView? renderViewToAdjust =
91+
statusBarBrightness != null && defaultTargetPlatform == TargetPlatform.iOS
92+
? _findImplicitRenderView()
93+
: null;
94+
if (renderViewToAdjust != null) {
95+
previousAutomaticSystemUiAdjustment =
96+
renderViewToAdjust.automaticSystemUiAdjustment;
97+
renderViewToAdjust.automaticSystemUiAdjustment = false;
9798
SystemChrome.setSystemUIOverlayStyle(statusBarBrightness == Brightness.light
9899
? SystemUiOverlayStyle.dark
99100
: SystemUiOverlayStyle.light);
@@ -110,11 +111,9 @@ Future<bool> launch(
110111
webOnlyWindowName: webOnlyWindowName,
111112
);
112113

113-
if (statusBarBrightness != null &&
114-
_ambiguate(WidgetsBinding.instance) != null) {
115-
_ambiguate(WidgetsBinding.instance)!
116-
.renderView
117-
.automaticSystemUiAdjustment = previousAutomaticSystemUiAdjustment;
114+
if (renderViewToAdjust != null) {
115+
renderViewToAdjust.automaticSystemUiAdjustment =
116+
previousAutomaticSystemUiAdjustment;
118117
}
119118

120119
return result;
@@ -146,8 +145,22 @@ Future<void> closeWebView() async {
146145
return UrlLauncherPlatform.instance.closeWebView();
147146
}
148147

149-
/// This allows a value of type T or T? to be treated as a value of type T?.
148+
/// Returns the [RenderView] associated with the implicit [FlutterView], if any.
150149
///
151-
/// We use this so that APIs that have become non-nullable can still be used
152-
/// with `!` and `?` on the stable branch.
153-
T? _ambiguate<T>(T? value) => value;
150+
/// [launch] predates multi-window support, and it doesn't have enough context
151+
/// to get the right render view, so this assumes anyone still trying to use
152+
/// the deprecated API with `statusBarBrightness` is in a single-view scenario.
153+
/// This allows a best-effort implementation of the deprecated API for as long
154+
/// as it continues to exist, without depending on deprecated Flutter APIs (and
155+
/// therefore keeping url_launcher forward-compatible with future versions of
156+
/// Flutter for longer).
157+
RenderView? _findImplicitRenderView() {
158+
final FlutterView? implicitFlutterView =
159+
WidgetsBinding.instance.platformDispatcher.implicitView;
160+
if (implicitFlutterView == null) {
161+
return null;
162+
}
163+
return WidgetsBinding.instance.renderViews
164+
.where((RenderView v) => v.flutterView == implicitFlutterView)
165+
.firstOrNull;
166+
}

packages/url_launcher/url_launcher/pubspec.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ description: Flutter plugin for launching a URL. Supports
33
web, phone, SMS, and email schemes.
44
repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher
55
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
6-
version: 6.2.4
6+
version: 6.2.5
77

88
environment:
9-
sdk: ">=3.1.0 <4.0.0"
10-
flutter: ">=3.13.0"
9+
sdk: ">=3.2.0 <4.0.0"
10+
flutter: ">=3.16.0"
1111

1212
flutter:
1313
plugin:

packages/url_launcher/url_launcher/test/src/legacy_api_test.dart

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,11 @@ void main() {
235235
..setResponse(true);
236236

237237
final TestWidgetsFlutterBinding binding =
238-
_anonymize(TestWidgetsFlutterBinding.ensureInitialized())!
239-
as TestWidgetsFlutterBinding;
238+
TestWidgetsFlutterBinding.ensureInitialized();
240239
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
241-
final RenderView renderView = binding.renderView;
240+
final RenderView renderView =
241+
RenderView(view: binding.platformDispatcher.implicitView!);
242+
binding.addRenderView(renderView);
242243
renderView.automaticSystemUiAdjustment = true;
243244
final Future<bool> launchResult =
244245
launch('http://flutter.dev/', statusBarBrightness: Brightness.dark);
@@ -248,6 +249,7 @@ void main() {
248249
expect(renderView.automaticSystemUiAdjustment, isFalse);
249250
await launchResult;
250251
expect(renderView.automaticSystemUiAdjustment, isTrue);
252+
binding.removeRenderView(renderView);
251253
});
252254

253255
test('sets automaticSystemUiAdjustment to not be null', () async {
@@ -265,10 +267,11 @@ void main() {
265267
..setResponse(true);
266268

267269
final TestWidgetsFlutterBinding binding =
268-
_anonymize(TestWidgetsFlutterBinding.ensureInitialized())!
269-
as TestWidgetsFlutterBinding;
270+
TestWidgetsFlutterBinding.ensureInitialized();
270271
debugDefaultTargetPlatformOverride = TargetPlatform.android;
271-
final RenderView renderView = binding.renderView;
272+
final RenderView renderView =
273+
RenderView(view: binding.platformDispatcher.implicitView!);
274+
binding.addRenderView(renderView);
272275
expect(renderView.automaticSystemUiAdjustment, true);
273276
final Future<bool> launchResult =
274277
launch('http://flutter.dev/', statusBarBrightness: Brightness.dark);
@@ -278,6 +281,7 @@ void main() {
278281
expect(renderView.automaticSystemUiAdjustment, true);
279282
await launchResult;
280283
expect(renderView.automaticSystemUiAdjustment, true);
284+
binding.removeRenderView(renderView);
281285
});
282286

283287
test('open non-parseable url', () async {
@@ -317,9 +321,3 @@ void main() {
317321
});
318322
});
319323
}
320-
321-
/// This removes the type information from a value so that it can be cast
322-
/// to another type even if that cast is redundant.
323-
/// We use this so that APIs whose type have become more descriptive can still
324-
/// be used on the stable branch where they require a cast.
325-
Object? _anonymize<T>(T? value) => value;

0 commit comments

Comments
 (0)