Rewrite license code to avoid async* (#95130)
This commit is contained in:
parent
126ee23a5a
commit
fc1d17d35c
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user