Skip to content

Commit 65e7bdb

Browse files
[url_launcher_linux] Add Linux url_launcher plugin (flutter#2857)
Adds url_launcher_linux, the federated implementation of url_launcher. Not yet endorsed by url_launcher Part of flutter/flutter#41721
1 parent a5db6e0 commit 65e7bdb

29 files changed

+953
-0
lines changed

.ci/Dockerfile-LinuxDesktop

+8
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,11 @@ RUN sudo apt-get install -y xvfb libegl1-mesa
2121
RUN sudo apt-get install -y clang cmake ninja-build file pkg-config
2222
# Install necessary libraries.
2323
RUN sudo apt-get install -y libgtk-3-dev
24+
25+
# Add repo for Google Chrome and install it, for url_launcher tests.
26+
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
27+
RUN echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list
28+
RUN sudo apt-get update && sudo apt-get install -y --no-install-recommends google-chrome-stable
29+
# Make it the default so http: has a handler.
30+
RUN sudo apt-get install -y xdg-utils
31+
RUN xdg-settings set default-web-browser google-chrome.desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.packages
2+
.flutter-plugins
3+
pubspec.lock
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: 4b12050112afd581ddf53df848275fa681f908f3
8+
channel: master
9+
10+
project_type: plugin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# 0.0.1
2+
* The initial implementation of url_launcher for Linux
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2020 The Chromium Authors. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are
5+
// met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above
10+
// copyright notice, this list of conditions and the following disclaimer
11+
// in the documentation and/or other materials provided with the
12+
// distribution.
13+
// * Neither the name of Google Inc. nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# url_launcher_linux
2+
3+
The Linux implementation of [`url_launcher`][1].
4+
5+
## Usage
6+
7+
### Import the package
8+
9+
This package is an unendorsed Linux implementation of `url_launcher`.
10+
11+
In order to use this now, you'll need to depend on `url_launcher_linux`.
12+
When this package is endorsed it will be automatically used by the `url_launcher` package and you can switch to that API.
13+
14+
```yaml
15+
...
16+
dependencies:
17+
...
18+
url_launcher_linux: ^0.0.1
19+
...
20+
```
21+
22+
[1]: ../
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
12+
# IntelliJ related
13+
*.iml
14+
*.ipr
15+
*.iws
16+
.idea/
17+
18+
# The .vscode folder contains launch configuration and tasks you configure in
19+
# VS Code which you may wish to be included in version control, so this line
20+
# is commented out by default.
21+
#.vscode/
22+
23+
# Flutter/Dart/Pub related
24+
**/doc/api/
25+
**/ios/Flutter/.last_build_id
26+
.dart_tool/
27+
.flutter-plugins
28+
.flutter-plugins-dependencies
29+
.packages
30+
.pub-cache/
31+
.pub/
32+
/build/
33+
34+
# Web related
35+
lib/generated_plugin_registrant.dart
36+
37+
# Symbolication related
38+
app.*.symbols
39+
40+
# Obfuscation related
41+
app.*.map.json
42+
43+
# Exceptions to above rules.
44+
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: 4b12050112afd581ddf53df848275fa681f908f3
8+
channel: master
9+
10+
project_type: app
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# url_launcher_example
2+
3+
Demonstrates how to use the url_launcher plugin.
4+
5+
## Getting Started
6+
7+
For help getting started with Flutter, view our online
8+
[documentation](http://flutter.io/).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs
6+
7+
import 'dart:async';
8+
import 'package:flutter/material.dart';
9+
import 'package:url_launcher/url_launcher.dart';
10+
11+
void main() {
12+
runApp(MyApp());
13+
}
14+
15+
class MyApp extends StatelessWidget {
16+
@override
17+
Widget build(BuildContext context) {
18+
return MaterialApp(
19+
title: 'URL Launcher',
20+
theme: ThemeData(
21+
primarySwatch: Colors.blue,
22+
),
23+
home: MyHomePage(title: 'URL Launcher'),
24+
);
25+
}
26+
}
27+
28+
class MyHomePage extends StatefulWidget {
29+
MyHomePage({Key key, this.title}) : super(key: key);
30+
final String title;
31+
32+
@override
33+
_MyHomePageState createState() => _MyHomePageState();
34+
}
35+
36+
class _MyHomePageState extends State<MyHomePage> {
37+
Future<void> _launched;
38+
String _phone = '';
39+
40+
Future<void> _launchInBrowser(String url) async {
41+
if (await canLaunch(url)) {
42+
await launch(
43+
url,
44+
forceSafariVC: false,
45+
forceWebView: false,
46+
headers: <String, String>{'my_header_key': 'my_header_value'},
47+
);
48+
} else {
49+
throw 'Could not launch $url';
50+
}
51+
}
52+
53+
Future<void> _launchInWebViewOrVC(String url) async {
54+
if (await canLaunch(url)) {
55+
await launch(
56+
url,
57+
forceSafariVC: true,
58+
forceWebView: true,
59+
headers: <String, String>{'my_header_key': 'my_header_value'},
60+
);
61+
} else {
62+
throw 'Could not launch $url';
63+
}
64+
}
65+
66+
Future<void> _launchInWebViewWithJavaScript(String url) async {
67+
if (await canLaunch(url)) {
68+
await launch(
69+
url,
70+
forceSafariVC: true,
71+
forceWebView: true,
72+
enableJavaScript: true,
73+
);
74+
} else {
75+
throw 'Could not launch $url';
76+
}
77+
}
78+
79+
Future<void> _launchInWebViewWithDomStorage(String url) async {
80+
if (await canLaunch(url)) {
81+
await launch(
82+
url,
83+
forceSafariVC: true,
84+
forceWebView: true,
85+
enableDomStorage: true,
86+
);
87+
} else {
88+
throw 'Could not launch $url';
89+
}
90+
}
91+
92+
Future<void> _launchUniversalLinkIos(String url) async {
93+
if (await canLaunch(url)) {
94+
final bool nativeAppLaunchSucceeded = await launch(
95+
url,
96+
forceSafariVC: false,
97+
universalLinksOnly: true,
98+
);
99+
if (!nativeAppLaunchSucceeded) {
100+
await launch(
101+
url,
102+
forceSafariVC: true,
103+
);
104+
}
105+
}
106+
}
107+
108+
Widget _launchStatus(BuildContext context, AsyncSnapshot<void> snapshot) {
109+
if (snapshot.hasError) {
110+
return Text('Error: ${snapshot.error}');
111+
} else {
112+
return const Text('');
113+
}
114+
}
115+
116+
Future<void> _makePhoneCall(String url) async {
117+
if (await canLaunch(url)) {
118+
await launch(url);
119+
} else {
120+
throw 'Could not launch $url';
121+
}
122+
}
123+
124+
@override
125+
Widget build(BuildContext context) {
126+
const String toLaunch = 'https://www.cylog.org/headers/';
127+
return Scaffold(
128+
appBar: AppBar(
129+
title: Text(widget.title),
130+
),
131+
body: ListView(
132+
children: <Widget>[
133+
Column(
134+
mainAxisAlignment: MainAxisAlignment.center,
135+
children: <Widget>[
136+
Padding(
137+
padding: const EdgeInsets.all(16.0),
138+
child: TextField(
139+
onChanged: (String text) => _phone = text,
140+
decoration: const InputDecoration(
141+
hintText: 'Input the phone number to launch')),
142+
),
143+
RaisedButton(
144+
onPressed: () => setState(() {
145+
_launched = _makePhoneCall('tel:$_phone');
146+
}),
147+
child: const Text('Make phone call'),
148+
),
149+
const Padding(
150+
padding: EdgeInsets.all(16.0),
151+
child: Text(toLaunch),
152+
),
153+
RaisedButton(
154+
onPressed: () => setState(() {
155+
_launched = _launchInBrowser(toLaunch);
156+
}),
157+
child: const Text('Launch in browser'),
158+
),
159+
const Padding(padding: EdgeInsets.all(16.0)),
160+
RaisedButton(
161+
onPressed: () => setState(() {
162+
_launched = _launchInWebViewOrVC(toLaunch);
163+
}),
164+
child: const Text('Launch in app'),
165+
),
166+
RaisedButton(
167+
onPressed: () => setState(() {
168+
_launched = _launchInWebViewWithJavaScript(toLaunch);
169+
}),
170+
child: const Text('Launch in app(JavaScript ON)'),
171+
),
172+
RaisedButton(
173+
onPressed: () => setState(() {
174+
_launched = _launchInWebViewWithDomStorage(toLaunch);
175+
}),
176+
child: const Text('Launch in app(DOM storage ON)'),
177+
),
178+
const Padding(padding: EdgeInsets.all(16.0)),
179+
RaisedButton(
180+
onPressed: () => setState(() {
181+
_launched = _launchUniversalLinkIos(toLaunch);
182+
}),
183+
child: const Text(
184+
'Launch a universal link in a native app, fallback to Safari.(Youtube)'),
185+
),
186+
const Padding(padding: EdgeInsets.all(16.0)),
187+
FutureBuilder<void>(future: _launched, builder: _launchStatus),
188+
],
189+
),
190+
],
191+
),
192+
);
193+
}
194+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
flutter/ephemeral

0 commit comments

Comments
 (0)