// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; const MethodChannel _channel = MethodChannel('plugins.flutter.io/url_launcher'); /// Parses the specified URL string and delegates handling of it to the /// underlying platform. /// /// The returned future completes with a [PlatformException] on invalid URLs and /// schemes which cannot be handled, that is when [canLaunch] would complete /// with false. /// /// [forceSafariVC] is only used in iOS. If unset, the launcher opens web URLs /// in the safari VC, anything else is opened using the default handler on the /// platform. If set to true, it opens the URL in the Safari view controller. /// If false, the URL is opened in the default browser of the phone. Set this to /// false if you want to use the cookies/context of the main browser of the app /// (such as SSO flows). /// /// [forceWebView] is an Android only setting. If null or false, the URL is /// always launched with the default browser on device. If set to true, the URL /// is launched in a webview. Unlike iOS, browser context is shared across /// WebViews. /// [enableJavaScript] is an Android only setting. If true, webview enable /// javascript. /// /// Note that if any of the above are set to true but the URL is not a web URL, /// this will throw a [PlatformException]. /// /// [statusBarBrightness] Sets the status bar brightness of the application /// after opening a link on iOS. Does nothing if no value is passed. This does /// not handle reseting the previous status bar style. Future launch( String urlString, { bool forceSafariVC, bool forceWebView, bool enableJavaScript, Brightness statusBarBrightness, }) { assert(urlString != null); final Uri url = Uri.parse(urlString.trimLeft()); final bool isWebURL = url.scheme == 'http' || url.scheme == 'https'; if ((forceSafariVC == true || forceWebView == true) && !isWebURL) { throw PlatformException( code: 'NOT_A_WEB_SCHEME', message: 'To use webview or safariVC, you need to pass' 'in a web URL. This $urlString is not a web URL.'); } bool previousAutomaticSystemUiAdjustment; if (statusBarBrightness != null && defaultTargetPlatform == TargetPlatform.iOS) { previousAutomaticSystemUiAdjustment = WidgetsBinding.instance.renderView.automaticSystemUiAdjustment; WidgetsBinding.instance.renderView.automaticSystemUiAdjustment = false; SystemChrome.setSystemUIOverlayStyle(statusBarBrightness == Brightness.light ? SystemUiOverlayStyle.dark : SystemUiOverlayStyle.light); } return _channel.invokeMethod( 'launch', { 'url': urlString, 'useSafariVC': forceSafariVC ?? isWebURL, 'useWebView': forceWebView ?? false, 'enableJavaScript': enableJavaScript ?? false, }, ).then((void _) { if (statusBarBrightness != null) { WidgetsBinding.instance.renderView.automaticSystemUiAdjustment = previousAutomaticSystemUiAdjustment; } }); } /// Checks whether the specified URL can be handled by some app installed on the /// device. Future canLaunch(String urlString) async { if (urlString == null) { return false; } return await _channel.invokeMethod( 'canLaunch', {'url': urlString}, ); } /// Closes the current WebView, if one was previously opened via a call to [launch]. /// /// If [launch] was never called, then this call will not have any effect. /// /// On Android systems, if [launch] was called without `forceWebView` being set to /// `true`, this call will not do anything either, simply because there is no /// WebView available to be closed. Future closeWebView() async { return await _channel.invokeMethod('closeWebView'); }