Unverified Commit 31cb4482 authored by liyuqian's avatar liyuqian Committed by GitHub

Add --cache-sksl flag to drive and run (#42353)

So we can test SkSL precompile using the command line tools.
See https://github.com/flutter/engine/pull/12412.
parent 3f1f22c2
......@@ -326,8 +326,9 @@ class AndroidDevice extends Device {
}
return true;
} catch (e) {
} catch (e, stacktrace) {
printError('Unexpected failure from adb: $e');
printError('Stacktrace: $stacktrace');
return false;
}
}
......@@ -574,6 +575,8 @@ class AndroidDevice extends Device {
...<String>['--ez', 'trace-systrace', 'true'],
if (debuggingOptions.dumpSkpOnShaderCompilation)
...<String>['--ez', 'dump-skp-on-shader-compilation', 'true'],
if (debuggingOptions.cacheSkSL)
...<String>['--ez', 'cache-sksl', 'true'],
if (debuggingOptions.debuggingEnabled) ...<String>[
if (debuggingOptions.buildInfo.isDebug) ...<String>[
...<String>['--ez', 'enable-checked-mode', 'true'],
......
......@@ -275,6 +275,7 @@ Future<LaunchResult> _startApp(DriveCommand command) async {
startPaused: true,
observatoryPort: command.observatoryPort,
verboseSystemLogs: command.verboseSystemLogs,
cacheSkSL: command.cacheSkSL,
),
platformArgs: platformArgs,
prebuiltApplication: !command.shouldBuild,
......
......@@ -41,6 +41,9 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
negatable: false,
help: 'Include verbose logging from the flutter engine.',
)
..addFlag('cache-sksl',
negatable: false,
help: 'Only cache the shader in SkSL instead of binary or GLSL.',)
..addOption('route',
help: 'Which route to load when running the app.',
)
......@@ -59,6 +62,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
}
bool get traceStartup => argResults['trace-startup'];
bool get cacheSkSL => argResults['cache-sksl'];
String get route => argResults['route'];
}
......@@ -306,6 +310,7 @@ class RunCommand extends RunCommandBase {
traceSkia: argResults['trace-skia'],
traceSystrace: argResults['trace-systrace'],
dumpSkpOnShaderCompilation: argResults['dump-skp-on-shader-compilation'],
cacheSkSL: cacheSkSL,
observatoryPort: observatoryPort,
verboseSystemLogs: argResults['verbose-system-logs'],
initializePlatform: argResults['web-initialize-platform'],
......
......@@ -492,6 +492,7 @@ class DebuggingOptions {
this.traceSkia = false,
this.traceSystrace = false,
this.dumpSkpOnShaderCompilation = false,
this.cacheSkSL = false,
this.useTestFonts = false,
this.verboseSystemLogs = false,
this.observatoryPort,
......@@ -502,7 +503,7 @@ class DebuggingOptions {
this.vmserviceOutFile,
}) : debuggingEnabled = true;
DebuggingOptions.disabled(this.buildInfo, { this.initializePlatform = true, this.port, this.hostname })
DebuggingOptions.disabled(this.buildInfo, { this.initializePlatform = true, this.port, this.hostname, this.cacheSkSL = false, })
: debuggingEnabled = false,
useTestFonts = false,
startPaused = false,
......@@ -529,6 +530,7 @@ class DebuggingOptions {
final bool traceSkia;
final bool traceSystrace;
final bool dumpSkpOnShaderCompilation;
final bool cacheSkSL;
final bool useTestFonts;
final bool verboseSystemLogs;
/// Whether to invoke webOnlyInitializePlatform in Flutter for web.
......
......@@ -324,6 +324,7 @@ class IOSDevice extends Device {
if (debuggingOptions.traceSkia) '--trace-skia',
if (debuggingOptions.dumpSkpOnShaderCompilation) '--dump-skp-on-shader-compilation',
if (debuggingOptions.verboseSystemLogs) '--verbose-logging',
if (debuggingOptions.cacheSkSL) '--cache-sksl',
if (platformArgs['trace-startup'] ?? false) '--trace-startup',
];
......
......@@ -15,6 +15,8 @@ import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:mockito/mockito.dart';
......@@ -24,6 +26,65 @@ import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart';
class MockFile extends Mock implements File {
@override
bool existsSync() {
return true;
}
@override
String get path => '.';
}
class MockAndroidApk extends Mock implements AndroidApk {
@override
String get id => '0';
@override
File get file => MockFile();
}
class MockProcessUtils extends Mock implements ProcessUtils {
@override
Future<RunResult> run(
List<String> cmd, {
bool throwOnError = false,
RunResultChecker whiteListFailures,
String workingDirectory,
bool allowReentrantFlutter = false,
Map<String, String> environment,
Duration timeout,
int timeoutRetries = 0,
}) async {
if (cmd.contains('version')) {
return RunResult(ProcessResult(0, 0, 'Android Debug Bridge version 1.0.41', ''), cmd);
}
if (cmd.contains('android.intent.action.RUN')) {
_runCmd = cmd;
}
return RunResult(ProcessResult(0, 0, '', ''), cmd);
}
@override
Future<int> stream(
List<String> cmd, {
String workingDirectory,
bool allowReentrantFlutter = false,
String prefix = '',
bool trace = false,
RegExp filter,
StringConverter mapFunction,
Map<String, String> environment,
}) async {
return 0;
}
List<String> _runCmd;
List<String> get runCmd => _runCmd;
}
class MockAndroidSdkVersion extends Mock implements AndroidSdkVersion {}
void main() {
group('android_device', () {
testUsingContext('stores the requested id', () {
......@@ -31,6 +92,55 @@ void main() {
final AndroidDevice device = AndroidDevice(deviceId);
expect(device.id, deviceId);
});
group('startApp', () {
final MockAndroidApk mockApk = MockAndroidApk();
final MockProcessManager mockProcessManager = MockProcessManager();
final MockAndroidSdk mockAndroidSdk = MockAndroidSdk();
final MockProcessUtils mockProcessUtils = MockProcessUtils();
testUsingContext(' succeeds with --cache-sksl', () async {
const String deviceId = '1234';
final AndroidDevice device = AndroidDevice(deviceId, modelID: 'TestModel');
final Directory sdkDir = MockAndroidSdk.createSdkDirectory();
Config.instance.setValue('android-sdk', sdkDir.path);
final File adbExe = fs.file(getAdbPath(androidSdk));
when(mockAndroidSdk.licensesAvailable).thenReturn(true);
when(mockAndroidSdk.latestVersion).thenReturn(MockAndroidSdkVersion());
when(mockProcessManager.run(
<String>[adbExe.path, '-s', deviceId, 'shell', 'getprop'],
stdoutEncoding: latin1,
stderrEncoding: latin1,
)).thenAnswer((_) async {
return ProcessResult(0, 0, '[ro.build.version.sdk]: [24]', '');
});
final LaunchResult launchResult = await device.startApp(
mockApk,
prebuiltApplication: true,
debuggingOptions: DebuggingOptions.disabled(
const BuildInfo(BuildMode.release, null),
cacheSkSL: true,
),
platformArgs: <String, dynamic>{},
);
expect(launchResult.started, isTrue);
final int cmdIndex = mockProcessUtils.runCmd.indexOf('cache-sksl');
expect(
mockProcessUtils.runCmd.sublist(cmdIndex - 1, cmdIndex + 2),
equals(<String>['--ez', 'cache-sksl', 'true']),
);
}, overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
FileSystem: () => MemoryFileSystem(),
ProcessManager: () => mockProcessManager,
ProcessUtils: () => mockProcessUtils,
});
});
});
group('getAdbDevices', () {
......
......@@ -392,6 +392,50 @@ void main() {
ProcessManager: () => mockProcessManager,
});
testUsingContext(' succeeds with --cache-sksl', () async {
final IOSDevice device = IOSDevice('123');
device.setLogReader(mockApp, mockLogReader);
final Uri uri = Uri(
scheme: 'http',
host: '127.0.0.1',
port: 1234,
path: 'observatory',
);
when(mockMDnsObservatoryDiscovery.getObservatoryUri(any, any, any))
.thenAnswer((Invocation invocation) => Future<Uri>.value(uri));
List<String> args;
when(mockIosDeploy.runApp(
deviceId: anyNamed('deviceId'),
bundlePath: anyNamed('bundlePath'),
launchArguments: anyNamed('launchArguments'),
)).thenAnswer((Invocation inv) {
args = inv.namedArguments[const Symbol('launchArguments')];
return Future<int>.value(0);
});
final LaunchResult launchResult = await device.startApp(mockApp,
prebuiltApplication: true,
debuggingOptions: DebuggingOptions.enabled(
const BuildInfo(BuildMode.debug, null),
cacheSkSL: true,
),
platformArgs: <String, dynamic>{},
);
expect(launchResult.started, isTrue);
expect(args, contains('--cache-sksl'));
expect(await device.stopApp(mockApp), isFalse);
}, overrides: <Type, Generator>{
Artifacts: () => mockArtifacts,
Cache: () => mockCache,
FileSystem: () => mockFileSystem,
MDnsObservatoryDiscovery: () => mockMDnsObservatoryDiscovery,
Platform: () => macPlatform,
ProcessManager: () => mockProcessManager,
Usage: () => mockUsage,
IOSDeploy: () => mockIosDeploy,
});
void testNonPrebuilt({
@required bool showBuildSettingsFlakes,
}) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment