Unverified Commit 8e2da841 authored by maRci002's avatar maRci002 Committed by GitHub

Handle transitions to AppLifecycleState.detached in lifecycle state generation (#142523)

Generates the correct lifecycle state transitions in ServicesBinding when detaching.
parent 8431cae8
...@@ -289,12 +289,6 @@ mixin ServicesBinding on BindingBase, SchedulerBinding { ...@@ -289,12 +289,6 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
if (previousState == state) { if (previousState == state) {
return const <AppLifecycleState>[]; return const <AppLifecycleState>[];
} }
if (previousState == AppLifecycleState.paused && state == AppLifecycleState.detached) {
// Handle the wrap-around from paused to detached
return const <AppLifecycleState>[
AppLifecycleState.detached,
];
}
final List<AppLifecycleState> stateChanges = <AppLifecycleState>[]; final List<AppLifecycleState> stateChanges = <AppLifecycleState>[];
if (previousState == null) { if (previousState == null) {
// If there was no previous state, just jump directly to the new state. // If there was no previous state, just jump directly to the new state.
...@@ -304,7 +298,12 @@ mixin ServicesBinding on BindingBase, SchedulerBinding { ...@@ -304,7 +298,12 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
final int stateIndex = AppLifecycleState.values.indexOf(state); final int stateIndex = AppLifecycleState.values.indexOf(state);
assert(previousStateIndex != -1, 'State $previousState missing in stateOrder array'); assert(previousStateIndex != -1, 'State $previousState missing in stateOrder array');
assert(stateIndex != -1, 'State $state missing in stateOrder array'); assert(stateIndex != -1, 'State $state missing in stateOrder array');
if (previousStateIndex > stateIndex) { if (state == AppLifecycleState.detached) {
for (int i = previousStateIndex + 1; i < AppLifecycleState.values.length; ++i) {
stateChanges.add(AppLifecycleState.values[i]);
}
stateChanges.add(AppLifecycleState.detached);
} else if (previousStateIndex > stateIndex) {
for (int i = stateIndex; i < previousStateIndex; ++i) { for (int i = stateIndex; i < previousStateIndex; ++i) {
stateChanges.insert(0, AppLifecycleState.values[i]); stateChanges.insert(0, AppLifecycleState.values[i]);
} }
......
...@@ -129,10 +129,11 @@ void main() { ...@@ -129,10 +129,11 @@ void main() {
await setAppLifeCycleState(AppLifecycleState.resumed); await setAppLifeCycleState(AppLifecycleState.resumed);
expect(transitions, equals(<String>['restart', 'show', 'resume'])); expect(transitions, equals(<String>['restart', 'show', 'resume']));
// Generates intermediate states. // Generates intermediate states from lower to higher lifecycle states.
transitions.clear(); transitions.clear();
await setAppLifeCycleState(AppLifecycleState.paused); await setAppLifeCycleState(AppLifecycleState.paused);
expect(transitions, equals(<String>['inactive', 'hide', 'pause'])); expect(transitions, equals(<String>['inactive', 'hide', 'pause']));
// Wraps around from pause to detach. // Wraps around from pause to detach.
await setAppLifeCycleState(AppLifecycleState.detached); await setAppLifeCycleState(AppLifecycleState.detached);
expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach'])); expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach']));
...@@ -140,14 +141,16 @@ void main() { ...@@ -140,14 +141,16 @@ void main() {
expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach', 'resume'])); expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach', 'resume']));
await setAppLifeCycleState(AppLifecycleState.paused); await setAppLifeCycleState(AppLifecycleState.paused);
expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach', 'resume', 'inactive', 'hide', 'pause'])); expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach', 'resume', 'inactive', 'hide', 'pause']));
// Generates intermediate states from higher to lower lifecycle states.
transitions.clear(); transitions.clear();
await setAppLifeCycleState(AppLifecycleState.resumed); await setAppLifeCycleState(AppLifecycleState.resumed);
expect(transitions, equals(<String>['restart', 'show', 'resume'])); expect(transitions, equals(<String>['restart', 'show', 'resume']));
// Asserts on bad transitions // Go to detached
await expectLater(() => setAppLifeCycleState(AppLifecycleState.detached), throwsAssertionError); transitions.clear();
await setAppLifeCycleState(AppLifecycleState.paused);
await setAppLifeCycleState(AppLifecycleState.detached); await setAppLifeCycleState(AppLifecycleState.detached);
expect(transitions, equals(<String>['inactive', 'hide', 'pause', 'detach']));
}); });
testWidgets('Receives exit requests', (WidgetTester tester) async { testWidgets('Receives exit requests', (WidgetTester tester) async {
......
...@@ -224,7 +224,13 @@ void main() { ...@@ -224,7 +224,13 @@ void main() {
]); ]);
observer.accumulatedStates.clear(); observer.accumulatedStates.clear();
await expectLater(() async => setAppLifeCycleState(AppLifecycleState.detached), throwsAssertionError); await setAppLifeCycleState(AppLifecycleState.detached);
expect(observer.accumulatedStates, <AppLifecycleState>[
AppLifecycleState.inactive,
AppLifecycleState.hidden,
AppLifecycleState.paused,
AppLifecycleState.detached,
]);
WidgetsBinding.instance.removeObserver(observer); WidgetsBinding.instance.removeObserver(observer);
}); });
......
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