Unverified Commit f320d140 authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Fix lifecycle for API level 28 (#99433)

parent 9bd88165
...@@ -446,6 +446,7 @@ class AndroidDevice extends Device { ...@@ -446,6 +446,7 @@ class AndroidDevice extends Device {
@override @override
final String deviceId; final String deviceId;
String deviceInfo = ''; String deviceInfo = '';
int apiLevel = 0;
/// Whether the device is awake. /// Whether the device is awake.
@override @override
...@@ -539,8 +540,10 @@ class AndroidDevice extends Device { ...@@ -539,8 +540,10 @@ class AndroidDevice extends Device {
} }
final List<String> list = info.split('\n'); final List<String> list = info.split('\n');
if (list.length == 3) { if (list.length == 3) {
deviceInfo = 'fingerprint: ${list[0]} os: ${list[1]} api-level: ${list[2]}'; apiLevel = int.parse(list[2]);
deviceInfo = 'fingerprint: ${list[0]} os: ${list[1]} api-level: $apiLevel';
} else { } else {
apiLevel = 0;
deviceInfo = ''; deviceInfo = '';
} }
} }
......
...@@ -17,8 +17,8 @@ const String _kOrgName = 'com.example.activitydestroy'; ...@@ -17,8 +17,8 @@ const String _kOrgName = 'com.example.activitydestroy';
final RegExp _lifecycleSentinelRegExp = RegExp(r'==== lifecycle\: (.+) ===='); final RegExp _lifecycleSentinelRegExp = RegExp(r'==== lifecycle\: (.+) ====');
/// Tests the following Android lifecycles: Activity#onStop(), Activity#onResume(), Activity#onPause() /// Tests the following Android lifecycles: Activity#onStop(), Activity#onResume(), Activity#onPause(),
/// from Dart perspective in debug, profile, and release modes. /// and Activity#onDestroy() from Dart perspective in debug, profile, and release modes.
TaskFunction androidLifecyclesTest({ TaskFunction androidLifecyclesTest({
Map<String, String>? environment, Map<String, String>? environment,
}) { }) {
...@@ -69,10 +69,11 @@ void main() { ...@@ -69,10 +69,11 @@ void main() {
} }
''', flush: true); ''', flush: true);
final List<String> androidLifecycles = <String>[];
Future<TaskResult> runTestFor(String mode) async { Future<TaskResult> runTestFor(String mode) async {
section('Flutter run (mode: $mode)'); 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; late Process run;
await inDirectory(path.join(tempDir.path, 'app'), () async { await inDirectory(path.join(tempDir.path, 'app'), () async {
...@@ -82,10 +83,8 @@ void main() { ...@@ -82,10 +83,8 @@ void main() {
); );
}); });
final AndroidDevice device = await devices.workingDevice as AndroidDevice;
await device.unlock();
final StreamController<String> lifecyles = StreamController<String>(); final StreamController<String> lifecyles = StreamController<String>();
final StreamIterator<String> lifecycleItr = StreamIterator<String>(lifecyles.stream);
final StreamSubscription<void> stdout = run.stdout final StreamSubscription<void> stdout = run.stdout
.transform<String>(utf8.decoder) .transform<String>(utf8.decoder)
...@@ -97,8 +96,6 @@ void main() { ...@@ -97,8 +96,6 @@ void main() {
return; return;
} }
final String lifecycle = match[1]!; final String lifecycle = match[1]!;
androidLifecycles.add(lifecycle);
print('stdout: Found app lifecycle: $lifecycle'); print('stdout: Found app lifecycle: $lifecycle');
lifecyles.add(lifecycle); lifecyles.add(lifecycle);
}); });
...@@ -110,73 +107,44 @@ void main() { ...@@ -110,73 +107,44 @@ void main() {
print('stderr: $log'); print('stderr: $log');
}); });
final StreamIterator<String> lifecycleItr = StreamIterator<String>(lifecyles.stream); Future<void> expectedLifecycle(String expected) async {
section('Wait for lifecycle: $expected (mode: $mode)');
{
const String expected = 'AppLifecycleState.resumed';
await lifecycleItr.moveNext(); await lifecycleItr.moveNext();
final String got = lifecycleItr.current; final String got = lifecycleItr.current;
if (expected != got) { if (expected != got) {
return TaskResult.failure('expected lifecycles: `$expected`, but got` $got`'); throw TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
} }
} }
await expectedLifecycle('AppLifecycleState.resumed');
section('Toggling app switch (mode: $mode)'); section('Toggling app switch (mode: $mode)');
await device.shellExec('input', <String>['keyevent', 'KEYCODE_APP_SWITCH']); await device.shellExec('input', <String>['keyevent', 'KEYCODE_APP_SWITCH']);
{ await expectedLifecycle('AppLifecycleState.inactive');
const String expected = 'AppLifecycleState.inactive'; if (device.apiLevel == 28) { // Device lab currently runs 28.
await lifecycleItr.moveNext(); await expectedLifecycle('AppLifecycleState.paused');
final String got = lifecycleItr.current; await expectedLifecycle('AppLifecycleState.detached');
if (expected != got) {
return TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
}
} }
section('Bring activity to foreground (mode: $mode)'); section('Bring activity to foreground (mode: $mode)');
await device.shellExec('am', <String>['start', '--activity-single-top', '$_kOrgName.app/.MainActivity']); await device.shellExec('am', <String>['start', '-n', '$_kOrgName.app/.MainActivity']);
{ await expectedLifecycle('AppLifecycleState.resumed');
const String expected = 'AppLifecycleState.resumed';
await lifecycleItr.moveNext();
final String got = lifecycleItr.current;
if (expected != got) {
return TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
}
}
section('Launch Settings app (mode: $mode)'); section('Launch Settings app (mode: $mode)');
await device.shellExec('am', <String>['start', '-a', 'android.settings.SETTINGS']); await device.shellExec('am', <String>['start', '-a', 'android.settings.SETTINGS']);
{ await expectedLifecycle('AppLifecycleState.inactive');
const String expected = 'AppLifecycleState.inactive'; if (device.apiLevel == 28) { // Device lab currently runs 28.
await lifecycleItr.moveNext(); await expectedLifecycle('AppLifecycleState.paused');
final String got = lifecycleItr.current; await expectedLifecycle('AppLifecycleState.detached');
if (expected != got) {
return TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
}
}
{
const String expected = 'AppLifecycleState.paused';
await lifecycleItr.moveNext();
final String got = lifecycleItr.current;
if (expected != got) {
return TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
}
} }
section('Bring activity to foreground (mode: $mode)'); section('Bring activity to foreground (mode: $mode)');
await device.shellExec('am', <String>['start', '--activity-single-top', '$_kOrgName.app/.MainActivity']); await device.shellExec('am', <String>['start', '-n', '$_kOrgName.app/.MainActivity']);
{ await expectedLifecycle('AppLifecycleState.resumed');
const String expected = 'AppLifecycleState.resumed';
await lifecycleItr.moveNext();
final String got = lifecycleItr.current;
if (expected != got) {
return TaskResult.failure('expected lifecycles: `$expected`, but got` $got`');
}
}
run.kill(); run.kill();
...@@ -205,6 +173,8 @@ void main() { ...@@ -205,6 +173,8 @@ void main() {
} }
return TaskResult.success(null); return TaskResult.success(null);
} on TaskResult catch (error) {
return error;
} finally { } finally {
rmTree(tempDir); rmTree(tempDir);
} }
......
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