Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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? implicitFlutteView =
WidgetsBinding.instance.platformDispatcher.implicitView;
if (implicitFlutteView == null) {
return null;
}
return WidgetsBinding.instance.renderViews
.where((RenderView v) => v.flutterView == implicitFlutteView)
.firstOrNull;
}
2 changes: 1 addition & 1 deletion packages/url_launcher/url_launcher/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
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;