Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
fc1d17d3
Unverified
Commit
fc1d17d3
authored
Dec 13, 2021
by
Dan Field
Committed by
GitHub
Dec 13, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite license code to avoid async* (#95130)
parent
126ee23a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
43 additions
and
50 deletions
+43
-50
licenses.dart
packages/flutter/lib/src/foundation/licenses.dart
+19
-11
binding.dart
packages/flutter/lib/src/services/binding.dart
+24
-39
No files found.
packages/flutter/lib/src/foundation/licenses.dart
View file @
fc1d17d3
...
...
@@ -2,6 +2,8 @@
// 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:meta/meta.dart'
show
visibleForTesting
;
/// Signature for callbacks passed to [LicenseRegistry.addLicense].
...
...
@@ -70,8 +72,8 @@ enum _LicenseEntryWithLineBreaksParserState {
///
/// ```dart
/// void initMyLibrary() {
/// LicenseRegistry.addLicense(()
async* {
///
yield
const LicenseEntryWithLineBreaks(<String>['my_library'], '''
/// LicenseRegistry.addLicense(()
=> Stream<LicenseEntry>.value(
/// const LicenseEntryWithLineBreaks(<String>['my_library'], '''
/// Copyright 2016 The Sample Authors. All rights reserved.
///
/// Redistribution and use in source and binary forms, with or without
...
...
@@ -98,8 +100,9 @@ enum _LicenseEntryWithLineBreaksParserState {
/// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
/// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
/// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''');
/// });
/// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
/// ),
/// ));
/// }
/// ```
/// {@end-tool}
...
...
@@ -309,14 +312,19 @@ class LicenseRegistry {
/// Returns the licenses that have been registered.
///
/// Generating the list of licenses is expensive.
// TODO(dnfield): Refactor the license logic.
// https://github.com/flutter/flutter/issues/95043
// flutter_ignore: no_sync_async_star
static
Stream
<
LicenseEntry
>
get
licenses
async
*
{
static
Stream
<
LicenseEntry
>
get
licenses
{
if
(
_collectors
==
null
)
return
;
for
(
final
LicenseEntryCollector
collector
in
_collectors
!)
yield
*
collector
();
return
const
Stream
<
LicenseEntry
>.
empty
();
late
final
StreamController
<
LicenseEntry
>
controller
;
controller
=
StreamController
<
LicenseEntry
>(
onListen:
()
async
{
for
(
final
LicenseEntryCollector
collector
in
_collectors
!)
await
controller
.
addStream
(
collector
());
await
controller
.
close
();
},
);
return
controller
.
stream
;
}
/// Resets the internal state of [LicenseRegistry]. Intended for use in
...
...
packages/flutter/lib/src/services/binding.dart
View file @
fc1d17d3
...
...
@@ -6,6 +6,7 @@
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:io'
;
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
;
import
'package:flutter/foundation.dart'
;
...
...
@@ -144,45 +145,29 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
LicenseRegistry
.
addLicense
(
_addLicenses
);
}
// TODO(dnfield): Refactor the license logic.
// https://github.com/flutter/flutter/issues/95043
// flutter_ignore: no_sync_async_star
Stream
<
LicenseEntry
>
_addLicenses
()
async
*
{
// Using _something_ here to break
// this into two parts is important because isolates take a while to copy
// data at the moment, and if we receive the data in the same event loop
// iteration as we send the data to the next isolate, we are definitely
// going to miss frames. Another solution would be to have the work all
// happen in one isolate, and we may go there eventually, but first we are
// going to see if isolate communication can be made cheaper.
// See: https://github.com/dart-lang/sdk/issues/31959
// https://github.com/dart-lang/sdk/issues/31960
// TODO(ianh): Remove this complexity once these bugs are fixed.
final
Completer
<
String
>
rawLicenses
=
Completer
<
String
>();
scheduleTask
(()
async
{
rawLicenses
.
complete
(
kIsWeb
// NOTICES for web isn't compressed since we don't have access to
// dart:io on the client side and it's already compressed between
// the server and client.
?
rootBundle
.
loadString
(
'NOTICES'
,
cache:
false
)
:
()
async
{
// The compressed version doesn't have a more common .gz extension
// because gradle for Android non-transparently manipulates .gz files.
final
ByteData
licenseBytes
=
await
rootBundle
.
load
(
'NOTICES.Z'
);
List
<
int
>
bytes
=
licenseBytes
.
buffer
.
asUint8List
();
bytes
=
gzip
.
decode
(
bytes
);
return
utf8
.
decode
(
bytes
);
}(),
);
},
Priority
.
animation
);
await
rawLicenses
.
future
;
final
Completer
<
List
<
LicenseEntry
>>
parsedLicenses
=
Completer
<
List
<
LicenseEntry
>>();
scheduleTask
(()
async
{
parsedLicenses
.
complete
(
compute
<
String
,
List
<
LicenseEntry
>>(
_parseLicenses
,
await
rawLicenses
.
future
,
debugLabel:
'parseLicenses'
));
},
Priority
.
animation
);
await
parsedLicenses
.
future
;
yield
*
Stream
<
LicenseEntry
>.
fromIterable
(
await
parsedLicenses
.
future
);
Stream
<
LicenseEntry
>
_addLicenses
()
{
late
final
StreamController
<
LicenseEntry
>
controller
;
controller
=
StreamController
<
LicenseEntry
>(
onListen:
()
async
{
late
final
String
rawLicenses
;
if
(
kIsWeb
)
{
// NOTICES for web isn't compressed since we don't have access to
// dart:io on the client side and it's already compressed between
// the server and client.
rawLicenses
=
await
rootBundle
.
loadString
(
'NOTICES'
,
cache:
false
);
}
else
{
// The compressed version doesn't have a more common .gz extension
// because gradle for Android non-transparently manipulates .gz files.
final
ByteData
licenseBytes
=
await
rootBundle
.
load
(
'NOTICES.Z'
);
final
List
<
int
>
unzippedBytes
=
await
compute
<
List
<
int
>,
List
<
int
>>(
gzip
.
decode
,
licenseBytes
.
buffer
.
asUint8List
(),
debugLabel:
'decompressLicenses'
);
rawLicenses
=
await
compute
<
List
<
int
>,
String
>(
utf8
.
decode
,
unzippedBytes
,
debugLabel:
'utf8DecodeLicenses'
);
}
final
List
<
LicenseEntry
>
licenses
=
await
compute
<
String
,
List
<
LicenseEntry
>>(
_parseLicenses
,
rawLicenses
,
debugLabel:
'parseLicenses'
);
licenses
.
forEach
(
controller
.
add
);
await
controller
.
close
();
},
);
return
controller
.
stream
;
}
// This is run in another isolate created by _addLicenses above.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment