Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Changes from all 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
178 changes: 78 additions & 100 deletions shell/common/fixtures/shell_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +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' show scheduleMicrotask;
// ignore_for_file: avoid_print

import 'dart:convert' show json, utf8;
import 'dart:isolate';
import 'dart:typed_data';
Expand Down Expand Up @@ -78,14 +79,15 @@ void drawFrames() {
@pragma('vm:entry-point')
void reportTimingsMain() {
PlatformDispatcher.instance.onReportTimings = (List<FrameTiming> timings) {
List<int> timestamps = [];
for (FrameTiming t in timings) {
for (FramePhase phase in FramePhase.values) {
final timestamps = <int>[];
for (final t in timings) {
for (final phase in FramePhase.values) {
timestamps.add(t.timestampInMicroseconds(phase));
}
}
nativeReportTimingsCallback(timestamps);
PlatformDispatcher.instance.onReportTimings = (List<FrameTiming> timings) {};
PlatformDispatcher.instance.onReportTimings =
(List<FrameTiming> timings) {};
};
}

Expand All @@ -100,8 +102,8 @@ void onBeginFrameMain() {
@pragma('vm:entry-point')
void onPointerDataPacketMain() {
PlatformDispatcher.instance.onPointerDataPacket = (PointerDataPacket packet) {
List<int> sequence = <int>[];
for (PointerData data in packet.data) {
final sequence = <int>[];
for (final data in packet.data) {
sequence.add(PointerChange.values.indexOf(data.change));
}
nativeOnPointerDataPacket(sequence);
Expand All @@ -123,7 +125,8 @@ void reportMetrics() {
}

@pragma('vm:external-name', 'ReportMetrics')
external void _reportMetrics(double devicePixelRatio, double width, double height);
external void _reportMetrics(
double devicePixelRatio, double width, double height);

@pragma('vm:entry-point')
void dummyReportTimingsMain() {
Expand All @@ -150,7 +153,7 @@ void thousandCallsToNative() {
}

void secondaryIsolateMain(String message) {
print('Secondary isolate got message: ' + message);
print('Secondary isolate got message: $message');
notifyNative();
}

Expand All @@ -162,21 +165,23 @@ void testCanLaunchSecondaryIsolate() {

@pragma('vm:entry-point')
void testSkiaResourceCacheSendsResponse() {
final PlatformMessageResponseCallback callback = (ByteData? data) {
void callback(ByteData? data) {
if (data == null) {
throw 'Response must not be null.';
throw AssertionError('Response must not be null.');
}
final String response = utf8.decode(data.buffer.asUint8List());
final List<bool> jsonResponse = json.decode(response).cast<bool>();
if (jsonResponse[0] != true) {
throw 'Response was not true';
final jsonResponse = (json.decode(response) as List).cast<bool>();
if (!jsonResponse[0]) {
throw AssertionError('Response was not true');
}
notifyNative();
};
const String jsonRequest = '''{
"method": "Skia.setResourceCacheMaxBytes",
"args": 10000
}''';
}

const String jsonRequest = '''
{
"method": "Skia.setResourceCacheMaxBytes",
"args": 10000
}''';
PlatformDispatcher.instance.sendPlatformMessage(
'flutter/skia',
ByteData.sublistView(utf8.encode(jsonRequest)),
Expand Down Expand Up @@ -211,17 +216,22 @@ void canCreateImageFromDecompressedData() {
void canAccessIsolateLaunchData() {
notifyMessage(
utf8.decode(
PlatformDispatcher.instance.getPersistentIsolateData()!.buffer.asUint8List(),
PlatformDispatcher.instance
.getPersistentIsolateData()!
.buffer
.asUint8List(),
),
);
}

@pragma('vm:entry-point')
void performanceModeImpactsNotifyIdle() {
notifyNativeBool(false);
PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.latency);
PlatformDispatcher.instance
.requestDartPerformanceMode(DartPerformanceMode.latency);
notifyNativeBool(true);
PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.balanced);
PlatformDispatcher.instance
.requestDartPerformanceMode(DartPerformanceMode.balanced);
}

@pragma('vm:entry-point')
Expand Down Expand Up @@ -252,12 +262,12 @@ external bool waitFixture();
// Return local date-time as a string, to an hour resolution. So, "2020-07-23
// 14:03:22" will become "2020-07-23 14".
String localTimeAsString() {
final now = DateTime.now().toLocal();
// This is: "$y-$m-$d $h:$min:$sec.$ms$us";
final timeStr = now.toString();
// Forward only "$y-$m-$d $h" for timestamp comparison. Not using DateTime
// formatting since package:intl is not available.
return timeStr.split(":")[0];
final now = DateTime.now().toLocal();
// This is: "$y-$m-$d $h:$min:$sec.$ms$us";
final timeStr = now.toString();
// Forward only "$y-$m-$d $h" for timestamp comparison. Not using DateTime
// formatting since package:intl is not available.
return timeStr.split(':')[0];
}

@pragma('vm:entry-point')
Expand All @@ -279,7 +289,7 @@ external void notifyCanAccessResource(bool success);
external void notifySetAssetBundlePath();

@pragma('vm:entry-point')
void canAccessResourceFromAssetDir() async {
Future<void> canAccessResourceFromAssetDir() async {
notifySetAssetBundlePath();
window.sendPlatformMessage(
'flutter/assets',
Expand All @@ -298,12 +308,14 @@ external void notifyNativeWhenEngineSpawn(bool success);

@pragma('vm:entry-point')
void canReceiveArgumentsWhenEngineRun(List<String> args) {
notifyNativeWhenEngineRun(args.length == 2 && args[0] == 'foo' && args[1] == 'bar');
notifyNativeWhenEngineRun(
args.length == 2 && args[0] == 'foo' && args[1] == 'bar');
}

@pragma('vm:entry-point')
void canReceiveArgumentsWhenEngineSpawn(List<String> args) {
notifyNativeWhenEngineSpawn(args.length == 2 && args[0] == 'arg1' && args[1] == 'arg2');
notifyNativeWhenEngineSpawn(
args.length == 2 && args[0] == 'arg1' && args[1] == 'arg2');
}

@pragma('vm:entry-point')
Expand All @@ -315,38 +327,16 @@ void onBeginFrameWithNotifyNativeMain() {
}

@pragma('vm:entry-point')
void frameCallback(Object? image, int durationMilliseconds, String decodeError) {
void frameCallback(
Object? image, int durationMilliseconds, String decodeError) {
if (image == null) {
throw Exception('Expeccted image in frame callback to be non-null');
}
}

Picture CreateRedBox(Size size) {
Paint paint = Paint()
..color = Color.fromARGB(255, 255, 0, 0)
..style = PaintingStyle.fill;
PictureRecorder baseRecorder = PictureRecorder();
Canvas canvas = Canvas(baseRecorder);
canvas.drawRect(Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint);
return baseRecorder.endRecording();
}

@pragma('vm:entry-point')
void scene_with_red_box() {
PlatformDispatcher.instance.onBeginFrame = (Duration duration) {
SceneBuilder builder = SceneBuilder();
builder.pushOffset(0.0, 0.0);
builder.addPicture(Offset(0.0, 0.0), CreateRedBox(Size(2.0, 2.0)));
builder.pop();
PlatformDispatcher.instance.views.first.render(builder.build());
};
PlatformDispatcher.instance.scheduleFrame();
}

@pragma('vm:external-name', 'NativeOnBeforeToImageSync')
external void onBeforeToImageSync();


@pragma('vm:entry-point')
Future<void> toImageSync() async {
final PictureRecorder recorder = PictureRecorder();
Expand Down Expand Up @@ -386,13 +376,9 @@ Future<void> toImageSync() async {
}

@pragma('vm:entry-point')
Future<void> included() async {

}

Future<void> excluded() async {
Future<void> included() async {}

}
Future<void> excluded() async {}

class IsolateParam {
const IsolateParam(this.sendPort, this.rawHandle);
Expand All @@ -403,13 +389,13 @@ class IsolateParam {
@pragma('vm:entry-point')
Future<void> runCallback(IsolateParam param) async {
try {
final Future<dynamic> Function() func = PluginUtilities.getCallbackFromHandle(
CallbackHandle.fromRawHandle(param.rawHandle)
)! as Future<dynamic> Function();
final Future<dynamic> Function() func =
PluginUtilities.getCallbackFromHandle(
CallbackHandle.fromRawHandle(param.rawHandle))!
as Future<dynamic> Function();
await func.call();
param.sendPort.send(true);
}
on NoSuchMethodError {
} on NoSuchMethodError {
param.sendPort.send(false);
}
}
Expand All @@ -424,13 +410,10 @@ external void notifyDestroyed();
Future<void> testPluginUtilitiesCallbackHandle() async {
ReceivePort port = ReceivePort();
await Isolate.spawn(
runCallback,
IsolateParam(
port.sendPort,
PluginUtilities.getCallbackHandle(included)!.toRawHandle()
),
onError: port.sendPort
);
runCallback,
IsolateParam(port.sendPort,
PluginUtilities.getCallbackHandle(included)!.toRawHandle()),
onError: port.sendPort);
final dynamic result1 = await port.first;
if (result1 != true) {
print('Expected $result1 to == true');
Expand All @@ -441,13 +424,10 @@ Future<void> testPluginUtilitiesCallbackHandle() async {
if (const bool.fromEnvironment('dart.vm.product')) {
port = ReceivePort();
await Isolate.spawn(
runCallback,
IsolateParam(
port.sendPort,
PluginUtilities.getCallbackHandle(excluded)!.toRawHandle()
),
onError: port.sendPort
);
runCallback,
IsolateParam(port.sendPort,
PluginUtilities.getCallbackHandle(excluded)!.toRawHandle()),
onError: port.sendPort);
final dynamic result2 = await port.first;
if (result2 != false) {
print('Expected $result2 to == false');
Expand All @@ -463,18 +443,19 @@ Future<void> testPluginUtilitiesCallbackHandle() async {
Future<void> testThatAssetLoadingHappensOnWorkerThread() async {
try {
await ImmutableBuffer.fromAsset('DoesNotExist');
} catch (err) { /* Do nothing */ }
} catch (err) {/* Do nothing */}
notifyNative();
}

@pragma('vm:external-name', 'NativeReportViewIdsCallback')
external void nativeReportViewIdsCallback(bool hasImplicitView, List<int> viewIds);
external void nativeReportViewIdsCallback(
bool hasImplicitView, List<int> viewIds);

List<int> getCurrentViewIds() {
final List<int> result = PlatformDispatcher.instance.views
.map((FlutterView view) => view.viewId)
.toList()
..sort();
..sort();
assert(result.toSet().length == result.length,
'Unexpected duplicate view ID found: $result');
return result;
Expand All @@ -498,12 +479,14 @@ bool listEquals<T>(List<T> a, List<T> b) {
@pragma('vm:entry-point')
void testReportViewIds() {
List<int> viewIds = getCurrentViewIds();
nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds);
nativeReportViewIdsCallback(
PlatformDispatcher.instance.implicitView != null, viewIds);
PlatformDispatcher.instance.onMetricsChanged = () {
final List<int> newViewIds = getCurrentViewIds();
if (!listEquals(viewIds, newViewIds)) {
viewIds = newViewIds;
nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds);
nativeReportViewIdsCallback(
PlatformDispatcher.instance.implicitView != null, viewIds);
}
};
}
Expand Down Expand Up @@ -550,9 +533,7 @@ void renderDummyToView(FlutterView view) {
@pragma('vm:entry-point')
void onDrawFrameRenderAllViews() {
PlatformDispatcher.instance.onDrawFrame = () {
for (final FlutterView view in PlatformDispatcher.instance.views) {
renderDummyToView(view);
}
PlatformDispatcher.instance.views.forEach(renderDummyToView);
};
notifyNative();
}
Expand All @@ -567,7 +548,7 @@ void renderViewsInFrameAndOutOfFrame() {
}

@pragma('vm:external-name', 'CaptureRootLayer')
external _captureRootLayer(SceneBuilder sceneBuilder);
external void _captureRootLayer(SceneBuilder sceneBuilder);

@pragma('vm:entry-point')
void renderTwiceForOneView() {
Expand Down Expand Up @@ -637,17 +618,14 @@ void renderWarmUpImplicitView() {
void renderWarmUpView1and2() {
bool beginFrameCalled = false;

PlatformDispatcher.instance.scheduleWarmUpFrame(
beginFrame: () {
expect(beginFrameCalled, false);
beginFrameCalled = true;
},
drawFrame: () {
expect(beginFrameCalled, true);
PlatformDispatcher.instance.scheduleWarmUpFrame(beginFrame: () {
expect(beginFrameCalled, false);
beginFrameCalled = true;
}, drawFrame: () {
expect(beginFrameCalled, true);

for (final int viewId in <int>[1, 2]) {
renderDummyToView(PlatformDispatcher.instance.view(id: viewId)!);
}
for (final int viewId in <int>[1, 2]) {
renderDummyToView(PlatformDispatcher.instance.view(id: viewId)!);
}
);
});
}