Skip to content

Commit 3b9cc90

Browse files
authored
Merge branch 'main' into fix/db-common-cmake-collision
2 parents 8dfbdcd + 25fe3f0 commit 3b9cc90

File tree

42 files changed

+474
-58
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+474
-58
lines changed

packages/aft/test/version_bump/data/repo_snapshot/packages/aws_common/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/aft/test/version_bump/data/repo_snapshot/packages/notifications/push/amplify_push_notifications/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/aft/test/version_bump/data/repo_snapshot/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/amplify_core/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 2.4.2
2+
3+
### Features
4+
- feat(api): move App Sync subscription headers to protocol ([#5301](https://github.com/aws-amplify/amplify-flutter/pull/5301))
5+
6+
### Fixes
7+
- fix(api): Reconnect WebSocket when resuming app from a paused state ([#5567](https://github.com/aws-amplify/amplify-flutter/pull/5567))
8+
19
## 2.4.1
210

311
### Fixes

packages/amplify_core/lib/src/version.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/amplify_core/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: amplify_core
22
description: The base package containing common types and utilities that are shared across the Amplify Flutter packages.
3-
version: 2.4.1
3+
version: 2.4.2
44
homepage: https://docs.amplify.aws/lib/q/platform/flutter/
55
repository: https://github.com/aws-amplify/amplify-flutter/tree/main/packages/amplify_core
66
issue_tracker: https://github.com/aws-amplify/amplify-flutter/issues
@@ -10,7 +10,7 @@ environment:
1010

1111
dependencies:
1212
async: ^2.10.0
13-
aws_common: ">=0.7.3 <0.8.0"
13+
aws_common: ">=0.7.4 <0.8.0"
1414
aws_signature_v4: ">=0.6.3 <0.7.0"
1515
collection: ^1.15.0
1616
graphs: ^2.1.0

packages/amplify_datastore/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.4.2
2+
3+
- Minor bug fixes and improvements
4+
15
## 2.4.1
26

37
### Fixes

packages/amplify_datastore/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: amplify_datastore
22
description: The Amplify Flutter DataStore category plugin, providing a queryable, on-device data store.
3-
version: 2.4.1
3+
version: 2.4.2
44
homepage: https://docs.amplify.aws/lib/q/platform/flutter/
55
repository: https://github.com/aws-amplify/amplify-flutter/tree/main/packages/amplify_datastore
66
issue_tracker: https://github.com/aws-amplify/amplify-flutter/issues
@@ -13,7 +13,7 @@ dependencies:
1313
flutter:
1414
sdk: flutter
1515
amplify_datastore_plugin_interface: ">=2.4.1 <2.5.0"
16-
amplify_core: ">=2.4.1 <2.5.0"
16+
amplify_core: ">=2.4.2 <2.5.0"
1717
plugin_platform_interface: ^2.0.0
1818
meta: ^1.7.0
1919
collection: ^1.14.13

packages/api/amplify_api/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.4.2
2+
3+
### Fixes
4+
- fix(api): Reconnect WebSocket when resuming app from a paused state ([#5567](https://github.com/aws-amplify/amplify-flutter/pull/5567))
5+
16
## 2.4.1
27

38
- Minor bug fixes and improvements

packages/api/amplify_api/lib/amplify_api.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@ library amplify_api;
55

66
export 'package:amplify_api/src/api_plugin_impl.dart';
77
export 'package:amplify_api_dart/amplify_api_dart.dart'
8-
hide AmplifyAPIDart, ConnectivityPlatform, ConnectivityStatus;
8+
hide
9+
AmplifyAPIDart,
10+
ConnectivityPlatform,
11+
ProcessLifeCycle,
12+
ConnectivityStatus;

packages/api/amplify_api/lib/src/api_plugin_impl.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import 'package:amplify_api/src/connectivity_plus_platform.dart';
5+
import 'package:amplify_api/src/flutter_life_cycle.dart';
56
import 'package:amplify_api_dart/amplify_api_dart.dart';
67
import 'package:amplify_core/amplify_core.dart';
78

@@ -14,6 +15,7 @@ class AmplifyAPI extends AmplifyAPIDart with AWSDebuggable {
1415
super.options,
1516
}) : super(
1617
connectivity: const ConnectivityPlusPlatform(),
18+
processLifeCycle: FlutterLifeCycle(),
1719
);
1820

1921
@override
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import 'dart:async';
5+
6+
import 'package:amplify_api_dart/amplify_api_dart.dart';
7+
import 'package:flutter/widgets.dart';
8+
import 'package:meta/meta.dart';
9+
10+
/// {@template amplify_api.flutter_life_cycle}
11+
/// Creates a stream of [ProcessStatus] mapped from [AppLifecycleListener](https://api.flutter.dev/flutter/widgets/AppLifecycleListener-class.html).
12+
/// {@endtemplate}
13+
@internal
14+
class FlutterLifeCycle extends ProcessLifeCycle {
15+
/// {@macro amplify_api.flutter_life_cycle}
16+
FlutterLifeCycle() {
17+
AppLifecycleListener(
18+
onStateChange: _onStateChange,
19+
);
20+
}
21+
22+
final _stateController =
23+
StreamController<ProcessStatus>.broadcast(sync: true);
24+
25+
@override
26+
Stream<ProcessStatus> get onStateChanged => _stateController.stream;
27+
28+
void _onStateChange(AppLifecycleState state) {
29+
switch (state) {
30+
case AppLifecycleState.detached:
31+
_stateController.add(ProcessStatus.detached);
32+
case AppLifecycleState.paused:
33+
_stateController.add(ProcessStatus.paused);
34+
case AppLifecycleState.hidden:
35+
_stateController.add(ProcessStatus.hidden);
36+
case AppLifecycleState.inactive:
37+
_stateController.add(ProcessStatus.inactive);
38+
case AppLifecycleState.resumed:
39+
_stateController.add(ProcessStatus.resumed);
40+
}
41+
}
42+
}

packages/api/amplify_api/pubspec.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: amplify_api
22
description: The Amplify Flutter API category plugin, supporting GraphQL and REST operations.
3-
version: 2.4.1
3+
version: 2.4.2
44
homepage: https://docs.amplify.aws/lib/q/platform/flutter/
55
repository: https://github.com/aws-amplify/amplify-flutter/tree/main/packages/api/amplify_api
66
issue_tracker: https://github.com/aws-amplify/amplify-flutter/issues
@@ -19,8 +19,8 @@ platforms:
1919
web:
2020

2121
dependencies:
22-
amplify_api_dart: ">=0.5.5 <0.6.0"
23-
amplify_core: ">=2.4.1 <2.5.0"
22+
amplify_api_dart: ">=0.5.6 <0.6.0"
23+
amplify_core: ">=2.4.2 <2.5.0"
2424
amplify_flutter: ">=2.4.1 <2.5.0"
2525
connectivity_plus: ^6.0.1
2626
flutter:

packages/api/amplify_api_dart/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.5.6
2+
3+
### Features
4+
- feat(api): move App Sync subscription headers to protocol ([#5301](https://github.com/aws-amplify/amplify-flutter/pull/5301))
5+
6+
### Fixes
7+
- fix(api): Reconnect WebSocket when resuming app from a paused state ([#5567](https://github.com/aws-amplify/amplify-flutter/pull/5567))
8+
19
## 0.5.5
210

311
### Fixes

packages/api/amplify_api_dart/lib/amplify_api_dart.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ export 'src/graphql/model_helpers/model_subscriptions.dart';
1919

2020
/// Network connectivity util not needed by consumers of Flutter package amplify_api.
2121
export 'src/graphql/web_socket/types/connectivity_platform.dart';
22+
export 'src/graphql/web_socket/types/process_life_cycle.dart';

packages/api/amplify_api_dart/lib/src/api_plugin_impl.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:amplify_api_dart/src/graphql/web_socket/blocs/web_socket_bloc.da
1111
import 'package:amplify_api_dart/src/graphql/web_socket/services/web_socket_service.dart';
1212
import 'package:amplify_api_dart/src/graphql/web_socket/state/web_socket_state.dart';
1313
import 'package:amplify_api_dart/src/graphql/web_socket/types/connectivity_platform.dart';
14+
import 'package:amplify_api_dart/src/graphql/web_socket/types/process_life_cycle.dart';
1415
import 'package:amplify_api_dart/src/util/amplify_api_config.dart';
1516
import 'package:amplify_api_dart/src/util/amplify_authorization_rest_client.dart';
1617
import 'package:amplify_core/amplify_core.dart';
@@ -30,8 +31,10 @@ class AmplifyAPIDart extends APIPluginInterface with AWSDebuggable {
3031
AmplifyAPIDart({
3132
APIPluginOptions options = const APIPluginOptions(),
3233
ConnectivityPlatform connectivity = const ConnectivityPlatform(),
34+
ProcessLifeCycle processLifeCycle = const ProcessLifeCycle(),
3335
}) : _options = options,
34-
_connectivity = connectivity {
36+
_connectivity = connectivity,
37+
_processLifeCycle = processLifeCycle {
3538
_options.authProviders.forEach(registerAuthProvider);
3639
}
3740

@@ -43,6 +46,9 @@ class AmplifyAPIDart extends APIPluginInterface with AWSDebuggable {
4346
/// Creates a stream representing network connectivity at the hardware level.
4447
final ConnectivityPlatform _connectivity;
4548

49+
/// Creates a stream representing the process life cycle state.
50+
final ProcessLifeCycle _processLifeCycle;
51+
4652
/// A map of the keys from the Amplify API config with auth modes to HTTP clients
4753
/// to use for requests to that endpoint/auth mode. e.g. { "myEndpoint.AWS_IAM": AWSHttpClient}
4854
final Map<String, AWSHttpClient> _clientPool = {};
@@ -277,6 +283,7 @@ class AmplifyAPIDart extends APIPluginInterface with AWSDebuggable {
277283
wsService: AmplifyWebSocketService(),
278284
subscriptionOptions: _options.subscriptionOptions,
279285
connectivity: _connectivity,
286+
processLifeCycle: _processLifeCycle,
280287
);
281288
}
282289

packages/api/amplify_api_dart/lib/src/graphql/web_socket/blocs/web_socket_bloc.dart

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:amplify_api_dart/src/graphql/web_socket/services/web_socket_serv
99
import 'package:amplify_api_dart/src/graphql/web_socket/state/web_socket_state.dart';
1010
import 'package:amplify_api_dart/src/graphql/web_socket/state/ws_subscriptions_state.dart';
1111
import 'package:amplify_api_dart/src/graphql/web_socket/types/connectivity_platform.dart';
12+
import 'package:amplify_api_dart/src/graphql/web_socket/types/process_life_cycle.dart';
1213
import 'package:amplify_api_dart/src/graphql/web_socket/types/subscriptions_event.dart';
1314
import 'package:amplify_api_dart/src/graphql/web_socket/types/web_socket_types.dart';
1415
import 'package:amplify_core/amplify_core.dart' hide SubscriptionEvent;
@@ -33,8 +34,10 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
3334
required WebSocketService wsService,
3435
required GraphQLSubscriptionOptions subscriptionOptions,
3536
required ConnectivityPlatform connectivity,
37+
required ProcessLifeCycle processLifeCycle,
3638
AWSHttpClient? pollClientOverride,
3739
}) : _connectivity = connectivity,
40+
_processLifeCycle = processLifeCycle,
3841
_pollClient = pollClientOverride ?? AWSHttpClient() {
3942
final subBlocs = <String, SubscriptionBloc<Object?>>{};
4043

@@ -49,6 +52,7 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
4952
);
5053
final blocStream = _wsEventStream.asyncExpand(_eventTransformer);
5154
_networkSubscription = _getConnectivityStream();
55+
_processLifeCycleSubscription = _getProcessLifecycleStream();
5256
_stateSubscription = blocStream.listen(_emit);
5357
add(const InitEvent());
5458
}
@@ -81,10 +85,14 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
8185
late final Stream<WebSocketEvent> _wsEventStream = _wsEventController.stream;
8286
late final StreamSubscription<WebSocketState> _stateSubscription;
8387
late final StreamSubscription<ConnectivityStatus> _networkSubscription;
88+
late final StreamSubscription<ProcessStatus> _processLifeCycleSubscription;
8489

8590
/// Creates a stream representing network connectivity at the hardware level.
8691
final ConnectivityPlatform _connectivity;
8792

93+
/// Creates a stream representing the process life cycle state.
94+
final ProcessLifeCycle _processLifeCycle;
95+
8896
/// The underlying event stream, used only in testing.
8997
@visibleForTesting
9098
Stream<WebSocketEvent> get wsEventStream => _wsEventStream;
@@ -164,6 +172,8 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
164172
yield* _networkLoss();
165173
} else if (event is NetworkFoundEvent) {
166174
yield* _networkFound();
175+
} else if (event is ProcessResumeEvent) {
176+
yield* _processResumed();
167177
} else if (event is PollSuccessEvent) {
168178
yield* _pollSuccess();
169179
} else if (event is PollFailedEvent) {
@@ -328,6 +338,16 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
328338
yield* const Stream.empty();
329339
}
330340

341+
Stream<WebSocketState> _processResumed() async* {
342+
final state = _currentState;
343+
if (state is ConnectedState) {
344+
yield state.reconnecting(networkState: NetworkState.disconnected);
345+
add(const ReconnectEvent());
346+
}
347+
// TODO(dnys1): Yield broken on web debug build.
348+
yield* const Stream.empty();
349+
}
350+
331351
/// Handle successful polls
332352
Stream<WebSocketState> _pollSuccess() async* {
333353
// TODO(dnys1): Yield broken on web debug build.
@@ -467,6 +487,7 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
467487
await Future.wait<void>([
468488
// TODO(equartey): https://github.com/fluttercommunity/plus_plugins/issues/1382
469489
if (!isWindows()) _networkSubscription.cancel(),
490+
_processLifeCycleSubscription.cancel(),
470491
Future.value(_pollClient.close()),
471492
_stateSubscription.cancel(),
472493
_wsEventController.close(),
@@ -507,6 +528,41 @@ class WebSocketBloc with AWSDebuggable, AmplifyLoggerMixin {
507528
);
508529
}
509530

531+
/// Process life cycle stream monitors when the process resumes from a paused state.
532+
StreamSubscription<ProcessStatus> _getProcessLifecycleStream() {
533+
var prev = ProcessStatus.detached;
534+
return _processLifeCycle.onStateChanged.listen(
535+
(state) {
536+
if (_isResuming(state, prev)) {
537+
// ignore: invalid_use_of_internal_member
538+
if (!WebSocketOptions.autoReconnect) {
539+
_shutdownWithException(
540+
const NetworkException(
541+
'Unable to recover network connection, web socket will close.',
542+
recoverySuggestion: 'Avoid pausing the process.',
543+
),
544+
StackTrace.current,
545+
);
546+
} else {
547+
add(const ProcessResumeEvent());
548+
}
549+
}
550+
551+
prev = state;
552+
},
553+
onError: (Object e, StackTrace st) =>
554+
logger.error('Error in process life cycle stream $e, $st'),
555+
);
556+
}
557+
558+
bool _isResuming(ProcessStatus current, ProcessStatus previous) {
559+
if (previous != ProcessStatus.paused) return false;
560+
561+
return current == ProcessStatus.hidden ||
562+
current == ProcessStatus.inactive ||
563+
current == ProcessStatus.resumed;
564+
}
565+
510566
Future<void> _poll() async {
511567
try {
512568
final res = await _sendPollRequest();
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/// Possible process life cycle states
5+
enum ProcessStatus {
6+
/// Engine is running without a view.
7+
detached,
8+
9+
/// Application is not visible to the user or responding to user input.
10+
paused,
11+
12+
/// All views of an application are hidden.
13+
hidden,
14+
15+
/// A view of the application is visible, but none have input.
16+
inactive,
17+
18+
/// Default running mode.
19+
resumed,
20+
}
21+
22+
/// {@template amplify_api_dart.process_life_cycle}
23+
/// Used to create a stream representing the process life cycle state.
24+
///
25+
/// The generated stream is empty.
26+
/// {@endtemplate}
27+
class ProcessLifeCycle {
28+
/// {@macro amplify_api_dart.process_life_cycle}
29+
const ProcessLifeCycle();
30+
31+
/// Generates a new stream of [ProcessStatus].
32+
Stream<ProcessStatus> get onStateChanged => const Stream.empty();
33+
}

0 commit comments

Comments
 (0)