flutter/dev/devicelab/lib/tasks/android_lifecycles_test.dart
Anis Alibegić 81d80c587d
Fixed a lot of typos (#141431)
Fair amount of typos spotted and fixed. Some of them are in comments, some of them are in code and some of them are in nondart files.

There is no need for issues since it's a typo fix.

I have doubts about [packages/flutter_tools/lib/src/ios/core_devices.dart](https://github.com/flutter/flutter/compare/master...anisalibegic:flutter:master#diff-fdbc1496b4bbe7e2b445a567fd385677af861c0093774e3d8cc460fdd5b794fa), I have a feeling it might broke some things on the other end, even though it's a typo.
2024-01-12 22:10:25 +00:00

183 lines
5.8 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 'package:path/path.dart' as path;
import '../framework/devices.dart';
import '../framework/framework.dart';
import '../framework/task_result.dart';
import '../framework/utils.dart';
const String _kOrgName = 'com.example.activitydestroy';
final RegExp _lifecycleSentinelRegExp = RegExp(r'==== lifecycle\: (.+) ====');
/// Tests the following Android lifecycles: Activity#onStop(), Activity#onResume(), Activity#onPause(),
/// and Activity#onDestroy() from Dart perspective in debug, profile, and release modes.
TaskFunction androidLifecyclesTest({
Map<String, String>? environment,
}) {
final Directory tempDir = Directory.systemTemp
.createTempSync('flutter_devicelab_activity_destroy.');
return () async {
try {
section('Create app');
await inDirectory(tempDir, () async {
await flutter(
'create',
options: <String>[
'--platforms',
'android',
'--org',
_kOrgName,
'app',
],
environment: environment,
);
});
final File mainDart = File(path.join(
tempDir.absolute.path,
'app',
'lib',
'main.dart',
));
if (!mainDart.existsSync()) {
return TaskResult.failure('${mainDart.path} does not exist');
}
section('Patch lib/main.dart');
await mainDart.writeAsString(r'''
import 'package:flutter/widgets.dart';
class LifecycleObserver extends WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('==== lifecycle: $state ====');
}
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
WidgetsBinding.instance.addObserver(LifecycleObserver());
runApp(Container());
}
''', flush: true);
Future<TaskResult> runTestFor(String mode) async {
final AndroidDevice device = await devices.workingDevice as AndroidDevice;
await device.unlock();
section('Flutter run on device running API level ${device.apiLevel} (mode: $mode)');
late Process run;
await inDirectory(path.join(tempDir.path, 'app'), () async {
run = await startFlutter(
'run',
options: <String>['--$mode'],
);
});
final StreamController<String> lifecycles = StreamController<String>();
final StreamIterator<String> lifecycleItr = StreamIterator<String>(lifecycles.stream);
final StreamSubscription<void> stdout = run.stdout
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter())
.listen((String log) {
final RegExpMatch? match = _lifecycleSentinelRegExp.firstMatch(log);
print('stdout: $log');
if (match == null) {
return;
}
final String lifecycle = match[1]!;
print('stdout: Found app lifecycle: $lifecycle');
lifecycles.add(lifecycle);
});
final StreamSubscription<void> stderr = run.stderr
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter())
.listen((String log) {
print('stderr: $log');
});
Future<void> expectedLifecycle(String expected) async {
section('Wait for lifecycle: $expected (mode: $mode)');
await lifecycleItr.moveNext();
final String got = lifecycleItr.current;
if (expected != got) {
throw TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
}
}
await expectedLifecycle('AppLifecycleState.resumed');
section('Toggling app switch (mode: $mode)');
await device.shellExec('input', <String>['keyevent', 'KEYCODE_APP_SWITCH']);
await expectedLifecycle('AppLifecycleState.inactive');
if (device.apiLevel == 28) { // Device lab currently runs 28.
await expectedLifecycle('AppLifecycleState.paused');
await expectedLifecycle('AppLifecycleState.detached');
}
section('Bring activity to foreground (mode: $mode)');
await device.shellExec('am', <String>['start', '-n', '$_kOrgName.app/.MainActivity']);
await expectedLifecycle('AppLifecycleState.resumed');
section('Launch Settings app (mode: $mode)');
await device.shellExec('am', <String>['start', '-a', 'android.settings.SETTINGS']);
await expectedLifecycle('AppLifecycleState.inactive');
if (device.apiLevel == 28) { // Device lab currently runs 28.
await expectedLifecycle('AppLifecycleState.paused');
await expectedLifecycle('AppLifecycleState.detached');
}
section('Bring activity to foreground (mode: $mode)');
await device.shellExec('am', <String>['start', '-n', '$_kOrgName.app/.MainActivity']);
await expectedLifecycle('AppLifecycleState.resumed');
run.kill();
section('Stop subscriptions (mode: $mode)');
await lifecycleItr.cancel();
await lifecycles.close();
await stdout.cancel();
await stderr.cancel();
return TaskResult.success(null);
}
final TaskResult debugResult = await runTestFor('debug');
if (debugResult.failed) {
return debugResult;
}
final TaskResult profileResult = await runTestFor('profile');
if (profileResult.failed) {
return profileResult;
}
final TaskResult releaseResult = await runTestFor('release');
if (releaseResult.failed) {
return releaseResult;
}
return TaskResult.success(null);
} on TaskResult catch (error) {
return error;
} finally {
rmTree(tempDir);
}
};
}