mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

This auto-formats all *.dart files in the repository outside of the `engine` subdirectory and enforces that these files stay formatted with a presubmit check. **Reviewers:** Please carefully review all the commits except for the one titled "formatted". The "formatted" commit was auto-generated by running `dev/tools/format.sh -a -f`. The other commits were hand-crafted to prepare the repo for the formatting change. I recommend reviewing the commits one-by-one via the "Commits" tab and avoiding Github's "Files changed" tab as it will likely slow down your browser because of the size of this PR. --------- Co-authored-by: Kate Lovett <katelovett@google.com> Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
453 lines
12 KiB
Dart
453 lines
12 KiB
Dart
// Copyright 2014 The Flutter 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 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:collection/collection.dart' show ListEquality, MapEquality;
|
|
|
|
import 'package:flutter_devicelab/framework/devices.dart';
|
|
import 'package:meta/meta.dart';
|
|
|
|
import 'common.dart';
|
|
|
|
void main() {
|
|
group('device', () {
|
|
late Device device;
|
|
|
|
setUp(() {
|
|
FakeDevice.resetLog();
|
|
device = FakeDevice(deviceId: 'fakeDeviceId');
|
|
});
|
|
|
|
tearDown(() {});
|
|
|
|
group('cpu check', () {
|
|
test('arm64', () async {
|
|
FakeDevice.pretendArm64();
|
|
final AndroidDevice androidDevice = device as AndroidDevice;
|
|
expect(await androidDevice.isArm64(), isTrue);
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'getprop', arguments: <String>['ro.product.cpu.abi']),
|
|
]);
|
|
});
|
|
});
|
|
|
|
group('isAwake/isAsleep', () {
|
|
test('reads Awake', () async {
|
|
FakeDevice.pretendAwake();
|
|
expect(await device.isAwake(), isTrue);
|
|
expect(await device.isAsleep(), isFalse);
|
|
});
|
|
|
|
test('reads Awake - samsung devices', () async {
|
|
FakeDevice.pretendAwakeSamsung();
|
|
expect(await device.isAwake(), isTrue);
|
|
expect(await device.isAsleep(), isFalse);
|
|
});
|
|
|
|
test('reads Asleep', () async {
|
|
FakeDevice.pretendAsleep();
|
|
expect(await device.isAwake(), isFalse);
|
|
expect(await device.isAsleep(), isTrue);
|
|
});
|
|
});
|
|
|
|
group('togglePower', () {
|
|
test('sends power event', () async {
|
|
await device.togglePower();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'input', arguments: <String>['keyevent', '26']),
|
|
]);
|
|
});
|
|
});
|
|
|
|
group('wakeUp', () {
|
|
test('when awake', () async {
|
|
FakeDevice.pretendAwake();
|
|
await device.wakeUp();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'dumpsys', arguments: <String>['power']),
|
|
]);
|
|
});
|
|
|
|
test('when asleep', () async {
|
|
FakeDevice.pretendAsleep();
|
|
await device.wakeUp();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'dumpsys', arguments: <String>['power']),
|
|
cmd(command: 'input', arguments: <String>['keyevent', '26']),
|
|
]);
|
|
});
|
|
});
|
|
|
|
group('sendToSleep', () {
|
|
test('when asleep', () async {
|
|
FakeDevice.pretendAsleep();
|
|
await device.sendToSleep();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'dumpsys', arguments: <String>['power']),
|
|
]);
|
|
});
|
|
|
|
test('when awake', () async {
|
|
FakeDevice.pretendAwake();
|
|
await device.sendToSleep();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'dumpsys', arguments: <String>['power']),
|
|
cmd(command: 'input', arguments: <String>['keyevent', '26']),
|
|
]);
|
|
});
|
|
});
|
|
|
|
group('unlock', () {
|
|
test('sends unlock event', () async {
|
|
FakeDevice.pretendAwake();
|
|
await device.unlock();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'getprop',
|
|
arguments: <String>[
|
|
'ro.bootimage.build.fingerprint',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.release',
|
|
';',
|
|
'getprop',
|
|
'ro.build.version.sdk',
|
|
],
|
|
),
|
|
cmd(command: 'dumpsys', arguments: <String>['power']),
|
|
cmd(command: 'input', arguments: <String>['keyevent', '82']),
|
|
]);
|
|
});
|
|
});
|
|
|
|
group('adb', () {
|
|
test('tap', () async {
|
|
FakeDevice.resetLog();
|
|
await device.tap(100, 200);
|
|
expectLog(<CommandArgs>[
|
|
cmd(command: 'input', arguments: <String>['tap', '100', '200']),
|
|
]);
|
|
});
|
|
|
|
test('awaitDevice', () async {
|
|
FakeDevice.resetLog();
|
|
// The expected value from `adb shell getprop sys.boot_completed`
|
|
FakeDevice.output = '1';
|
|
await device.awaitDevice();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'adb',
|
|
environment: <String, String>{FakeDevice.canFailKey: 'false'},
|
|
arguments: <String>['-s', device.deviceId, 'wait-for-device'],
|
|
),
|
|
cmd(
|
|
command: 'adb',
|
|
environment: <String, String>{FakeDevice.canFailKey: 'false'},
|
|
arguments: <String>['-s', device.deviceId, 'shell', 'getprop sys.boot_completed'],
|
|
),
|
|
]);
|
|
});
|
|
|
|
test('reboot', () async {
|
|
FakeDevice.resetLog();
|
|
await device.reboot();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'adb',
|
|
environment: <String, String>{FakeDevice.canFailKey: 'false'},
|
|
arguments: <String>['-s', device.deviceId, 'reboot'],
|
|
),
|
|
]);
|
|
});
|
|
|
|
test('clearLog', () async {
|
|
FakeDevice.resetLog();
|
|
await device.clearLogs();
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'adb',
|
|
environment: <String, String>{FakeDevice.canFailKey: 'true'},
|
|
arguments: <String>['-s', device.deviceId, 'logcat', '-c'],
|
|
),
|
|
]);
|
|
});
|
|
|
|
test('startLoggingToSink calls adb', () async {
|
|
FakeDevice.resetLog();
|
|
await device.startLoggingToSink(IOSink(_MemoryIOSink()));
|
|
expectLog(<CommandArgs>[
|
|
cmd(
|
|
command: 'adb',
|
|
environment: <String, String>{FakeDevice.canFailKey: 'true'},
|
|
arguments: <String>['-s', device.deviceId, 'logcat', '--clear'],
|
|
),
|
|
]);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
void expectLog(List<CommandArgs> log) {
|
|
expect(FakeDevice.commandLog, log);
|
|
}
|
|
|
|
CommandArgs cmd({
|
|
required String command,
|
|
List<String>? arguments,
|
|
Map<String, String>? environment,
|
|
}) {
|
|
return CommandArgs(command: command, arguments: arguments, environment: environment);
|
|
}
|
|
|
|
@immutable
|
|
class CommandArgs {
|
|
const CommandArgs({required this.command, this.arguments, this.environment});
|
|
|
|
final String command;
|
|
final List<String>? arguments;
|
|
final Map<String, String>? environment;
|
|
|
|
@override
|
|
String toString() =>
|
|
'CommandArgs(command: $command, arguments: $arguments, environment: $environment)';
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (other.runtimeType != CommandArgs) {
|
|
return false;
|
|
}
|
|
return other is CommandArgs &&
|
|
other.command == command &&
|
|
const ListEquality<String>().equals(other.arguments, arguments) &&
|
|
const MapEquality<String, String>().equals(other.environment, environment);
|
|
}
|
|
|
|
@override
|
|
int get hashCode {
|
|
return Object.hash(
|
|
command,
|
|
Object.hashAll(arguments ?? const <String>[]),
|
|
Object.hashAllUnordered(environment?.keys ?? const <String>[]),
|
|
Object.hashAllUnordered(environment?.values ?? const <String>[]),
|
|
);
|
|
}
|
|
}
|
|
|
|
class FakeDevice extends AndroidDevice {
|
|
FakeDevice({required super.deviceId});
|
|
|
|
static const String canFailKey = 'canFail';
|
|
|
|
static String output = '';
|
|
|
|
static List<CommandArgs> commandLog = <CommandArgs>[];
|
|
|
|
static void resetLog() {
|
|
commandLog.clear();
|
|
}
|
|
|
|
static void pretendAwake() {
|
|
output = '''
|
|
mWakefulness=Awake
|
|
''';
|
|
}
|
|
|
|
static void pretendAwakeSamsung() {
|
|
output = '''
|
|
getWakefulnessLocked()=Awake
|
|
''';
|
|
}
|
|
|
|
static void pretendAsleep() {
|
|
output = '''
|
|
mWakefulness=Asleep
|
|
''';
|
|
}
|
|
|
|
static void pretendArm64() {
|
|
output = '''
|
|
arm64
|
|
''';
|
|
}
|
|
|
|
@override
|
|
Future<String> adb(
|
|
List<String> arguments, {
|
|
Map<String, String>? environment,
|
|
bool silent = false,
|
|
bool canFail = false,
|
|
}) async {
|
|
environment ??= <String, String>{};
|
|
commandLog.add(
|
|
CommandArgs(
|
|
command: 'adb',
|
|
// ignore: prefer_spread_collections
|
|
arguments: <String>['-s', deviceId]..addAll(arguments),
|
|
environment: environment..putIfAbsent('canFail', () => '$canFail'),
|
|
),
|
|
);
|
|
return output;
|
|
}
|
|
|
|
@override
|
|
Future<String> shellEval(
|
|
String command,
|
|
List<String> arguments, {
|
|
Map<String, String>? environment,
|
|
bool silent = false,
|
|
}) async {
|
|
commandLog.add(CommandArgs(command: command, arguments: arguments, environment: environment));
|
|
return output;
|
|
}
|
|
|
|
@override
|
|
Future<void> shellExec(
|
|
String command,
|
|
List<String> arguments, {
|
|
Map<String, String>? environment,
|
|
bool silent = false,
|
|
}) async {
|
|
commandLog.add(CommandArgs(command: command, arguments: arguments, environment: environment));
|
|
}
|
|
}
|
|
|
|
/// An IOSink that collects whatever is written to it.
|
|
/// Inspired by packages/flutter_tools/lib/src/base/net.dart
|
|
class _MemoryIOSink implements IOSink {
|
|
@override
|
|
Encoding encoding = utf8;
|
|
|
|
final BytesBuilder writes = BytesBuilder(copy: false);
|
|
|
|
@override
|
|
void add(List<int> data) {
|
|
writes.add(data);
|
|
}
|
|
|
|
@override
|
|
Future<void> addStream(Stream<List<int>> stream) {
|
|
final Completer<void> completer = Completer<void>();
|
|
stream.listen(add).onDone(completer.complete);
|
|
return completer.future;
|
|
}
|
|
|
|
@override
|
|
void writeCharCode(int charCode) {
|
|
add(<int>[charCode]);
|
|
}
|
|
|
|
@override
|
|
void write(Object? obj) {
|
|
add(encoding.encode('$obj'));
|
|
}
|
|
|
|
@override
|
|
void writeln([Object? obj = '']) {
|
|
add(encoding.encode('$obj\n'));
|
|
}
|
|
|
|
@override
|
|
void writeAll(Iterable<dynamic> objects, [String separator = '']) {
|
|
bool addSeparator = false;
|
|
for (final dynamic object in objects) {
|
|
if (addSeparator) {
|
|
write(separator);
|
|
}
|
|
write(object);
|
|
addSeparator = true;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void addError(dynamic error, [StackTrace? stackTrace]) {
|
|
throw UnimplementedError();
|
|
}
|
|
|
|
@override
|
|
Future<void> get done => close();
|
|
|
|
@override
|
|
Future<void> close() async {}
|
|
|
|
@override
|
|
Future<void> flush() async {}
|
|
}
|