Skip to content

[url_launcher] Remove renderView usage #6137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/url_launcher/url_launcher/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
49 changes: 31 additions & 18 deletions packages/url_launcher/url_launcher/lib/src/legacy_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -85,15 +87,14 @@ Future<bool> 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);
Expand All @@ -110,11 +111,9 @@ Future<bool> launch(
webOnlyWindowName: webOnlyWindowName,
);

if (statusBarBrightness != null &&
_ambiguate(WidgetsBinding.instance) != null) {
_ambiguate(WidgetsBinding.instance)!
.renderView
.automaticSystemUiAdjustment = previousAutomaticSystemUiAdjustment;
if (renderViewToAdjust != null) {
renderViewToAdjust.automaticSystemUiAdjustment =
previousAutomaticSystemUiAdjustment;
}

return result;
Expand Down Expand Up @@ -146,8 +145,22 @@ Future<void> 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>(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? implicitFlutterView =
WidgetsBinding.instance.platformDispatcher.implicitView;
if (implicitFlutterView == null) {
return null;
}
return WidgetsBinding.instance.renderViews
.where((RenderView v) => v.flutterView == implicitFlutterView)
.firstOrNull;
}
6 changes: 3 additions & 3 deletions packages/url_launcher/url_launcher/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ 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"
flutter: ">=3.13.0"
sdk: ">=3.2.0 <4.0.0"
flutter: ">=3.16.0"

flutter:
plugin:
Expand Down
22 changes: 10 additions & 12 deletions packages/url_launcher/url_launcher/test/src/legacy_api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool> launchResult =
launch('http://flutter.dev/', statusBarBrightness: Brightness.dark);
Expand All @@ -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 {
Expand All @@ -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<bool> launchResult =
launch('http://flutter.dev/', statusBarBrightness: Brightness.dark);
Expand All @@ -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 {
Expand Down Expand Up @@ -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>(T? value) => value;