Skip to content

Commit

Permalink
Merge pull request #381 from ably/fix/public-member-documentation
Browse files Browse the repository at this point in the history
Extend public member documentation
  • Loading branch information
ikurek committed Apr 27, 2022
2 parents a14bb12 + 35b784a commit 10a94c3
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 24 deletions.
1 change: 1 addition & 0 deletions lib/src/authentication/src/token_params.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class TokenParams {
this.ttl,
});

/// converts to a map of objects
Map<String, dynamic> toMap() {
final jsonMap = <String, dynamic>{};
if (capability != null) jsonMap['capability'] = capability;
Expand Down
26 changes: 19 additions & 7 deletions lib/src/crypto/src/crypto.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ import 'package:ably_flutter/src/platform/platform_internal.dart';
/// Utility methods for creating keys ([generateRandomKey]) and configuration
/// objects ([CipherParams]) for symmetric encryption.
class Crypto {
/// Default algorithm used of encryption
/// Currently only AES is supported
static const defaultAlgorithm = 'aes';
static const defaultBlockLengthInBytes = 16;
static const defaultKeyLengthInBits = 256;

/// Default length of the key in bits
/// Equals to [keyLength256bits]
static const defaultKeyLengthInBits = keyLength256bits;

/// Length of 256-bit key
static const keyLength256bits = 256;

/// Length of 128-bit key
static const keyLength128bits = 128;

/// Default mode used of encryption
/// Currently only CBC is supported
static const defaultMode = 'cbc';
static const keyTypeErrorMessage = 'key must be a String or Uint8List.';
static const keyLengthErrorMessage = 'key must be 256 bits or 128 bits long.';

/// Gets the CipherParams which can be used to with [RestChannelOptions] or
/// [RealtimeChannelOptions] to specify encryption.
Expand All @@ -30,7 +40,7 @@ class Crypto {
ensureSupportedKeyLength(key);
} else {
throw AblyException(
message: keyTypeErrorMessage,
message: 'key must be a String or Uint8List.',
);
}

Expand All @@ -43,11 +53,13 @@ class Crypto {
);
}

/// Validates the length of provided [key]
/// Throws [AblyException] if key length is different than 128 or 256 bits
static void ensureSupportedKeyLength(Uint8List key) {
if (key.length != defaultKeyLengthInBits / 8 &&
if (key.length != keyLength256bits / 8 &&
key.length != keyLength128bits / 8) {
throw AblyException(
message: keyLengthErrorMessage,
message: 'Key must be 256 bits or 128 bits long.',
);
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/src/logging/src/log_level.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import 'package:ably_flutter/ably_flutter.dart';
/// Can be used for [ClientOptions.logLevel]
///
/// https://docs.ably.com/client-lib-development-guide/features/#TO3b
// ignore: public_member_api_docs
enum LogLevel { none, verbose, debug, info, warn, error }
3 changes: 3 additions & 0 deletions lib/src/platform/src/background_android_isolate_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class BackgroundIsolateAndroidPlatform {
Future<void> _onPushBackgroundMessage(RemoteMessage remoteMessage) async =>
_pushNotificationEvents.handleBackgroundMessage(remoteMessage);

/// Equivalent of [Platform.invokePlatformMethod] which cannot be used here
/// because we may not be able to acquire [Platform] instance here, so we
/// need to use a raw [MethodChannel] communication
Future<T?> invokeMethod<T>(String method, [dynamic arguments]) async =>
_methodChannel.invokeMethod<T>(method, arguments);
}
21 changes: 14 additions & 7 deletions lib/src/platform/src/cipher_params_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,19 @@ import 'package:ably_flutter/ably_flutter.dart';
/// needing to store instances on the Android side and pass references/handles
/// to the dart side.
class CipherParamsInternal implements CipherParams {
/// Android only
/// Handle value read from platform implementation
int? androidHandle;

/// iOS only
/// Encryption key returned by platform implementation
Uint8List? key;

/// iOS only
/// Encryption algorithm returned by platform implementation
String? algorithm;

String? mode = 'cbc';

/// Create a Dart side representation of CipherParams
/// Create a Dart side representation of CipherParams for iOS devices
CipherParamsInternal.forIOS({
required this.algorithm,
required this.key,
Expand All @@ -41,6 +46,7 @@ class CipherParamsInternal implements CipherParams {
}
}

/// Create a Dart side representation of CipherParams for Android devices
CipherParamsInternal.forAndroid({
required this.androidHandle,
}) {
Expand All @@ -56,10 +62,11 @@ class CipherParamsInternal implements CipherParams {
}
}

/// Explicitly cast the [CipherParams] to [CipherParamsInternal] so
/// it's possible to access the internal implementation details
///
/// This method is actually package-private, because [CipherParamsInternal]
/// is not exposed outside of the package
static CipherParamsInternal fromCipherParams(CipherParams cipherParams) =>
cipherParams as CipherParamsInternal;

/// Explicitly cast the [CipherParamsInternal] to [CipherParams] so
/// users do not see implementation details (e.g. [androidHandle]).
CipherParams toCipherParams() => this;
}
8 changes: 4 additions & 4 deletions lib/src/platform/src/method_call_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class AblyMethodCallHandler {
return _pushNotificationEvents
.showNotificationInForeground(call.arguments as RemoteMessage);
case PlatformMethod.pushOnNotificationTap:
return onNotificationTap(call.arguments as RemoteMessage);
return _onNotificationTap(call.arguments as RemoteMessage);
case PlatformMethod.pushOpenSettingsFor:
return onOpenSettingsFor();
return _onOpenSettingsFor();
default:
throw PlatformException(
code: 'Received invalid method channel call from Platform side',
Expand Down Expand Up @@ -94,13 +94,13 @@ class AblyMethodCallHandler {
return null;
}

Future<Object?> onNotificationTap(RemoteMessage remoteMessage) async {
Future<Object?> _onNotificationTap(RemoteMessage remoteMessage) async {
_pushNotificationEvents.onNotificationTapStreamController
.add(remoteMessage);
return null;
}

Future<Object?> onOpenSettingsFor() async {
Future<Object?> _onOpenSettingsFor() async {
if (_pushNotificationEvents.onOpenSettingsHandler != null) {
_pushNotificationEvents.onOpenSettingsHandler!();
}
Expand Down
8 changes: 7 additions & 1 deletion lib/src/platform/src/platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import 'package:ably_flutter/ably_flutter.dart';
import 'package:ably_flutter/src/platform/platform_internal.dart';
import 'package:flutter/services.dart';

/// Used to communicate between Dart and native platforms
/// holds reference to [MethodChannel] and exposes methods used to invoke
/// platform calls and listen to platform data streams
class Platform {
Platform._internal({MethodChannel? methodChannel}) {
_methodChannel = methodChannel;
Expand Down Expand Up @@ -33,6 +36,7 @@ class Platform {
/// instance of method channel to listen to android/ios events
late final StreamsChannel? _streamsChannel;

/// Call a platform method which may return null/void as a result
Future<T?> invokePlatformMethod<T>(String method,
[AblyMessage<Map<String, dynamic>>? arguments]) async {
try {
Expand All @@ -50,7 +54,7 @@ class Platform {
}
}

/// Call a platform method which always provides a result.
/// Call a platform method which always provides a non-null result
Future<T> invokePlatformMethodNonNull<T>(String method,
[AblyMessage<Map<String, dynamic>>? arguments]) async {
final result = await invokePlatformMethod<T>(method, arguments);
Expand All @@ -63,6 +67,8 @@ class Platform {
}
}

/// Call a platform method which always provides an observable stream
/// of data as a result
Stream<T> receiveBroadcastStream<T>(String methodName, int handle,
[final Object? payload]) =>
_streamsChannel!.receiveBroadcastStream<T>(
Expand Down
9 changes: 9 additions & 0 deletions lib/src/platform/src/push_activation_events_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ import 'dart:async';

import 'package:ably_flutter/ably_flutter.dart';

/// package-private implementation of [PushActivationEvents]
/// used internally by [Push] instances
// FIXME: StreamControllers here may leak, we should add a `close()` method
// See: https://github.com/ably/ably-flutter/issues/382
class PushActivationEventsInternal extends PushActivationEvents {
/// [StreamController] used to handle onActivate events
StreamController<ErrorInfo?> onActivateStreamController = StreamController();

/// [StreamController] used to handle onDeactivate events
StreamController<ErrorInfo?> onDeactivateStreamController =
StreamController();

/// [StreamController] used to handle onUpdateFailed events
StreamController<ErrorInfo> onUpdateFailedStreamController =
StreamController();

Expand Down
14 changes: 12 additions & 2 deletions lib/src/platform/src/push_notification_events_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ import 'dart:ui';
import 'package:ably_flutter/ably_flutter.dart';
import 'package:ably_flutter/src/platform/platform_internal.dart';

/// package-private implementation of [PushNotificationEvents]
class PushNotificationEventsInternal implements PushNotificationEvents {
/// Invoked when pushOpenSettingsFor platform method is called
VoidCallback? onOpenSettingsHandler;

/// Invoked when pushOnShowNotificationInForeground platform method is called
Future<bool> Function(RemoteMessage message)?
onShowNotificationInForegroundHandler;

/// Exposes stream of received [RemoteMessage] objects
/// New message is emitted after pushOnMessage platform method is called
StreamController<RemoteMessage> onMessageStreamController =
StreamController();

/// Controller used to indicate notification was tapped
StreamController<RemoteMessage> onNotificationTapStreamController =
StreamController();

BackgroundMessageHandler? _onBackgroundMessage;

@override
Future<RemoteMessage?> get notificationTapLaunchedAppFromTerminated =>
Platform().invokePlatformMethod<RemoteMessage>(
Expand Down Expand Up @@ -48,8 +57,6 @@ class PushNotificationEventsInternal implements PushNotificationEvents {
return onShowNotificationInForegroundHandler!(message);
}

BackgroundMessageHandler? _onBackgroundMessage;

/// Implementation of setOnBackgroundMessage. For more documentation,
/// see [PushNotificationEvents.setOnBackgroundMessage]
@override
Expand Down Expand Up @@ -77,6 +84,9 @@ class PushNotificationEventsInternal implements PushNotificationEvents {
}
}

/// Used to close internal [StreamController] instances
// FIXME: This method is not called anywhere
// See: https://github.com/ably/ably-flutter/issues/382
void close() {
onMessageStreamController.close();
onNotificationTapStreamController.close();
Expand Down
1 change: 1 addition & 0 deletions lib/src/platform/src/realtime/connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Connection extends PlatformObject {
/// https://docs.ably.com/client-lib-development-guide/features/#connection-states-operations
ConnectionState get state => _state;

/// stream of connection events with specified [ConnectionEvent] type
Stream<ConnectionStateChange> on([ConnectionEvent? connectionEvent]) =>
listen<ConnectionStateChange>(
PlatformMethod.onRealtimeConnectionStateChanged,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/platform/src/realtime/realtime_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ class RealtimeChannel extends PlatformObject {
/// (see IDL for more details)
late PushChannel push;

/// Current state of the channel
///
/// https://docs.ably.com/client-lib-development-guide/features/#RTL2b
ChannelState state;

/// Attaches the realtime client to this channel.
Expand All @@ -124,6 +127,7 @@ class RealtimeChannel extends PlatformObject {
TxTransportKeys.options: options,
});

/// stream of channel events with specified [ChannelEvent] type
Stream<ChannelStateChange> on([ChannelEvent? channelEvent]) =>
listen<ChannelStateChange>(
PlatformMethod.onRealtimeChannelStateChanged,
Expand Down
6 changes: 3 additions & 3 deletions lib/src/platform/src/rest/rest_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ class RestChannel extends PlatformObject {
/// name of the channel
String name;

late RestPresence _presence;

/// presence interface for this channel
///
/// can only query presence on the channel and presence history
/// https://docs.ably.com/client-lib-development-guide/features/#RSL3
late RestPresence _presence;
RestPresence get presence => _presence;

/// instantiates with [Rest], [name] and [RestChannelOptions]
RestChannel(this.rest, this.push, this.name) {
_presence = RestPresence(this);
}

RestPresence get presence => _presence;

/// createPlatformInstance will return restPlatformObject's handle
/// as that is what will be required in platforms end to find rest instance
/// and send message to channel
Expand Down
2 changes: 2 additions & 0 deletions lib/src/push_notifications/src/ios_notification_settings.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: public_member_api_docs

import 'package:ably_flutter/ably_flutter.dart';

/// This file contains push notification types specific to iOS. All types begin
Expand Down
1 change: 1 addition & 0 deletions lib/src/push_notifications/src/notification.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Notification {
this.body,
});

/// Creates an instance from the map
factory Notification.fromMap(Map<String, dynamic> map) => Notification(
body: map[TxNotification.body] as String?,
title: map[TxNotification.title] as String,
Expand Down
2 changes: 2 additions & 0 deletions lib/src/push_notifications/src/push_notification_events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'dart:ui';

import 'package:ably_flutter/ably_flutter.dart';

/// type definition for a callback invoked when background push message
/// is received
typedef BackgroundMessageHandler = void Function(RemoteMessage message);

/// Push Notification events, such as message arriving or notification tap.
Expand Down
1 change: 1 addition & 0 deletions lib/src/push_notifications/src/remote_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class RemoteMessage {
this.notification,
}) : data = data ??= {};

/// create instance from a map
factory RemoteMessage.fromMap(Map<String, dynamic> map) => RemoteMessage(
data: (map[TxRemoteMessage.data] == null)
? <String, dynamic>{}
Expand Down

0 comments on commit 10a94c3

Please sign in to comment.