From f517f65bad1791ff1932ea9e69325a46b49f414a Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:13:44 +0000 Subject: [PATCH 01/51] Add script to format all files --- format-files.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 format-files.sh diff --git a/format-files.sh b/format-files.sh new file mode 100755 index 000000000..7e2bfed58 --- /dev/null +++ b/format-files.sh @@ -0,0 +1,44 @@ +#!/bin/zsh + +set -e + +MY_PATH=$(dirname "$0") + +# Pre-requisites +# 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. +if ! [ -x "$(command -v flutter)" ]; then + echo "FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 + exit 1 +fi + +# 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. +if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then + echo "FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; + exit 1; +fi + +# 3. Install using brew by running `brew install swiftformat`. This provides the Swift formatting tool. +if ! [ -x "$(command -v swiftformat)" ]; then + echo "FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 + exit 1 +fi + +echo "Formatting Dart files..." +flutter format $MY_PATH +echo "Formatted Dart files.\n" + +echo "Formatting Java files..." +JAVA_FILES=$(find $MY_PATH -name "*java" -type f -exec ls {} \;) +echo $JAVA_FILES | xargs java \ + --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + -jar $GOOGLE_JAVA_FORMAT_PATH --replace +echo "Formatted Java files.\n" + +echo "Formatting Swift files..." +SWIFT_VERSION=5.5 +swiftformat --swiftversion $SWIFT_VERSION $MY_PATH +echo "Formatted Swift files.\n" From b13f4bb1a4bab74262524b98097ea5436a7436e5 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:13:59 +0000 Subject: [PATCH 02/51] Improve steps for getting started with contributing --- CONTRIBUTING.md | 96 ++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 397750656..869762071 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,20 +2,29 @@ ## Getting Started -The code in this repository has been constructed to be -[built as a Flutter Plugin](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin). -It is not yet constructed as a federated plugin but this is in our backlog as -[issue 118](https://github.com/ably/ably-flutter/issues/118). - -After checking out this repository, run the following command: - - flutter pub get +- Clone the repository +- Install [Flutter](https://docs.flutter.dev/get-started/install) +- Install Android Studio, and then in Android Studio, install the [Flutter plugin](https://plugins.jetbrains.com/plugin/9212-flutter). + - Though you can debug Dart code from Visual Studio Code, you cannot debug the Android code. +- Download the dependencies listed in `pubspec.yaml` by running `flutter pub get` +- If using Android Studio, delete the `.packages` file. It is a deprecated autogenerated file which confuses Android Studio into thinking all files are build outputs instead of source files. +- If you have any issues, run `flutter doctor` and begin investigating. +- Write, test and debug platform (Android/iOS) code: + - Android: You can open the Android code in a separate window. In the Flutter project window, launch the application in debug mode in Android Studio. Then, in the Android project window, attach the debugger to the Android process. You can also do this with IntelliJ Idea. + - iOS: To debug iOS code, you must use and set breakpoints in Xcode or AppCode. In Android Studio or command line, run the flutter run --dart-define` command you would usually run. This ensures when you build with Xcode, the environment variables are available to the app. Then, re-run the application using Xcode. Then, in Android Studio, click `Run` > `Flutter Attach`, or click the `Flutter Attach` button. + - AppCode: AppCode is much better at navigating the code base, and refactoring the code. + +## Making changes + +We use Github actions to check code is formatted correctly. You should format your code using the same style to avoid Github CI job failures, since we do not automatically commit and format code. +- To format files, run `./format-files.sh`. See the files to see formatting commands for each language, e.g. `flutter format .` for Dart code. +- To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. + +## High level architecture -You may also find it insightful to run the following command, as it can reveal issues with your development environment: - - flutter doctor - -If using Android Studio, delete the `.packages` file. It is a deprecated autogenerated file which confuses Android Studio into thinking all files are build outputs instead of source files. +The code in this repository has been constructed to be +[built as a Flutter Plugin](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin). +It invokes methods in other Ably SDKs (Ably Android and Ably Cocoa) through `MethodChannels` and `EventChannels`. This means Android and iOS code provided in the plugin runs when the user's application is launched, even without them calling any methods in Ably directly. ## Implementation Notes @@ -88,12 +97,6 @@ got both iOS and Android emulators open: flutter run -d all -## Debugging notes (Android Studio) - -To debug both platform and Dart code simultaneously: -- In Android: in the Flutter project window, launch the application in debug mode in Android Studio. Then, in the Android project window, attach the debugger to the Android process. -- In iOS: To debug iOS code, you must set breakpoints in Xcode. In Android Studio or command line, run the flutter run --dart-define` command you would usually run. This ensures when you build with Xcode, the environment variables are available to the app. Then, re-run the application using Xcode. Then, in Android Studio, click `Run` > `Flutter Attach`, or click the `Flutter Attach` button. - ## Testing changes in dependencies After making changes to `ably-java` or `ably-cocoa`, you can test changes without releasing those dependencies to users. To do this, you need a local copy of the repo with the changes you want to test. @@ -118,17 +121,40 @@ being a specialized package that includes platform-specific implementation code - Flutter [documentation](https://flutter.dev/docs), offering tutorials, samples, guidance on mobile development, and a full API reference. + +## Serialization +Data is JSON-serialized back and forth from Dart to Android/iOS, where a dictionary/hashmap containing string constants as key (e.g. "name"), and the data as the value. Files containing constants (strings, integers) shared across Dart, Android and iOS are generated from the contents of `codegen_context.dart`. The output of this code generation is `platform_constants.dart`, -## Generating platform constants +You'll notice 3 categories of constants: +- CodecTypes: These constants help identify which type has just been received from the Dart or platform so that we can deserialize it. +- PlatformMethod: Method invocations called from Dart to platform side, or vice-versa. +- JSON-serialization property names. These are strings used to identify values between Dart and platform. + - For the case of enums: e.g. an enum from Java is converted to a String and converted back into the correct enum, based on the string value. + - To send dictionaries/maps containing data, we need to identify each one. For example, to send a `ChannelOptions` type which contains `params`, `modes` and `cipherParams`, we would send a Map containing these 3 keys, and their values contain the data. The receiving side can immediately get the `modes` from the dictionary. -Some files in the project are generated to maintain sync between - platform constants on both native and dart side. - Generated file paths are configured as values in `bin/codegen.dart` for `toGenerate` Map +In the future, this serialization code can be [significantly simplified using Pigeon](https://github.com/ably/ably-flutter/issues/28), but as we could also work on implementing the features in pure Dart SDK and avoid serialization altogether, this work has not yet been started. + +In cases where instances cannot be fully serialized between Dart and the platform, we instead store these instances and pass a handle instead. For example, a Realtime client is stored in a Map on the Platform side (e.g. `AblyClientStore.java`), and a handle is passed to the Dart side. + +### Updating serialization -[Read about generation of platform specific constant files](bin/README.md) +You'll need to re-generate the platform constants whenever you: +- Change the serialization: + - A new codec type - required when a new top level serializable object is required (ex: `ErrorInfo` and `ClientOptions`) + - Platform and event names - when implementing a new method in `MethodChannel` or new event in `EventChannel` + - A new type needs to be serialized (either top-level, or nested) +- Change the templates: To change the structure of files being generated, you can modify the templates: + - `lib/src/generated/platformconstants.dart` for use in Flutter/Dart + - `android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java` for use in Android/Java + - `ios/Classes/codec/AblyPlatformConstants.h` for use in iOS/Objective-C + - `ios/Classes/codec/AblyPlatformConstants.m` for use in iOS/Objective-C -## Implementing new codec types +- To add or modify existing platform constants, modify: `codegen_context.dart` +- Then, to regenerate the platform constants using the latest "context", run `cd bin` and `dart codegen.dart` +- Once you have updated these constants, you have to now use these in the implementation. + +### Implementing new codec types 1. Add new type along with value in `_types` list at [bin/codegen_context.dart](bin/codegen_context.dart) 2. Add an object definition with object name and its properties to `objects` list at [bin/codegen_context.dart](bin/codegen_context.dart) @@ -147,28 +173,10 @@ Generate platform constants and continue 8. add new codec encoder method in [ios.classes.codec.AblyFlutterReader](ios/Classes/codec/AblyFlutterReader.m) and update `getDecoder` so that new codec decoder is called -## Implementing new platform methods +### Implementing new platform methods 1. Add new method name in `_platformMethods` list at [bin/codegen_context.dart](bin/codegen_context.dart) -Generate platform constants and use wherever required - -## Static plugin code analyzer - -The new flutter analyzer does a great job at analyzing complete flutter package. - -Running `flutter analyze` in project root will analyze dart files in complete project, - i.e., plugin code and example code - - -Or, use the good old dart analyzer - -```bash -dartanalyzer --fatal-warnings lib/**/*.dart - -dartanalyzer --fatal-warnings example/lib/**/*.dart -``` - ## dartdoc ### Tool Installation From e6762386b6b3e6ce70fdaab4c5023f364b440297 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:14:24 +0000 Subject: [PATCH 03/51] Remove unnecessary readme, since contents have been merged into main README --- bin/README.md | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 bin/README.md diff --git a/bin/README.md b/bin/README.md deleted file mode 100644 index 0e8fcbe05..000000000 --- a/bin/README.md +++ /dev/null @@ -1,47 +0,0 @@ -## Code generation to keep platform constants in sync - -There are many platform constants that need to be sync on dart side and platform side. -Following are the constants that are being generated: -1. codec types -2. platform method and event names -3. serializable property names for serialization and de-serialization - -#### Generating files - -```bash -cd bin -dart codegen.dart -``` - -#### Template format - -A straight forward templates creating using dart string interpolation: - -#### Template and Context files - -source template files are available in `bin/templates` - and source context data in `bin/codegencontext.dart`. - - -#### Generated files - -These files are generated/modified upon code generation - -1. `lib/src/generated/platformconstants.dart` for use in Flutter/Dart -2. `android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java` for use in Android/Java -3. `ios/Classes/codec/AblyPlatformConstants.h` for use in iOS/Objective-C -4. `ios/Classes/codec/AblyPlatformConstants.m` for use in iOS/Objective-C - -#### When would I need to run code generation? - -When any of the below need to be added/updated -1. A new codec type - required when a new top level serializable object is required (ex: `ErrorInfo` and `ClientOptions`) -2. Platform and event names - when implementing a new method in `MethodChannel` or new event in `EventChannel` -3. A new object needs to be serialized (either top-level, or nested) - - -#### What should I do after running code generation? - -1. Test that everything still works -2. Commit changes to the template(s) -3. Commit changes to the generate files From 715902d7651d2ef7bc10b0f14011afb5783daead Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:17:27 +0000 Subject: [PATCH 04/51] Add emoji so each line is clearer --- format-files.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/format-files.sh b/format-files.sh index 7e2bfed58..efe23326b 100755 --- a/format-files.sh +++ b/format-files.sh @@ -7,27 +7,27 @@ MY_PATH=$(dirname "$0") # Pre-requisites # 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. if ! [ -x "$(command -v flutter)" ]; then - echo "FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 + echo "🚨 FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 exit 1 fi # 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then - echo "FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; + echo "🚨 FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; exit 1; fi # 3. Install using brew by running `brew install swiftformat`. This provides the Swift formatting tool. if ! [ -x "$(command -v swiftformat)" ]; then - echo "FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 + echo "🚨 FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 exit 1 fi -echo "Formatting Dart files..." +echo "Formatting Dart 🐣 files..." flutter format $MY_PATH -echo "Formatted Dart files.\n" +echo "Formatted Dart 🐥 files.\n" -echo "Formatting Java files..." +echo "Formatting Java 🌰 files..." JAVA_FILES=$(find $MY_PATH -name "*java" -type f -exec ls {} \;) echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ @@ -36,9 +36,9 @@ echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ -jar $GOOGLE_JAVA_FORMAT_PATH --replace -echo "Formatted Java files.\n" +echo "Formatted Java ☕️ files.\n" -echo "Formatting Swift files..." +echo "Formatting Swift 💨 files..." SWIFT_VERSION=5.5 swiftformat --swiftversion $SWIFT_VERSION $MY_PATH -echo "Formatted Swift files.\n" +echo "Formatted Swift 🌬 files.\n" From 18586a84dd5a8f6149512dd8bc2f4a5771fd4abe Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:21:30 +0000 Subject: [PATCH 05/51] Add removed section --- CONTRIBUTING.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 869762071..df09ee79e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -177,6 +177,23 @@ Generate platform constants and continue 1. Add new method name in `_platformMethods` list at [bin/codegen_context.dart](bin/codegen_context.dart) +Generate platform constants and use wherever required + +## Static plugin code analyzer + +The new flutter analyzer does a great job at analyzing complete flutter package. + +Running `flutter analyze` in project root will analyze dart files in complete project, +i.e., plugin code and example code + + +Or, use the good old dart analyzer + +```bash +dartanalyzer --fatal-warnings lib/**/*.dart +dartanalyzer --fatal-warnings example/lib/**/*.dart +``` + ## dartdoc ### Tool Installation From 53504a3a115f1950b75a5fc42978455e6f192049 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:06:01 +0000 Subject: [PATCH 06/51] Add formatting checks for Swift and Java --- .github/workflows/check.yaml | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 763a01f10..9eca12ccb 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -5,7 +5,31 @@ on: - main jobs: - check: + swift: + name: "Swift formatting checks" + runs-on: ubuntu-latest + steps: + - name: 'Build and install Mint' + run: | + git clone https://github.com/yonaskolb/Mint.git + cd Mint + make + + - name: 'Install SwiftFormat' + run: 'mint install nicklockwood/SwiftFormat' + + - name: Run SwiftFormat + run: mint run swiftformat --lint --swiftversion 5.5 . + java: + name: "Java formatting checks" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: axel-op/googlejavaformat-action@v3 + with: + args: "--set-exit-if-changed" + dart: + name: "Dart formatting checks" runs-on: ubuntu-latest steps: @@ -20,7 +44,7 @@ jobs: cd test_integration && flutter pub get && cd .. cd example && flutter pub get && cd .. - - name: 'Check formatting issues in the code' + - name: 'Check Dart formatting issues in the code' run: flutter format --set-exit-if-changed . - name: 'Flutter analyze help' From df021bd74da02da0169aea044de07c80786cc480 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:11:45 +0000 Subject: [PATCH 07/51] Use macos & brew instead of ubuntu & mint --- .github/workflows/check.yaml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 9eca12ccb..8417b02ac 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -7,19 +7,13 @@ on: jobs: swift: name: "Swift formatting checks" - runs-on: ubuntu-latest + runs-on: macos-latest steps: - - name: 'Build and install Mint' - run: | - git clone https://github.com/yonaskolb/Mint.git - cd Mint - make - - name: 'Install SwiftFormat' - run: 'mint install nicklockwood/SwiftFormat' + run: 'brew install swiftformat' - name: Run SwiftFormat - run: mint run swiftformat --lint --swiftversion 5.5 . + run: swiftformat --lint --swiftversion 5.5 . java: name: "Java formatting checks" runs-on: ubuntu-latest From 8551b4dc1902577c75ccceb30d6ce1f224514318 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:18:24 +0000 Subject: [PATCH 08/51] Rename job --- .github/workflows/check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 8417b02ac..0f97e159f 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -23,7 +23,7 @@ jobs: with: args: "--set-exit-if-changed" dart: - name: "Dart formatting checks" + name: "Dart formatting and analyzer checks" runs-on: ubuntu-latest steps: From 9ad8441f3aa59314eb2b925a8cf70e2de3cebb28 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:19:34 +0000 Subject: [PATCH 09/51] Introduce some temporary formatting issues to confirm all formatting checks fail --- .../main/java/io/ably/flutter/plugin/AblyMessageCodec.java | 1 + ios/Classes/codec/CryptoCodec.swift | 6 ++++-- lib/src/platform/src/codec.dart | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java index c73a318c4..ab0c68303 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java @@ -416,6 +416,7 @@ private PlatformClientOptions decodeClientOptions(Map jsonMap) { return new PlatformClientOptions( o, + jsonMap.containsKey(PlatformConstants.TxClientOptions.hasAuthCallback) ? ((boolean) jsonMap.get(PlatformConstants.TxClientOptions.hasAuthCallback)) : false); diff --git a/ios/Classes/codec/CryptoCodec.swift b/ios/Classes/codec/CryptoCodec.swift index 67d50a960..2ba223cf2 100644 --- a/ios/Classes/codec/CryptoCodec.swift +++ b/ios/Classes/codec/CryptoCodec.swift @@ -6,8 +6,10 @@ public class CryptoCodec: NSObject { public static let readCipherParams: ([String: Any]) -> ARTCipherParams = { dictionary in let algorithm = dictionary[TxCipherParams_iosAlgorithm] as! String let key = dictionary[TxCipherParams_iosKey] as! FlutterStandardTypedData - return ARTCipherParams(algorithm: algorithm, key: key.data as NSData) - } + return ARTCipherParams(algorithm: algorithm, + key: key.data as NSData) + } + @objc public static let encodeCipherParams: (ARTCipherParams) -> [String: Any] = { cipherParams in diff --git a/lib/src/platform/src/codec.dart b/lib/src/platform/src/codec.dart index 5f3988a7b..049ae0694 100644 --- a/lib/src/platform/src/codec.dart +++ b/lib/src/platform/src/codec.dart @@ -68,6 +68,7 @@ class Codec extends StandardMessageCodec { _CodecPair(_encodeTokenRequest, null), CodecTypes.restChannelOptions: _CodecPair(_encodeRestChannelOptions, null), + CodecTypes.realtimeChannelOptions: _CodecPair( _encodeRealtimeChannelOptions, null, From d9195232a9be2b2fea1930a638961cd93f930c72 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:23:45 +0000 Subject: [PATCH 10/51] Update args for java formatter --- .github/workflows/check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 0f97e159f..b46748722 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v2 - uses: axel-op/googlejavaformat-action@v3 with: - args: "--set-exit-if-changed" + args: "--set-exit-if-changed --replace" # We use --replace so that the files are not printed to stdout. dart: name: "Dart formatting and analyzer checks" runs-on: ubuntu-latest From 01ce78179643ea47f9e201b865a22b34e286ef86 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:28:43 +0000 Subject: [PATCH 11/51] Revert "Introduce some temporary formatting issues to confirm all formatting checks fail" This reverts commit 9ad8441f3aa59314eb2b925a8cf70e2de3cebb28. --- .../main/java/io/ably/flutter/plugin/AblyMessageCodec.java | 1 - ios/Classes/codec/CryptoCodec.swift | 6 ++---- lib/src/platform/src/codec.dart | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java index ab0c68303..c73a318c4 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java @@ -416,7 +416,6 @@ private PlatformClientOptions decodeClientOptions(Map jsonMap) { return new PlatformClientOptions( o, - jsonMap.containsKey(PlatformConstants.TxClientOptions.hasAuthCallback) ? ((boolean) jsonMap.get(PlatformConstants.TxClientOptions.hasAuthCallback)) : false); diff --git a/ios/Classes/codec/CryptoCodec.swift b/ios/Classes/codec/CryptoCodec.swift index 2ba223cf2..67d50a960 100644 --- a/ios/Classes/codec/CryptoCodec.swift +++ b/ios/Classes/codec/CryptoCodec.swift @@ -6,10 +6,8 @@ public class CryptoCodec: NSObject { public static let readCipherParams: ([String: Any]) -> ARTCipherParams = { dictionary in let algorithm = dictionary[TxCipherParams_iosAlgorithm] as! String let key = dictionary[TxCipherParams_iosKey] as! FlutterStandardTypedData - return ARTCipherParams(algorithm: algorithm, - key: key.data as NSData) - } - + return ARTCipherParams(algorithm: algorithm, key: key.data as NSData) + } @objc public static let encodeCipherParams: (ARTCipherParams) -> [String: Any] = { cipherParams in diff --git a/lib/src/platform/src/codec.dart b/lib/src/platform/src/codec.dart index 049ae0694..5f3988a7b 100644 --- a/lib/src/platform/src/codec.dart +++ b/lib/src/platform/src/codec.dart @@ -68,7 +68,6 @@ class Codec extends StandardMessageCodec { _CodecPair(_encodeTokenRequest, null), CodecTypes.restChannelOptions: _CodecPair(_encodeRestChannelOptions, null), - CodecTypes.realtimeChannelOptions: _CodecPair( _encodeRealtimeChannelOptions, null, From 9ea9f6f5ab80952e4d2baa33b771ca420854b1cd Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:29:12 +0000 Subject: [PATCH 12/51] Introduce formatting issue in Swift to test CI formatter --- ios/Classes/codec/CryptoCodec.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Classes/codec/CryptoCodec.swift b/ios/Classes/codec/CryptoCodec.swift index 67d50a960..ef5abac86 100644 --- a/ios/Classes/codec/CryptoCodec.swift +++ b/ios/Classes/codec/CryptoCodec.swift @@ -4,7 +4,7 @@ import Foundation public class CryptoCodec: NSObject { @objc public static let readCipherParams: ([String: Any]) -> ARTCipherParams = { dictionary in - let algorithm = dictionary[TxCipherParams_iosAlgorithm] as! String + let algorithm = dictionary[TxCipherParams_iosAlgorithm] as! String let key = dictionary[TxCipherParams_iosKey] as! FlutterStandardTypedData return ARTCipherParams(algorithm: algorithm, key: key.data as NSData) } From 04f8be8ce44c532e9f0be61a41234f14f6b27aba Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:31:28 +0000 Subject: [PATCH 13/51] Add checkout action --- .github/workflows/check.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index b46748722..2ac527a8a 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -9,6 +9,9 @@ jobs: name: "Swift formatting checks" runs-on: macos-latest steps: + - name: Checkout + uses: actions/checkout@v2 + - name: 'Install SwiftFormat' run: 'brew install swiftformat' From f76909dcec8cee45feaf862afecb99a47e0b0732 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 29 Nov 2021 22:33:33 +0000 Subject: [PATCH 14/51] Revert "Introduce formatting issue in Swift to test CI formatter" This reverts commit 9ea9f6f5ab80952e4d2baa33b771ca420854b1cd. --- ios/Classes/codec/CryptoCodec.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Classes/codec/CryptoCodec.swift b/ios/Classes/codec/CryptoCodec.swift index ef5abac86..67d50a960 100644 --- a/ios/Classes/codec/CryptoCodec.swift +++ b/ios/Classes/codec/CryptoCodec.swift @@ -4,7 +4,7 @@ import Foundation public class CryptoCodec: NSObject { @objc public static let readCipherParams: ([String: Any]) -> ARTCipherParams = { dictionary in - let algorithm = dictionary[TxCipherParams_iosAlgorithm] as! String + let algorithm = dictionary[TxCipherParams_iosAlgorithm] as! String let key = dictionary[TxCipherParams_iosKey] as! FlutterStandardTypedData return ARTCipherParams(algorithm: algorithm, key: key.data as NSData) } From d963fda6db12dc0292db7380a7f44678ac4782d7 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:31:26 +0000 Subject: [PATCH 15/51] Add pre-commit hook and guidance on how to use it --- .githooks/pre-commit | 52 ++++++++++++++++++++++++++++++++++++ .github/workflows/check.yaml | 2 +- CONTRIBUTING.md | 2 ++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 000000000..7580fc0c5 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,52 @@ +#!/bin/sh + +set -e +set -o pipefail + +# This file is saved in $project_directory/.git/hooks/ +MY_PATH=$(pwd) + +echo "Checking formatting of Dart, Swift and Java. This won't format the files." +echo "❓ To format files, run '. format-files.sh'\n" +# Objective-C files are not checked. + +# Redirect output to stderr. +exec 1>&2 + +# Pre-requisites +# 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. +if ! [ -x "$(command -v flutter)" ]; then + echo "🚨 FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 + exit 1 +fi + +# 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. +if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then + echo "🚨 FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; + exit 1; +fi + +# 3. Install using brew by running `brew install swiftformat`. This provides the Swift formatting tool. +if ! [ -x "$(command -v swiftformat)" ]; then + echo "🚨 FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 + exit 1 +fi + +echo "❓ Dart file formatting being checked..." +/opt/flutter/bin/flutter format --set-exit-if-changed $MY_PATH +echo "✅ Dart file formatting checked. \n" + +echo "❓ Java file formatting being checked..." +JAVA_FILES=$(find $MY_PATH -name "*java" -type f -exec ls {} \;) +echo $JAVA_FILES | xargs java \ + --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + -jar $GOOGLE_JAVA_FORMAT_PATH --set-exit-if-changed --dry-run +echo "✅ Java file formatting checked. \n" + +echo "❓ Swift file formatting being checked..." +swiftformat --lint --swiftversion 5.5 $MY_PATH +echo "✅ Swift file formatting checked. \n" \ No newline at end of file diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 2ac527a8a..cef8b0d08 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v2 - uses: axel-op/googlejavaformat-action@v3 with: - args: "--set-exit-if-changed --replace" # We use --replace so that the files are not printed to stdout. + args: "--set-exit-if-changed --dry-run" dart: name: "Dart formatting and analyzer checks" runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df09ee79e..51733687d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,6 +19,8 @@ We use Github actions to check code is formatted correctly. You should format your code using the same style to avoid Github CI job failures, since we do not automatically commit and format code. - To format files, run `./format-files.sh`. See the files to see formatting commands for each language, e.g. `flutter format .` for Dart code. - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. +- To automatically check formatting before committing, you can use the git hook shared in this repo. + - Run `git config core.hooksPath .githooks` ## High level architecture From c23801675452a81f6d88c37fd32901f74dc6e7b8 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:32:38 +0000 Subject: [PATCH 16/51] Add note about SourceTree --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 51733687d..818cff5af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ We use Github actions to check code is formatted correctly. You should format yo - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. - To automatically check formatting before committing, you can use the git hook shared in this repo. - Run `git config core.hooksPath .githooks` - + - Git hooks don't work well in SourceTree, as per [SourceTree : Hook failing because paths don't seem to be set correctly](https://community.atlassian.com/t5/Bitbucket-questions/SourceTree-Hook-failing-because-paths-don-t-seem-to-be-set/qaq-p/274792). You will need to open SourceTree using `open /Applications/SourceTree.app/Contents/MacOS/SourceTree`. ## High level architecture The code in this repository has been constructed to be From 23104b71a43318400a4c6f7b0fe71c11e502bceb Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:36:21 +0000 Subject: [PATCH 17/51] Remove outdated comment --- .githooks/pre-commit | 1 - 1 file changed, 1 deletion(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 7580fc0c5..93d4eab25 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -3,7 +3,6 @@ set -e set -o pipefail -# This file is saved in $project_directory/.git/hooks/ MY_PATH=$(pwd) echo "Checking formatting of Dart, Swift and Java. This won't format the files." From 252e1ce1a486098ed799804314c13a1ac36de1f9 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:37:23 +0000 Subject: [PATCH 18/51] Update message --- .githooks/pre-commit | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 93d4eab25..1268de8fb 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -5,9 +5,8 @@ set -o pipefail MY_PATH=$(pwd) -echo "Checking formatting of Dart, Swift and Java. This won't format the files." -echo "❓ To format files, run '. format-files.sh'\n" -# Objective-C files are not checked. +echo "Checking formatting of Dart, Swift and Java files, without modifying them." +echo "❓ To format files, run '. format-files.sh'\n" # Objective-C files are not checked. # Redirect output to stderr. exec 1>&2 From cd6900120bac8953c5c2bce27e6761bb1d9c3783 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:16:47 +0000 Subject: [PATCH 19/51] Rename .githooks directory to `hooks` --- CONTRIBUTING.md | 2 +- {.githooks => hooks}/pre-commit | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {.githooks => hooks}/pre-commit (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 818cff5af..6bedb0586 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ We use Github actions to check code is formatted correctly. You should format yo - To format files, run `./format-files.sh`. See the files to see formatting commands for each language, e.g. `flutter format .` for Dart code. - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. - To automatically check formatting before committing, you can use the git hook shared in this repo. - - Run `git config core.hooksPath .githooks` + - Run `git config core.hooksPath hooks` - Git hooks don't work well in SourceTree, as per [SourceTree : Hook failing because paths don't seem to be set correctly](https://community.atlassian.com/t5/Bitbucket-questions/SourceTree-Hook-failing-because-paths-don-t-seem-to-be-set/qaq-p/274792). You will need to open SourceTree using `open /Applications/SourceTree.app/Contents/MacOS/SourceTree`. ## High level architecture diff --git a/.githooks/pre-commit b/hooks/pre-commit similarity index 100% rename from .githooks/pre-commit rename to hooks/pre-commit From 80b6265d7be9658cfcb1bb0aa2f78a1b8e87c0c5 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:18:49 +0000 Subject: [PATCH 20/51] Check `android` files only, to avoid checking formatting for dependencies and example app --- format-files.sh | 2 +- hooks/pre-commit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/format-files.sh b/format-files.sh index efe23326b..ac21f9c61 100755 --- a/format-files.sh +++ b/format-files.sh @@ -28,7 +28,7 @@ flutter format $MY_PATH echo "Formatted Dart 🐥 files.\n" echo "Formatting Java 🌰 files..." -JAVA_FILES=$(find $MY_PATH -name "*java" -type f -exec ls {} \;) +JAVA_FILES=$(find $MY_PATH/android -name "*java" -type f -exec ls {} \;) echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ diff --git a/hooks/pre-commit b/hooks/pre-commit index 1268de8fb..fcdb9b91c 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -35,7 +35,7 @@ echo "❓ Dart file formatting being checked..." echo "✅ Dart file formatting checked. \n" echo "❓ Java file formatting being checked..." -JAVA_FILES=$(find $MY_PATH -name "*java" -type f -exec ls {} \;) +JAVA_FILES=$(find $MY_PATH/android -name "*java" -type f -exec ls {} \;) echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ From 0689c364a9abdfde0517c27666c1c0b269a3d82f Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:30:20 +0000 Subject: [PATCH 21/51] Move dependency checks into a separate file --- format-files-dependencies.sh | 22 ++++++++++++++++++++++ format-files.sh | 19 +------------------ hooks/pre-commit | 19 +------------------ 3 files changed, 24 insertions(+), 36 deletions(-) create mode 100644 format-files-dependencies.sh diff --git a/format-files-dependencies.sh b/format-files-dependencies.sh new file mode 100644 index 000000000..8248603a8 --- /dev/null +++ b/format-files-dependencies.sh @@ -0,0 +1,22 @@ + +echo "Checking file formatting dependencies are installed..." + +# 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. +if ! [ -x "$(command -v flutter)" ]; then + echo "🚨 FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 + exit 1 +fi + +# 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. +if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then + echo "🚨 FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; + exit 1; +fi + +# 3. Install using brew by running `brew install swiftformat`. This provides the Swift formatting tool. +if ! [ -x "$(command -v swiftformat)" ]; then + echo "🚨 FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 + exit 1 +fi + +echo " ✅ File formatting dependencies available.\n" \ No newline at end of file diff --git a/format-files.sh b/format-files.sh index ac21f9c61..fea9dad92 100755 --- a/format-files.sh +++ b/format-files.sh @@ -4,24 +4,7 @@ set -e MY_PATH=$(dirname "$0") -# Pre-requisites -# 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. -if ! [ -x "$(command -v flutter)" ]; then - echo "🚨 FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 - exit 1 -fi - -# 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. -if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then - echo "🚨 FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; - exit 1; -fi - -# 3. Install using brew by running `brew install swiftformat`. This provides the Swift formatting tool. -if ! [ -x "$(command -v swiftformat)" ]; then - echo "🚨 FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 - exit 1 -fi +. format-files-dependencies.sh echo "Formatting Dart 🐣 files..." flutter format $MY_PATH diff --git a/hooks/pre-commit b/hooks/pre-commit index fcdb9b91c..b71d9f924 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -11,24 +11,7 @@ echo "❓ To format files, run '. format-files.sh'\n" # Objective-C files are no # Redirect output to stderr. exec 1>&2 -# Pre-requisites -# 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. -if ! [ -x "$(command -v flutter)" ]; then - echo "🚨 FAILURE: Missing dependency, you must install Flutter, download it from https://docs.flutter.dev/get-started/install/macos" >&2 - exit 1 -fi - -# 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. -if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then - echo "🚨 FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; - exit 1; -fi - -# 3. Install using brew by running `brew install swiftformat`. This provides the Swift formatting tool. -if ! [ -x "$(command -v swiftformat)" ]; then - echo "🚨 FAILURE: Missing dependency, you must install swiftformat, e.g. run 'brew install swiftformat'" >&2 - exit 1 -fi +. format-files-dependencies.sh echo "❓ Dart file formatting being checked..." /opt/flutter/bin/flutter format --set-exit-if-changed $MY_PATH From ba7f505c6c35c3b250c34c8dbdf98a965d348603 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:32:28 +0000 Subject: [PATCH 22/51] Replace emojis with simpler messages --- format-files.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/format-files.sh b/format-files.sh index fea9dad92..67add2e33 100755 --- a/format-files.sh +++ b/format-files.sh @@ -6,11 +6,11 @@ MY_PATH=$(dirname "$0") . format-files-dependencies.sh -echo "Formatting Dart 🐣 files..." +echo "Formatting Dart files..." flutter format $MY_PATH -echo "Formatted Dart 🐥 files.\n" +echo " ✅ Formatted Dart files.\n" -echo "Formatting Java 🌰 files..." +echo "Formatting Java files..." JAVA_FILES=$(find $MY_PATH/android -name "*java" -type f -exec ls {} \;) echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ @@ -19,9 +19,9 @@ echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ -jar $GOOGLE_JAVA_FORMAT_PATH --replace -echo "Formatted Java ☕️ files.\n" +echo " ✅ Formatted Java files.\n" -echo "Formatting Swift 💨 files..." +echo "Formatting Swift files..." SWIFT_VERSION=5.5 swiftformat --swiftversion $SWIFT_VERSION $MY_PATH -echo "Formatted Swift 🌬 files.\n" +echo " ✅ Formatted Swift files.\n" From 12a10db93877b4383481a9c4ccfa0ac6cac853fc Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:40:30 +0000 Subject: [PATCH 23/51] Allow scripts to be run from any directory --- format-files-dependencies.sh | 0 format-files.sh | 2 +- hooks/pre-commit | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 format-files-dependencies.sh diff --git a/format-files-dependencies.sh b/format-files-dependencies.sh old mode 100644 new mode 100755 diff --git a/format-files.sh b/format-files.sh index 67add2e33..873259eba 100755 --- a/format-files.sh +++ b/format-files.sh @@ -4,7 +4,7 @@ set -e MY_PATH=$(dirname "$0") -. format-files-dependencies.sh +bash $MY_PATH/format-files-dependencies.sh echo "Formatting Dart files..." flutter format $MY_PATH diff --git a/hooks/pre-commit b/hooks/pre-commit index b71d9f924..fac8ce50f 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -11,7 +11,7 @@ echo "❓ To format files, run '. format-files.sh'\n" # Objective-C files are no # Redirect output to stderr. exec 1>&2 -. format-files-dependencies.sh +bash $MY_PATH/format-files-dependencies.sh echo "❓ Dart file formatting being checked..." /opt/flutter/bin/flutter format --set-exit-if-changed $MY_PATH From 21f7e4295c24eb676ee0f0475084e457d44be54c Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:42:00 +0000 Subject: [PATCH 24/51] Remove whitespace in log lines --- format-files-dependencies.sh | 2 +- format-files.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/format-files-dependencies.sh b/format-files-dependencies.sh index 8248603a8..90173ed89 100755 --- a/format-files-dependencies.sh +++ b/format-files-dependencies.sh @@ -19,4 +19,4 @@ if ! [ -x "$(command -v swiftformat)" ]; then exit 1 fi -echo " ✅ File formatting dependencies available.\n" \ No newline at end of file +echo "✅ File formatting dependencies exist.\n" \ No newline at end of file diff --git a/format-files.sh b/format-files.sh index 873259eba..c2f8966e6 100755 --- a/format-files.sh +++ b/format-files.sh @@ -8,7 +8,7 @@ bash $MY_PATH/format-files-dependencies.sh echo "Formatting Dart files..." flutter format $MY_PATH -echo " ✅ Formatted Dart files.\n" +echo "✅ Formatted Dart files.\n" echo "Formatting Java files..." JAVA_FILES=$(find $MY_PATH/android -name "*java" -type f -exec ls {} \;) @@ -19,9 +19,9 @@ echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ -jar $GOOGLE_JAVA_FORMAT_PATH --replace -echo " ✅ Formatted Java files.\n" +echo "✅ Formatted Java files.\n" echo "Formatting Swift files..." SWIFT_VERSION=5.5 swiftformat --swiftversion $SWIFT_VERSION $MY_PATH -echo " ✅ Formatted Swift files.\n" +echo "✅ Formatted Swift files.\n" From 57acd8317ba752260c9132285241b7aa85ea4c11 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:43:04 +0000 Subject: [PATCH 25/51] Replace `bash` with `source` in script --- format-files-dependencies.sh | 2 +- format-files.sh | 2 +- hooks/pre-commit | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/format-files-dependencies.sh b/format-files-dependencies.sh index 90173ed89..a897829e7 100755 --- a/format-files-dependencies.sh +++ b/format-files-dependencies.sh @@ -1,5 +1,5 @@ -echo "Checking file formatting dependencies are installed..." +echo "❓ Checking file formatting dependencies are installed..." # 1. You should have Flutter installed (e.g. in `/opt/flutter`) and on your PATH. This provides the Dart formatting tool, `flutter format`. if ! [ -x "$(command -v flutter)" ]; then diff --git a/format-files.sh b/format-files.sh index c2f8966e6..ea1792b8f 100755 --- a/format-files.sh +++ b/format-files.sh @@ -4,7 +4,7 @@ set -e MY_PATH=$(dirname "$0") -bash $MY_PATH/format-files-dependencies.sh +source $MY_PATH/format-files-dependencies.sh echo "Formatting Dart files..." flutter format $MY_PATH diff --git a/hooks/pre-commit b/hooks/pre-commit index fac8ce50f..78c1d4a0c 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -6,12 +6,12 @@ set -o pipefail MY_PATH=$(pwd) echo "Checking formatting of Dart, Swift and Java files, without modifying them." -echo "❓ To format files, run '. format-files.sh'\n" # Objective-C files are not checked. +echo "To format files, run '. format-files.sh'\n" # Objective-C files are not checked. # Redirect output to stderr. exec 1>&2 -bash $MY_PATH/format-files-dependencies.sh +source $MY_PATH/format-files-dependencies.sh echo "❓ Dart file formatting being checked..." /opt/flutter/bin/flutter format --set-exit-if-changed $MY_PATH From 828ce6fcbf617f774ef995a51c60cebf07068861 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Sat, 4 Dec 2021 15:47:29 +0000 Subject: [PATCH 26/51] Use emoji to be clearer --- format-files.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/format-files.sh b/format-files.sh index ea1792b8f..38de99878 100755 --- a/format-files.sh +++ b/format-files.sh @@ -6,11 +6,11 @@ MY_PATH=$(dirname "$0") source $MY_PATH/format-files-dependencies.sh -echo "Formatting Dart files..." +echo "❓ Formatting Dart files..." flutter format $MY_PATH echo "✅ Formatted Dart files.\n" -echo "Formatting Java files..." +echo "❓ Formatting Java files..." JAVA_FILES=$(find $MY_PATH/android -name "*java" -type f -exec ls {} \;) echo $JAVA_FILES | xargs java \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ @@ -21,7 +21,7 @@ echo $JAVA_FILES | xargs java \ -jar $GOOGLE_JAVA_FORMAT_PATH --replace echo "✅ Formatted Java files.\n" -echo "Formatting Swift files..." +echo "❓ Formatting Swift files..." SWIFT_VERSION=5.5 swiftformat --swiftversion $SWIFT_VERSION $MY_PATH echo "✅ Formatted Swift files.\n" From 38afe168b377024c10bc1788fb6af96b2c1b27dc Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Mon, 6 Dec 2021 08:20:36 +0000 Subject: [PATCH 27/51] Elaborate on device deactivation documentation --- PushNotifications.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PushNotifications.md b/PushNotifications.md index bf2be484a..f3ed1ab0f 100644 --- a/PushNotifications.md +++ b/PushNotifications.md @@ -358,9 +358,11 @@ Take a look at the example app platform specific code to handle messages. For iO **iOS:** Some iOS dependencies perform techniques such as [method swizzling](https://nshipster.com/method-swizzling/) which break other iOS dependencies and Flutter Plugin packages. -### Deactivating the device +## Device deactivation -Do this only if you do not want the device to receive push notifications at all. You usually do not need to run this at all. +Do this only if you do not want the device to receive push notifications at all. You usually do not need to run this at all, and especially don't need to deactivate and re-activate on every launch. + +Like device activation, the `Future` returned by `activate` is not guaranteed to complete quickly. ```dart try { From abb0dfc96989cd166c72d9dee7b9b62a737854ef Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:44:23 +0000 Subject: [PATCH 28/51] Improve error message if google-java-format is not installed --- format-files-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/format-files-dependencies.sh b/format-files-dependencies.sh index a897829e7..67502f699 100755 --- a/format-files-dependencies.sh +++ b/format-files-dependencies.sh @@ -9,7 +9,7 @@ fi # 2. Download the release from https://github.com/google/google-java-format/releases, and update your environment variable. This provides the Java formatting tool. if [ "$GOOGLE_JAVA_FORMAT_PATH" = "" ]; then - echo "🚨 FAILURE: You must download https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded."; + echo "🚨 FAILURE: You must download the latest 'all-deps.jar' from https://github.com/google/google-java-format/releases and set GOOGLE_JAVA_FORMAT_PATH to the jar you downloaded, e.g. add the following to ~/.zshrc: 'export GOOGLE_JAVA_FORMAT_PATH=path/to/google_java_format_path.jar'"; exit 1; fi From 0fe71e9ac791698bea7f997284884739aaef9a0d Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:48:07 +0000 Subject: [PATCH 29/51] Elaborate on run/debug and formatting scripts --- CONTRIBUTING.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6bedb0586..0f45b5946 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,17 +7,23 @@ - Install Android Studio, and then in Android Studio, install the [Flutter plugin](https://plugins.jetbrains.com/plugin/9212-flutter). - Though you can debug Dart code from Visual Studio Code, you cannot debug the Android code. - Download the dependencies listed in `pubspec.yaml` by running `flutter pub get` -- If using Android Studio, delete the `.packages` file. It is a deprecated autogenerated file which confuses Android Studio into thinking all files are build outputs instead of source files. -- If you have any issues, run `flutter doctor` and begin investigating. -- Write, test and debug platform (Android/iOS) code: - - Android: You can open the Android code in a separate window. In the Flutter project window, launch the application in debug mode in Android Studio. Then, in the Android project window, attach the debugger to the Android process. You can also do this with IntelliJ Idea. - - iOS: To debug iOS code, you must use and set breakpoints in Xcode or AppCode. In Android Studio or command line, run the flutter run --dart-define` command you would usually run. This ensures when you build with Xcode, the environment variables are available to the app. Then, re-run the application using Xcode. Then, in Android Studio, click `Run` > `Flutter Attach`, or click the `Flutter Attach` button. - - AppCode: AppCode is much better at navigating the code base, and refactoring the code. + - Files have a yellow background in Android Studio's project [tool window](https://developer.android.com/studio/intro) because they are marked as a library. This is intended as per [this IntelliJ Flutter plugin issue](https://github.com/flutter/flutter-intellij/issues/5596), but may be confusing or potentially limiting. You can delete the `.packages` file every time `flutter pub get` is run. This is optional. It is a deprecated autogenerated file which confuses Android Studio into thinking all files are build outputs instead of source files. +- Run `flutter doctor` to confirm your environment is setup correctly. +- Edit platform (Android/iOS) code, including package files and example app files: + - **Android:** You can edit Android code by opening the example app with another Android Studio window. This example project shows all gradle modules in the repository, including the example app, the Ably Flutter package, but also all other packages installed in your `pubspec.yaml` which provide gradle modules. + - **iOS:** You can edit iOS code by opening the example app with [AppCode](https://www.jetbrains.com/objc/) or [Xcode](https://developer.apple.com/xcode/). The example project has access to the main plugin iOS code via symlinks. + - Recommended usage of Xcode and AppCode: + - Xcode: For modifying configuration (e.g. signing and capabilities, `Info.plist`) or other features not supported by AppCode + - AppCode: For code refactoring. +- Run / debug (Android/iOS) code: + - You cannot run packages independently, so Flutter package plugins include an example app to use the package. + - **Android:** In the Flutter project window, launch the application in debug mode in Android Studio. Then, in the Android project window, attach the debugger to the Android process. You can also do this with IntelliJ Idea. + - **iOS:** Both AppCode and Xcode can build and debug your flutter application. `flutter run` will automatically run `pod install` in the `example/ios` folder, but if you don't use `flutter run`, you would have to remember to run `pod install`. To use breakpoints, set them in AppCode or Xcode. ## Making changes We use Github actions to check code is formatted correctly. You should format your code using the same style to avoid Github CI job failures, since we do not automatically commit and format code. -- To format files, run `./format-files.sh`. See the files to see formatting commands for each language, e.g. `flutter format .` for Dart code. +- To format files, run `./format-files.sh`. It requires a few tools to be installed. Try to run `./format-files.sh` or read `format-files.sh` to detemrine the dependencies, e.g. `flutter format .` for Dart code. - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. - To automatically check formatting before committing, you can use the git hook shared in this repo. - Run `git config core.hooksPath hooks` From a4bf72ceff0fe3066b17ceb73b9134be1095d7ed Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:48:48 +0000 Subject: [PATCH 30/51] Only attempt to format/lint source code files, avoiding symlinked files provided by other pods --- format-files.sh | 3 ++- hooks/pre-commit | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/format-files.sh b/format-files.sh index 38de99878..2fc3529f9 100755 --- a/format-files.sh +++ b/format-files.sh @@ -23,5 +23,6 @@ echo "✅ Formatted Java files.\n" echo "❓ Formatting Swift files..." SWIFT_VERSION=5.5 -swiftformat --swiftversion $SWIFT_VERSION $MY_PATH +swiftformat --swiftversion $SWIFT_VERSION $MY_PATH/ios +swiftformat --swiftversion $SWIFT_VERSION $MY_PATH/example/ios/Runner echo "✅ Formatted Swift files.\n" diff --git a/hooks/pre-commit b/hooks/pre-commit index 78c1d4a0c..1c5db5cd9 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -29,5 +29,7 @@ echo $JAVA_FILES | xargs java \ echo "✅ Java file formatting checked. \n" echo "❓ Swift file formatting being checked..." -swiftformat --lint --swiftversion 5.5 $MY_PATH -echo "✅ Swift file formatting checked. \n" \ No newline at end of file +SWIFT_VERSION=5.5 +swiftformat --lint --swiftversion $SWIFT_VERSION $MY_PATH/ios +swiftformat --lint --swiftversion $SWIFT_VERSION $MY_PATH/example/ios/Runner +echo "✅ Swift file formatting checked. \n" From 6fbe8faa4969305b00e23aead5d738151f3de30b Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:50:42 +0000 Subject: [PATCH 31/51] Add more notes about pre-commit script --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f45b5946..b47f8a620 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,7 @@ We use Github actions to check code is formatted correctly. You should format yo - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. - To automatically check formatting before committing, you can use the git hook shared in this repo. - Run `git config core.hooksPath hooks` + - This is the "linting" version of `./format-files.sh`, and does not format any code. - Git hooks don't work well in SourceTree, as per [SourceTree : Hook failing because paths don't seem to be set correctly](https://community.atlassian.com/t5/Bitbucket-questions/SourceTree-Hook-failing-because-paths-don-t-seem-to-be-set/qaq-p/274792). You will need to open SourceTree using `open /Applications/SourceTree.app/Contents/MacOS/SourceTree`. ## High level architecture From eeb2f90addd37bb61e2570e62a2fb65f5602e6cc Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:58:16 +0000 Subject: [PATCH 32/51] Fix typo and add more info to contributing.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b47f8a620..7a2825ba8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ ## Making changes We use Github actions to check code is formatted correctly. You should format your code using the same style to avoid Github CI job failures, since we do not automatically commit and format code. -- To format files, run `./format-files.sh`. It requires a few tools to be installed. Try to run `./format-files.sh` or read `format-files.sh` to detemrine the dependencies, e.g. `flutter format .` for Dart code. +- To format files, run `./format-files.sh`. It requires a few tools to be installed (e.g. `flutter`, `swiftformat` and `google-java-format`). Try to run `./format-files.sh` or read `format-files.sh` to discover and install the dependencies. - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. - To automatically check formatting before committing, you can use the git hook shared in this repo. - Run `git config core.hooksPath hooks` From 77ee8cbbebbf5efc24aa5e5a4db78245735e0482 Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 15:25:21 +0000 Subject: [PATCH 33/51] Move out 2 bullet points into sections --- CONTRIBUTING.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7a2825ba8..83d22f23d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,16 +9,21 @@ - Download the dependencies listed in `pubspec.yaml` by running `flutter pub get` - Files have a yellow background in Android Studio's project [tool window](https://developer.android.com/studio/intro) because they are marked as a library. This is intended as per [this IntelliJ Flutter plugin issue](https://github.com/flutter/flutter-intellij/issues/5596), but may be confusing or potentially limiting. You can delete the `.packages` file every time `flutter pub get` is run. This is optional. It is a deprecated autogenerated file which confuses Android Studio into thinking all files are build outputs instead of source files. - Run `flutter doctor` to confirm your environment is setup correctly. -- Edit platform (Android/iOS) code, including package files and example app files: - - **Android:** You can edit Android code by opening the example app with another Android Studio window. This example project shows all gradle modules in the repository, including the example app, the Ably Flutter package, but also all other packages installed in your `pubspec.yaml` which provide gradle modules. - - **iOS:** You can edit iOS code by opening the example app with [AppCode](https://www.jetbrains.com/objc/) or [Xcode](https://developer.apple.com/xcode/). The example project has access to the main plugin iOS code via symlinks. - - Recommended usage of Xcode and AppCode: - - Xcode: For modifying configuration (e.g. signing and capabilities, `Info.plist`) or other features not supported by AppCode - - AppCode: For code refactoring. -- Run / debug (Android/iOS) code: - - You cannot run packages independently, so Flutter package plugins include an example app to use the package. - - **Android:** In the Flutter project window, launch the application in debug mode in Android Studio. Then, in the Android project window, attach the debugger to the Android process. You can also do this with IntelliJ Idea. - - **iOS:** Both AppCode and Xcode can build and debug your flutter application. `flutter run` will automatically run `pod install` in the `example/ios` folder, but if you don't use `flutter run`, you would have to remember to run `pod install`. To use breakpoints, set them in AppCode or Xcode. + +## Editing and writing platform (Android/iOS) code + +- You can edit both example app and package code in the same IDE (Xcode, Android Studio or AppCode) window. +- **Android:** You can edit Android code by opening the example app with another Android Studio window. This example project shows all gradle modules in the repository, including the example app, the Ably Flutter package, but also all other packages installed in your `pubspec.yaml` which provide gradle modules. +- **iOS:** You can edit iOS code by opening the example app with [AppCode](https://www.jetbrains.com/objc/) or [Xcode](https://developer.apple.com/xcode/). The example project has access to the main plugin iOS code via symlinks. + - Recommended usage of Xcode and AppCode: + - Xcode: For modifying configuration (e.g. signing and capabilities, `Info.plist`) or other features not supported by AppCode + - AppCode: For writing code, refactoring or debugging. + +## Runing and debugging (Android/iOS) code + +- You cannot run packages independently, so Flutter package plugins include an example app to use the package. +- **Android:** In the Flutter project window, launch the application in debug mode in Android Studio. Then, in the Android project window, attach the debugger to the Android process. You can also do this with IntelliJ Idea. +- **iOS:** Both AppCode and Xcode can build and debug your flutter application. To use breakpoints, set them in AppCode or Xcode, but not Android Studio. **Warning:** `flutter run` will automatically run `pod install` in the `example/ios` folder, but if you don't use `flutter run` and use Xcode or AppCode, you may face Cocoapods errors if any dependencies are added or removed, and will need to run `pod install`. ## Making changes @@ -27,7 +32,6 @@ We use Github actions to check code is formatted correctly. You should format yo - To run this command successfully, you need to setup your environment. Read `format-files.sh` for more information. - To automatically check formatting before committing, you can use the git hook shared in this repo. - Run `git config core.hooksPath hooks` - - This is the "linting" version of `./format-files.sh`, and does not format any code. - Git hooks don't work well in SourceTree, as per [SourceTree : Hook failing because paths don't seem to be set correctly](https://community.atlassian.com/t5/Bitbucket-questions/SourceTree-Hook-failing-because-paths-don-t-seem-to-be-set/qaq-p/274792). You will need to open SourceTree using `open /Applications/SourceTree.app/Contents/MacOS/SourceTree`. ## High level architecture From 2cfab16ca29fc0ed158d643c4f8342c7ed95b8bc Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 15:31:39 +0000 Subject: [PATCH 34/51] Add link to docs --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83d22f23d..95335f9f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ There are 3 types of "refreshes" you might see in a Flutter app: - **Hot restart:** The Flutter application is restarted, but the host application (Android and iOS apps which host the Flutter application) does not. - State of the flutter application is reset. This means fields are all reset to their default values (or null). - This also means we must remember to clear the state in the host application when the app hot restarts. We do this by calling `await methodChannel.invokeMethod(PlatformMethod.resetAblyClients);`. - - From Flutter documentation: + - From [Flutter documentation](https://docs.flutter.dev/development/tools/hot-reload): > With a hot restart, the program starts from the beginning, executes the new version of main(), and builds a widget tree that displays the text Hello. - **App restart:** The entire application is restarted, clearing the state of both the Flutter application and the host application (Android and iOS apps). From 67d4d3239a20c474ba89c51df861f01c1ad2bc1e Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 20:56:10 +0000 Subject: [PATCH 35/51] Add more detail to contributing guide --- CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95335f9f3..8b0aec071 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,27 +64,48 @@ appropriate for programmer's failures on the Dart side of things. But time will ### Push Notifications -#### Push Notifications activation and deactivation +Read [Push Notification documentation](https://ably.com/documentation/general/push) for more information about what these features do. This document focuses on implementation. -The platform SDKs ([ably-android](https://github.com/ably/ably-java) and [ably-cocoa](https://github.com/ably/ably-cocoa)) enable users to check if device activation, deactivation, or registration update fails. On Android, these errors are sent in Intents which users should register for at runtime. In Cocoa, errors are returned through `ARTPushRegistererDelegate` methods. However, in both SDKs, this error does not always return quickly. For example, if there was no internet connection, then `Push.activate()` will not throw an error, it will just block forever, because errors are not provided by the SDKs. Once an internet connection is made, the Intent will be sent and delegate methods will be called. +#### Device activation -Ably Flutter does this by passing a reference to the `FlutterResult` used to pass back the result to the Dart side, when the activation or deactivation completes. This makes it convenient for users: they can `await push.activate()`. However, users should not rely on this Future completing, in the case of network issues. +- **Android:** The result (success or error) are sent via Intents which users should register for at runtime. In the case of activation, users listen for an intent with the `io.ably.broadcast.PUSH_ACTIVATE` action. +- **iOS:** Errors are returned through ``ARTPushRegistererDelegate#didActivateAblyPush`` methods. However, in both SDKs, this error does not always return quickly. For example, if there was no internet connection, then `Push.activate()` will not throw an error, it will just block forever, because errors are not provided by the SDKs. Once an internet connection is made, the Intent will be sent and delegate methods will be called. + +Ably Flutter does this by passing a reference to the `FlutterResult` used to pass back the result to the Dart side, when the activation or deactivation completes. This makes it convenient for users: they can `await push.activate()`. However, users should not rely on this Future completing, in the case of network issues. + +#### Device deactivation + +- **Android:**: The implementation is similar to `activate`, but the result is provided via an intent with `io.ably.broadcast.PUSH_DEACTIVATE` action. +- **iOS:** The implementation is similar to `deactivate`, but the result is provided in the `ARTPushRegistererDelegate#didDeactivateAblyPush` method. + +#### Device registration update + +The users application (and therefore Ably Flutter) may be provided with a new device token when one expires. The SDK would then update Ably servers with the device token. However, this might fail. Users will only be able be told if the update fails, but not if it succeeds. However, because this method is not invoked by the user, but instead the device token is provided by the OS method, the only way a user can find out about an error is if they listen to the `Push#onUpdateFailed` stream. #### Notification tap handling -Android's Firebase Messaging library enables users to select the Intent action used when the automatically-generated notification is tapped by the user. Users can do this by setting `fcm.notification.click_action` in Ably's push payload. However, for this to work, users would need to declare the intent action within their `AndroidManifest.xml`. Therefore, we don't really tell users they can modify `click_action` and configure it. However, they can do so if they wish. +Android's Firebase Messaging library enables users to select the Intent action used when the automatically-generated notification is tapped by the user. Users can do this by setting `fcm.notification.click_action` in Ably's push payload. However, for this to work, users would need to declare the intent action within their `AndroidManifest.xml`. Ably Flutter does not handle these click actions or implement any code to allow users to know which intent was launched on the Android side. Therefore, we don't really tell users they can modify `click_action` and configure it. However, users may attempt to do this by configuring their Android app. + +#### Displaying notifications in foregrounded apps + +iOS enables users to show the notification received remotely even if the app is in the foreground, by calling a delegate method ([`userNotificationCenter(_:willPresent:withCompletionHandler:)`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/1649518-usernotificationcenter)) which the user can choose to show the message to the user, based on the notification content. Android / FCM does not provide this functionality. Users can only configure this behaviour for iOS, by using `PushNotificationEvents#setOnShowNotificationInForeground`. + +#### Why Ably Flutter doesn't use or support [Firebase Messaging](https://pub.dev/packages/firebase_messaging) -#### Notifications generation for Foreground Apps +- Firebase Messaging ignores any messages received on iOS devices which do not originate from FCM, and so will not allow users to handle push notifications on iOS sent from Ably. This rules out using Firebase Messaging on iOS. +- Because of point 1, we cannot even use the Firebase Messaging flutter package. This is because when a package is added as a dependency to `pubspec.yaml`, code is automatically run on the iOS and Android side regardless of any code being called in the Flutter application. This code includes method swizzling, and unfortunately seem to break any push notification handlers implemented by our package. +- Therefore, we needed a way to use Firebase Messaging without using it on iOS. This ruled out [`flutter_apns`](https://github.com/mwaylabs/flutter-apns) and [`firebase_messaging`](https://pub.dev/packages/firebase_messaging) packages. +- Instead, Ably Flutter depends directly on the Firebase Messaging Android library. -iOS enables users to show the notification received remotely even if the app is in the foreground, by calling a delegate method ([`userNotificationCenter(_:willPresent:withCompletionHandler:)`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/1649518-usernotificationcenter)) which the user can choose to show the message to the user, based on the notification content. FCM does not provide this functionality. Users can only configure this behaviour for iOS, by using `PushNotificationEvents#setOnShowNotificationInForeground`. +#### Background message handling -#### Push Notifications Background Message Handling +It is much easier to handle push notifications on iOS than Android. This is because the user's Flutter application is launched automatically in `FlutterViewController` (by being defined in the `Main.storyboard`). This `ViewController` is launched even when the app is just processing a push notification when in the background. This is not the case on Android. The user's Flutter application is only launched when an activity is created, but activities are not created in response to a push notification being received. Therefore, we manually launch the users Flutter application in this case, to allow the user to handle the push notification with their a callback written in Dart in their Flutter application. -Background processing in Flutter is a complicated subject that has not been explored publicly in detail. It involves creating Dart isolates manually (for Android), passing messages back and forth, etc. +A good starting point to understanding background execution of a Flutter application is explained in [Executing Dart in the Background with Flutter Plugins and Geofencing](https://medium.com/flutter/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124), or by reading the [implemnentation of `firebase_messaging`](https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging). An understanding of that article and android components will provide a solid understanding of the motivations of the architecture taken by Ably Flutter to handle push notifications. It is simpler whilst using up-to-date Android components, whilst also gives more flexibility to the user. -Differences between Ably Flutter and Firebase Messaging implementation (Android only): +Differences between Ably Flutter and [Firebase Messaging](https://pub.dev/packages/firebase_messaging) flutter package implementation (on Android only): - **Isolate code:** Firebase Messaging explicitly defines a callback which is launched in a custom isolate. Ably Flutter does not launch a custom dart entrypoint, but instead re-uses the user's default entrypoint (their Flutter application), by using `DartExecutor.DartEntrypoint.createDefault()`. Therefore, Ably Flutter provides the same environment for message handling on both Android and iOS: users application **is running** when we handle the message. -- **Resource consumption tradeoffs:** Firebase launches an isolate capable of only handling messages at app launch, even if users' application isn't handling remote messages. Firebase Messaging keeps this isolate running throughout the app, and have a queue process to queue messages by maintaining an Android Service. This allows 10 minutes of execution time, where as on iOS, Firebase Messaging only has 30 seconds of execution time. Instead, Ably Flutter launches a new isolate on every message if the application is not yet running and avoids creating a service and queueing work. A new message will spawn a new engine. +- **Resource consumption tradeoffs:** Firebase launches an isolate capable of only handling messages at app launch, even if users' application isn't handling remote messages. Firebase Messaging keeps this isolate running throughout the app, and have a queue process to queue messages by maintaining an Android Service. This allows 10 minutes of execution time, where as on iOS, Firebase Messaging only has 30 seconds of execution time. Instead, Ably Flutter launches a new isolate on every message if the application is not yet running and avoids creating a service and queueing work. A new message will spawn a new engine. It also uses a deprecated class, `JobIntentService`. - **Execution time:** Ably Flutter provides users with an execution time of 30 seconds on both Android and iOS to handle each message. On Android, Firebase messaging launches a Service which has [approximately 10 minutes](https://stackoverflow.com/questions/48630606/how-long-is-the-jobservice-execution-time-limit-mentioned-in-androids-jobinte) of execution time from it's launch to handle all messages received before Android stops the service. It's unclear if the Service will be automatically launched by iOS immediately, or if it will only be launched in the future. On iOS, each message has 30 seconds of execution time. This seems to be a bug in the design of firebase_messaging. Users can extend their execution time by using [package:workmanager](https://pub.dev/packages/workmanager). Because of this architectural simplicity, Ably Flutter does not need to use [`PluginUtilities`](https://stackoverflow.com/questions/69208164/what-does-pluginutilities-do-in-flutters-dartui-library-and-how-do-i-use/69208165#69208165), pass references of two methods between Dart and host platform, or save and load these methods in `SharedPreferences`. Ably Flutter avoids conflicts between the default `FlutterEngine` launched with a `FlutterActivity` and the one manually launched in the `BroadcastReceiver`, by using method channels with unique channel names. From 7f5c0a75d8bf625476c45461dab465766c5d058c Mon Sep 17 00:00:00 2001 From: Ben Butterworth <24711048+ben-xD@users.noreply.github.com> Date: Wed, 15 Dec 2021 21:14:37 +0000 Subject: [PATCH 36/51] Add more information about IDE autoformatting --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b0aec071..f9f553d57 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,6 +33,7 @@ We use Github actions to check code is formatted correctly. You should format yo - To automatically check formatting before committing, you can use the git hook shared in this repo. - Run `git config core.hooksPath hooks` - Git hooks don't work well in SourceTree, as per [SourceTree : Hook failing because paths don't seem to be set correctly](https://community.atlassian.com/t5/Bitbucket-questions/SourceTree-Hook-failing-because-paths-don-t-seem-to-be-set/qaq-p/274792). You will need to open SourceTree using `open /Applications/SourceTree.app/Contents/MacOS/SourceTree`. +- To autoformat Java code in Android Studio, follow the documentation: [IntelliJ, Android Studio, and other JetBrains IDEs](https://github.com/google/google-java-format#intellij-android-studio-and-other-jetbrains-ides). ## High level architecture The code in this repository has been constructed to be From cfe177bb13c539921207c06178e85bfb78ae03fd Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 16 Dec 2021 15:25:45 +0000 Subject: [PATCH 37/51] Code formatting --- .../flutter/plugin/AblyMethodCallHandler.java | 1832 ++++++++--------- .../plugin/generated/PlatformConstants.java | 884 ++++---- 2 files changed, 1357 insertions(+), 1359 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java index efa02535b..fce3e4746 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java @@ -3,12 +3,9 @@ import android.content.Context; import android.os.Handler; import android.os.Looper; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import com.google.firebase.messaging.RemoteMessage; - import io.ably.flutter.plugin.generated.PlatformConstants; import io.ably.flutter.plugin.push.PushActivationEventHandlers; import io.ably.flutter.plugin.types.PlatformClientOptions; @@ -33,7 +30,6 @@ import io.ably.lib.util.Log; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; - import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; @@ -42,943 +38,943 @@ import java.util.concurrent.CountDownLatch; public class AblyMethodCallHandler implements MethodChannel.MethodCallHandler { - private static final String TAG = AblyMethodCallHandler.class.getName(); - private final Context applicationContext; - private final MethodChannel methodChannel; - private final StreamsChannel streamsChannel; - private final Map> _map; - private final AblyInstanceStore instanceStore; - @Nullable - private RemoteMessage remoteMessageFromUserTapLaunchesApp; - - public AblyMethodCallHandler( - final MethodChannel methodChannel, - final StreamsChannel streamsChannel, - final Context applicationContext) { - this.methodChannel = methodChannel; - this.streamsChannel = streamsChannel; - this.applicationContext = applicationContext; - this.instanceStore = AblyInstanceStore.getInstance(); - _map = new HashMap<>(); - _map.put(PlatformConstants.PlatformMethod.getPlatformVersion, this::getPlatformVersion); - _map.put(PlatformConstants.PlatformMethod.getVersion, this::getVersion); - _map.put(PlatformConstants.PlatformMethod.resetAblyClients, this::resetAblyClients); - - // Rest - _map.put(PlatformConstants.PlatformMethod.createRest, this::createRest); - _map.put(PlatformConstants.PlatformMethod.setRestChannelOptions, this::setRestChannelOptions); - _map.put(PlatformConstants.PlatformMethod.publish, this::publishRestMessage); - _map.put(PlatformConstants.PlatformMethod.restHistory, this::getRestHistory); - _map.put(PlatformConstants.PlatformMethod.restPresenceGet, this::getRestPresence); - _map.put(PlatformConstants.PlatformMethod.restPresenceHistory, this::getRestPresenceHistory); - _map.put(PlatformConstants.PlatformMethod.releaseRestChannel, this::releaseRestChannel); - - // Realtime - _map.put(PlatformConstants.PlatformMethod.createRealtime, this::createRealtime); - _map.put(PlatformConstants.PlatformMethod.connectRealtime, this::connectRealtime); - _map.put(PlatformConstants.PlatformMethod.closeRealtime, this::closeRealtime); - _map.put(PlatformConstants.PlatformMethod.attachRealtimeChannel, this::attachRealtimeChannel); - _map.put(PlatformConstants.PlatformMethod.detachRealtimeChannel, this::detachRealtimeChannel); - _map.put( - PlatformConstants.PlatformMethod.setRealtimeChannelOptions, - this::setRealtimeChannelOptions); - _map.put( - PlatformConstants.PlatformMethod.publishRealtimeChannelMessage, - this::publishRealtimeChannelMessage); - _map.put(PlatformConstants.PlatformMethod.realtimeHistory, this::getRealtimeHistory); - _map.put(PlatformConstants.PlatformMethod.realtimePresenceGet, this::getRealtimePresence); - _map.put( - PlatformConstants.PlatformMethod.realtimePresenceHistory, this::getRealtimePresenceHistory); - _map.put(PlatformConstants.PlatformMethod.realtimePresenceEnter, this::enterRealtimePresence); - _map.put(PlatformConstants.PlatformMethod.realtimePresenceUpdate, this::updateRealtimePresence); - _map.put(PlatformConstants.PlatformMethod.realtimePresenceLeave, this::leaveRealtimePresence); - _map.put(PlatformConstants.PlatformMethod.releaseRealtimeChannel, this::releaseRealtimeChannel); - _map.put(PlatformConstants.PlatformMethod.realtimeTime, this::realtimeTime); - _map.put(PlatformConstants.PlatformMethod.restTime, this::restTime); - - // Push Notifications - _map.put(PlatformConstants.PlatformMethod.pushActivate, this::pushActivate); - _map.put(PlatformConstants.PlatformMethod.pushDeactivate, this::pushDeactivate); - _map.put(PlatformConstants.PlatformMethod.pushSubscribeDevice, this::pushSubscribeDevice); - _map.put(PlatformConstants.PlatformMethod.pushUnsubscribeDevice, this::pushUnsubscribeDevice); - _map.put(PlatformConstants.PlatformMethod.pushSubscribeClient, this::pushSubscribeClient); - _map.put(PlatformConstants.PlatformMethod.pushUnsubscribeClient, this::pushUnsubscribeClient); - _map.put(PlatformConstants.PlatformMethod.pushListSubscriptions, this::pushListSubscriptions); - _map.put(PlatformConstants.PlatformMethod.pushDevice, this::pushDevice); - _map.put( - PlatformConstants.PlatformMethod.pushNotificationTapLaunchedAppFromTerminated, - this::pushNotificationTapLaunchedAppFromTerminated); - - // paginated results - _map.put(PlatformConstants.PlatformMethod.nextPage, this::getNextPage); - _map.put(PlatformConstants.PlatformMethod.firstPage, this::getFirstPage); - - // Encryption - _map.put(PlatformConstants.PlatformMethod.cryptoGetParams, this::cryptoGetParams); - _map.put( - PlatformConstants.PlatformMethod.cryptoGenerateRandomKey, this::cryptoGenerateRandomKey); - } - - // MethodChannel.Result wrapper that responds on the platform thread. - // - // Plugins crash with "Methods marked with @UiThread must be executed on the main thread." - // This happens while making network calls in thread other than main thread - // - // https://github.com/flutter/flutter/issues/34993#issue-459900986 - // https://github.com/aloisdeniel/flutter_geocoder/commit/bc34cfe473bfd1934fe098bb7053248b75200241 - private static class MethodResultWrapper implements MethodChannel.Result { - private final MethodChannel.Result methodResult; - private final Handler handler; - - MethodResultWrapper(MethodChannel.Result result) { - methodResult = result; - handler = new Handler(Looper.getMainLooper()); - } - - @Override - public void success(final Object result) { - handler.post(() -> methodResult.success(result)); - } - - @Override - public void error( - final String errorCode, final String errorMessage, final Object errorDetails) { - handler.post(() -> methodResult.error(errorCode, errorMessage, errorDetails)); - } - - @Override - public void notImplemented() { - handler.post(methodResult::notImplemented); - } - } - - private void handleAblyException(@NonNull MethodChannel.Result result, @NonNull AblyException e) { - result.error(Integer.toString(e.errorInfo.code), e.getMessage(), e.errorInfo); + private static final String TAG = AblyMethodCallHandler.class.getName(); + private final Context applicationContext; + private final MethodChannel methodChannel; + private final StreamsChannel streamsChannel; + private final Map> _map; + private final AblyInstanceStore instanceStore; + @Nullable private RemoteMessage remoteMessageFromUserTapLaunchesApp; + + public AblyMethodCallHandler( + final MethodChannel methodChannel, + final StreamsChannel streamsChannel, + final Context applicationContext) { + this.methodChannel = methodChannel; + this.streamsChannel = streamsChannel; + this.applicationContext = applicationContext; + this.instanceStore = AblyInstanceStore.getInstance(); + _map = new HashMap<>(); + _map.put(PlatformConstants.PlatformMethod.getPlatformVersion, this::getPlatformVersion); + _map.put(PlatformConstants.PlatformMethod.getVersion, this::getVersion); + _map.put(PlatformConstants.PlatformMethod.resetAblyClients, this::resetAblyClients); + + // Rest + _map.put(PlatformConstants.PlatformMethod.createRest, this::createRest); + _map.put(PlatformConstants.PlatformMethod.setRestChannelOptions, this::setRestChannelOptions); + _map.put(PlatformConstants.PlatformMethod.publish, this::publishRestMessage); + _map.put(PlatformConstants.PlatformMethod.restHistory, this::getRestHistory); + _map.put(PlatformConstants.PlatformMethod.restPresenceGet, this::getRestPresence); + _map.put(PlatformConstants.PlatformMethod.restPresenceHistory, this::getRestPresenceHistory); + _map.put(PlatformConstants.PlatformMethod.releaseRestChannel, this::releaseRestChannel); + + // Realtime + _map.put(PlatformConstants.PlatformMethod.createRealtime, this::createRealtime); + _map.put(PlatformConstants.PlatformMethod.connectRealtime, this::connectRealtime); + _map.put(PlatformConstants.PlatformMethod.closeRealtime, this::closeRealtime); + _map.put(PlatformConstants.PlatformMethod.attachRealtimeChannel, this::attachRealtimeChannel); + _map.put(PlatformConstants.PlatformMethod.detachRealtimeChannel, this::detachRealtimeChannel); + _map.put( + PlatformConstants.PlatformMethod.setRealtimeChannelOptions, + this::setRealtimeChannelOptions); + _map.put( + PlatformConstants.PlatformMethod.publishRealtimeChannelMessage, + this::publishRealtimeChannelMessage); + _map.put(PlatformConstants.PlatformMethod.realtimeHistory, this::getRealtimeHistory); + _map.put(PlatformConstants.PlatformMethod.realtimePresenceGet, this::getRealtimePresence); + _map.put( + PlatformConstants.PlatformMethod.realtimePresenceHistory, this::getRealtimePresenceHistory); + _map.put(PlatformConstants.PlatformMethod.realtimePresenceEnter, this::enterRealtimePresence); + _map.put(PlatformConstants.PlatformMethod.realtimePresenceUpdate, this::updateRealtimePresence); + _map.put(PlatformConstants.PlatformMethod.realtimePresenceLeave, this::leaveRealtimePresence); + _map.put(PlatformConstants.PlatformMethod.releaseRealtimeChannel, this::releaseRealtimeChannel); + _map.put(PlatformConstants.PlatformMethod.realtimeTime, this::realtimeTime); + _map.put(PlatformConstants.PlatformMethod.restTime, this::restTime); + + // Push Notifications + _map.put(PlatformConstants.PlatformMethod.pushActivate, this::pushActivate); + _map.put(PlatformConstants.PlatformMethod.pushDeactivate, this::pushDeactivate); + _map.put(PlatformConstants.PlatformMethod.pushSubscribeDevice, this::pushSubscribeDevice); + _map.put(PlatformConstants.PlatformMethod.pushUnsubscribeDevice, this::pushUnsubscribeDevice); + _map.put(PlatformConstants.PlatformMethod.pushSubscribeClient, this::pushSubscribeClient); + _map.put(PlatformConstants.PlatformMethod.pushUnsubscribeClient, this::pushUnsubscribeClient); + _map.put(PlatformConstants.PlatformMethod.pushListSubscriptions, this::pushListSubscriptions); + _map.put(PlatformConstants.PlatformMethod.pushDevice, this::pushDevice); + _map.put( + PlatformConstants.PlatformMethod.pushNotificationTapLaunchedAppFromTerminated, + this::pushNotificationTapLaunchedAppFromTerminated); + + // paginated results + _map.put(PlatformConstants.PlatformMethod.nextPage, this::getNextPage); + _map.put(PlatformConstants.PlatformMethod.firstPage, this::getFirstPage); + + // Encryption + _map.put(PlatformConstants.PlatformMethod.cryptoGetParams, this::cryptoGetParams); + _map.put( + PlatformConstants.PlatformMethod.cryptoGenerateRandomKey, this::cryptoGenerateRandomKey); + } + + // MethodChannel.Result wrapper that responds on the platform thread. + // + // Plugins crash with "Methods marked with @UiThread must be executed on the main thread." + // This happens while making network calls in thread other than main thread + // + // https://github.com/flutter/flutter/issues/34993#issue-459900986 + // https://github.com/aloisdeniel/flutter_geocoder/commit/bc34cfe473bfd1934fe098bb7053248b75200241 + private static class MethodResultWrapper implements MethodChannel.Result { + private final MethodChannel.Result methodResult; + private final Handler handler; + + MethodResultWrapper(MethodChannel.Result result) { + methodResult = result; + handler = new Handler(Looper.getMainLooper()); } @Override - public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result rawResult) { - final MethodChannel.Result result = new MethodResultWrapper(rawResult); - Log.v( - TAG, - String.format("onMethodCall: Ably Flutter platform method \"%s\" invoked.", call.method)); - final BiConsumer handler = _map.get(call.method); - if (null == handler) { - // We don't have a handler for a method with this name so tell the caller. - result.notImplemented(); - } else { - // We have a handler for a method with this name so delegate to it. - handler.accept(call, result); - } + public void success(final Object result) { + handler.post(() -> methodResult.success(result)); } - private CompletionListener handleCompletionWithListener(@NonNull MethodChannel.Result result) { - return new CompletionListener() { - @Override - public void onSuccess() { - result.success(null); - } - - @Override - public void onError(ErrorInfo reason) { - handleAblyException(result, AblyException.fromErrorInfo(reason)); - } - }; + @Override + public void error( + final String errorCode, final String errorMessage, final Object errorDetails) { + handler.post(() -> methodResult.error(errorCode, errorMessage, errorDetails)); } - private void resetAblyClients(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - streamsChannel.reset(); - instanceStore.reset(); + @Override + public void notImplemented() { + handler.post(methodResult::notImplemented); + } + } + + private void handleAblyException(@NonNull MethodChannel.Result result, @NonNull AblyException e) { + result.error(Integer.toString(e.errorInfo.code), e.getMessage(), e.errorInfo); + } + + @Override + public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result rawResult) { + final MethodChannel.Result result = new MethodResultWrapper(rawResult); + Log.v( + TAG, + String.format("onMethodCall: Ably Flutter platform method \"%s\" invoked.", call.method)); + final BiConsumer handler = _map.get(call.method); + if (null == handler) { + // We don't have a handler for a method with this name so tell the caller. + result.notImplemented(); + } else { + // We have a handler for a method with this name so delegate to it. + handler.accept(call, result); + } + } + + private CompletionListener handleCompletionWithListener(@NonNull MethodChannel.Result result) { + return new CompletionListener() { + @Override + public void onSuccess() { result.success(null); - } - - private void createRest(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = - (AblyFlutterMessage) call.arguments; - this.ablyDo( - message, - (ablyLibrary, clientOptions) -> { - try { - final long handle = ablyLibrary.getHandleForNextClient(); - if (clientOptions.hasAuthCallback) { - clientOptions.options.authCallback = - (Auth.TokenParams params) -> { - final Object[] token = {null}; - final CountDownLatch latch = new CountDownLatch(1); - new Handler(Looper.getMainLooper()) - .post( - () -> { - AblyFlutterMessage channelMessage = - new AblyFlutterMessage<>(params, handle); - methodChannel.invokeMethod( - PlatformConstants.PlatformMethod.authCallback, - channelMessage, - new MethodChannel.Result() { - @Override - public void success(@Nullable Object result) { - token[0] = result; - latch.countDown(); - } - - @Override - public void error( - String errorCode, - @Nullable String errorMessage, - @Nullable Object errorDetails) { - Log.w( - TAG, - String.format( - "\"%s\" platform method received error from Dart" - + " side: %s", - PlatformConstants.PlatformMethod.authCallback, - errorMessage)); - latch.countDown(); - } - - @Override - public void notImplemented() { - Log.w( - TAG, - String.format( - "\"%s\" platform method not implemented on Dart side:" - + " %s", - PlatformConstants.PlatformMethod.authCallback)); - latch.countDown(); - } - }); - }); - - try { - latch.await(); - } catch (InterruptedException e) { - throw AblyException.fromErrorInfo( - e, - new ErrorInfo( - "Exception while waiting for authCallback to return", 400, 40000)); - } - - return token[0]; - }; - } - result.success(ablyLibrary.createRest(clientOptions.options, applicationContext)); - } catch (final AblyException e) { - handleAblyException(result, e); - } - }); - } + } + + @Override + public void onError(ErrorInfo reason) { + handleAblyException(result, AblyException.fromErrorInfo(reason)); + } + }; + } + + private void resetAblyClients(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + streamsChannel.reset(); + instanceStore.reset(); + result.success(null); + } + + private void createRest(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = + (AblyFlutterMessage) call.arguments; + this.ablyDo( + message, + (ablyLibrary, clientOptions) -> { + try { + final long handle = ablyLibrary.getHandleForNextClient(); + if (clientOptions.hasAuthCallback) { + clientOptions.options.authCallback = + (Auth.TokenParams params) -> { + final Object[] token = {null}; + final CountDownLatch latch = new CountDownLatch(1); + new Handler(Looper.getMainLooper()) + .post( + () -> { + AblyFlutterMessage channelMessage = + new AblyFlutterMessage<>(params, handle); + methodChannel.invokeMethod( + PlatformConstants.PlatformMethod.authCallback, + channelMessage, + new MethodChannel.Result() { + @Override + public void success(@Nullable Object result) { + token[0] = result; + latch.countDown(); + } + + @Override + public void error( + String errorCode, + @Nullable String errorMessage, + @Nullable Object errorDetails) { + Log.w( + TAG, + String.format( + "\"%s\" platform method received error from Dart" + + " side: %s", + PlatformConstants.PlatformMethod.authCallback, + errorMessage)); + latch.countDown(); + } + + @Override + public void notImplemented() { + Log.w( + TAG, + String.format( + "\"%s\" platform method not implemented on Dart side:" + + " %s", + PlatformConstants.PlatformMethod.authCallback)); + latch.countDown(); + } + }); + }); - private void setRestChannelOptions( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - // setOptions is not supported on a rest instance directly - // Track @ https://github.com/ably/ably-flutter/issues/14 - // An alternative is to use the side effect of get channel - // with options which updates passed channel options. - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - final ChannelOptions channelOptions = - (ChannelOptions) map.get(PlatformConstants.TxTransportKeys.options); try { - ablyLibrary.getRest(messageData.handle).channels.get(channelName, channelOptions); - result.success(null); - } catch (AblyException ae) { - handleAblyException(result, ae); + latch.await(); + } catch (InterruptedException e) { + throw AblyException.fromErrorInfo( + e, + new ErrorInfo( + "Exception while waiting for authCallback to return", 400, 40000)); } - }); - } - private void publishRestMessage(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - final ArrayList channelMessages = - (ArrayList) map.get(PlatformConstants.TxTransportKeys.messages); - if (channelMessages == null) { - result.error("Messages cannot be null", null, null); - return; - } - Message[] messages = new Message[channelMessages.size()]; - messages = channelMessages.toArray(messages); + return token[0]; + }; + } + result.success(ablyLibrary.createRest(clientOptions.options, applicationContext)); + } catch (final AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void setRestChannelOptions( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + // setOptions is not supported on a rest instance directly + // Track @ https://github.com/ably/ably-flutter/issues/14 + // An alternative is to use the side effect of get channel + // with options which updates passed channel options. + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + final ChannelOptions channelOptions = + (ChannelOptions) map.get(PlatformConstants.TxTransportKeys.options); + try { + ablyLibrary.getRest(messageData.handle).channels.get(channelName, channelOptions); + result.success(null); + } catch (AblyException ae) { + handleAblyException(result, ae); + } + }); + } + + private void publishRestMessage(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + final ArrayList channelMessages = + (ArrayList) map.get(PlatformConstants.TxTransportKeys.messages); + if (channelMessages == null) { + result.error("Messages cannot be null", null, null); + return; + } + Message[] messages = new Message[channelMessages.size()]; + messages = channelMessages.toArray(messages); + ablyLibrary + .getRest(messageData.handle) + .channels + .get(channelName) + .publishAsync(messages, handleCompletionWithListener(result)); + }); + } + + private void releaseRestChannel(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>ablyDo( + message, + (ablyLibrary, messageData) -> { + final String channelName = messageData.message; + ablyLibrary.getRest(messageData.handle).channels.release(channelName); + result.success(null); + }); + } + + private Callback> paginatedResponseHandler( + @NonNull MethodChannel.Result result, Integer handle) { + return new Callback>() { + @Override + public void onSuccess(AsyncPaginatedResult paginatedResult) { + long paginatedResultHandle = instanceStore.setPaginatedResult(paginatedResult, handle); + result.success(new AblyFlutterMessage<>(paginatedResult, paginatedResultHandle)); + } + + @Override + public void onError(ErrorInfo reason) { + handleAblyException(result, AblyException.fromErrorInfo(reason)); + } + }; + } + + private void getRestHistory(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + ablyLibrary + .getRest(messageData.handle) + .channels + .get(channelName) + .historyAsync(params, this.paginatedResponseHandler(result, null)); + }); + } + + private void getRestPresence(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + ablyLibrary + .getRest(messageData.handle) + .channels + .get(channelName) + .presence + .getAsync(params, this.paginatedResponseHandler(result, null)); + }); + } + + private void getRestPresenceHistory( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + ablyLibrary + .getRest(messageData.handle) + .channels + .get(channelName) + .presence + .historyAsync(params, this.paginatedResponseHandler(result, null)); + }); + } + + private void getRealtimePresence(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + try { + result.success( + Arrays.asList( ablyLibrary - .getRest(messageData.handle) - .channels - .get(channelName) - .publishAsync(messages, handleCompletionWithListener(result)); - }); - } - - private void releaseRestChannel(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>ablyDo( - message, - (ablyLibrary, messageData) -> { - final String channelName = messageData.message; - ablyLibrary.getRest(messageData.handle).channels.release(channelName); - result.success(null); - }); - } - - private Callback> paginatedResponseHandler( - @NonNull MethodChannel.Result result, Integer handle) { - return new Callback>() { - @Override - public void onSuccess(AsyncPaginatedResult paginatedResult) { - long paginatedResultHandle = instanceStore.setPaginatedResult(paginatedResult, handle); - result.success(new AblyFlutterMessage<>(paginatedResult, paginatedResultHandle)); + .getRealtime(messageData.handle) + .channels + .get(channelName) + .presence + .get(params))); + } catch (AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void getRealtimePresenceHistory( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + ablyLibrary + .getRealtime(messageData.handle) + .channels + .get(channelName) + .presence + .historyAsync(params, this.paginatedResponseHandler(result, null)); + }); + } + + private void enterRealtimePresence( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + final String clientId = (String) map.get(PlatformConstants.TxTransportKeys.clientId); + final Object data = map.get(PlatformConstants.TxTransportKeys.data); + final Presence presence = + ablyLibrary.getRealtime(messageData.handle).channels.get(channelName).presence; + try { + presence.enterClient(clientId, data, handleCompletionWithListener(result)); + } catch (AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void updateRealtimePresence( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + final String clientId = (String) map.get(PlatformConstants.TxTransportKeys.clientId); + final Object data = map.get(PlatformConstants.TxTransportKeys.data); + final Presence presence = + ablyLibrary.getRealtime(messageData.handle).channels.get(channelName).presence; + try { + if (clientId != null) { + presence.updateClient(clientId, data, handleCompletionWithListener(result)); + } else { + presence.update(data, handleCompletionWithListener(result)); } - - @Override - public void onError(ErrorInfo reason) { - handleAblyException(result, AblyException.fromErrorInfo(reason)); + } catch (AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void leaveRealtimePresence( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + final String clientId = (String) map.get(PlatformConstants.TxTransportKeys.clientId); + final Object data = map.get(PlatformConstants.TxTransportKeys.data); + final Presence presence = + ablyLibrary.getRealtime(messageData.handle).channels.get(channelName).presence; + try { + if (clientId != null) { + presence.leaveClient(clientId, data, handleCompletionWithListener(result)); + } else { + presence.leave(data, handleCompletionWithListener(result)); } - }; - } - - private void getRestHistory(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; - } - ablyLibrary - .getRest(messageData.handle) - .channels - .get(channelName) - .historyAsync(params, this.paginatedResponseHandler(result, null)); - }); - } - - private void getRestPresence(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; - } - ablyLibrary - .getRest(messageData.handle) - .channels - .get(channelName) - .presence - .getAsync(params, this.paginatedResponseHandler(result, null)); - }); - } - - private void getRestPresenceHistory( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; - } - ablyLibrary - .getRest(messageData.handle) - .channels - .get(channelName) - .presence - .historyAsync(params, this.paginatedResponseHandler(result, null)); - }); - } - - private void getRealtimePresence(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; - } - try { - result.success( - Arrays.asList( - ablyLibrary - .getRealtime(messageData.handle) - .channels - .get(channelName) - .presence - .get(params))); - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void getRealtimePresenceHistory( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; - } - ablyLibrary - .getRealtime(messageData.handle) - .channels - .get(channelName) - .presence - .historyAsync(params, this.paginatedResponseHandler(result, null)); - }); - } - - private void enterRealtimePresence( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - final String clientId = (String) map.get(PlatformConstants.TxTransportKeys.clientId); - final Object data = map.get(PlatformConstants.TxTransportKeys.data); - final Presence presence = - ablyLibrary.getRealtime(messageData.handle).channels.get(channelName).presence; - try { - presence.enterClient(clientId, data, handleCompletionWithListener(result)); - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void updateRealtimePresence( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - final String clientId = (String) map.get(PlatformConstants.TxTransportKeys.clientId); - final Object data = map.get(PlatformConstants.TxTransportKeys.data); - final Presence presence = - ablyLibrary.getRealtime(messageData.handle).channels.get(channelName).presence; - try { - if (clientId != null) { - presence.updateClient(clientId, data, handleCompletionWithListener(result)); - } else { - presence.update(data, handleCompletionWithListener(result)); - } - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void leaveRealtimePresence( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - final String clientId = (String) map.get(PlatformConstants.TxTransportKeys.clientId); - final Object data = map.get(PlatformConstants.TxTransportKeys.data); - final Presence presence = - ablyLibrary.getRealtime(messageData.handle).channels.get(channelName).presence; - try { - if (clientId != null) { - presence.leaveClient(clientId, data, handleCompletionWithListener(result)); - } else { - presence.leave(data, handleCompletionWithListener(result)); - } - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void createRealtime(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = - (AblyFlutterMessage) call.arguments; - this.ablyDo( - message, - (ablyLibrary, clientOptions) -> { - try { - final long handle = ablyLibrary.getHandleForNextClient(); - if (clientOptions.hasAuthCallback) { - clientOptions.options.authCallback = - (Auth.TokenParams params) -> { - final Object[] token = {null}; - final CountDownLatch latch = new CountDownLatch(1); - new Handler(Looper.getMainLooper()) - .post( - () -> { - AblyFlutterMessage channelMessage = - new AblyFlutterMessage<>(params, handle); - methodChannel.invokeMethod( - PlatformConstants.PlatformMethod.realtimeAuthCallback, - channelMessage, - new MethodChannel.Result() { - @Override - public void success(@Nullable Object result) { - if (result != null) { - token[0] = result; - latch.countDown(); - } - } - - @Override - public void error( - String errorCode, - @Nullable String errorMessage, - @Nullable Object errorDetails) { - Log.w( - TAG, - String.format( - "\"%s\" platform method received error from Dart" - + " side: %s", - PlatformConstants.PlatformMethod.realtimeAuthCallback, - errorMessage)); - latch.countDown(); - } - - @Override - public void notImplemented() { - Log.w( - TAG, - String.format( - "\"%s\" platform method not implemented on Dart side:" - + " %s", - PlatformConstants.PlatformMethod - .realtimeAuthCallback)); - latch.countDown(); - } - }); - }); - - try { - latch.await(); - } catch (InterruptedException e) { - throw AblyException.fromErrorInfo( - e, - new ErrorInfo( - "Exception while waiting for authCallback to return", 400, 40000)); - } - - return token[0]; - }; - } - result.success(ablyLibrary.createRealtime(clientOptions.options, applicationContext)); - } catch (final AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void connectRealtime(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - if (call.arguments instanceof Integer) { - final Integer realtimeHandle = (Integer) call.arguments; - instanceStore.getRealtime(realtimeHandle.longValue()).connect(); - } else { - // Using Number (the superclass of both Long and Integer) because Flutter could send us - // either depending on how big the value is. - // See: https://flutter.dev/docs/development/platform-integration/platform-channels#codec - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - final Integer realtimeHandle = message.message; - instanceStore.getRealtime(realtimeHandle.longValue()).connect(); - } - result.success(null); - } - - private void attachRealtimeChannel( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, ablyMessage) -> { - try { - final String channelName = - (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - ablyLibrary - .getRealtime(ablyMessage.handle) - .channels - .get(channelName) - .attach(handleCompletionWithListener(result)); - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void detachRealtimeChannel( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, ablyMessage) -> { - try { - final String channelName = - (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - ablyLibrary - .getRealtime(ablyMessage.handle) - .channels - .get(channelName) - .detach(handleCompletionWithListener(result)); - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } - - private void setRealtimeChannelOptions( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, ablyMessage) -> { - try { - final String channelName = - (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - final ChannelOptions channelOptions = - (ChannelOptions) ablyMessage.message.get(PlatformConstants.TxTransportKeys.options); - ablyLibrary - .getRealtime(ablyMessage.handle) - .channels - .get(channelName) - .setOptions(channelOptions); - result.success(null); - } catch (AblyException e) { - handleAblyException(result, e); - } - }); - } + } catch (AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void createRealtime(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = + (AblyFlutterMessage) call.arguments; + this.ablyDo( + message, + (ablyLibrary, clientOptions) -> { + try { + final long handle = ablyLibrary.getHandleForNextClient(); + if (clientOptions.hasAuthCallback) { + clientOptions.options.authCallback = + (Auth.TokenParams params) -> { + final Object[] token = {null}; + final CountDownLatch latch = new CountDownLatch(1); + new Handler(Looper.getMainLooper()) + .post( + () -> { + AblyFlutterMessage channelMessage = + new AblyFlutterMessage<>(params, handle); + methodChannel.invokeMethod( + PlatformConstants.PlatformMethod.realtimeAuthCallback, + channelMessage, + new MethodChannel.Result() { + @Override + public void success(@Nullable Object result) { + if (result != null) { + token[0] = result; + latch.countDown(); + } + } + + @Override + public void error( + String errorCode, + @Nullable String errorMessage, + @Nullable Object errorDetails) { + Log.w( + TAG, + String.format( + "\"%s\" platform method received error from Dart" + + " side: %s", + PlatformConstants.PlatformMethod.realtimeAuthCallback, + errorMessage)); + latch.countDown(); + } + + @Override + public void notImplemented() { + Log.w( + TAG, + String.format( + "\"%s\" platform method not implemented on Dart side:" + + " %s", + PlatformConstants.PlatformMethod + .realtimeAuthCallback)); + latch.countDown(); + } + }); + }); - private void publishRealtimeChannelMessage( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, ablyMessage) -> { try { - final String channelName = - (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - final Channel channel = - ablyLibrary.getRealtime(ablyMessage.handle).channels.get(channelName); - - final ArrayList channelMessages = - (ArrayList) - ablyMessage.message.get(PlatformConstants.TxTransportKeys.messages); - if (channelMessages == null) { - result.error("Messages cannot be null", null, null); - return; - } - Message[] messages = new Message[channelMessages.size()]; - messages = channelMessages.toArray(messages); - channel.publish(messages, handleCompletionWithListener(result)); - } catch (AblyException e) { - handleAblyException(result, e); + latch.await(); + } catch (InterruptedException e) { + throw AblyException.fromErrorInfo( + e, + new ErrorInfo( + "Exception while waiting for authCallback to return", 400, 40000)); } - }); - } - - private void releaseRealtimeChannel( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>ablyDo( - message, - (ablyLibrary, messageData) -> { - final String channelName = messageData.message; - ablyLibrary.getRealtime(messageData.handle).channels.release(channelName); - result.success(null); - }); - } - - private void realtimeTime(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) methodCall.arguments; - time(methodCall, result, instanceStore.getRealtime((int) message.message)); - } - - private void restTime(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) methodCall.arguments; - time(methodCall, result, instanceStore.getRest((int) message.message)); - } - - private void time(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result, AblyBase client) { - final AblyFlutterMessage message = (AblyFlutterMessage) methodCall.arguments; - Callback callback = new Callback() { - @Override - public void onSuccess(Long timeResult) { - result.success(timeResult); - } - @Override - public void onError(ErrorInfo reason) { - result.error("40000", reason.message, reason); + return token[0]; + }; } - }; - client.timeAsync(callback); - } - - - private void getRealtimeHistory(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.>>ablyDo( - message, - (ablyLibrary, messageData) -> { - final Map map = messageData.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; - } - ablyLibrary - .getRealtime(messageData.handle) - .channels - .get(channelName) - .historyAsync(params, this.paginatedResponseHandler(result, null)); - }); - } - - private void closeRealtime(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.ablyDo( - message, - (ablyLibrary, realtimeHandle) -> { - ablyLibrary.getRealtime(realtimeHandle.longValue()).close(); - result.success(null); - }); - } - - private void pushActivate(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - try { - Integer handle = (Integer) message.message; - PushActivationEventHandlers.setResultForActivate(result); - instanceStore.getPush(handle).activate(); - } catch (AblyException e) { + result.success(ablyLibrary.createRealtime(clientOptions.options, applicationContext)); + } catch (final AblyException e) { handleAblyException(result, e); - } - } - - private void pushDeactivate(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - try { - Integer handle = (Integer) message.message; - PushActivationEventHandlers.setResultForDeactivate(result); - instanceStore.getPush(handle).deactivate(); - } catch (AblyException e) { + } + }); + } + + private void connectRealtime(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + if (call.arguments instanceof Integer) { + final Integer realtimeHandle = (Integer) call.arguments; + instanceStore.getRealtime(realtimeHandle.longValue()).connect(); + } else { + // Using Number (the superclass of both Long and Integer) because Flutter could send us + // either depending on how big the value is. + // See: https://flutter.dev/docs/development/platform-integration/platform-channels#codec + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + final Integer realtimeHandle = message.message; + instanceStore.getRealtime(realtimeHandle.longValue()).connect(); + } + result.success(null); + } + + private void attachRealtimeChannel( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, ablyMessage) -> { + try { + final String channelName = + (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + ablyLibrary + .getRealtime(ablyMessage.handle) + .channels + .get(channelName) + .attach(handleCompletionWithListener(result)); + } catch (AblyException e) { handleAblyException(result, e); - } - } - - private void pushSubscribeDevice(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage>> message = - (AblyFlutterMessage) call.arguments; - AblyFlutterMessage> nestedMessage = message.message; - final String channelName = - (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - instanceStore - .getPushChannel(nestedMessage.handle, channelName) - .subscribeDeviceAsync(handleCompletionWithListener(result)); - } - - private void pushUnsubscribeDevice( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage>> message = - (AblyFlutterMessage) call.arguments; - AblyFlutterMessage> nestedMessage = message.message; - final String channelName = - (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - instanceStore - .getPushChannel(nestedMessage.handle, channelName) - .unsubscribeDeviceAsync(handleCompletionWithListener(result)); - } - - private void pushSubscribeClient(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage>> message = - (AblyFlutterMessage) call.arguments; - AblyFlutterMessage> nestedMessage = message.message; - final String channelName = - (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - instanceStore - .getPushChannel(nestedMessage.handle, channelName) - .subscribeClientAsync(handleCompletionWithListener(result)); - } - - private void pushUnsubscribeClient( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage>> message = - (AblyFlutterMessage) call.arguments; - AblyFlutterMessage> nestedMessage = message.message; - final String channelName = - (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - instanceStore - .getPushChannel(nestedMessage.handle, channelName) - .unsubscribeClientAsync(handleCompletionWithListener(result)); - } - - private void pushListSubscriptions( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage>> message = - (AblyFlutterMessage>>) call.arguments; - AblyFlutterMessage> nestedMessage = message.message; - final String channelName = - (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); - final Map paramsMap = - (Map) nestedMessage.message.get(PlatformConstants.TxTransportKeys.params); - instanceStore - .getPushChannel(nestedMessage.handle, channelName) - .listSubscriptionsAsync( - createParamsArrayFromMap(paramsMap), this.paginatedResponseHandler(result, null)); - } - - private Param[] createParamsArrayFromMap(@Nullable Map paramsMap) { - if (paramsMap == null) { - return new Param[0]; - } - Param[] params = new Param[paramsMap.size()]; - int paramsSize = 0; - for (Map.Entry entry : paramsMap.entrySet()) { - Param param = new Param(entry.getKey(), entry.getValue()); - params[paramsSize] = param; - paramsSize += 1; - } - return params; - } - - private void pushDevice(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - long handle = message.message; - try { - AblyRealtime realtime = instanceStore.getRealtime(handle); - if (realtime != null) { - result.success(realtime.device()); - return; - } - - AblyRest rest = instanceStore.getRest(handle); - if (rest != null) { - result.success(rest.device()); - return; + } + }); + } + + private void detachRealtimeChannel( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, ablyMessage) -> { + try { + final String channelName = + (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + ablyLibrary + .getRealtime(ablyMessage.handle) + .channels + .get(channelName) + .detach(handleCompletionWithListener(result)); + } catch (AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void setRealtimeChannelOptions( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, ablyMessage) -> { + try { + final String channelName = + (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + final ChannelOptions channelOptions = + (ChannelOptions) ablyMessage.message.get(PlatformConstants.TxTransportKeys.options); + ablyLibrary + .getRealtime(ablyMessage.handle) + .channels + .get(channelName) + .setOptions(channelOptions); + result.success(null); + } catch (AblyException e) { + handleAblyException(result, e); + } + }); + } + + private void publishRealtimeChannelMessage( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, ablyMessage) -> { + try { + final String channelName = + (String) ablyMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + final Channel channel = + ablyLibrary.getRealtime(ablyMessage.handle).channels.get(channelName); + + final ArrayList channelMessages = + (ArrayList) + ablyMessage.message.get(PlatformConstants.TxTransportKeys.messages); + if (channelMessages == null) { + result.error("Messages cannot be null", null, null); + return; } - - throw AblyException.fromErrorInfo(new ErrorInfo("No Ably client exists", 400, 40000)); - } catch (AblyException e) { + Message[] messages = new Message[channelMessages.size()]; + messages = channelMessages.toArray(messages); + channel.publish(messages, handleCompletionWithListener(result)); + } catch (AblyException e) { handleAblyException(result, e); - } - } - - public void setRemoteMessageFromUserTapLaunchesApp(@Nullable RemoteMessage message) { - remoteMessageFromUserTapLaunchesApp = message; - } - - private void pushNotificationTapLaunchedAppFromTerminated( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - result.success(remoteMessageFromUserTapLaunchesApp); - remoteMessageFromUserTapLaunchesApp = null; - } - - private void getNextPage(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - this.ablyDo( - message, - (ablyLibrary, pageHandle) -> - ablyLibrary - .getPaginatedResult(pageHandle) - .next(this.paginatedResponseHandler(result, pageHandle))); - } - - private void getFirstPage(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage> message = - (AblyFlutterMessage>) call.arguments; - Integer pageHandle = message.message.message; - instanceStore + } + }); + } + + private void releaseRealtimeChannel( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>ablyDo( + message, + (ablyLibrary, messageData) -> { + final String channelName = messageData.message; + ablyLibrary.getRealtime(messageData.handle).channels.release(channelName); + result.success(null); + }); + } + + private void realtimeTime(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) methodCall.arguments; + time(methodCall, result, instanceStore.getRealtime((int) message.message)); + } + + private void restTime(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) methodCall.arguments; + time(methodCall, result, instanceStore.getRest((int) message.message)); + } + + private void time( + @NonNull MethodCall methodCall, @NonNull MethodChannel.Result result, AblyBase client) { + final AblyFlutterMessage message = (AblyFlutterMessage) methodCall.arguments; + Callback callback = + new Callback() { + @Override + public void onSuccess(Long timeResult) { + result.success(timeResult); + } + + @Override + public void onError(ErrorInfo reason) { + result.error("40000", reason.message, reason); + } + }; + client.timeAsync(callback); + } + + private void getRealtimeHistory(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.>>ablyDo( + message, + (ablyLibrary, messageData) -> { + final Map map = messageData.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + ablyLibrary + .getRealtime(messageData.handle) + .channels + .get(channelName) + .historyAsync(params, this.paginatedResponseHandler(result, null)); + }); + } + + private void closeRealtime(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.ablyDo( + message, + (ablyLibrary, realtimeHandle) -> { + ablyLibrary.getRealtime(realtimeHandle.longValue()).close(); + result.success(null); + }); + } + + private void pushActivate(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + try { + Integer handle = (Integer) message.message; + PushActivationEventHandlers.setResultForActivate(result); + instanceStore.getPush(handle).activate(); + } catch (AblyException e) { + handleAblyException(result, e); + } + } + + private void pushDeactivate(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + try { + Integer handle = (Integer) message.message; + PushActivationEventHandlers.setResultForDeactivate(result); + instanceStore.getPush(handle).deactivate(); + } catch (AblyException e) { + handleAblyException(result, e); + } + } + + private void pushSubscribeDevice(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage>> message = + (AblyFlutterMessage) call.arguments; + AblyFlutterMessage> nestedMessage = message.message; + final String channelName = + (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + instanceStore + .getPushChannel(nestedMessage.handle, channelName) + .subscribeDeviceAsync(handleCompletionWithListener(result)); + } + + private void pushUnsubscribeDevice( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage>> message = + (AblyFlutterMessage) call.arguments; + AblyFlutterMessage> nestedMessage = message.message; + final String channelName = + (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + instanceStore + .getPushChannel(nestedMessage.handle, channelName) + .unsubscribeDeviceAsync(handleCompletionWithListener(result)); + } + + private void pushSubscribeClient(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage>> message = + (AblyFlutterMessage) call.arguments; + AblyFlutterMessage> nestedMessage = message.message; + final String channelName = + (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + instanceStore + .getPushChannel(nestedMessage.handle, channelName) + .subscribeClientAsync(handleCompletionWithListener(result)); + } + + private void pushUnsubscribeClient( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage>> message = + (AblyFlutterMessage) call.arguments; + AblyFlutterMessage> nestedMessage = message.message; + final String channelName = + (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + instanceStore + .getPushChannel(nestedMessage.handle, channelName) + .unsubscribeClientAsync(handleCompletionWithListener(result)); + } + + private void pushListSubscriptions( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage>> message = + (AblyFlutterMessage>>) call.arguments; + AblyFlutterMessage> nestedMessage = message.message; + final String channelName = + (String) nestedMessage.message.get(PlatformConstants.TxTransportKeys.channelName); + final Map paramsMap = + (Map) nestedMessage.message.get(PlatformConstants.TxTransportKeys.params); + instanceStore + .getPushChannel(nestedMessage.handle, channelName) + .listSubscriptionsAsync( + createParamsArrayFromMap(paramsMap), this.paginatedResponseHandler(result, null)); + } + + private Param[] createParamsArrayFromMap(@Nullable Map paramsMap) { + if (paramsMap == null) { + return new Param[0]; + } + Param[] params = new Param[paramsMap.size()]; + int paramsSize = 0; + for (Map.Entry entry : paramsMap.entrySet()) { + Param param = new Param(entry.getKey(), entry.getValue()); + params[paramsSize] = param; + paramsSize += 1; + } + return params; + } + + private void pushDevice(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + long handle = message.message; + try { + AblyRealtime realtime = instanceStore.getRealtime(handle); + if (realtime != null) { + result.success(realtime.device()); + return; + } + + AblyRest rest = instanceStore.getRest(handle); + if (rest != null) { + result.success(rest.device()); + return; + } + + throw AblyException.fromErrorInfo(new ErrorInfo("No Ably client exists", 400, 40000)); + } catch (AblyException e) { + handleAblyException(result, e); + } + } + + public void setRemoteMessageFromUserTapLaunchesApp(@Nullable RemoteMessage message) { + remoteMessageFromUserTapLaunchesApp = message; + } + + private void pushNotificationTapLaunchedAppFromTerminated( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + result.success(remoteMessageFromUserTapLaunchesApp); + remoteMessageFromUserTapLaunchesApp = null; + } + + private void getNextPage(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + this.ablyDo( + message, + (ablyLibrary, pageHandle) -> + ablyLibrary .getPaginatedResult(pageHandle) - .first(this.paginatedResponseHandler(result, pageHandle)); - } - - private void cryptoGetParams(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final Map message = (Map) call.arguments; - final String algorithm = (String) message.get(PlatformConstants.TxCryptoGetParams.algorithm); - final byte[] keyData = getKeyData(message.get(PlatformConstants.TxCryptoGetParams.key)); - if (keyData == null) { - result.error( - "40000", - "A key must be set for encryption, being either a base64 encoded key, or a byte array.", - null); - return; - } - - try { - result.success(Crypto.getParams(algorithm, keyData)); - } catch (NoSuchAlgorithmException e) { - result.error("40000", "cryptoGetParams: No algorithm found. " + e, e); - } - } - - private byte[] getKeyData(Object key) { - if (key == null) { - return null; - } - if (key instanceof String) { - return Base64Coder.decode((String) key); - } else if (key instanceof byte[]) { - return (byte[]) key; - } else { - return null; - } - } - - private void cryptoGenerateRandomKey( - @NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final Integer keyLength = (Integer) call.arguments; - result.success(Crypto.generateRandomKey(keyLength)); - } - - // Extracts the message from an AblyFlutterMessage. - // - // It also passed the ablyLibrary argument, which you can just get with _ably without using this - // method - // The benefit of using this method is questionable: it allows you to reduce manually casting. - void ablyDo( - final AblyFlutterMessage message, final BiConsumer consumer) { - consumer.accept(instanceStore, (T) message.message); - } - - private void getPlatformVersion(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - result.success("Android " + android.os.Build.VERSION.RELEASE); - } - - private void getVersion(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - result.success(Defaults.ABLY_AGENT_VERSION); - } + .next(this.paginatedResponseHandler(result, pageHandle))); + } + + private void getFirstPage(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage> message = + (AblyFlutterMessage>) call.arguments; + Integer pageHandle = message.message.message; + instanceStore + .getPaginatedResult(pageHandle) + .first(this.paginatedResponseHandler(result, pageHandle)); + } + + private void cryptoGetParams(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final Map message = (Map) call.arguments; + final String algorithm = (String) message.get(PlatformConstants.TxCryptoGetParams.algorithm); + final byte[] keyData = getKeyData(message.get(PlatformConstants.TxCryptoGetParams.key)); + if (keyData == null) { + result.error( + "40000", + "A key must be set for encryption, being either a base64 encoded key, or a byte array.", + null); + return; + } + + try { + result.success(Crypto.getParams(algorithm, keyData)); + } catch (NoSuchAlgorithmException e) { + result.error("40000", "cryptoGetParams: No algorithm found. " + e, e); + } + } + + private byte[] getKeyData(Object key) { + if (key == null) { + return null; + } + if (key instanceof String) { + return Base64Coder.decode((String) key); + } else if (key instanceof byte[]) { + return (byte[]) key; + } else { + return null; + } + } + + private void cryptoGenerateRandomKey( + @NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final Integer keyLength = (Integer) call.arguments; + result.success(Crypto.generateRandomKey(keyLength)); + } + + // Extracts the message from an AblyFlutterMessage. + // + // It also passed the ablyLibrary argument, which you can just get with _ably without using this + // method + // The benefit of using this method is questionable: it allows you to reduce manually casting. + void ablyDo( + final AblyFlutterMessage message, final BiConsumer consumer) { + consumer.accept(instanceStore, (T) message.message); + } + + private void getPlatformVersion(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + result.success("Android " + android.os.Build.VERSION.RELEASE); + } + + private void getVersion(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + result.success(Defaults.ABLY_AGENT_VERSION); + } } diff --git a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java index e4c295ca8..58382b6e6 100644 --- a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java +++ b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java @@ -5,445 +5,447 @@ package io.ably.flutter.plugin.generated; - -final public class PlatformConstants { - - static final public class CodecTypes { - public static final byte ablyMessage = (byte) 128; - public static final byte ablyEventMessage = (byte) 129; - public static final byte clientOptions = (byte) 130; - public static final byte messageData = (byte) 131; - public static final byte messageExtras = (byte) 132; - public static final byte message = (byte) 133; - public static final byte tokenParams = (byte) 134; - public static final byte tokenDetails = (byte) 135; - public static final byte tokenRequest = (byte) 136; - public static final byte restChannelOptions = (byte) 137; - public static final byte realtimeChannelOptions = (byte) 138; - public static final byte paginatedResult = (byte) 139; - public static final byte restHistoryParams = (byte) 140; - public static final byte realtimeHistoryParams = (byte) 141; - public static final byte restPresenceParams = (byte) 142; - public static final byte presenceMessage = (byte) 143; - public static final byte realtimePresenceParams = (byte) 144; - public static final byte deviceDetails = (byte) 145; - public static final byte localDevice = (byte) 146; - public static final byte pushChannelSubscription = (byte) 147; - public static final byte unNotificationSettings = (byte) 148; - public static final byte remoteMessage = (byte) 149; - public static final byte errorInfo = (byte) 150; - public static final byte logLevel = (byte) 151; - public static final byte connectionStateChange = (byte) 152; - public static final byte channelStateChange = (byte) 153; - public static final byte cipherParams = (byte) 154; - } - - static final public class PlatformMethod { - public static final String getPlatformVersion = "getPlatformVersion"; - public static final String getVersion = "getVersion"; - public static final String resetAblyClients = "resetAblyClients"; - public static final String authCallback = "authCallback"; - public static final String realtimeAuthCallback = "realtimeAuthCallback"; - public static final String createRest = "createRest"; - public static final String setRestChannelOptions = "setRestChannelOptions"; - public static final String publish = "publish"; - public static final String restHistory = "restHistory"; - public static final String restPresenceGet = "restPresenceGet"; - public static final String restPresenceHistory = "restPresenceHistory"; - public static final String releaseRestChannel = "releaseRestChannel"; - public static final String createRealtime = "createRealtime"; - public static final String connectRealtime = "connectRealtime"; - public static final String closeRealtime = "closeRealtime"; - public static final String attachRealtimeChannel = "attachRealtimeChannel"; - public static final String detachRealtimeChannel = "detachRealtimeChannel"; - public static final String setRealtimeChannelOptions = "setRealtimeChannelOptions"; - public static final String realtimePresenceGet = "realtimePresenceGet"; - public static final String realtimePresenceHistory = "realtimePresenceHistory"; - public static final String realtimePresenceEnter = "realtimePresenceEnter"; - public static final String realtimePresenceUpdate = "realtimePresenceUpdate"; - public static final String realtimePresenceLeave = "realtimePresenceLeave"; - public static final String onRealtimePresenceMessage = "onRealtimePresenceMessage"; - public static final String publishRealtimeChannelMessage = "publishRealtimeChannelMessage"; - public static final String releaseRealtimeChannel = "releaseRealtimeChannel"; - public static final String realtimeHistory = "realtimeHistory"; - public static final String realtimeTime = "realtimeTime"; - public static final String restTime = "restTime"; - public static final String pushActivate = "pushActivate"; - public static final String pushDeactivate = "pushDeactivate"; - public static final String pushSubscribeDevice = "pushSubscribeDevice"; - public static final String pushUnsubscribeDevice = "pushUnsubscribeDevice"; - public static final String pushSubscribeClient = "pushSubscribeClient"; - public static final String pushUnsubscribeClient = "pushUnsubscribeClient"; - public static final String pushListSubscriptions = "pushListSubscriptions"; - public static final String pushDevice = "pushDevice"; - public static final String pushRequestPermission = "pushRequestPermission"; - public static final String pushGetNotificationSettings = "pushGetNotificationSettings"; - public static final String pushOpenSettingsFor = "pushOpenSettingsFor"; - public static final String pushOnActivate = "pushOnActivate"; - public static final String pushOnDeactivate = "pushOnDeactivate"; - public static final String pushOnUpdateFailed = "pushOnUpdateFailed"; - public static final String pushNotificationTapLaunchedAppFromTerminated = "pushNotificationTapLaunchedAppFromTerminated"; - public static final String pushOnShowNotificationInForeground = "pushOnShowNotificationInForeground"; - public static final String pushOnMessage = "pushOnMessage"; - public static final String pushOnBackgroundMessage = "pushOnBackgroundMessage"; - public static final String pushOnNotificationTap = "pushOnNotificationTap"; - public static final String pushBackgroundFlutterApplicationReadyOnAndroid = "pushBackgroundFlutterApplicationReadyOnAndroid"; - public static final String onRealtimeConnectionStateChanged = "onRealtimeConnectionStateChanged"; - public static final String onRealtimeChannelStateChanged = "onRealtimeChannelStateChanged"; - public static final String onRealtimeChannelMessage = "onRealtimeChannelMessage"; - public static final String nextPage = "nextPage"; - public static final String firstPage = "firstPage"; - public static final String cryptoGetParams = "cryptoGetParams"; - public static final String cryptoGenerateRandomKey = "cryptoGenerateRandomKey"; - } - - static final public class TxTransportKeys { - public static final String channelName = "channelName"; - public static final String params = "params"; - public static final String data = "data"; - public static final String clientId = "clientId"; - public static final String options = "options"; - public static final String messages = "messages"; - } - - static final public class TxAblyMessage { - public static final String registrationHandle = "registrationHandle"; - public static final String type = "type"; - public static final String message = "message"; - } - - static final public class TxAblyEventMessage { - public static final String eventName = "eventName"; - public static final String type = "type"; - public static final String message = "message"; - } - - static final public class TxErrorInfo { - public static final String code = "code"; - public static final String message = "message"; - public static final String statusCode = "statusCode"; - public static final String href = "href"; - public static final String requestId = "requestId"; - public static final String cause = "cause"; - } - - static final public class TxMessageData { - public static final String data = "data"; - public static final String type = "type"; - } - - static final public class TxDeltaExtras { - public static final String format = "format"; - public static final String from = "from"; - } - - static final public class TxMessageExtras { - public static final String extras = "extras"; - public static final String delta = "delta"; - } - - static final public class TxClientOptions { - public static final String authUrl = "authUrl"; - public static final String authMethod = "authMethod"; - public static final String key = "key"; - public static final String tokenDetails = "tokenDetails"; - public static final String authHeaders = "authHeaders"; - public static final String authParams = "authParams"; - public static final String queryTime = "queryTime"; - public static final String useTokenAuth = "useTokenAuth"; - public static final String hasAuthCallback = "hasAuthCallback"; - public static final String clientId = "clientId"; - public static final String logLevel = "logLevel"; - public static final String tls = "tls"; - public static final String restHost = "restHost"; - public static final String realtimeHost = "realtimeHost"; - public static final String port = "port"; - public static final String tlsPort = "tlsPort"; - public static final String autoConnect = "autoConnect"; - public static final String useBinaryProtocol = "useBinaryProtocol"; - public static final String queueMessages = "queueMessages"; - public static final String echoMessages = "echoMessages"; - public static final String recover = "recover"; - public static final String environment = "environment"; - public static final String idempotentRestPublishing = "idempotentRestPublishing"; - public static final String httpOpenTimeout = "httpOpenTimeout"; - public static final String httpRequestTimeout = "httpRequestTimeout"; - public static final String httpMaxRetryCount = "httpMaxRetryCount"; - public static final String realtimeRequestTimeout = "realtimeRequestTimeout"; - public static final String fallbackHosts = "fallbackHosts"; - public static final String fallbackHostsUseDefault = "fallbackHostsUseDefault"; - public static final String fallbackRetryTimeout = "fallbackRetryTimeout"; - public static final String defaultTokenParams = "defaultTokenParams"; - public static final String channelRetryTimeout = "channelRetryTimeout"; - public static final String transportParams = "transportParams"; - } - - static final public class TxRestChannelOptions { - public static final String cipherParams = "cipherParams"; - } - - static final public class TxRealtimeChannelOptions { - public static final String params = "params"; - public static final String modes = "modes"; - public static final String cipherParams = "cipherParams"; - } - - static final public class TxCipherParams { - public static final String androidHandle = "androidHandle"; - public static final String iosAlgorithm = "iosAlgorithm"; - public static final String iosKey = "iosKey"; - } - - static final public class TxTokenDetails { - public static final String token = "token"; - public static final String expires = "expires"; - public static final String issued = "issued"; - public static final String capability = "capability"; - public static final String clientId = "clientId"; - } - - static final public class TxTokenParams { - public static final String capability = "capability"; - public static final String clientId = "clientId"; - public static final String nonce = "nonce"; - public static final String timestamp = "timestamp"; - public static final String ttl = "ttl"; - } - - static final public class TxTokenRequest { - public static final String capability = "capability"; - public static final String clientId = "clientId"; - public static final String keyName = "keyName"; - public static final String mac = "mac"; - public static final String nonce = "nonce"; - public static final String timestamp = "timestamp"; - public static final String ttl = "ttl"; - } - - static final public class TxEnumConstants { - public static final String initialized = "initialized"; - public static final String connecting = "connecting"; - public static final String connected = "connected"; - public static final String disconnected = "disconnected"; - public static final String attaching = "attaching"; - public static final String attached = "attached"; - public static final String detaching = "detaching"; - public static final String detached = "detached"; - public static final String suspended = "suspended"; - public static final String closing = "closing"; - public static final String closed = "closed"; - public static final String failed = "failed"; - public static final String absent = "absent"; - public static final String leave = "leave"; - public static final String enter = "enter"; - public static final String present = "present"; - public static final String update = "update"; - public static final String presence = "presence"; - public static final String publish = "publish"; - public static final String subscribe = "subscribe"; - public static final String presenceSubscribe = "presenceSubscribe"; - } - - static final public class TxFormFactorEnum { - public static final String phone = "phone"; - public static final String tablet = "tablet"; - public static final String desktop = "desktop"; - public static final String tv = "tv"; - public static final String watch = "watch"; - public static final String car = "car"; - public static final String embedded = "embedded"; - public static final String other = "other"; - } - - static final public class TxLogLevelEnum { - public static final String none = "none"; - public static final String verbose = "verbose"; - public static final String debug = "debug"; - public static final String info = "info"; - public static final String warn = "warn"; - public static final String error = "error"; - } - - static final public class TxDevicePlatformEnum { - public static final String ios = "ios"; - public static final String android = "android"; - public static final String browser = "browser"; - } - - static final public class TxDevicePushStateEnum { - public static final String active = "active"; - public static final String failing = "failing"; - public static final String failed = "failed"; - } - - static final public class TxConnectionStateChange { - public static final String current = "current"; - public static final String previous = "previous"; - public static final String event = "event"; - public static final String retryIn = "retryIn"; - public static final String reason = "reason"; - } - - static final public class TxChannelStateChange { - public static final String current = "current"; - public static final String previous = "previous"; - public static final String event = "event"; - public static final String resumed = "resumed"; - public static final String reason = "reason"; - } - - static final public class TxMessage { - public static final String id = "id"; - public static final String timestamp = "timestamp"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - public static final String encoding = "encoding"; - public static final String data = "data"; - public static final String name = "name"; - public static final String extras = "extras"; - } - - static final public class TxPresenceMessage { - public static final String id = "id"; - public static final String action = "action"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - public static final String data = "data"; - public static final String encoding = "encoding"; - public static final String extras = "extras"; - public static final String timestamp = "timestamp"; - } - - static final public class TxPaginatedResult { - public static final String items = "items"; - public static final String type = "type"; - public static final String hasNext = "hasNext"; - } - - static final public class TxRestHistoryParams { - public static final String start = "start"; - public static final String end = "end"; - public static final String direction = "direction"; - public static final String limit = "limit"; - } - - static final public class TxRealtimeHistoryParams { - public static final String start = "start"; - public static final String end = "end"; - public static final String direction = "direction"; - public static final String limit = "limit"; - public static final String untilAttach = "untilAttach"; - } - - static final public class TxRestPresenceParams { - public static final String limit = "limit"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - } - - static final public class TxRealtimePresenceParams { - public static final String waitForSync = "waitForSync"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - } - - static final public class TxDeviceDetails { - public static final String id = "id"; - public static final String clientId = "clientId"; - public static final String platform = "platform"; - public static final String formFactor = "formFactor"; - public static final String metadata = "metadata"; - public static final String devicePushDetails = "devicePushDetails"; - } - - static final public class TxDevicePushDetails { - public static final String recipient = "recipient"; - public static final String state = "state"; - public static final String errorReason = "errorReason"; - } - - static final public class TxLocalDevice { - public static final String deviceSecret = "deviceSecret"; - public static final String deviceIdentityToken = "deviceIdentityToken"; - } - - static final public class TxPushChannelSubscription { - public static final String channel = "channel"; - public static final String deviceId = "deviceId"; - public static final String clientId = "clientId"; - } - - static final public class TxPushRequestPermission { - public static final String badge = "badge"; - public static final String sound = "sound"; - public static final String alert = "alert"; - public static final String carPlay = "carPlay"; - public static final String criticalAlert = "criticalAlert"; - public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; - public static final String provisional = "provisional"; - public static final String announcement = "announcement"; - } - - static final public class TxUNNotificationSettings { - public static final String authorizationStatus = "authorizationStatus"; - public static final String soundSetting = "soundSetting"; - public static final String badgeSetting = "badgeSetting"; - public static final String alertSetting = "alertSetting"; - public static final String notificationCenterSetting = "notificationCenterSetting"; - public static final String lockScreenSetting = "lockScreenSetting"; - public static final String carPlaySetting = "carPlaySetting"; - public static final String alertStyle = "alertStyle"; - public static final String showPreviewsSetting = "showPreviewsSetting"; - public static final String criticalAlertSetting = "criticalAlertSetting"; - public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; - public static final String announcementSetting = "announcementSetting"; - public static final String scheduledDeliverySetting = "scheduledDeliverySetting"; - public static final String timeSensitiveSetting = "timeSensitiveSetting"; - } - - static final public class TxUNNotificationSettingEnum { - public static final String notSupported = "notSupported"; - public static final String disabled = "disabled"; - public static final String enabled = "enabled"; - } - - static final public class TxUNAlertStyleEnum { - public static final String none = "none"; - public static final String banner = "banner"; - public static final String alert = "alert"; - } - - static final public class TxUNAuthorizationStatusEnum { - public static final String notDetermined = "notDetermined"; - public static final String denied = "denied"; - public static final String authorized = "authorized"; - public static final String provisional = "provisional"; - public static final String ephemeral = "ephemeral"; - } - - static final public class TxUNShowPreviewsSettingEnum { - public static final String always = "always"; - public static final String whenAuthenticated = "whenAuthenticated"; - public static final String never = "never"; - } - - static final public class TxRemoteMessage { - public static final String data = "data"; - public static final String notification = "notification"; - } - - static final public class TxNotification { - public static final String title = "title"; - public static final String body = "body"; - } - - static final public class TxCryptoGetParams { - public static final String algorithm = "algorithm"; - public static final String key = "key"; - } - - static final public class TxCryptoGenerateRandomKey { - public static final String keyLength = "keyLength"; - } - +public final class PlatformConstants { + + public static final class CodecTypes { + public static final byte ablyMessage = (byte) 128; + public static final byte ablyEventMessage = (byte) 129; + public static final byte clientOptions = (byte) 130; + public static final byte messageData = (byte) 131; + public static final byte messageExtras = (byte) 132; + public static final byte message = (byte) 133; + public static final byte tokenParams = (byte) 134; + public static final byte tokenDetails = (byte) 135; + public static final byte tokenRequest = (byte) 136; + public static final byte restChannelOptions = (byte) 137; + public static final byte realtimeChannelOptions = (byte) 138; + public static final byte paginatedResult = (byte) 139; + public static final byte restHistoryParams = (byte) 140; + public static final byte realtimeHistoryParams = (byte) 141; + public static final byte restPresenceParams = (byte) 142; + public static final byte presenceMessage = (byte) 143; + public static final byte realtimePresenceParams = (byte) 144; + public static final byte deviceDetails = (byte) 145; + public static final byte localDevice = (byte) 146; + public static final byte pushChannelSubscription = (byte) 147; + public static final byte unNotificationSettings = (byte) 148; + public static final byte remoteMessage = (byte) 149; + public static final byte errorInfo = (byte) 150; + public static final byte logLevel = (byte) 151; + public static final byte connectionStateChange = (byte) 152; + public static final byte channelStateChange = (byte) 153; + public static final byte cipherParams = (byte) 154; + } + + public static final class PlatformMethod { + public static final String getPlatformVersion = "getPlatformVersion"; + public static final String getVersion = "getVersion"; + public static final String resetAblyClients = "resetAblyClients"; + public static final String authCallback = "authCallback"; + public static final String realtimeAuthCallback = "realtimeAuthCallback"; + public static final String createRest = "createRest"; + public static final String setRestChannelOptions = "setRestChannelOptions"; + public static final String publish = "publish"; + public static final String restHistory = "restHistory"; + public static final String restPresenceGet = "restPresenceGet"; + public static final String restPresenceHistory = "restPresenceHistory"; + public static final String releaseRestChannel = "releaseRestChannel"; + public static final String createRealtime = "createRealtime"; + public static final String connectRealtime = "connectRealtime"; + public static final String closeRealtime = "closeRealtime"; + public static final String attachRealtimeChannel = "attachRealtimeChannel"; + public static final String detachRealtimeChannel = "detachRealtimeChannel"; + public static final String setRealtimeChannelOptions = "setRealtimeChannelOptions"; + public static final String realtimePresenceGet = "realtimePresenceGet"; + public static final String realtimePresenceHistory = "realtimePresenceHistory"; + public static final String realtimePresenceEnter = "realtimePresenceEnter"; + public static final String realtimePresenceUpdate = "realtimePresenceUpdate"; + public static final String realtimePresenceLeave = "realtimePresenceLeave"; + public static final String onRealtimePresenceMessage = "onRealtimePresenceMessage"; + public static final String publishRealtimeChannelMessage = "publishRealtimeChannelMessage"; + public static final String releaseRealtimeChannel = "releaseRealtimeChannel"; + public static final String realtimeHistory = "realtimeHistory"; + public static final String realtimeTime = "realtimeTime"; + public static final String restTime = "restTime"; + public static final String pushActivate = "pushActivate"; + public static final String pushDeactivate = "pushDeactivate"; + public static final String pushSubscribeDevice = "pushSubscribeDevice"; + public static final String pushUnsubscribeDevice = "pushUnsubscribeDevice"; + public static final String pushSubscribeClient = "pushSubscribeClient"; + public static final String pushUnsubscribeClient = "pushUnsubscribeClient"; + public static final String pushListSubscriptions = "pushListSubscriptions"; + public static final String pushDevice = "pushDevice"; + public static final String pushRequestPermission = "pushRequestPermission"; + public static final String pushGetNotificationSettings = "pushGetNotificationSettings"; + public static final String pushOpenSettingsFor = "pushOpenSettingsFor"; + public static final String pushOnActivate = "pushOnActivate"; + public static final String pushOnDeactivate = "pushOnDeactivate"; + public static final String pushOnUpdateFailed = "pushOnUpdateFailed"; + public static final String pushNotificationTapLaunchedAppFromTerminated = + "pushNotificationTapLaunchedAppFromTerminated"; + public static final String pushOnShowNotificationInForeground = + "pushOnShowNotificationInForeground"; + public static final String pushOnMessage = "pushOnMessage"; + public static final String pushOnBackgroundMessage = "pushOnBackgroundMessage"; + public static final String pushOnNotificationTap = "pushOnNotificationTap"; + public static final String pushBackgroundFlutterApplicationReadyOnAndroid = + "pushBackgroundFlutterApplicationReadyOnAndroid"; + public static final String onRealtimeConnectionStateChanged = + "onRealtimeConnectionStateChanged"; + public static final String onRealtimeChannelStateChanged = "onRealtimeChannelStateChanged"; + public static final String onRealtimeChannelMessage = "onRealtimeChannelMessage"; + public static final String nextPage = "nextPage"; + public static final String firstPage = "firstPage"; + public static final String cryptoGetParams = "cryptoGetParams"; + public static final String cryptoGenerateRandomKey = "cryptoGenerateRandomKey"; + } + + public static final class TxTransportKeys { + public static final String channelName = "channelName"; + public static final String params = "params"; + public static final String data = "data"; + public static final String clientId = "clientId"; + public static final String options = "options"; + public static final String messages = "messages"; + } + + public static final class TxAblyMessage { + public static final String registrationHandle = "registrationHandle"; + public static final String type = "type"; + public static final String message = "message"; + } + + public static final class TxAblyEventMessage { + public static final String eventName = "eventName"; + public static final String type = "type"; + public static final String message = "message"; + } + + public static final class TxErrorInfo { + public static final String code = "code"; + public static final String message = "message"; + public static final String statusCode = "statusCode"; + public static final String href = "href"; + public static final String requestId = "requestId"; + public static final String cause = "cause"; + } + + public static final class TxMessageData { + public static final String data = "data"; + public static final String type = "type"; + } + + public static final class TxDeltaExtras { + public static final String format = "format"; + public static final String from = "from"; + } + + public static final class TxMessageExtras { + public static final String extras = "extras"; + public static final String delta = "delta"; + } + + public static final class TxClientOptions { + public static final String authUrl = "authUrl"; + public static final String authMethod = "authMethod"; + public static final String key = "key"; + public static final String tokenDetails = "tokenDetails"; + public static final String authHeaders = "authHeaders"; + public static final String authParams = "authParams"; + public static final String queryTime = "queryTime"; + public static final String useTokenAuth = "useTokenAuth"; + public static final String hasAuthCallback = "hasAuthCallback"; + public static final String clientId = "clientId"; + public static final String logLevel = "logLevel"; + public static final String tls = "tls"; + public static final String restHost = "restHost"; + public static final String realtimeHost = "realtimeHost"; + public static final String port = "port"; + public static final String tlsPort = "tlsPort"; + public static final String autoConnect = "autoConnect"; + public static final String useBinaryProtocol = "useBinaryProtocol"; + public static final String queueMessages = "queueMessages"; + public static final String echoMessages = "echoMessages"; + public static final String recover = "recover"; + public static final String environment = "environment"; + public static final String idempotentRestPublishing = "idempotentRestPublishing"; + public static final String httpOpenTimeout = "httpOpenTimeout"; + public static final String httpRequestTimeout = "httpRequestTimeout"; + public static final String httpMaxRetryCount = "httpMaxRetryCount"; + public static final String realtimeRequestTimeout = "realtimeRequestTimeout"; + public static final String fallbackHosts = "fallbackHosts"; + public static final String fallbackHostsUseDefault = "fallbackHostsUseDefault"; + public static final String fallbackRetryTimeout = "fallbackRetryTimeout"; + public static final String defaultTokenParams = "defaultTokenParams"; + public static final String channelRetryTimeout = "channelRetryTimeout"; + public static final String transportParams = "transportParams"; + } + + public static final class TxRestChannelOptions { + public static final String cipherParams = "cipherParams"; + } + + public static final class TxRealtimeChannelOptions { + public static final String params = "params"; + public static final String modes = "modes"; + public static final String cipherParams = "cipherParams"; + } + + public static final class TxCipherParams { + public static final String androidHandle = "androidHandle"; + public static final String iosAlgorithm = "iosAlgorithm"; + public static final String iosKey = "iosKey"; + } + + public static final class TxTokenDetails { + public static final String token = "token"; + public static final String expires = "expires"; + public static final String issued = "issued"; + public static final String capability = "capability"; + public static final String clientId = "clientId"; + } + + public static final class TxTokenParams { + public static final String capability = "capability"; + public static final String clientId = "clientId"; + public static final String nonce = "nonce"; + public static final String timestamp = "timestamp"; + public static final String ttl = "ttl"; + } + + public static final class TxTokenRequest { + public static final String capability = "capability"; + public static final String clientId = "clientId"; + public static final String keyName = "keyName"; + public static final String mac = "mac"; + public static final String nonce = "nonce"; + public static final String timestamp = "timestamp"; + public static final String ttl = "ttl"; + } + + public static final class TxEnumConstants { + public static final String initialized = "initialized"; + public static final String connecting = "connecting"; + public static final String connected = "connected"; + public static final String disconnected = "disconnected"; + public static final String attaching = "attaching"; + public static final String attached = "attached"; + public static final String detaching = "detaching"; + public static final String detached = "detached"; + public static final String suspended = "suspended"; + public static final String closing = "closing"; + public static final String closed = "closed"; + public static final String failed = "failed"; + public static final String absent = "absent"; + public static final String leave = "leave"; + public static final String enter = "enter"; + public static final String present = "present"; + public static final String update = "update"; + public static final String presence = "presence"; + public static final String publish = "publish"; + public static final String subscribe = "subscribe"; + public static final String presenceSubscribe = "presenceSubscribe"; + } + + public static final class TxFormFactorEnum { + public static final String phone = "phone"; + public static final String tablet = "tablet"; + public static final String desktop = "desktop"; + public static final String tv = "tv"; + public static final String watch = "watch"; + public static final String car = "car"; + public static final String embedded = "embedded"; + public static final String other = "other"; + } + + public static final class TxLogLevelEnum { + public static final String none = "none"; + public static final String verbose = "verbose"; + public static final String debug = "debug"; + public static final String info = "info"; + public static final String warn = "warn"; + public static final String error = "error"; + } + + public static final class TxDevicePlatformEnum { + public static final String ios = "ios"; + public static final String android = "android"; + public static final String browser = "browser"; + } + + public static final class TxDevicePushStateEnum { + public static final String active = "active"; + public static final String failing = "failing"; + public static final String failed = "failed"; + } + + public static final class TxConnectionStateChange { + public static final String current = "current"; + public static final String previous = "previous"; + public static final String event = "event"; + public static final String retryIn = "retryIn"; + public static final String reason = "reason"; + } + + public static final class TxChannelStateChange { + public static final String current = "current"; + public static final String previous = "previous"; + public static final String event = "event"; + public static final String resumed = "resumed"; + public static final String reason = "reason"; + } + + public static final class TxMessage { + public static final String id = "id"; + public static final String timestamp = "timestamp"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + public static final String encoding = "encoding"; + public static final String data = "data"; + public static final String name = "name"; + public static final String extras = "extras"; + } + + public static final class TxPresenceMessage { + public static final String id = "id"; + public static final String action = "action"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + public static final String data = "data"; + public static final String encoding = "encoding"; + public static final String extras = "extras"; + public static final String timestamp = "timestamp"; + } + + public static final class TxPaginatedResult { + public static final String items = "items"; + public static final String type = "type"; + public static final String hasNext = "hasNext"; + } + + public static final class TxRestHistoryParams { + public static final String start = "start"; + public static final String end = "end"; + public static final String direction = "direction"; + public static final String limit = "limit"; + } + + public static final class TxRealtimeHistoryParams { + public static final String start = "start"; + public static final String end = "end"; + public static final String direction = "direction"; + public static final String limit = "limit"; + public static final String untilAttach = "untilAttach"; + } + + public static final class TxRestPresenceParams { + public static final String limit = "limit"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + } + + public static final class TxRealtimePresenceParams { + public static final String waitForSync = "waitForSync"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + } + + public static final class TxDeviceDetails { + public static final String id = "id"; + public static final String clientId = "clientId"; + public static final String platform = "platform"; + public static final String formFactor = "formFactor"; + public static final String metadata = "metadata"; + public static final String devicePushDetails = "devicePushDetails"; + } + + public static final class TxDevicePushDetails { + public static final String recipient = "recipient"; + public static final String state = "state"; + public static final String errorReason = "errorReason"; + } + + public static final class TxLocalDevice { + public static final String deviceSecret = "deviceSecret"; + public static final String deviceIdentityToken = "deviceIdentityToken"; + } + + public static final class TxPushChannelSubscription { + public static final String channel = "channel"; + public static final String deviceId = "deviceId"; + public static final String clientId = "clientId"; + } + + public static final class TxPushRequestPermission { + public static final String badge = "badge"; + public static final String sound = "sound"; + public static final String alert = "alert"; + public static final String carPlay = "carPlay"; + public static final String criticalAlert = "criticalAlert"; + public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; + public static final String provisional = "provisional"; + public static final String announcement = "announcement"; + } + + public static final class TxUNNotificationSettings { + public static final String authorizationStatus = "authorizationStatus"; + public static final String soundSetting = "soundSetting"; + public static final String badgeSetting = "badgeSetting"; + public static final String alertSetting = "alertSetting"; + public static final String notificationCenterSetting = "notificationCenterSetting"; + public static final String lockScreenSetting = "lockScreenSetting"; + public static final String carPlaySetting = "carPlaySetting"; + public static final String alertStyle = "alertStyle"; + public static final String showPreviewsSetting = "showPreviewsSetting"; + public static final String criticalAlertSetting = "criticalAlertSetting"; + public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; + public static final String announcementSetting = "announcementSetting"; + public static final String scheduledDeliverySetting = "scheduledDeliverySetting"; + public static final String timeSensitiveSetting = "timeSensitiveSetting"; + } + + public static final class TxUNNotificationSettingEnum { + public static final String notSupported = "notSupported"; + public static final String disabled = "disabled"; + public static final String enabled = "enabled"; + } + + public static final class TxUNAlertStyleEnum { + public static final String none = "none"; + public static final String banner = "banner"; + public static final String alert = "alert"; + } + + public static final class TxUNAuthorizationStatusEnum { + public static final String notDetermined = "notDetermined"; + public static final String denied = "denied"; + public static final String authorized = "authorized"; + public static final String provisional = "provisional"; + public static final String ephemeral = "ephemeral"; + } + + public static final class TxUNShowPreviewsSettingEnum { + public static final String always = "always"; + public static final String whenAuthenticated = "whenAuthenticated"; + public static final String never = "never"; + } + + public static final class TxRemoteMessage { + public static final String data = "data"; + public static final String notification = "notification"; + } + + public static final class TxNotification { + public static final String title = "title"; + public static final String body = "body"; + } + + public static final class TxCryptoGetParams { + public static final String algorithm = "algorithm"; + public static final String key = "key"; + } + + public static final class TxCryptoGenerateRandomKey { + public static final String keyLength = "keyLength"; + } } From acde5bae161c2f2077f0140eaf62b8835ecebcbb Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 16 Dec 2021 15:36:11 +0000 Subject: [PATCH 38/51] Codegen for realtime stats --- .../plugin/generated/PlatformConstants.java | 885 +++++++++--------- bin/codegen_context.dart | 1 + ios/Classes/codec/AblyPlatformConstants.h | 1 + ios/Classes/codec/AblyPlatformConstants.m | 1 + lib/src/generated/platform_constants.dart | 7 +- lib/src/platform/src/realtime/realtime.dart | 6 +- 6 files changed, 451 insertions(+), 450 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java index 58382b6e6..a750fbb56 100644 --- a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java +++ b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java @@ -5,447 +5,446 @@ package io.ably.flutter.plugin.generated; -public final class PlatformConstants { - - public static final class CodecTypes { - public static final byte ablyMessage = (byte) 128; - public static final byte ablyEventMessage = (byte) 129; - public static final byte clientOptions = (byte) 130; - public static final byte messageData = (byte) 131; - public static final byte messageExtras = (byte) 132; - public static final byte message = (byte) 133; - public static final byte tokenParams = (byte) 134; - public static final byte tokenDetails = (byte) 135; - public static final byte tokenRequest = (byte) 136; - public static final byte restChannelOptions = (byte) 137; - public static final byte realtimeChannelOptions = (byte) 138; - public static final byte paginatedResult = (byte) 139; - public static final byte restHistoryParams = (byte) 140; - public static final byte realtimeHistoryParams = (byte) 141; - public static final byte restPresenceParams = (byte) 142; - public static final byte presenceMessage = (byte) 143; - public static final byte realtimePresenceParams = (byte) 144; - public static final byte deviceDetails = (byte) 145; - public static final byte localDevice = (byte) 146; - public static final byte pushChannelSubscription = (byte) 147; - public static final byte unNotificationSettings = (byte) 148; - public static final byte remoteMessage = (byte) 149; - public static final byte errorInfo = (byte) 150; - public static final byte logLevel = (byte) 151; - public static final byte connectionStateChange = (byte) 152; - public static final byte channelStateChange = (byte) 153; - public static final byte cipherParams = (byte) 154; - } - - public static final class PlatformMethod { - public static final String getPlatformVersion = "getPlatformVersion"; - public static final String getVersion = "getVersion"; - public static final String resetAblyClients = "resetAblyClients"; - public static final String authCallback = "authCallback"; - public static final String realtimeAuthCallback = "realtimeAuthCallback"; - public static final String createRest = "createRest"; - public static final String setRestChannelOptions = "setRestChannelOptions"; - public static final String publish = "publish"; - public static final String restHistory = "restHistory"; - public static final String restPresenceGet = "restPresenceGet"; - public static final String restPresenceHistory = "restPresenceHistory"; - public static final String releaseRestChannel = "releaseRestChannel"; - public static final String createRealtime = "createRealtime"; - public static final String connectRealtime = "connectRealtime"; - public static final String closeRealtime = "closeRealtime"; - public static final String attachRealtimeChannel = "attachRealtimeChannel"; - public static final String detachRealtimeChannel = "detachRealtimeChannel"; - public static final String setRealtimeChannelOptions = "setRealtimeChannelOptions"; - public static final String realtimePresenceGet = "realtimePresenceGet"; - public static final String realtimePresenceHistory = "realtimePresenceHistory"; - public static final String realtimePresenceEnter = "realtimePresenceEnter"; - public static final String realtimePresenceUpdate = "realtimePresenceUpdate"; - public static final String realtimePresenceLeave = "realtimePresenceLeave"; - public static final String onRealtimePresenceMessage = "onRealtimePresenceMessage"; - public static final String publishRealtimeChannelMessage = "publishRealtimeChannelMessage"; - public static final String releaseRealtimeChannel = "releaseRealtimeChannel"; - public static final String realtimeHistory = "realtimeHistory"; - public static final String realtimeTime = "realtimeTime"; - public static final String restTime = "restTime"; - public static final String pushActivate = "pushActivate"; - public static final String pushDeactivate = "pushDeactivate"; - public static final String pushSubscribeDevice = "pushSubscribeDevice"; - public static final String pushUnsubscribeDevice = "pushUnsubscribeDevice"; - public static final String pushSubscribeClient = "pushSubscribeClient"; - public static final String pushUnsubscribeClient = "pushUnsubscribeClient"; - public static final String pushListSubscriptions = "pushListSubscriptions"; - public static final String pushDevice = "pushDevice"; - public static final String pushRequestPermission = "pushRequestPermission"; - public static final String pushGetNotificationSettings = "pushGetNotificationSettings"; - public static final String pushOpenSettingsFor = "pushOpenSettingsFor"; - public static final String pushOnActivate = "pushOnActivate"; - public static final String pushOnDeactivate = "pushOnDeactivate"; - public static final String pushOnUpdateFailed = "pushOnUpdateFailed"; - public static final String pushNotificationTapLaunchedAppFromTerminated = - "pushNotificationTapLaunchedAppFromTerminated"; - public static final String pushOnShowNotificationInForeground = - "pushOnShowNotificationInForeground"; - public static final String pushOnMessage = "pushOnMessage"; - public static final String pushOnBackgroundMessage = "pushOnBackgroundMessage"; - public static final String pushOnNotificationTap = "pushOnNotificationTap"; - public static final String pushBackgroundFlutterApplicationReadyOnAndroid = - "pushBackgroundFlutterApplicationReadyOnAndroid"; - public static final String onRealtimeConnectionStateChanged = - "onRealtimeConnectionStateChanged"; - public static final String onRealtimeChannelStateChanged = "onRealtimeChannelStateChanged"; - public static final String onRealtimeChannelMessage = "onRealtimeChannelMessage"; - public static final String nextPage = "nextPage"; - public static final String firstPage = "firstPage"; - public static final String cryptoGetParams = "cryptoGetParams"; - public static final String cryptoGenerateRandomKey = "cryptoGenerateRandomKey"; - } - - public static final class TxTransportKeys { - public static final String channelName = "channelName"; - public static final String params = "params"; - public static final String data = "data"; - public static final String clientId = "clientId"; - public static final String options = "options"; - public static final String messages = "messages"; - } - - public static final class TxAblyMessage { - public static final String registrationHandle = "registrationHandle"; - public static final String type = "type"; - public static final String message = "message"; - } - - public static final class TxAblyEventMessage { - public static final String eventName = "eventName"; - public static final String type = "type"; - public static final String message = "message"; - } - - public static final class TxErrorInfo { - public static final String code = "code"; - public static final String message = "message"; - public static final String statusCode = "statusCode"; - public static final String href = "href"; - public static final String requestId = "requestId"; - public static final String cause = "cause"; - } - - public static final class TxMessageData { - public static final String data = "data"; - public static final String type = "type"; - } - - public static final class TxDeltaExtras { - public static final String format = "format"; - public static final String from = "from"; - } - - public static final class TxMessageExtras { - public static final String extras = "extras"; - public static final String delta = "delta"; - } - - public static final class TxClientOptions { - public static final String authUrl = "authUrl"; - public static final String authMethod = "authMethod"; - public static final String key = "key"; - public static final String tokenDetails = "tokenDetails"; - public static final String authHeaders = "authHeaders"; - public static final String authParams = "authParams"; - public static final String queryTime = "queryTime"; - public static final String useTokenAuth = "useTokenAuth"; - public static final String hasAuthCallback = "hasAuthCallback"; - public static final String clientId = "clientId"; - public static final String logLevel = "logLevel"; - public static final String tls = "tls"; - public static final String restHost = "restHost"; - public static final String realtimeHost = "realtimeHost"; - public static final String port = "port"; - public static final String tlsPort = "tlsPort"; - public static final String autoConnect = "autoConnect"; - public static final String useBinaryProtocol = "useBinaryProtocol"; - public static final String queueMessages = "queueMessages"; - public static final String echoMessages = "echoMessages"; - public static final String recover = "recover"; - public static final String environment = "environment"; - public static final String idempotentRestPublishing = "idempotentRestPublishing"; - public static final String httpOpenTimeout = "httpOpenTimeout"; - public static final String httpRequestTimeout = "httpRequestTimeout"; - public static final String httpMaxRetryCount = "httpMaxRetryCount"; - public static final String realtimeRequestTimeout = "realtimeRequestTimeout"; - public static final String fallbackHosts = "fallbackHosts"; - public static final String fallbackHostsUseDefault = "fallbackHostsUseDefault"; - public static final String fallbackRetryTimeout = "fallbackRetryTimeout"; - public static final String defaultTokenParams = "defaultTokenParams"; - public static final String channelRetryTimeout = "channelRetryTimeout"; - public static final String transportParams = "transportParams"; - } - - public static final class TxRestChannelOptions { - public static final String cipherParams = "cipherParams"; - } - - public static final class TxRealtimeChannelOptions { - public static final String params = "params"; - public static final String modes = "modes"; - public static final String cipherParams = "cipherParams"; - } - - public static final class TxCipherParams { - public static final String androidHandle = "androidHandle"; - public static final String iosAlgorithm = "iosAlgorithm"; - public static final String iosKey = "iosKey"; - } - - public static final class TxTokenDetails { - public static final String token = "token"; - public static final String expires = "expires"; - public static final String issued = "issued"; - public static final String capability = "capability"; - public static final String clientId = "clientId"; - } - - public static final class TxTokenParams { - public static final String capability = "capability"; - public static final String clientId = "clientId"; - public static final String nonce = "nonce"; - public static final String timestamp = "timestamp"; - public static final String ttl = "ttl"; - } - - public static final class TxTokenRequest { - public static final String capability = "capability"; - public static final String clientId = "clientId"; - public static final String keyName = "keyName"; - public static final String mac = "mac"; - public static final String nonce = "nonce"; - public static final String timestamp = "timestamp"; - public static final String ttl = "ttl"; - } - - public static final class TxEnumConstants { - public static final String initialized = "initialized"; - public static final String connecting = "connecting"; - public static final String connected = "connected"; - public static final String disconnected = "disconnected"; - public static final String attaching = "attaching"; - public static final String attached = "attached"; - public static final String detaching = "detaching"; - public static final String detached = "detached"; - public static final String suspended = "suspended"; - public static final String closing = "closing"; - public static final String closed = "closed"; - public static final String failed = "failed"; - public static final String absent = "absent"; - public static final String leave = "leave"; - public static final String enter = "enter"; - public static final String present = "present"; - public static final String update = "update"; - public static final String presence = "presence"; - public static final String publish = "publish"; - public static final String subscribe = "subscribe"; - public static final String presenceSubscribe = "presenceSubscribe"; - } - - public static final class TxFormFactorEnum { - public static final String phone = "phone"; - public static final String tablet = "tablet"; - public static final String desktop = "desktop"; - public static final String tv = "tv"; - public static final String watch = "watch"; - public static final String car = "car"; - public static final String embedded = "embedded"; - public static final String other = "other"; - } - - public static final class TxLogLevelEnum { - public static final String none = "none"; - public static final String verbose = "verbose"; - public static final String debug = "debug"; - public static final String info = "info"; - public static final String warn = "warn"; - public static final String error = "error"; - } - - public static final class TxDevicePlatformEnum { - public static final String ios = "ios"; - public static final String android = "android"; - public static final String browser = "browser"; - } - - public static final class TxDevicePushStateEnum { - public static final String active = "active"; - public static final String failing = "failing"; - public static final String failed = "failed"; - } - - public static final class TxConnectionStateChange { - public static final String current = "current"; - public static final String previous = "previous"; - public static final String event = "event"; - public static final String retryIn = "retryIn"; - public static final String reason = "reason"; - } - - public static final class TxChannelStateChange { - public static final String current = "current"; - public static final String previous = "previous"; - public static final String event = "event"; - public static final String resumed = "resumed"; - public static final String reason = "reason"; - } - - public static final class TxMessage { - public static final String id = "id"; - public static final String timestamp = "timestamp"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - public static final String encoding = "encoding"; - public static final String data = "data"; - public static final String name = "name"; - public static final String extras = "extras"; - } - - public static final class TxPresenceMessage { - public static final String id = "id"; - public static final String action = "action"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - public static final String data = "data"; - public static final String encoding = "encoding"; - public static final String extras = "extras"; - public static final String timestamp = "timestamp"; - } - - public static final class TxPaginatedResult { - public static final String items = "items"; - public static final String type = "type"; - public static final String hasNext = "hasNext"; - } - - public static final class TxRestHistoryParams { - public static final String start = "start"; - public static final String end = "end"; - public static final String direction = "direction"; - public static final String limit = "limit"; - } - - public static final class TxRealtimeHistoryParams { - public static final String start = "start"; - public static final String end = "end"; - public static final String direction = "direction"; - public static final String limit = "limit"; - public static final String untilAttach = "untilAttach"; - } - - public static final class TxRestPresenceParams { - public static final String limit = "limit"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - } - - public static final class TxRealtimePresenceParams { - public static final String waitForSync = "waitForSync"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - } - - public static final class TxDeviceDetails { - public static final String id = "id"; - public static final String clientId = "clientId"; - public static final String platform = "platform"; - public static final String formFactor = "formFactor"; - public static final String metadata = "metadata"; - public static final String devicePushDetails = "devicePushDetails"; - } - - public static final class TxDevicePushDetails { - public static final String recipient = "recipient"; - public static final String state = "state"; - public static final String errorReason = "errorReason"; - } - - public static final class TxLocalDevice { - public static final String deviceSecret = "deviceSecret"; - public static final String deviceIdentityToken = "deviceIdentityToken"; - } - - public static final class TxPushChannelSubscription { - public static final String channel = "channel"; - public static final String deviceId = "deviceId"; - public static final String clientId = "clientId"; - } - - public static final class TxPushRequestPermission { - public static final String badge = "badge"; - public static final String sound = "sound"; - public static final String alert = "alert"; - public static final String carPlay = "carPlay"; - public static final String criticalAlert = "criticalAlert"; - public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; - public static final String provisional = "provisional"; - public static final String announcement = "announcement"; - } - - public static final class TxUNNotificationSettings { - public static final String authorizationStatus = "authorizationStatus"; - public static final String soundSetting = "soundSetting"; - public static final String badgeSetting = "badgeSetting"; - public static final String alertSetting = "alertSetting"; - public static final String notificationCenterSetting = "notificationCenterSetting"; - public static final String lockScreenSetting = "lockScreenSetting"; - public static final String carPlaySetting = "carPlaySetting"; - public static final String alertStyle = "alertStyle"; - public static final String showPreviewsSetting = "showPreviewsSetting"; - public static final String criticalAlertSetting = "criticalAlertSetting"; - public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; - public static final String announcementSetting = "announcementSetting"; - public static final String scheduledDeliverySetting = "scheduledDeliverySetting"; - public static final String timeSensitiveSetting = "timeSensitiveSetting"; - } - - public static final class TxUNNotificationSettingEnum { - public static final String notSupported = "notSupported"; - public static final String disabled = "disabled"; - public static final String enabled = "enabled"; - } - - public static final class TxUNAlertStyleEnum { - public static final String none = "none"; - public static final String banner = "banner"; - public static final String alert = "alert"; - } - - public static final class TxUNAuthorizationStatusEnum { - public static final String notDetermined = "notDetermined"; - public static final String denied = "denied"; - public static final String authorized = "authorized"; - public static final String provisional = "provisional"; - public static final String ephemeral = "ephemeral"; - } - - public static final class TxUNShowPreviewsSettingEnum { - public static final String always = "always"; - public static final String whenAuthenticated = "whenAuthenticated"; - public static final String never = "never"; - } - - public static final class TxRemoteMessage { - public static final String data = "data"; - public static final String notification = "notification"; - } - - public static final class TxNotification { - public static final String title = "title"; - public static final String body = "body"; - } - - public static final class TxCryptoGetParams { - public static final String algorithm = "algorithm"; - public static final String key = "key"; - } - - public static final class TxCryptoGenerateRandomKey { - public static final String keyLength = "keyLength"; - } + +final public class PlatformConstants { + + static final public class CodecTypes { + public static final byte ablyMessage = (byte) 128; + public static final byte ablyEventMessage = (byte) 129; + public static final byte clientOptions = (byte) 130; + public static final byte messageData = (byte) 131; + public static final byte messageExtras = (byte) 132; + public static final byte message = (byte) 133; + public static final byte tokenParams = (byte) 134; + public static final byte tokenDetails = (byte) 135; + public static final byte tokenRequest = (byte) 136; + public static final byte restChannelOptions = (byte) 137; + public static final byte realtimeChannelOptions = (byte) 138; + public static final byte paginatedResult = (byte) 139; + public static final byte restHistoryParams = (byte) 140; + public static final byte realtimeHistoryParams = (byte) 141; + public static final byte restPresenceParams = (byte) 142; + public static final byte presenceMessage = (byte) 143; + public static final byte realtimePresenceParams = (byte) 144; + public static final byte deviceDetails = (byte) 145; + public static final byte localDevice = (byte) 146; + public static final byte pushChannelSubscription = (byte) 147; + public static final byte unNotificationSettings = (byte) 148; + public static final byte remoteMessage = (byte) 149; + public static final byte errorInfo = (byte) 150; + public static final byte logLevel = (byte) 151; + public static final byte connectionStateChange = (byte) 152; + public static final byte channelStateChange = (byte) 153; + public static final byte cipherParams = (byte) 154; + } + + static final public class PlatformMethod { + public static final String getPlatformVersion = "getPlatformVersion"; + public static final String getVersion = "getVersion"; + public static final String resetAblyClients = "resetAblyClients"; + public static final String authCallback = "authCallback"; + public static final String realtimeAuthCallback = "realtimeAuthCallback"; + public static final String createRest = "createRest"; + public static final String setRestChannelOptions = "setRestChannelOptions"; + public static final String publish = "publish"; + public static final String restHistory = "restHistory"; + public static final String restPresenceGet = "restPresenceGet"; + public static final String restPresenceHistory = "restPresenceHistory"; + public static final String releaseRestChannel = "releaseRestChannel"; + public static final String createRealtime = "createRealtime"; + public static final String connectRealtime = "connectRealtime"; + public static final String closeRealtime = "closeRealtime"; + public static final String attachRealtimeChannel = "attachRealtimeChannel"; + public static final String detachRealtimeChannel = "detachRealtimeChannel"; + public static final String setRealtimeChannelOptions = "setRealtimeChannelOptions"; + public static final String realtimePresenceGet = "realtimePresenceGet"; + public static final String realtimePresenceHistory = "realtimePresenceHistory"; + public static final String realtimePresenceEnter = "realtimePresenceEnter"; + public static final String realtimePresenceUpdate = "realtimePresenceUpdate"; + public static final String realtimePresenceLeave = "realtimePresenceLeave"; + public static final String onRealtimePresenceMessage = "onRealtimePresenceMessage"; + public static final String publishRealtimeChannelMessage = "publishRealtimeChannelMessage"; + public static final String releaseRealtimeChannel = "releaseRealtimeChannel"; + public static final String realtimeHistory = "realtimeHistory"; + public static final String realtimeTime = "realtimeTime"; + public static final String restTime = "restTime"; + public static final String realtimeStats = "realtimeStats"; + public static final String pushActivate = "pushActivate"; + public static final String pushDeactivate = "pushDeactivate"; + public static final String pushSubscribeDevice = "pushSubscribeDevice"; + public static final String pushUnsubscribeDevice = "pushUnsubscribeDevice"; + public static final String pushSubscribeClient = "pushSubscribeClient"; + public static final String pushUnsubscribeClient = "pushUnsubscribeClient"; + public static final String pushListSubscriptions = "pushListSubscriptions"; + public static final String pushDevice = "pushDevice"; + public static final String pushRequestPermission = "pushRequestPermission"; + public static final String pushGetNotificationSettings = "pushGetNotificationSettings"; + public static final String pushOpenSettingsFor = "pushOpenSettingsFor"; + public static final String pushOnActivate = "pushOnActivate"; + public static final String pushOnDeactivate = "pushOnDeactivate"; + public static final String pushOnUpdateFailed = "pushOnUpdateFailed"; + public static final String pushNotificationTapLaunchedAppFromTerminated = "pushNotificationTapLaunchedAppFromTerminated"; + public static final String pushOnShowNotificationInForeground = "pushOnShowNotificationInForeground"; + public static final String pushOnMessage = "pushOnMessage"; + public static final String pushOnBackgroundMessage = "pushOnBackgroundMessage"; + public static final String pushOnNotificationTap = "pushOnNotificationTap"; + public static final String pushBackgroundFlutterApplicationReadyOnAndroid = "pushBackgroundFlutterApplicationReadyOnAndroid"; + public static final String onRealtimeConnectionStateChanged = "onRealtimeConnectionStateChanged"; + public static final String onRealtimeChannelStateChanged = "onRealtimeChannelStateChanged"; + public static final String onRealtimeChannelMessage = "onRealtimeChannelMessage"; + public static final String nextPage = "nextPage"; + public static final String firstPage = "firstPage"; + public static final String cryptoGetParams = "cryptoGetParams"; + public static final String cryptoGenerateRandomKey = "cryptoGenerateRandomKey"; + } + + static final public class TxTransportKeys { + public static final String channelName = "channelName"; + public static final String params = "params"; + public static final String data = "data"; + public static final String clientId = "clientId"; + public static final String options = "options"; + public static final String messages = "messages"; + } + + static final public class TxAblyMessage { + public static final String registrationHandle = "registrationHandle"; + public static final String type = "type"; + public static final String message = "message"; + } + + static final public class TxAblyEventMessage { + public static final String eventName = "eventName"; + public static final String type = "type"; + public static final String message = "message"; + } + + static final public class TxErrorInfo { + public static final String code = "code"; + public static final String message = "message"; + public static final String statusCode = "statusCode"; + public static final String href = "href"; + public static final String requestId = "requestId"; + public static final String cause = "cause"; + } + + static final public class TxMessageData { + public static final String data = "data"; + public static final String type = "type"; + } + + static final public class TxDeltaExtras { + public static final String format = "format"; + public static final String from = "from"; + } + + static final public class TxMessageExtras { + public static final String extras = "extras"; + public static final String delta = "delta"; + } + + static final public class TxClientOptions { + public static final String authUrl = "authUrl"; + public static final String authMethod = "authMethod"; + public static final String key = "key"; + public static final String tokenDetails = "tokenDetails"; + public static final String authHeaders = "authHeaders"; + public static final String authParams = "authParams"; + public static final String queryTime = "queryTime"; + public static final String useTokenAuth = "useTokenAuth"; + public static final String hasAuthCallback = "hasAuthCallback"; + public static final String clientId = "clientId"; + public static final String logLevel = "logLevel"; + public static final String tls = "tls"; + public static final String restHost = "restHost"; + public static final String realtimeHost = "realtimeHost"; + public static final String port = "port"; + public static final String tlsPort = "tlsPort"; + public static final String autoConnect = "autoConnect"; + public static final String useBinaryProtocol = "useBinaryProtocol"; + public static final String queueMessages = "queueMessages"; + public static final String echoMessages = "echoMessages"; + public static final String recover = "recover"; + public static final String environment = "environment"; + public static final String idempotentRestPublishing = "idempotentRestPublishing"; + public static final String httpOpenTimeout = "httpOpenTimeout"; + public static final String httpRequestTimeout = "httpRequestTimeout"; + public static final String httpMaxRetryCount = "httpMaxRetryCount"; + public static final String realtimeRequestTimeout = "realtimeRequestTimeout"; + public static final String fallbackHosts = "fallbackHosts"; + public static final String fallbackHostsUseDefault = "fallbackHostsUseDefault"; + public static final String fallbackRetryTimeout = "fallbackRetryTimeout"; + public static final String defaultTokenParams = "defaultTokenParams"; + public static final String channelRetryTimeout = "channelRetryTimeout"; + public static final String transportParams = "transportParams"; + } + + static final public class TxRestChannelOptions { + public static final String cipherParams = "cipherParams"; + } + + static final public class TxRealtimeChannelOptions { + public static final String params = "params"; + public static final String modes = "modes"; + public static final String cipherParams = "cipherParams"; + } + + static final public class TxCipherParams { + public static final String androidHandle = "androidHandle"; + public static final String iosAlgorithm = "iosAlgorithm"; + public static final String iosKey = "iosKey"; + } + + static final public class TxTokenDetails { + public static final String token = "token"; + public static final String expires = "expires"; + public static final String issued = "issued"; + public static final String capability = "capability"; + public static final String clientId = "clientId"; + } + + static final public class TxTokenParams { + public static final String capability = "capability"; + public static final String clientId = "clientId"; + public static final String nonce = "nonce"; + public static final String timestamp = "timestamp"; + public static final String ttl = "ttl"; + } + + static final public class TxTokenRequest { + public static final String capability = "capability"; + public static final String clientId = "clientId"; + public static final String keyName = "keyName"; + public static final String mac = "mac"; + public static final String nonce = "nonce"; + public static final String timestamp = "timestamp"; + public static final String ttl = "ttl"; + } + + static final public class TxEnumConstants { + public static final String initialized = "initialized"; + public static final String connecting = "connecting"; + public static final String connected = "connected"; + public static final String disconnected = "disconnected"; + public static final String attaching = "attaching"; + public static final String attached = "attached"; + public static final String detaching = "detaching"; + public static final String detached = "detached"; + public static final String suspended = "suspended"; + public static final String closing = "closing"; + public static final String closed = "closed"; + public static final String failed = "failed"; + public static final String absent = "absent"; + public static final String leave = "leave"; + public static final String enter = "enter"; + public static final String present = "present"; + public static final String update = "update"; + public static final String presence = "presence"; + public static final String publish = "publish"; + public static final String subscribe = "subscribe"; + public static final String presenceSubscribe = "presenceSubscribe"; + } + + static final public class TxFormFactorEnum { + public static final String phone = "phone"; + public static final String tablet = "tablet"; + public static final String desktop = "desktop"; + public static final String tv = "tv"; + public static final String watch = "watch"; + public static final String car = "car"; + public static final String embedded = "embedded"; + public static final String other = "other"; + } + + static final public class TxLogLevelEnum { + public static final String none = "none"; + public static final String verbose = "verbose"; + public static final String debug = "debug"; + public static final String info = "info"; + public static final String warn = "warn"; + public static final String error = "error"; + } + + static final public class TxDevicePlatformEnum { + public static final String ios = "ios"; + public static final String android = "android"; + public static final String browser = "browser"; + } + + static final public class TxDevicePushStateEnum { + public static final String active = "active"; + public static final String failing = "failing"; + public static final String failed = "failed"; + } + + static final public class TxConnectionStateChange { + public static final String current = "current"; + public static final String previous = "previous"; + public static final String event = "event"; + public static final String retryIn = "retryIn"; + public static final String reason = "reason"; + } + + static final public class TxChannelStateChange { + public static final String current = "current"; + public static final String previous = "previous"; + public static final String event = "event"; + public static final String resumed = "resumed"; + public static final String reason = "reason"; + } + + static final public class TxMessage { + public static final String id = "id"; + public static final String timestamp = "timestamp"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + public static final String encoding = "encoding"; + public static final String data = "data"; + public static final String name = "name"; + public static final String extras = "extras"; + } + + static final public class TxPresenceMessage { + public static final String id = "id"; + public static final String action = "action"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + public static final String data = "data"; + public static final String encoding = "encoding"; + public static final String extras = "extras"; + public static final String timestamp = "timestamp"; + } + + static final public class TxPaginatedResult { + public static final String items = "items"; + public static final String type = "type"; + public static final String hasNext = "hasNext"; + } + + static final public class TxRestHistoryParams { + public static final String start = "start"; + public static final String end = "end"; + public static final String direction = "direction"; + public static final String limit = "limit"; + } + + static final public class TxRealtimeHistoryParams { + public static final String start = "start"; + public static final String end = "end"; + public static final String direction = "direction"; + public static final String limit = "limit"; + public static final String untilAttach = "untilAttach"; + } + + static final public class TxRestPresenceParams { + public static final String limit = "limit"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + } + + static final public class TxRealtimePresenceParams { + public static final String waitForSync = "waitForSync"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + } + + static final public class TxDeviceDetails { + public static final String id = "id"; + public static final String clientId = "clientId"; + public static final String platform = "platform"; + public static final String formFactor = "formFactor"; + public static final String metadata = "metadata"; + public static final String devicePushDetails = "devicePushDetails"; + } + + static final public class TxDevicePushDetails { + public static final String recipient = "recipient"; + public static final String state = "state"; + public static final String errorReason = "errorReason"; + } + + static final public class TxLocalDevice { + public static final String deviceSecret = "deviceSecret"; + public static final String deviceIdentityToken = "deviceIdentityToken"; + } + + static final public class TxPushChannelSubscription { + public static final String channel = "channel"; + public static final String deviceId = "deviceId"; + public static final String clientId = "clientId"; + } + + static final public class TxPushRequestPermission { + public static final String badge = "badge"; + public static final String sound = "sound"; + public static final String alert = "alert"; + public static final String carPlay = "carPlay"; + public static final String criticalAlert = "criticalAlert"; + public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; + public static final String provisional = "provisional"; + public static final String announcement = "announcement"; + } + + static final public class TxUNNotificationSettings { + public static final String authorizationStatus = "authorizationStatus"; + public static final String soundSetting = "soundSetting"; + public static final String badgeSetting = "badgeSetting"; + public static final String alertSetting = "alertSetting"; + public static final String notificationCenterSetting = "notificationCenterSetting"; + public static final String lockScreenSetting = "lockScreenSetting"; + public static final String carPlaySetting = "carPlaySetting"; + public static final String alertStyle = "alertStyle"; + public static final String showPreviewsSetting = "showPreviewsSetting"; + public static final String criticalAlertSetting = "criticalAlertSetting"; + public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; + public static final String announcementSetting = "announcementSetting"; + public static final String scheduledDeliverySetting = "scheduledDeliverySetting"; + public static final String timeSensitiveSetting = "timeSensitiveSetting"; + } + + static final public class TxUNNotificationSettingEnum { + public static final String notSupported = "notSupported"; + public static final String disabled = "disabled"; + public static final String enabled = "enabled"; + } + + static final public class TxUNAlertStyleEnum { + public static final String none = "none"; + public static final String banner = "banner"; + public static final String alert = "alert"; + } + + static final public class TxUNAuthorizationStatusEnum { + public static final String notDetermined = "notDetermined"; + public static final String denied = "denied"; + public static final String authorized = "authorized"; + public static final String provisional = "provisional"; + public static final String ephemeral = "ephemeral"; + } + + static final public class TxUNShowPreviewsSettingEnum { + public static final String always = "always"; + public static final String whenAuthenticated = "whenAuthenticated"; + public static final String never = "never"; + } + + static final public class TxRemoteMessage { + public static final String data = "data"; + public static final String notification = "notification"; + } + + static final public class TxNotification { + public static final String title = "title"; + public static final String body = "body"; + } + + static final public class TxCryptoGetParams { + public static final String algorithm = "algorithm"; + public static final String key = "key"; + } + + static final public class TxCryptoGenerateRandomKey { + public static final String keyLength = "keyLength"; + } + } diff --git a/bin/codegen_context.dart b/bin/codegen_context.dart index e360ac433..6e20344af 100644 --- a/bin/codegen_context.dart +++ b/bin/codegen_context.dart @@ -96,6 +96,7 @@ const List> _platformMethods = [ {'name': 'realtimeHistory', 'value': 'realtimeHistory'}, {'name': 'realtimeTime', 'value': 'realtimeTime'}, {'name': 'restTime', 'value': 'restTime'}, + {'name': 'realtimeStats', 'value': 'realtimeStats'}, // Push Notifications {'name': 'pushActivate', 'value': 'pushActivate'}, diff --git a/ios/Classes/codec/AblyPlatformConstants.h b/ios/Classes/codec/AblyPlatformConstants.h index 3e70044cc..f7ab0f7a7 100644 --- a/ios/Classes/codec/AblyPlatformConstants.h +++ b/ios/Classes/codec/AblyPlatformConstants.h @@ -66,6 +66,7 @@ extern NSString *const AblyPlatformMethod_releaseRealtimeChannel; extern NSString *const AblyPlatformMethod_realtimeHistory; extern NSString *const AblyPlatformMethod_realtimeTime; extern NSString *const AblyPlatformMethod_restTime; +extern NSString *const AblyPlatformMethod_realtimeStats; extern NSString *const AblyPlatformMethod_pushActivate; extern NSString *const AblyPlatformMethod_pushDeactivate; extern NSString *const AblyPlatformMethod_pushSubscribeDevice; diff --git a/ios/Classes/codec/AblyPlatformConstants.m b/ios/Classes/codec/AblyPlatformConstants.m index 7f3f0acf3..ea516e0f8 100644 --- a/ios/Classes/codec/AblyPlatformConstants.m +++ b/ios/Classes/codec/AblyPlatformConstants.m @@ -36,6 +36,7 @@ NSString *const AblyPlatformMethod_realtimeHistory= @"realtimeHistory"; NSString *const AblyPlatformMethod_realtimeTime= @"realtimeTime"; NSString *const AblyPlatformMethod_restTime= @"restTime"; +NSString *const AblyPlatformMethod_realtimeStats= @"realtimeStats"; NSString *const AblyPlatformMethod_pushActivate= @"pushActivate"; NSString *const AblyPlatformMethod_pushDeactivate= @"pushDeactivate"; NSString *const AblyPlatformMethod_pushSubscribeDevice= @"pushSubscribeDevice"; diff --git a/lib/src/generated/platform_constants.dart b/lib/src/generated/platform_constants.dart index a744c4f39..10c0cfeb2 100644 --- a/lib/src/generated/platform_constants.dart +++ b/lib/src/generated/platform_constants.dart @@ -66,6 +66,7 @@ class PlatformMethod { static const String realtimeHistory = 'realtimeHistory'; static const String realtimeTime = 'realtimeTime'; static const String restTime = 'restTime'; + static const String realtimeStats = 'realtimeStats'; static const String pushActivate = 'pushActivate'; static const String pushDeactivate = 'pushDeactivate'; static const String pushSubscribeDevice = 'pushSubscribeDevice'; @@ -383,8 +384,7 @@ class TxPushRequestPermission { static const String alert = 'alert'; static const String carPlay = 'carPlay'; static const String criticalAlert = 'criticalAlert'; - static const String providesAppNotificationSettings = - 'providesAppNotificationSettings'; + static const String providesAppNotificationSettings = 'providesAppNotificationSettings'; static const String provisional = 'provisional'; static const String announcement = 'announcement'; } @@ -400,8 +400,7 @@ class TxUNNotificationSettings { static const String alertStyle = 'alertStyle'; static const String showPreviewsSetting = 'showPreviewsSetting'; static const String criticalAlertSetting = 'criticalAlertSetting'; - static const String providesAppNotificationSettings = - 'providesAppNotificationSettings'; + static const String providesAppNotificationSettings = 'providesAppNotificationSettings'; static const String announcementSetting = 'announcementSetting'; static const String scheduledDeliverySetting = 'scheduledDeliverySetting'; static const String timeSensitiveSetting = 'timeSensitiveSetting'; diff --git a/lib/src/platform/src/realtime/realtime.dart b/lib/src/platform/src/realtime/realtime.dart index 695d6a3e0..a8e215a2f 100644 --- a/lib/src/platform/src/realtime/realtime.dart +++ b/lib/src/platform/src/realtime/realtime.dart @@ -103,9 +103,9 @@ class Realtime extends PlatformObject { /// gets stats based on params as a [PaginatedResult] /// /// https://docs.ably.com/client-lib-development-guide/features/#RSC6 - // Future> stats([Map? params]) { - // throw UnimplementedError(); - // } + Future> stats([Map? params]) { + throw UnimplementedError(); + } /// returns server time /// From 94ab763e84a8ebd778cf7cc0e8b7384e672c7363 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Mon, 20 Dec 2021 14:03:01 +0000 Subject: [PATCH 39/51] Stats encoding from Android side --- .../ably/flutter/plugin/AblyMessageCodec.java | 85 +++++++++++++++++++ .../flutter/plugin/AblyMethodCallHandler.java | 16 ++++ .../plugin/generated/PlatformConstants.java | 51 +++++++++++ bin/codegen_context.dart | 65 ++++++++++++++ example/ios/Podfile.lock | 4 +- example/lib/ui/realtime_sliver.dart | 12 +++ ios/Classes/codec/AblyPlatformConstants.h | 44 ++++++++++ ios/Classes/codec/AblyPlatformConstants.m | 43 ++++++++++ lib/src/generated/platform_constants.dart | 51 +++++++++++ lib/src/platform/src/realtime/realtime.dart | 10 ++- 10 files changed, 377 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java index c73a318c4..6c56ef624 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java @@ -32,6 +32,7 @@ import io.ably.lib.types.MessageExtras; import io.ably.lib.types.Param; import io.ably.lib.types.PresenceMessage; +import io.ably.lib.types.Stats; import io.ably.lib.util.Crypto; import io.ably.lib.util.Log; import io.flutter.plugin.common.StandardMessageCodec; @@ -121,6 +122,9 @@ public AblyMessageCodec(CipherParamsStorage cipherParamsStorage) { put( PlatformConstants.CodecTypes.realtimeHistoryParams, new CodecPair<>(null, self::decodeRealtimeHistoryParams)); + put( + PlatformConstants.CodecTypes.stats, + new CodecPair<>(self::encodeStats,null)); put( PlatformConstants.CodecTypes.restPresenceParams, new CodecPair<>(null, self::decodeRestPresenceParams)); @@ -168,6 +172,87 @@ public AblyMessageCodec(CipherParamsStorage cipherParamsStorage) { }; } + private Map encodeStats(Stats stats) { + if (stats == null) return null; + final HashMap jsonMap = new HashMap<>(); + writeValueToJson(jsonMap, PlatformConstants.TxStats.all,encodeStatsMessageTypes(stats.all)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.apiRequests, encodeStatsRequestCount(stats.apiRequests)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.channels, encodeStatsResourceCount(stats.channels)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.connections, encodeStatsConnectionTypes(stats.connections)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.inbound, encodeStatsMessageTraffic(stats.inbound)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.intervalId, stats.intervalId); + writeValueToJson(jsonMap, PlatformConstants.TxStats.outbound, encodeStatsMessageTraffic(stats.outbound)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.persisted, encodeStatsMessageTypes(stats.persisted)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.tokenRequests, encodeStatsRequestCount(stats.tokenRequests)); + return jsonMap; + } + + private Map encodeStatsMessageTraffic(Stats.MessageTraffic messageTraffic) { + if (messageTraffic == null) return null; + final HashMap jsonMap = new HashMap<>(); + writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.all,encodeStatsMessageTypes(messageTraffic.all)); + writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.realtime, + encodeStatsMessageTypes(messageTraffic.realtime)); + writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.rest, + encodeStatsMessageTypes(messageTraffic.rest)); + writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.webhook, + encodeStatsMessageTypes(messageTraffic.webhook)); + return jsonMap; + } + + private Map encodeStatsConnectionTypes(Stats.ConnectionTypes connectionTypes) { + if (connectionTypes == null) return null; + final HashMap jsonMap = new HashMap<>(); + writeValueToJson(jsonMap, PlatformConstants.TxStatsConnectionTypes.all, + encodeStatsResourceCount(connectionTypes.all)); + writeValueToJson(jsonMap, PlatformConstants.TxStatsConnectionTypes.plain, + encodeStatsResourceCount(connectionTypes.plain)); + writeValueToJson(jsonMap, PlatformConstants.TxStatsConnectionTypes.tls, + encodeStatsResourceCount(connectionTypes.tls)); + return jsonMap; + } + + private Map encodeStatsResourceCount(Stats.ResourceCount resourceCount) { + if (resourceCount == null) return null; + final HashMap jsonMap = new HashMap<>(); + writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.mean,resourceCount.mean); + writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.min,resourceCount.min); + writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.opened,resourceCount.opened); + writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.peak,resourceCount.peak); + writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.refused,resourceCount.refused); + return jsonMap; + } + + private Map encodeStatsRequestCount(Stats.RequestCount apiRequests) { + if (apiRequests == null) return null; + final HashMap jsonMap = new HashMap<>(); + writeValueToJson(jsonMap,PlatformConstants.TxStatsRequestCount.succeeded,apiRequests.succeeded); + writeValueToJson(jsonMap,PlatformConstants.TxStatsRequestCount.failed,apiRequests.failed); + writeValueToJson(jsonMap,PlatformConstants.TxStatsRequestCount.refused,apiRequests.refused); + return jsonMap; + } + + private Map encodeStatsMessageTypes(Stats.MessageTypes messageTypes){ + if (messageTypes == null) return null; + final HashMap jsonMap = new HashMap<>(); + writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageTypes.all,encodeMessageCategory(messageTypes.all)); + writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageTypes.messages,encodeMessageCategory(messageTypes.messages)); + writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageTypes.presence,encodeMessageCategory(messageTypes.presence)); + return jsonMap; + } + //that's StatsMessageCount in Flutter's side + private Map encodeMessageCategory(Stats.MessageCategory category) { + if (category == null) return null; + if (category.category == null) return null; + final HashMap jsonMap = new HashMap<>(); + //There is a mapping consistencey issue between two, so just assume there is a single message for now + for (String key : category.category.keySet()){ + writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageCount.count, category.category.get(key).count); + writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageCount.data, category.category.get(key).data); + } + return jsonMap; + } + @Override protected Object readValueOfType(final byte type, final ByteBuffer buffer) { CodecPair pair = codecMap.get(type); diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java index fce3e4746..58114099f 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java @@ -90,6 +90,7 @@ public AblyMethodCallHandler( _map.put(PlatformConstants.PlatformMethod.releaseRealtimeChannel, this::releaseRealtimeChannel); _map.put(PlatformConstants.PlatformMethod.realtimeTime, this::realtimeTime); _map.put(PlatformConstants.PlatformMethod.restTime, this::restTime); + _map.put(PlatformConstants.PlatformMethod.realtimeStats, this::realtimeStats); // Push Notifications _map.put(PlatformConstants.PlatformMethod.pushActivate, this::pushActivate); @@ -357,6 +358,21 @@ private void getRestHistory(@NonNull MethodCall call, @NonNull MethodChannel.Res }); } + private void realtimeStats(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + final AblyFlutterMessage> paramsMessage = (AblyFlutterMessage>) message.message; + final Map map = paramsMessage.message; + final String channelName = + (String) map.get(PlatformConstants.TxTransportKeys.channelName); + Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); + if (params == null) { + params = new Param[0]; + } + instanceStore + .getRealtime(paramsMessage.handle) + .statsAsync(params, this.paginatedResponseHandler(result, null)); + } + private void getRestPresence(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; this.>>ablyDo( diff --git a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java index a750fbb56..509444846 100644 --- a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java +++ b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java @@ -36,6 +36,7 @@ static final public class CodecTypes { public static final byte connectionStateChange = (byte) 152; public static final byte channelStateChange = (byte) 153; public static final byte cipherParams = (byte) 154; + public static final byte stats = (byte) 155; } static final public class PlatformMethod { @@ -447,4 +448,54 @@ static final public class TxCryptoGenerateRandomKey { public static final String keyLength = "keyLength"; } + static final public class TxStats { + public static final String all = "all"; + public static final String apiRequests = "apiRequests"; + public static final String channels = "channels"; + public static final String connections = "connections"; + public static final String inbound = "inbound"; + public static final String intervalId = "intervalId"; + public static final String outbound = "outbound"; + public static final String persisted = "persisted"; + public static final String tokenRequests = "tokenRequests"; + } + + static final public class TxStatsMessageTypes { + public static final String all = "all"; + public static final String messages = "messages"; + public static final String presence = "presence"; + } + + static final public class TxStatsMessageCount { + public static final String count = "count"; + public static final String data = "data"; + } + + static final public class TxStatsRequestCount { + public static final String failed = "failed"; + public static final String refused = "refused"; + public static final String succeeded = "succeeded"; + } + + static final public class TxStatsResourceCount { + public static final String mean = "mean"; + public static final String min = "min"; + public static final String opened = "opened"; + public static final String peak = "peak"; + public static final String refused = "refused"; + } + + static final public class TxStatsConnectionTypes { + public static final String all = "all"; + public static final String plain = "plain"; + public static final String tls = "tls"; + } + + static final public class TxStatsMessageTraffic { + public static final String all = "all"; + public static final String realtime = "realtime"; + public static final String rest = "rest"; + public static final String webhook = "webhook"; + } + } diff --git a/bin/codegen_context.dart b/bin/codegen_context.dart index 6e20344af..190d58a2f 100644 --- a/bin/codegen_context.dart +++ b/bin/codegen_context.dart @@ -38,6 +38,7 @@ Iterable> get _types sync* { // Encryption 'cipherParams', + 'stats', ]; // Custom type values must be over 127. At the time of writing @@ -510,6 +511,70 @@ const List> _objects = [ { 'name': 'CryptoGenerateRandomKey', 'properties': ['keyLength'] + }, + { + 'name': 'Stats', + 'properties': [ + 'all', + 'apiRequests', + 'channels', + 'connections', + 'inbound', + 'intervalId', + 'outbound', + 'persisted', + 'tokenRequests' + ] + }, + { + 'name': 'StatsMessageTypes', + 'properties': [ + 'all', + 'messages', + 'presence' + ] + }, + { + 'name': 'StatsMessageCount', + 'properties': [ + 'count', + 'data' + ] + }, + { + 'name': 'StatsRequestCount', + 'properties': [ + 'failed', + 'refused', + 'succeeded' + ] + }, + { + 'name': 'StatsResourceCount', + 'properties': [ + 'mean', + 'min', + 'opened', + 'peak', + 'refused' + ] + }, + { + 'name': 'StatsConnectionTypes', + 'properties': [ + 'all', + 'plain', + 'tls' + ] + }, + { + 'name': 'StatsMessageTraffic', + 'properties': [ + 'all', + 'realtime', + 'rest', + 'webhook' + ] } ]; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 06942f913..f530dd118 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2,7 +2,7 @@ PODS: - Ably (1.2.7): - AblyDeltaCodec (= 1.3.2) - msgpack (= 0.4.0) - - ably_flutter (1.2.5): + - ably_flutter (1.2.6): - Ably (= 1.2.7) - Flutter - AblyDeltaCodec (1.3.2) @@ -45,7 +45,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Ably: f627c0c2e4489785b74d33d2c1287edeb9c6a7be - ably_flutter: 43b5908539837dd5020a07a3ed7a6133a3275fa2 + ably_flutter: 7cf00f53f2fbafa97409987fb93075aa254624b3 AblyDeltaCodec: 783d017270de70bbbc0a84e4235297b225d33636 device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a diff --git a/example/lib/ui/realtime_sliver.dart b/example/lib/ui/realtime_sliver.dart index fdfd14d4e..0cc726cdb 100644 --- a/example/lib/ui/realtime_sliver.dart +++ b/example/lib/ui/realtime_sliver.dart @@ -238,6 +238,18 @@ class RealtimeSliver extends HookWidget { TextRow('Data', message.data.toString()), ], )), + PaginatedResultViewer( + title: 'Stats', + subtitle: TextRow( + 'What is it?', + 'Realtime stats'), + query: () => realtime.stats(), + builder: (context, stat, _) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextRow('Statistics ', stat.toString()), + ], + )), RealtimePresenceSliver(realtime, channel), ], ); diff --git a/ios/Classes/codec/AblyPlatformConstants.h b/ios/Classes/codec/AblyPlatformConstants.h index f7ab0f7a7..7b30ca072 100644 --- a/ios/Classes/codec/AblyPlatformConstants.h +++ b/ios/Classes/codec/AblyPlatformConstants.h @@ -33,6 +33,7 @@ typedef NS_ENUM(UInt8, CodecType) { CodecTypeConnectionStateChange = 152, CodecTypeChannelStateChange = 153, CodecTypeCipherParams = 154, + CodecTypeStats = 155, }; @@ -401,3 +402,46 @@ extern NSString *const TxCryptoGetParams_key; // key constants for CryptoGenerateRandomKey extern NSString *const TxCryptoGenerateRandomKey_keyLength; + +// key constants for Stats +extern NSString *const TxStats_all; +extern NSString *const TxStats_apiRequests; +extern NSString *const TxStats_channels; +extern NSString *const TxStats_connections; +extern NSString *const TxStats_inbound; +extern NSString *const TxStats_intervalId; +extern NSString *const TxStats_outbound; +extern NSString *const TxStats_persisted; +extern NSString *const TxStats_tokenRequests; + +// key constants for StatsMessageTypes +extern NSString *const TxStatsMessageTypes_all; +extern NSString *const TxStatsMessageTypes_messages; +extern NSString *const TxStatsMessageTypes_presence; + +// key constants for StatsMessageCount +extern NSString *const TxStatsMessageCount_count; +extern NSString *const TxStatsMessageCount_data; + +// key constants for StatsRequestCount +extern NSString *const TxStatsRequestCount_failed; +extern NSString *const TxStatsRequestCount_refused; +extern NSString *const TxStatsRequestCount_succeeded; + +// key constants for StatsResourceCount +extern NSString *const TxStatsResourceCount_mean; +extern NSString *const TxStatsResourceCount_min; +extern NSString *const TxStatsResourceCount_opened; +extern NSString *const TxStatsResourceCount_peak; +extern NSString *const TxStatsResourceCount_refused; + +// key constants for StatsConnectionTypes +extern NSString *const TxStatsConnectionTypes_all; +extern NSString *const TxStatsConnectionTypes_plain; +extern NSString *const TxStatsConnectionTypes_tls; + +// key constants for StatsMessageTraffic +extern NSString *const TxStatsMessageTraffic_all; +extern NSString *const TxStatsMessageTraffic_realtime; +extern NSString *const TxStatsMessageTraffic_rest; +extern NSString *const TxStatsMessageTraffic_webhook; diff --git a/ios/Classes/codec/AblyPlatformConstants.m b/ios/Classes/codec/AblyPlatformConstants.m index ea516e0f8..35574d4ca 100644 --- a/ios/Classes/codec/AblyPlatformConstants.m +++ b/ios/Classes/codec/AblyPlatformConstants.m @@ -371,3 +371,46 @@ // key constants for CryptoGenerateRandomKey NSString *const TxCryptoGenerateRandomKey_keyLength = @"keyLength"; + +// key constants for Stats +NSString *const TxStats_all = @"all"; +NSString *const TxStats_apiRequests = @"apiRequests"; +NSString *const TxStats_channels = @"channels"; +NSString *const TxStats_connections = @"connections"; +NSString *const TxStats_inbound = @"inbound"; +NSString *const TxStats_intervalId = @"intervalId"; +NSString *const TxStats_outbound = @"outbound"; +NSString *const TxStats_persisted = @"persisted"; +NSString *const TxStats_tokenRequests = @"tokenRequests"; + +// key constants for StatsMessageTypes +NSString *const TxStatsMessageTypes_all = @"all"; +NSString *const TxStatsMessageTypes_messages = @"messages"; +NSString *const TxStatsMessageTypes_presence = @"presence"; + +// key constants for StatsMessageCount +NSString *const TxStatsMessageCount_count = @"count"; +NSString *const TxStatsMessageCount_data = @"data"; + +// key constants for StatsRequestCount +NSString *const TxStatsRequestCount_failed = @"failed"; +NSString *const TxStatsRequestCount_refused = @"refused"; +NSString *const TxStatsRequestCount_succeeded = @"succeeded"; + +// key constants for StatsResourceCount +NSString *const TxStatsResourceCount_mean = @"mean"; +NSString *const TxStatsResourceCount_min = @"min"; +NSString *const TxStatsResourceCount_opened = @"opened"; +NSString *const TxStatsResourceCount_peak = @"peak"; +NSString *const TxStatsResourceCount_refused = @"refused"; + +// key constants for StatsConnectionTypes +NSString *const TxStatsConnectionTypes_all = @"all"; +NSString *const TxStatsConnectionTypes_plain = @"plain"; +NSString *const TxStatsConnectionTypes_tls = @"tls"; + +// key constants for StatsMessageTraffic +NSString *const TxStatsMessageTraffic_all = @"all"; +NSString *const TxStatsMessageTraffic_realtime = @"realtime"; +NSString *const TxStatsMessageTraffic_rest = @"rest"; +NSString *const TxStatsMessageTraffic_webhook = @"webhook"; diff --git a/lib/src/generated/platform_constants.dart b/lib/src/generated/platform_constants.dart index 10c0cfeb2..4dad84c76 100644 --- a/lib/src/generated/platform_constants.dart +++ b/lib/src/generated/platform_constants.dart @@ -33,6 +33,7 @@ class CodecTypes { static const int connectionStateChange = 152; static const int channelStateChange = 153; static const int cipherParams = 154; + static const int stats = 155; } class PlatformMethod { @@ -450,3 +451,53 @@ class TxCryptoGetParams { class TxCryptoGenerateRandomKey { static const String keyLength = 'keyLength'; } + +class TxStats { + static const String all = 'all'; + static const String apiRequests = 'apiRequests'; + static const String channels = 'channels'; + static const String connections = 'connections'; + static const String inbound = 'inbound'; + static const String intervalId = 'intervalId'; + static const String outbound = 'outbound'; + static const String persisted = 'persisted'; + static const String tokenRequests = 'tokenRequests'; +} + +class TxStatsMessageTypes { + static const String all = 'all'; + static const String messages = 'messages'; + static const String presence = 'presence'; +} + +class TxStatsMessageCount { + static const String count = 'count'; + static const String data = 'data'; +} + +class TxStatsRequestCount { + static const String failed = 'failed'; + static const String refused = 'refused'; + static const String succeeded = 'succeeded'; +} + +class TxStatsResourceCount { + static const String mean = 'mean'; + static const String min = 'min'; + static const String opened = 'opened'; + static const String peak = 'peak'; + static const String refused = 'refused'; +} + +class TxStatsConnectionTypes { + static const String all = 'all'; + static const String plain = 'plain'; + static const String tls = 'tls'; +} + +class TxStatsMessageTraffic { + static const String all = 'all'; + static const String realtime = 'realtime'; + static const String rest = 'rest'; + static const String webhook = 'webhook'; +} diff --git a/lib/src/platform/src/realtime/realtime.dart b/lib/src/platform/src/realtime/realtime.dart index a8e215a2f..76cf0c07a 100644 --- a/lib/src/platform/src/realtime/realtime.dart +++ b/lib/src/platform/src/realtime/realtime.dart @@ -103,8 +103,14 @@ class Realtime extends PlatformObject { /// gets stats based on params as a [PaginatedResult] /// /// https://docs.ably.com/client-lib-development-guide/features/#RSC6 - Future> stats([Map? params]) { - throw UnimplementedError(); + Future> stats([Map params = const {}]) async{ + final message = + await invokeRequest(PlatformMethod.realtimeStats,{ + TxTransportKeys.params: params + }); + return PaginatedResult.fromAblyMessage( + AblyMessage.castFrom(message), + ); } /// returns server time From a0e4b9c519aad9aea287ff331b6840d3399b8ce7 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Tue, 21 Dec 2021 09:50:41 +0000 Subject: [PATCH 40/51] Moved stats mapping from realtime to rest --- .../flutter/plugin/AblyMethodCallHandler.java | 20 +++++++++++-------- .../plugin/generated/PlatformConstants.java | 2 +- bin/codegen_context.dart | 2 +- example/lib/ui/realtime_sliver.dart | 13 +----------- example/lib/ui/rest_sliver.dart | 13 ++++++++++++ ios/Classes/codec/AblyPlatformConstants.h | 2 +- ios/Classes/codec/AblyPlatformConstants.m | 2 +- lib/src/generated/platform_constants.dart | 2 +- lib/src/platform/src/realtime/realtime.dart | 13 ------------ lib/src/platform/src/rest/rest.dart | 12 ++++++++--- 10 files changed, 40 insertions(+), 41 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java index 58114099f..f7aa37684 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java @@ -90,7 +90,7 @@ public AblyMethodCallHandler( _map.put(PlatformConstants.PlatformMethod.releaseRealtimeChannel, this::releaseRealtimeChannel); _map.put(PlatformConstants.PlatformMethod.realtimeTime, this::realtimeTime); _map.put(PlatformConstants.PlatformMethod.restTime, this::restTime); - _map.put(PlatformConstants.PlatformMethod.realtimeStats, this::realtimeStats); + _map.put(PlatformConstants.PlatformMethod.stats, this::stats); // Push Notifications _map.put(PlatformConstants.PlatformMethod.pushActivate, this::pushActivate); @@ -358,18 +358,22 @@ private void getRestHistory(@NonNull MethodCall call, @NonNull MethodChannel.Res }); } - private void realtimeStats(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + private void stats(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; final AblyFlutterMessage> paramsMessage = (AblyFlutterMessage>) message.message; final Map map = paramsMessage.message; - final String channelName = - (String) map.get(PlatformConstants.TxTransportKeys.channelName); - Param[] params = (Param[]) map.get(PlatformConstants.TxTransportKeys.params); - if (params == null) { - params = new Param[0]; + final HashMap paramsMap = + (HashMap) map.get(PlatformConstants.TxTransportKeys.params); + Param[] params = new Param[paramsMap != null ? paramsMap.size():0]; + if (paramsMap != null) { + int i = 0; + for (String paramKey: paramsMap.keySet()){ + final Param param = new Param(paramKey,paramsMap.get(paramKey)); + params[i++] = param; + } } instanceStore - .getRealtime(paramsMessage.handle) + .getRest(paramsMessage.handle) .statsAsync(params, this.paginatedResponseHandler(result, null)); } diff --git a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java index 509444846..498c03cb5 100644 --- a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java +++ b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java @@ -69,7 +69,7 @@ static final public class PlatformMethod { public static final String realtimeHistory = "realtimeHistory"; public static final String realtimeTime = "realtimeTime"; public static final String restTime = "restTime"; - public static final String realtimeStats = "realtimeStats"; + public static final String stats = "stats"; public static final String pushActivate = "pushActivate"; public static final String pushDeactivate = "pushDeactivate"; public static final String pushSubscribeDevice = "pushSubscribeDevice"; diff --git a/bin/codegen_context.dart b/bin/codegen_context.dart index 190d58a2f..c836f55cd 100644 --- a/bin/codegen_context.dart +++ b/bin/codegen_context.dart @@ -97,7 +97,7 @@ const List> _platformMethods = [ {'name': 'realtimeHistory', 'value': 'realtimeHistory'}, {'name': 'realtimeTime', 'value': 'realtimeTime'}, {'name': 'restTime', 'value': 'restTime'}, - {'name': 'realtimeStats', 'value': 'realtimeStats'}, + {'name': 'stats', 'value': 'stats'}, // Push Notifications {'name': 'pushActivate', 'value': 'pushActivate'}, diff --git a/example/lib/ui/realtime_sliver.dart b/example/lib/ui/realtime_sliver.dart index 0cc726cdb..b38407461 100644 --- a/example/lib/ui/realtime_sliver.dart +++ b/example/lib/ui/realtime_sliver.dart @@ -238,18 +238,7 @@ class RealtimeSliver extends HookWidget { TextRow('Data', message.data.toString()), ], )), - PaginatedResultViewer( - title: 'Stats', - subtitle: TextRow( - 'What is it?', - 'Realtime stats'), - query: () => realtime.stats(), - builder: (context, stat, _) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextRow('Statistics ', stat.toString()), - ], - )), + RealtimePresenceSliver(realtime, channel), ], ); diff --git a/example/lib/ui/rest_sliver.dart b/example/lib/ui/rest_sliver.dart index 78195594a..740ffc6fb 100644 --- a/example/lib/ui/rest_sliver.dart +++ b/example/lib/ui/rest_sliver.dart @@ -91,7 +91,20 @@ class RestSliver extends HookWidget { channel.presence.history(ably.RestHistoryParams(limit: 10)), builder: (context, message, _) => TextRow('Message name', '${message.id}:${message.clientId}:${message.data}')), + PaginatedResultViewer( + title: 'Stats', + subtitle: TextRow( + 'What is it?', + 'Realtime stats'), + query: () => rest.stats(), + builder: (context, stat, _) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextRow('Statistics ', stat.toString()), + ], + )), ], ); + } } diff --git a/ios/Classes/codec/AblyPlatformConstants.h b/ios/Classes/codec/AblyPlatformConstants.h index 7b30ca072..193c4160b 100644 --- a/ios/Classes/codec/AblyPlatformConstants.h +++ b/ios/Classes/codec/AblyPlatformConstants.h @@ -67,7 +67,7 @@ extern NSString *const AblyPlatformMethod_releaseRealtimeChannel; extern NSString *const AblyPlatformMethod_realtimeHistory; extern NSString *const AblyPlatformMethod_realtimeTime; extern NSString *const AblyPlatformMethod_restTime; -extern NSString *const AblyPlatformMethod_realtimeStats; +extern NSString *const AblyPlatformMethod_stats; extern NSString *const AblyPlatformMethod_pushActivate; extern NSString *const AblyPlatformMethod_pushDeactivate; extern NSString *const AblyPlatformMethod_pushSubscribeDevice; diff --git a/ios/Classes/codec/AblyPlatformConstants.m b/ios/Classes/codec/AblyPlatformConstants.m index 35574d4ca..ead5db17b 100644 --- a/ios/Classes/codec/AblyPlatformConstants.m +++ b/ios/Classes/codec/AblyPlatformConstants.m @@ -36,7 +36,7 @@ NSString *const AblyPlatformMethod_realtimeHistory= @"realtimeHistory"; NSString *const AblyPlatformMethod_realtimeTime= @"realtimeTime"; NSString *const AblyPlatformMethod_restTime= @"restTime"; -NSString *const AblyPlatformMethod_realtimeStats= @"realtimeStats"; +NSString *const AblyPlatformMethod_stats= @"stats"; NSString *const AblyPlatformMethod_pushActivate= @"pushActivate"; NSString *const AblyPlatformMethod_pushDeactivate= @"pushDeactivate"; NSString *const AblyPlatformMethod_pushSubscribeDevice= @"pushSubscribeDevice"; diff --git a/lib/src/generated/platform_constants.dart b/lib/src/generated/platform_constants.dart index 4dad84c76..2d978f22a 100644 --- a/lib/src/generated/platform_constants.dart +++ b/lib/src/generated/platform_constants.dart @@ -67,7 +67,7 @@ class PlatformMethod { static const String realtimeHistory = 'realtimeHistory'; static const String realtimeTime = 'realtimeTime'; static const String restTime = 'restTime'; - static const String realtimeStats = 'realtimeStats'; + static const String stats = 'stats'; static const String pushActivate = 'pushActivate'; static const String pushDeactivate = 'pushDeactivate'; static const String pushSubscribeDevice = 'pushSubscribeDevice'; diff --git a/lib/src/platform/src/realtime/realtime.dart b/lib/src/platform/src/realtime/realtime.dart index 76cf0c07a..9912f6077 100644 --- a/lib/src/platform/src/realtime/realtime.dart +++ b/lib/src/platform/src/realtime/realtime.dart @@ -100,19 +100,6 @@ class Realtime extends PlatformObject { // throw UnimplementedError(); // } - /// gets stats based on params as a [PaginatedResult] - /// - /// https://docs.ably.com/client-lib-development-guide/features/#RSC6 - Future> stats([Map params = const {}]) async{ - final message = - await invokeRequest(PlatformMethod.realtimeStats,{ - TxTransportKeys.params: params - }); - return PaginatedResult.fromAblyMessage( - AblyMessage.castFrom(message), - ); - } - /// returns server time /// /// https://docs.ably.com/client-lib-development-guide/features/#RSC16 diff --git a/lib/src/platform/src/rest/rest.dart b/lib/src/platform/src/rest/rest.dart index 8c2e8e4a5..46367b3f2 100644 --- a/lib/src/platform/src/rest/rest.dart +++ b/lib/src/platform/src/rest/rest.dart @@ -58,9 +58,15 @@ class Rest extends PlatformObject { /// gets stats based on params as a [PaginatedResult] /// /// https://docs.ably.com/client-lib-development-guide/features/#RSC6 - // Future> stats([Map? params]) { - // throw UnimplementedError(); - // } + Future> stats([Map params = const {}]) async{ + final message = + await invokeRequest(PlatformMethod.stats,{ + TxTransportKeys.params: params + }); + return PaginatedResult.fromAblyMessage( + AblyMessage.castFrom(message), + ); + } /// returns server time /// From a473266b86b9e467924f762566209abbdff3fa00 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Tue, 21 Dec 2021 15:30:02 +0000 Subject: [PATCH 41/51] File formatting --- .../ably/flutter/plugin/AblyMessageCodec.java | 120 ++- .../flutter/plugin/AblyMethodCallHandler.java | 35 +- .../plugin/generated/PlatformConstants.java | 988 +++++++++--------- bin/codegen_context.dart | 38 +- example/lib/ui/realtime_sliver.dart | 1 - example/lib/ui/rest_sliver.dart | 15 +- lib/src/generated/platform_constants.dart | 6 +- lib/src/platform/src/rest/rest.dart | 8 +- 8 files changed, 611 insertions(+), 600 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java index 6c56ef624..be6b09550 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java @@ -122,9 +122,7 @@ public AblyMessageCodec(CipherParamsStorage cipherParamsStorage) { put( PlatformConstants.CodecTypes.realtimeHistoryParams, new CodecPair<>(null, self::decodeRealtimeHistoryParams)); - put( - PlatformConstants.CodecTypes.stats, - new CodecPair<>(self::encodeStats,null)); + put(PlatformConstants.CodecTypes.stats, new CodecPair<>(self::encodeStats, null)); put( PlatformConstants.CodecTypes.restPresenceParams, new CodecPair<>(null, self::decodeRestPresenceParams)); @@ -175,80 +173,120 @@ public AblyMessageCodec(CipherParamsStorage cipherParamsStorage) { private Map encodeStats(Stats stats) { if (stats == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson(jsonMap, PlatformConstants.TxStats.all,encodeStatsMessageTypes(stats.all)); - writeValueToJson(jsonMap, PlatformConstants.TxStats.apiRequests, encodeStatsRequestCount(stats.apiRequests)); - writeValueToJson(jsonMap, PlatformConstants.TxStats.channels, encodeStatsResourceCount(stats.channels)); - writeValueToJson(jsonMap, PlatformConstants.TxStats.connections, encodeStatsConnectionTypes(stats.connections)); - writeValueToJson(jsonMap, PlatformConstants.TxStats.inbound, encodeStatsMessageTraffic(stats.inbound)); + writeValueToJson(jsonMap, PlatformConstants.TxStats.all, encodeStatsMessageTypes(stats.all)); + writeValueToJson( + jsonMap, PlatformConstants.TxStats.apiRequests, encodeStatsRequestCount(stats.apiRequests)); + writeValueToJson( + jsonMap, PlatformConstants.TxStats.channels, encodeStatsResourceCount(stats.channels)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStats.connections, + encodeStatsConnectionTypes(stats.connections)); + writeValueToJson( + jsonMap, PlatformConstants.TxStats.inbound, encodeStatsMessageTraffic(stats.inbound)); writeValueToJson(jsonMap, PlatformConstants.TxStats.intervalId, stats.intervalId); - writeValueToJson(jsonMap, PlatformConstants.TxStats.outbound, encodeStatsMessageTraffic(stats.outbound)); - writeValueToJson(jsonMap, PlatformConstants.TxStats.persisted, encodeStatsMessageTypes(stats.persisted)); - writeValueToJson(jsonMap, PlatformConstants.TxStats.tokenRequests, encodeStatsRequestCount(stats.tokenRequests)); + writeValueToJson( + jsonMap, PlatformConstants.TxStats.outbound, encodeStatsMessageTraffic(stats.outbound)); + writeValueToJson( + jsonMap, PlatformConstants.TxStats.persisted, encodeStatsMessageTypes(stats.persisted)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStats.tokenRequests, + encodeStatsRequestCount(stats.tokenRequests)); return jsonMap; } private Map encodeStatsMessageTraffic(Stats.MessageTraffic messageTraffic) { if (messageTraffic == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.all,encodeStatsMessageTypes(messageTraffic.all)); - writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.realtime, - encodeStatsMessageTypes(messageTraffic.realtime)); - writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.rest, - encodeStatsMessageTypes(messageTraffic.rest)); - writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageTraffic.webhook, - encodeStatsMessageTypes(messageTraffic.webhook)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTraffic.all, + encodeStatsMessageTypes(messageTraffic.all)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTraffic.realtime, + encodeStatsMessageTypes(messageTraffic.realtime)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTraffic.rest, + encodeStatsMessageTypes(messageTraffic.rest)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTraffic.webhook, + encodeStatsMessageTypes(messageTraffic.webhook)); return jsonMap; } private Map encodeStatsConnectionTypes(Stats.ConnectionTypes connectionTypes) { if (connectionTypes == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson(jsonMap, PlatformConstants.TxStatsConnectionTypes.all, - encodeStatsResourceCount(connectionTypes.all)); - writeValueToJson(jsonMap, PlatformConstants.TxStatsConnectionTypes.plain, - encodeStatsResourceCount(connectionTypes.plain)); - writeValueToJson(jsonMap, PlatformConstants.TxStatsConnectionTypes.tls, - encodeStatsResourceCount(connectionTypes.tls)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsConnectionTypes.all, + encodeStatsResourceCount(connectionTypes.all)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsConnectionTypes.plain, + encodeStatsResourceCount(connectionTypes.plain)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsConnectionTypes.tls, + encodeStatsResourceCount(connectionTypes.tls)); return jsonMap; } private Map encodeStatsResourceCount(Stats.ResourceCount resourceCount) { if (resourceCount == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.mean,resourceCount.mean); - writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.min,resourceCount.min); - writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.opened,resourceCount.opened); - writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.peak,resourceCount.peak); - writeValueToJson(jsonMap,PlatformConstants.TxStatsResourceCount.refused,resourceCount.refused); + writeValueToJson(jsonMap, PlatformConstants.TxStatsResourceCount.mean, resourceCount.mean); + writeValueToJson(jsonMap, PlatformConstants.TxStatsResourceCount.min, resourceCount.min); + writeValueToJson(jsonMap, PlatformConstants.TxStatsResourceCount.opened, resourceCount.opened); + writeValueToJson(jsonMap, PlatformConstants.TxStatsResourceCount.peak, resourceCount.peak); + writeValueToJson( + jsonMap, PlatformConstants.TxStatsResourceCount.refused, resourceCount.refused); return jsonMap; } private Map encodeStatsRequestCount(Stats.RequestCount apiRequests) { if (apiRequests == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson(jsonMap,PlatformConstants.TxStatsRequestCount.succeeded,apiRequests.succeeded); - writeValueToJson(jsonMap,PlatformConstants.TxStatsRequestCount.failed,apiRequests.failed); - writeValueToJson(jsonMap,PlatformConstants.TxStatsRequestCount.refused,apiRequests.refused); + writeValueToJson( + jsonMap, PlatformConstants.TxStatsRequestCount.succeeded, apiRequests.succeeded); + writeValueToJson(jsonMap, PlatformConstants.TxStatsRequestCount.failed, apiRequests.failed); + writeValueToJson(jsonMap, PlatformConstants.TxStatsRequestCount.refused, apiRequests.refused); return jsonMap; } - private Map encodeStatsMessageTypes(Stats.MessageTypes messageTypes){ + private Map encodeStatsMessageTypes(Stats.MessageTypes messageTypes) { if (messageTypes == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageTypes.all,encodeMessageCategory(messageTypes.all)); - writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageTypes.messages,encodeMessageCategory(messageTypes.messages)); - writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageTypes.presence,encodeMessageCategory(messageTypes.presence)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTypes.all, + encodeMessageCategory(messageTypes.all)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTypes.messages, + encodeMessageCategory(messageTypes.messages)); + writeValueToJson( + jsonMap, + PlatformConstants.TxStatsMessageTypes.presence, + encodeMessageCategory(messageTypes.presence)); return jsonMap; } - //that's StatsMessageCount in Flutter's side + // that's StatsMessageCount in Flutter's side private Map encodeMessageCategory(Stats.MessageCategory category) { if (category == null) return null; if (category.category == null) return null; final HashMap jsonMap = new HashMap<>(); - //There is a mapping consistencey issue between two, so just assume there is a single message for now - for (String key : category.category.keySet()){ - writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageCount.count, category.category.get(key).count); - writeValueToJson(jsonMap,PlatformConstants.TxStatsMessageCount.data, category.category.get(key).data); + // There is a mapping consistencey issue between two, so just assume there is a single message + // for now + for (String key : category.category.keySet()) { + writeValueToJson( + jsonMap, PlatformConstants.TxStatsMessageCount.count, category.category.get(key).count); + writeValueToJson( + jsonMap, PlatformConstants.TxStatsMessageCount.data, category.category.get(key).data); } return jsonMap; } diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java index f7aa37684..c00f12461 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMethodCallHandler.java @@ -358,24 +358,25 @@ private void getRestHistory(@NonNull MethodCall call, @NonNull MethodChannel.Res }); } - private void stats(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; - final AblyFlutterMessage> paramsMessage = (AblyFlutterMessage>) message.message; - final Map map = paramsMessage.message; - final HashMap paramsMap = - (HashMap) map.get(PlatformConstants.TxTransportKeys.params); - Param[] params = new Param[paramsMap != null ? paramsMap.size():0]; - if (paramsMap != null) { - int i = 0; - for (String paramKey: paramsMap.keySet()){ - final Param param = new Param(paramKey,paramsMap.get(paramKey)); - params[i++] = param; - } - } - instanceStore - .getRest(paramsMessage.handle) - .statsAsync(params, this.paginatedResponseHandler(result, null)); + private void stats(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; + final AblyFlutterMessage> paramsMessage = + (AblyFlutterMessage>) message.message; + final Map map = paramsMessage.message; + final HashMap paramsMap = + (HashMap) map.get(PlatformConstants.TxTransportKeys.params); + Param[] params = new Param[paramsMap != null ? paramsMap.size() : 0]; + if (paramsMap != null) { + int i = 0; + for (String paramKey : paramsMap.keySet()) { + final Param param = new Param(paramKey, paramsMap.get(paramKey)); + params[i++] = param; + } } + instanceStore + .getRest(paramsMessage.handle) + .statsAsync(params, this.paginatedResponseHandler(result, null)); + } private void getRestPresence(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { final AblyFlutterMessage message = (AblyFlutterMessage) call.arguments; diff --git a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java index 498c03cb5..dfb539153 100644 --- a/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java +++ b/android/src/main/java/io/ably/flutter/plugin/generated/PlatformConstants.java @@ -5,497 +5,499 @@ package io.ably.flutter.plugin.generated; - -final public class PlatformConstants { - - static final public class CodecTypes { - public static final byte ablyMessage = (byte) 128; - public static final byte ablyEventMessage = (byte) 129; - public static final byte clientOptions = (byte) 130; - public static final byte messageData = (byte) 131; - public static final byte messageExtras = (byte) 132; - public static final byte message = (byte) 133; - public static final byte tokenParams = (byte) 134; - public static final byte tokenDetails = (byte) 135; - public static final byte tokenRequest = (byte) 136; - public static final byte restChannelOptions = (byte) 137; - public static final byte realtimeChannelOptions = (byte) 138; - public static final byte paginatedResult = (byte) 139; - public static final byte restHistoryParams = (byte) 140; - public static final byte realtimeHistoryParams = (byte) 141; - public static final byte restPresenceParams = (byte) 142; - public static final byte presenceMessage = (byte) 143; - public static final byte realtimePresenceParams = (byte) 144; - public static final byte deviceDetails = (byte) 145; - public static final byte localDevice = (byte) 146; - public static final byte pushChannelSubscription = (byte) 147; - public static final byte unNotificationSettings = (byte) 148; - public static final byte remoteMessage = (byte) 149; - public static final byte errorInfo = (byte) 150; - public static final byte logLevel = (byte) 151; - public static final byte connectionStateChange = (byte) 152; - public static final byte channelStateChange = (byte) 153; - public static final byte cipherParams = (byte) 154; - public static final byte stats = (byte) 155; - } - - static final public class PlatformMethod { - public static final String getPlatformVersion = "getPlatformVersion"; - public static final String getVersion = "getVersion"; - public static final String resetAblyClients = "resetAblyClients"; - public static final String authCallback = "authCallback"; - public static final String realtimeAuthCallback = "realtimeAuthCallback"; - public static final String createRest = "createRest"; - public static final String setRestChannelOptions = "setRestChannelOptions"; - public static final String publish = "publish"; - public static final String restHistory = "restHistory"; - public static final String restPresenceGet = "restPresenceGet"; - public static final String restPresenceHistory = "restPresenceHistory"; - public static final String releaseRestChannel = "releaseRestChannel"; - public static final String createRealtime = "createRealtime"; - public static final String connectRealtime = "connectRealtime"; - public static final String closeRealtime = "closeRealtime"; - public static final String attachRealtimeChannel = "attachRealtimeChannel"; - public static final String detachRealtimeChannel = "detachRealtimeChannel"; - public static final String setRealtimeChannelOptions = "setRealtimeChannelOptions"; - public static final String realtimePresenceGet = "realtimePresenceGet"; - public static final String realtimePresenceHistory = "realtimePresenceHistory"; - public static final String realtimePresenceEnter = "realtimePresenceEnter"; - public static final String realtimePresenceUpdate = "realtimePresenceUpdate"; - public static final String realtimePresenceLeave = "realtimePresenceLeave"; - public static final String onRealtimePresenceMessage = "onRealtimePresenceMessage"; - public static final String publishRealtimeChannelMessage = "publishRealtimeChannelMessage"; - public static final String releaseRealtimeChannel = "releaseRealtimeChannel"; - public static final String realtimeHistory = "realtimeHistory"; - public static final String realtimeTime = "realtimeTime"; - public static final String restTime = "restTime"; - public static final String stats = "stats"; - public static final String pushActivate = "pushActivate"; - public static final String pushDeactivate = "pushDeactivate"; - public static final String pushSubscribeDevice = "pushSubscribeDevice"; - public static final String pushUnsubscribeDevice = "pushUnsubscribeDevice"; - public static final String pushSubscribeClient = "pushSubscribeClient"; - public static final String pushUnsubscribeClient = "pushUnsubscribeClient"; - public static final String pushListSubscriptions = "pushListSubscriptions"; - public static final String pushDevice = "pushDevice"; - public static final String pushRequestPermission = "pushRequestPermission"; - public static final String pushGetNotificationSettings = "pushGetNotificationSettings"; - public static final String pushOpenSettingsFor = "pushOpenSettingsFor"; - public static final String pushOnActivate = "pushOnActivate"; - public static final String pushOnDeactivate = "pushOnDeactivate"; - public static final String pushOnUpdateFailed = "pushOnUpdateFailed"; - public static final String pushNotificationTapLaunchedAppFromTerminated = "pushNotificationTapLaunchedAppFromTerminated"; - public static final String pushOnShowNotificationInForeground = "pushOnShowNotificationInForeground"; - public static final String pushOnMessage = "pushOnMessage"; - public static final String pushOnBackgroundMessage = "pushOnBackgroundMessage"; - public static final String pushOnNotificationTap = "pushOnNotificationTap"; - public static final String pushBackgroundFlutterApplicationReadyOnAndroid = "pushBackgroundFlutterApplicationReadyOnAndroid"; - public static final String onRealtimeConnectionStateChanged = "onRealtimeConnectionStateChanged"; - public static final String onRealtimeChannelStateChanged = "onRealtimeChannelStateChanged"; - public static final String onRealtimeChannelMessage = "onRealtimeChannelMessage"; - public static final String nextPage = "nextPage"; - public static final String firstPage = "firstPage"; - public static final String cryptoGetParams = "cryptoGetParams"; - public static final String cryptoGenerateRandomKey = "cryptoGenerateRandomKey"; - } - - static final public class TxTransportKeys { - public static final String channelName = "channelName"; - public static final String params = "params"; - public static final String data = "data"; - public static final String clientId = "clientId"; - public static final String options = "options"; - public static final String messages = "messages"; - } - - static final public class TxAblyMessage { - public static final String registrationHandle = "registrationHandle"; - public static final String type = "type"; - public static final String message = "message"; - } - - static final public class TxAblyEventMessage { - public static final String eventName = "eventName"; - public static final String type = "type"; - public static final String message = "message"; - } - - static final public class TxErrorInfo { - public static final String code = "code"; - public static final String message = "message"; - public static final String statusCode = "statusCode"; - public static final String href = "href"; - public static final String requestId = "requestId"; - public static final String cause = "cause"; - } - - static final public class TxMessageData { - public static final String data = "data"; - public static final String type = "type"; - } - - static final public class TxDeltaExtras { - public static final String format = "format"; - public static final String from = "from"; - } - - static final public class TxMessageExtras { - public static final String extras = "extras"; - public static final String delta = "delta"; - } - - static final public class TxClientOptions { - public static final String authUrl = "authUrl"; - public static final String authMethod = "authMethod"; - public static final String key = "key"; - public static final String tokenDetails = "tokenDetails"; - public static final String authHeaders = "authHeaders"; - public static final String authParams = "authParams"; - public static final String queryTime = "queryTime"; - public static final String useTokenAuth = "useTokenAuth"; - public static final String hasAuthCallback = "hasAuthCallback"; - public static final String clientId = "clientId"; - public static final String logLevel = "logLevel"; - public static final String tls = "tls"; - public static final String restHost = "restHost"; - public static final String realtimeHost = "realtimeHost"; - public static final String port = "port"; - public static final String tlsPort = "tlsPort"; - public static final String autoConnect = "autoConnect"; - public static final String useBinaryProtocol = "useBinaryProtocol"; - public static final String queueMessages = "queueMessages"; - public static final String echoMessages = "echoMessages"; - public static final String recover = "recover"; - public static final String environment = "environment"; - public static final String idempotentRestPublishing = "idempotentRestPublishing"; - public static final String httpOpenTimeout = "httpOpenTimeout"; - public static final String httpRequestTimeout = "httpRequestTimeout"; - public static final String httpMaxRetryCount = "httpMaxRetryCount"; - public static final String realtimeRequestTimeout = "realtimeRequestTimeout"; - public static final String fallbackHosts = "fallbackHosts"; - public static final String fallbackHostsUseDefault = "fallbackHostsUseDefault"; - public static final String fallbackRetryTimeout = "fallbackRetryTimeout"; - public static final String defaultTokenParams = "defaultTokenParams"; - public static final String channelRetryTimeout = "channelRetryTimeout"; - public static final String transportParams = "transportParams"; - } - - static final public class TxRestChannelOptions { - public static final String cipherParams = "cipherParams"; - } - - static final public class TxRealtimeChannelOptions { - public static final String params = "params"; - public static final String modes = "modes"; - public static final String cipherParams = "cipherParams"; - } - - static final public class TxCipherParams { - public static final String androidHandle = "androidHandle"; - public static final String iosAlgorithm = "iosAlgorithm"; - public static final String iosKey = "iosKey"; - } - - static final public class TxTokenDetails { - public static final String token = "token"; - public static final String expires = "expires"; - public static final String issued = "issued"; - public static final String capability = "capability"; - public static final String clientId = "clientId"; - } - - static final public class TxTokenParams { - public static final String capability = "capability"; - public static final String clientId = "clientId"; - public static final String nonce = "nonce"; - public static final String timestamp = "timestamp"; - public static final String ttl = "ttl"; - } - - static final public class TxTokenRequest { - public static final String capability = "capability"; - public static final String clientId = "clientId"; - public static final String keyName = "keyName"; - public static final String mac = "mac"; - public static final String nonce = "nonce"; - public static final String timestamp = "timestamp"; - public static final String ttl = "ttl"; - } - - static final public class TxEnumConstants { - public static final String initialized = "initialized"; - public static final String connecting = "connecting"; - public static final String connected = "connected"; - public static final String disconnected = "disconnected"; - public static final String attaching = "attaching"; - public static final String attached = "attached"; - public static final String detaching = "detaching"; - public static final String detached = "detached"; - public static final String suspended = "suspended"; - public static final String closing = "closing"; - public static final String closed = "closed"; - public static final String failed = "failed"; - public static final String absent = "absent"; - public static final String leave = "leave"; - public static final String enter = "enter"; - public static final String present = "present"; - public static final String update = "update"; - public static final String presence = "presence"; - public static final String publish = "publish"; - public static final String subscribe = "subscribe"; - public static final String presenceSubscribe = "presenceSubscribe"; - } - - static final public class TxFormFactorEnum { - public static final String phone = "phone"; - public static final String tablet = "tablet"; - public static final String desktop = "desktop"; - public static final String tv = "tv"; - public static final String watch = "watch"; - public static final String car = "car"; - public static final String embedded = "embedded"; - public static final String other = "other"; - } - - static final public class TxLogLevelEnum { - public static final String none = "none"; - public static final String verbose = "verbose"; - public static final String debug = "debug"; - public static final String info = "info"; - public static final String warn = "warn"; - public static final String error = "error"; - } - - static final public class TxDevicePlatformEnum { - public static final String ios = "ios"; - public static final String android = "android"; - public static final String browser = "browser"; - } - - static final public class TxDevicePushStateEnum { - public static final String active = "active"; - public static final String failing = "failing"; - public static final String failed = "failed"; - } - - static final public class TxConnectionStateChange { - public static final String current = "current"; - public static final String previous = "previous"; - public static final String event = "event"; - public static final String retryIn = "retryIn"; - public static final String reason = "reason"; - } - - static final public class TxChannelStateChange { - public static final String current = "current"; - public static final String previous = "previous"; - public static final String event = "event"; - public static final String resumed = "resumed"; - public static final String reason = "reason"; - } - - static final public class TxMessage { - public static final String id = "id"; - public static final String timestamp = "timestamp"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - public static final String encoding = "encoding"; - public static final String data = "data"; - public static final String name = "name"; - public static final String extras = "extras"; - } - - static final public class TxPresenceMessage { - public static final String id = "id"; - public static final String action = "action"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - public static final String data = "data"; - public static final String encoding = "encoding"; - public static final String extras = "extras"; - public static final String timestamp = "timestamp"; - } - - static final public class TxPaginatedResult { - public static final String items = "items"; - public static final String type = "type"; - public static final String hasNext = "hasNext"; - } - - static final public class TxRestHistoryParams { - public static final String start = "start"; - public static final String end = "end"; - public static final String direction = "direction"; - public static final String limit = "limit"; - } - - static final public class TxRealtimeHistoryParams { - public static final String start = "start"; - public static final String end = "end"; - public static final String direction = "direction"; - public static final String limit = "limit"; - public static final String untilAttach = "untilAttach"; - } - - static final public class TxRestPresenceParams { - public static final String limit = "limit"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - } - - static final public class TxRealtimePresenceParams { - public static final String waitForSync = "waitForSync"; - public static final String clientId = "clientId"; - public static final String connectionId = "connectionId"; - } - - static final public class TxDeviceDetails { - public static final String id = "id"; - public static final String clientId = "clientId"; - public static final String platform = "platform"; - public static final String formFactor = "formFactor"; - public static final String metadata = "metadata"; - public static final String devicePushDetails = "devicePushDetails"; - } - - static final public class TxDevicePushDetails { - public static final String recipient = "recipient"; - public static final String state = "state"; - public static final String errorReason = "errorReason"; - } - - static final public class TxLocalDevice { - public static final String deviceSecret = "deviceSecret"; - public static final String deviceIdentityToken = "deviceIdentityToken"; - } - - static final public class TxPushChannelSubscription { - public static final String channel = "channel"; - public static final String deviceId = "deviceId"; - public static final String clientId = "clientId"; - } - - static final public class TxPushRequestPermission { - public static final String badge = "badge"; - public static final String sound = "sound"; - public static final String alert = "alert"; - public static final String carPlay = "carPlay"; - public static final String criticalAlert = "criticalAlert"; - public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; - public static final String provisional = "provisional"; - public static final String announcement = "announcement"; - } - - static final public class TxUNNotificationSettings { - public static final String authorizationStatus = "authorizationStatus"; - public static final String soundSetting = "soundSetting"; - public static final String badgeSetting = "badgeSetting"; - public static final String alertSetting = "alertSetting"; - public static final String notificationCenterSetting = "notificationCenterSetting"; - public static final String lockScreenSetting = "lockScreenSetting"; - public static final String carPlaySetting = "carPlaySetting"; - public static final String alertStyle = "alertStyle"; - public static final String showPreviewsSetting = "showPreviewsSetting"; - public static final String criticalAlertSetting = "criticalAlertSetting"; - public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; - public static final String announcementSetting = "announcementSetting"; - public static final String scheduledDeliverySetting = "scheduledDeliverySetting"; - public static final String timeSensitiveSetting = "timeSensitiveSetting"; - } - - static final public class TxUNNotificationSettingEnum { - public static final String notSupported = "notSupported"; - public static final String disabled = "disabled"; - public static final String enabled = "enabled"; - } - - static final public class TxUNAlertStyleEnum { - public static final String none = "none"; - public static final String banner = "banner"; - public static final String alert = "alert"; - } - - static final public class TxUNAuthorizationStatusEnum { - public static final String notDetermined = "notDetermined"; - public static final String denied = "denied"; - public static final String authorized = "authorized"; - public static final String provisional = "provisional"; - public static final String ephemeral = "ephemeral"; - } - - static final public class TxUNShowPreviewsSettingEnum { - public static final String always = "always"; - public static final String whenAuthenticated = "whenAuthenticated"; - public static final String never = "never"; - } - - static final public class TxRemoteMessage { - public static final String data = "data"; - public static final String notification = "notification"; - } - - static final public class TxNotification { - public static final String title = "title"; - public static final String body = "body"; - } - - static final public class TxCryptoGetParams { - public static final String algorithm = "algorithm"; - public static final String key = "key"; - } - - static final public class TxCryptoGenerateRandomKey { - public static final String keyLength = "keyLength"; - } - - static final public class TxStats { - public static final String all = "all"; - public static final String apiRequests = "apiRequests"; - public static final String channels = "channels"; - public static final String connections = "connections"; - public static final String inbound = "inbound"; - public static final String intervalId = "intervalId"; - public static final String outbound = "outbound"; - public static final String persisted = "persisted"; - public static final String tokenRequests = "tokenRequests"; - } - - static final public class TxStatsMessageTypes { - public static final String all = "all"; - public static final String messages = "messages"; - public static final String presence = "presence"; - } - - static final public class TxStatsMessageCount { - public static final String count = "count"; - public static final String data = "data"; - } - - static final public class TxStatsRequestCount { - public static final String failed = "failed"; - public static final String refused = "refused"; - public static final String succeeded = "succeeded"; - } - - static final public class TxStatsResourceCount { - public static final String mean = "mean"; - public static final String min = "min"; - public static final String opened = "opened"; - public static final String peak = "peak"; - public static final String refused = "refused"; - } - - static final public class TxStatsConnectionTypes { - public static final String all = "all"; - public static final String plain = "plain"; - public static final String tls = "tls"; - } - - static final public class TxStatsMessageTraffic { - public static final String all = "all"; - public static final String realtime = "realtime"; - public static final String rest = "rest"; - public static final String webhook = "webhook"; - } - +public final class PlatformConstants { + + public static final class CodecTypes { + public static final byte ablyMessage = (byte) 128; + public static final byte ablyEventMessage = (byte) 129; + public static final byte clientOptions = (byte) 130; + public static final byte messageData = (byte) 131; + public static final byte messageExtras = (byte) 132; + public static final byte message = (byte) 133; + public static final byte tokenParams = (byte) 134; + public static final byte tokenDetails = (byte) 135; + public static final byte tokenRequest = (byte) 136; + public static final byte restChannelOptions = (byte) 137; + public static final byte realtimeChannelOptions = (byte) 138; + public static final byte paginatedResult = (byte) 139; + public static final byte restHistoryParams = (byte) 140; + public static final byte realtimeHistoryParams = (byte) 141; + public static final byte restPresenceParams = (byte) 142; + public static final byte presenceMessage = (byte) 143; + public static final byte realtimePresenceParams = (byte) 144; + public static final byte deviceDetails = (byte) 145; + public static final byte localDevice = (byte) 146; + public static final byte pushChannelSubscription = (byte) 147; + public static final byte unNotificationSettings = (byte) 148; + public static final byte remoteMessage = (byte) 149; + public static final byte errorInfo = (byte) 150; + public static final byte logLevel = (byte) 151; + public static final byte connectionStateChange = (byte) 152; + public static final byte channelStateChange = (byte) 153; + public static final byte cipherParams = (byte) 154; + public static final byte stats = (byte) 155; + } + + public static final class PlatformMethod { + public static final String getPlatformVersion = "getPlatformVersion"; + public static final String getVersion = "getVersion"; + public static final String resetAblyClients = "resetAblyClients"; + public static final String authCallback = "authCallback"; + public static final String realtimeAuthCallback = "realtimeAuthCallback"; + public static final String createRest = "createRest"; + public static final String setRestChannelOptions = "setRestChannelOptions"; + public static final String publish = "publish"; + public static final String restHistory = "restHistory"; + public static final String restPresenceGet = "restPresenceGet"; + public static final String restPresenceHistory = "restPresenceHistory"; + public static final String releaseRestChannel = "releaseRestChannel"; + public static final String createRealtime = "createRealtime"; + public static final String connectRealtime = "connectRealtime"; + public static final String closeRealtime = "closeRealtime"; + public static final String attachRealtimeChannel = "attachRealtimeChannel"; + public static final String detachRealtimeChannel = "detachRealtimeChannel"; + public static final String setRealtimeChannelOptions = "setRealtimeChannelOptions"; + public static final String realtimePresenceGet = "realtimePresenceGet"; + public static final String realtimePresenceHistory = "realtimePresenceHistory"; + public static final String realtimePresenceEnter = "realtimePresenceEnter"; + public static final String realtimePresenceUpdate = "realtimePresenceUpdate"; + public static final String realtimePresenceLeave = "realtimePresenceLeave"; + public static final String onRealtimePresenceMessage = "onRealtimePresenceMessage"; + public static final String publishRealtimeChannelMessage = "publishRealtimeChannelMessage"; + public static final String releaseRealtimeChannel = "releaseRealtimeChannel"; + public static final String realtimeHistory = "realtimeHistory"; + public static final String realtimeTime = "realtimeTime"; + public static final String restTime = "restTime"; + public static final String stats = "stats"; + public static final String pushActivate = "pushActivate"; + public static final String pushDeactivate = "pushDeactivate"; + public static final String pushSubscribeDevice = "pushSubscribeDevice"; + public static final String pushUnsubscribeDevice = "pushUnsubscribeDevice"; + public static final String pushSubscribeClient = "pushSubscribeClient"; + public static final String pushUnsubscribeClient = "pushUnsubscribeClient"; + public static final String pushListSubscriptions = "pushListSubscriptions"; + public static final String pushDevice = "pushDevice"; + public static final String pushRequestPermission = "pushRequestPermission"; + public static final String pushGetNotificationSettings = "pushGetNotificationSettings"; + public static final String pushOpenSettingsFor = "pushOpenSettingsFor"; + public static final String pushOnActivate = "pushOnActivate"; + public static final String pushOnDeactivate = "pushOnDeactivate"; + public static final String pushOnUpdateFailed = "pushOnUpdateFailed"; + public static final String pushNotificationTapLaunchedAppFromTerminated = + "pushNotificationTapLaunchedAppFromTerminated"; + public static final String pushOnShowNotificationInForeground = + "pushOnShowNotificationInForeground"; + public static final String pushOnMessage = "pushOnMessage"; + public static final String pushOnBackgroundMessage = "pushOnBackgroundMessage"; + public static final String pushOnNotificationTap = "pushOnNotificationTap"; + public static final String pushBackgroundFlutterApplicationReadyOnAndroid = + "pushBackgroundFlutterApplicationReadyOnAndroid"; + public static final String onRealtimeConnectionStateChanged = + "onRealtimeConnectionStateChanged"; + public static final String onRealtimeChannelStateChanged = "onRealtimeChannelStateChanged"; + public static final String onRealtimeChannelMessage = "onRealtimeChannelMessage"; + public static final String nextPage = "nextPage"; + public static final String firstPage = "firstPage"; + public static final String cryptoGetParams = "cryptoGetParams"; + public static final String cryptoGenerateRandomKey = "cryptoGenerateRandomKey"; + } + + public static final class TxTransportKeys { + public static final String channelName = "channelName"; + public static final String params = "params"; + public static final String data = "data"; + public static final String clientId = "clientId"; + public static final String options = "options"; + public static final String messages = "messages"; + } + + public static final class TxAblyMessage { + public static final String registrationHandle = "registrationHandle"; + public static final String type = "type"; + public static final String message = "message"; + } + + public static final class TxAblyEventMessage { + public static final String eventName = "eventName"; + public static final String type = "type"; + public static final String message = "message"; + } + + public static final class TxErrorInfo { + public static final String code = "code"; + public static final String message = "message"; + public static final String statusCode = "statusCode"; + public static final String href = "href"; + public static final String requestId = "requestId"; + public static final String cause = "cause"; + } + + public static final class TxMessageData { + public static final String data = "data"; + public static final String type = "type"; + } + + public static final class TxDeltaExtras { + public static final String format = "format"; + public static final String from = "from"; + } + + public static final class TxMessageExtras { + public static final String extras = "extras"; + public static final String delta = "delta"; + } + + public static final class TxClientOptions { + public static final String authUrl = "authUrl"; + public static final String authMethod = "authMethod"; + public static final String key = "key"; + public static final String tokenDetails = "tokenDetails"; + public static final String authHeaders = "authHeaders"; + public static final String authParams = "authParams"; + public static final String queryTime = "queryTime"; + public static final String useTokenAuth = "useTokenAuth"; + public static final String hasAuthCallback = "hasAuthCallback"; + public static final String clientId = "clientId"; + public static final String logLevel = "logLevel"; + public static final String tls = "tls"; + public static final String restHost = "restHost"; + public static final String realtimeHost = "realtimeHost"; + public static final String port = "port"; + public static final String tlsPort = "tlsPort"; + public static final String autoConnect = "autoConnect"; + public static final String useBinaryProtocol = "useBinaryProtocol"; + public static final String queueMessages = "queueMessages"; + public static final String echoMessages = "echoMessages"; + public static final String recover = "recover"; + public static final String environment = "environment"; + public static final String idempotentRestPublishing = "idempotentRestPublishing"; + public static final String httpOpenTimeout = "httpOpenTimeout"; + public static final String httpRequestTimeout = "httpRequestTimeout"; + public static final String httpMaxRetryCount = "httpMaxRetryCount"; + public static final String realtimeRequestTimeout = "realtimeRequestTimeout"; + public static final String fallbackHosts = "fallbackHosts"; + public static final String fallbackHostsUseDefault = "fallbackHostsUseDefault"; + public static final String fallbackRetryTimeout = "fallbackRetryTimeout"; + public static final String defaultTokenParams = "defaultTokenParams"; + public static final String channelRetryTimeout = "channelRetryTimeout"; + public static final String transportParams = "transportParams"; + } + + public static final class TxRestChannelOptions { + public static final String cipherParams = "cipherParams"; + } + + public static final class TxRealtimeChannelOptions { + public static final String params = "params"; + public static final String modes = "modes"; + public static final String cipherParams = "cipherParams"; + } + + public static final class TxCipherParams { + public static final String androidHandle = "androidHandle"; + public static final String iosAlgorithm = "iosAlgorithm"; + public static final String iosKey = "iosKey"; + } + + public static final class TxTokenDetails { + public static final String token = "token"; + public static final String expires = "expires"; + public static final String issued = "issued"; + public static final String capability = "capability"; + public static final String clientId = "clientId"; + } + + public static final class TxTokenParams { + public static final String capability = "capability"; + public static final String clientId = "clientId"; + public static final String nonce = "nonce"; + public static final String timestamp = "timestamp"; + public static final String ttl = "ttl"; + } + + public static final class TxTokenRequest { + public static final String capability = "capability"; + public static final String clientId = "clientId"; + public static final String keyName = "keyName"; + public static final String mac = "mac"; + public static final String nonce = "nonce"; + public static final String timestamp = "timestamp"; + public static final String ttl = "ttl"; + } + + public static final class TxEnumConstants { + public static final String initialized = "initialized"; + public static final String connecting = "connecting"; + public static final String connected = "connected"; + public static final String disconnected = "disconnected"; + public static final String attaching = "attaching"; + public static final String attached = "attached"; + public static final String detaching = "detaching"; + public static final String detached = "detached"; + public static final String suspended = "suspended"; + public static final String closing = "closing"; + public static final String closed = "closed"; + public static final String failed = "failed"; + public static final String absent = "absent"; + public static final String leave = "leave"; + public static final String enter = "enter"; + public static final String present = "present"; + public static final String update = "update"; + public static final String presence = "presence"; + public static final String publish = "publish"; + public static final String subscribe = "subscribe"; + public static final String presenceSubscribe = "presenceSubscribe"; + } + + public static final class TxFormFactorEnum { + public static final String phone = "phone"; + public static final String tablet = "tablet"; + public static final String desktop = "desktop"; + public static final String tv = "tv"; + public static final String watch = "watch"; + public static final String car = "car"; + public static final String embedded = "embedded"; + public static final String other = "other"; + } + + public static final class TxLogLevelEnum { + public static final String none = "none"; + public static final String verbose = "verbose"; + public static final String debug = "debug"; + public static final String info = "info"; + public static final String warn = "warn"; + public static final String error = "error"; + } + + public static final class TxDevicePlatformEnum { + public static final String ios = "ios"; + public static final String android = "android"; + public static final String browser = "browser"; + } + + public static final class TxDevicePushStateEnum { + public static final String active = "active"; + public static final String failing = "failing"; + public static final String failed = "failed"; + } + + public static final class TxConnectionStateChange { + public static final String current = "current"; + public static final String previous = "previous"; + public static final String event = "event"; + public static final String retryIn = "retryIn"; + public static final String reason = "reason"; + } + + public static final class TxChannelStateChange { + public static final String current = "current"; + public static final String previous = "previous"; + public static final String event = "event"; + public static final String resumed = "resumed"; + public static final String reason = "reason"; + } + + public static final class TxMessage { + public static final String id = "id"; + public static final String timestamp = "timestamp"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + public static final String encoding = "encoding"; + public static final String data = "data"; + public static final String name = "name"; + public static final String extras = "extras"; + } + + public static final class TxPresenceMessage { + public static final String id = "id"; + public static final String action = "action"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + public static final String data = "data"; + public static final String encoding = "encoding"; + public static final String extras = "extras"; + public static final String timestamp = "timestamp"; + } + + public static final class TxPaginatedResult { + public static final String items = "items"; + public static final String type = "type"; + public static final String hasNext = "hasNext"; + } + + public static final class TxRestHistoryParams { + public static final String start = "start"; + public static final String end = "end"; + public static final String direction = "direction"; + public static final String limit = "limit"; + } + + public static final class TxRealtimeHistoryParams { + public static final String start = "start"; + public static final String end = "end"; + public static final String direction = "direction"; + public static final String limit = "limit"; + public static final String untilAttach = "untilAttach"; + } + + public static final class TxRestPresenceParams { + public static final String limit = "limit"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + } + + public static final class TxRealtimePresenceParams { + public static final String waitForSync = "waitForSync"; + public static final String clientId = "clientId"; + public static final String connectionId = "connectionId"; + } + + public static final class TxDeviceDetails { + public static final String id = "id"; + public static final String clientId = "clientId"; + public static final String platform = "platform"; + public static final String formFactor = "formFactor"; + public static final String metadata = "metadata"; + public static final String devicePushDetails = "devicePushDetails"; + } + + public static final class TxDevicePushDetails { + public static final String recipient = "recipient"; + public static final String state = "state"; + public static final String errorReason = "errorReason"; + } + + public static final class TxLocalDevice { + public static final String deviceSecret = "deviceSecret"; + public static final String deviceIdentityToken = "deviceIdentityToken"; + } + + public static final class TxPushChannelSubscription { + public static final String channel = "channel"; + public static final String deviceId = "deviceId"; + public static final String clientId = "clientId"; + } + + public static final class TxPushRequestPermission { + public static final String badge = "badge"; + public static final String sound = "sound"; + public static final String alert = "alert"; + public static final String carPlay = "carPlay"; + public static final String criticalAlert = "criticalAlert"; + public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; + public static final String provisional = "provisional"; + public static final String announcement = "announcement"; + } + + public static final class TxUNNotificationSettings { + public static final String authorizationStatus = "authorizationStatus"; + public static final String soundSetting = "soundSetting"; + public static final String badgeSetting = "badgeSetting"; + public static final String alertSetting = "alertSetting"; + public static final String notificationCenterSetting = "notificationCenterSetting"; + public static final String lockScreenSetting = "lockScreenSetting"; + public static final String carPlaySetting = "carPlaySetting"; + public static final String alertStyle = "alertStyle"; + public static final String showPreviewsSetting = "showPreviewsSetting"; + public static final String criticalAlertSetting = "criticalAlertSetting"; + public static final String providesAppNotificationSettings = "providesAppNotificationSettings"; + public static final String announcementSetting = "announcementSetting"; + public static final String scheduledDeliverySetting = "scheduledDeliverySetting"; + public static final String timeSensitiveSetting = "timeSensitiveSetting"; + } + + public static final class TxUNNotificationSettingEnum { + public static final String notSupported = "notSupported"; + public static final String disabled = "disabled"; + public static final String enabled = "enabled"; + } + + public static final class TxUNAlertStyleEnum { + public static final String none = "none"; + public static final String banner = "banner"; + public static final String alert = "alert"; + } + + public static final class TxUNAuthorizationStatusEnum { + public static final String notDetermined = "notDetermined"; + public static final String denied = "denied"; + public static final String authorized = "authorized"; + public static final String provisional = "provisional"; + public static final String ephemeral = "ephemeral"; + } + + public static final class TxUNShowPreviewsSettingEnum { + public static final String always = "always"; + public static final String whenAuthenticated = "whenAuthenticated"; + public static final String never = "never"; + } + + public static final class TxRemoteMessage { + public static final String data = "data"; + public static final String notification = "notification"; + } + + public static final class TxNotification { + public static final String title = "title"; + public static final String body = "body"; + } + + public static final class TxCryptoGetParams { + public static final String algorithm = "algorithm"; + public static final String key = "key"; + } + + public static final class TxCryptoGenerateRandomKey { + public static final String keyLength = "keyLength"; + } + + public static final class TxStats { + public static final String all = "all"; + public static final String apiRequests = "apiRequests"; + public static final String channels = "channels"; + public static final String connections = "connections"; + public static final String inbound = "inbound"; + public static final String intervalId = "intervalId"; + public static final String outbound = "outbound"; + public static final String persisted = "persisted"; + public static final String tokenRequests = "tokenRequests"; + } + + public static final class TxStatsMessageTypes { + public static final String all = "all"; + public static final String messages = "messages"; + public static final String presence = "presence"; + } + + public static final class TxStatsMessageCount { + public static final String count = "count"; + public static final String data = "data"; + } + + public static final class TxStatsRequestCount { + public static final String failed = "failed"; + public static final String refused = "refused"; + public static final String succeeded = "succeeded"; + } + + public static final class TxStatsResourceCount { + public static final String mean = "mean"; + public static final String min = "min"; + public static final String opened = "opened"; + public static final String peak = "peak"; + public static final String refused = "refused"; + } + + public static final class TxStatsConnectionTypes { + public static final String all = "all"; + public static final String plain = "plain"; + public static final String tls = "tls"; + } + + public static final class TxStatsMessageTraffic { + public static final String all = "all"; + public static final String realtime = "realtime"; + public static final String rest = "rest"; + public static final String webhook = "webhook"; + } } diff --git a/bin/codegen_context.dart b/bin/codegen_context.dart index c836f55cd..cd948bcd8 100644 --- a/bin/codegen_context.dart +++ b/bin/codegen_context.dart @@ -528,53 +528,27 @@ const List> _objects = [ }, { 'name': 'StatsMessageTypes', - 'properties': [ - 'all', - 'messages', - 'presence' - ] + 'properties': ['all', 'messages', 'presence'] }, { 'name': 'StatsMessageCount', - 'properties': [ - 'count', - 'data' - ] + 'properties': ['count', 'data'] }, { 'name': 'StatsRequestCount', - 'properties': [ - 'failed', - 'refused', - 'succeeded' - ] + 'properties': ['failed', 'refused', 'succeeded'] }, { 'name': 'StatsResourceCount', - 'properties': [ - 'mean', - 'min', - 'opened', - 'peak', - 'refused' - ] + 'properties': ['mean', 'min', 'opened', 'peak', 'refused'] }, { 'name': 'StatsConnectionTypes', - 'properties': [ - 'all', - 'plain', - 'tls' - ] + 'properties': ['all', 'plain', 'tls'] }, { 'name': 'StatsMessageTraffic', - 'properties': [ - 'all', - 'realtime', - 'rest', - 'webhook' - ] + 'properties': ['all', 'realtime', 'rest', 'webhook'] } ]; diff --git a/example/lib/ui/realtime_sliver.dart b/example/lib/ui/realtime_sliver.dart index b38407461..fdfd14d4e 100644 --- a/example/lib/ui/realtime_sliver.dart +++ b/example/lib/ui/realtime_sliver.dart @@ -238,7 +238,6 @@ class RealtimeSliver extends HookWidget { TextRow('Data', message.data.toString()), ], )), - RealtimePresenceSliver(realtime, channel), ], ); diff --git a/example/lib/ui/rest_sliver.dart b/example/lib/ui/rest_sliver.dart index 740ffc6fb..7fffcc6e8 100644 --- a/example/lib/ui/rest_sliver.dart +++ b/example/lib/ui/rest_sliver.dart @@ -93,18 +93,15 @@ class RestSliver extends HookWidget { '${message.id}:${message.clientId}:${message.data}')), PaginatedResultViewer( title: 'Stats', - subtitle: TextRow( - 'What is it?', - 'Realtime stats'), + subtitle: TextRow('What is it?', 'Realtime stats'), query: () => rest.stats(), builder: (context, stat, _) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextRow('Statistics ', stat.toString()), - ], - )), + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextRow('Statistics ', stat.toString()), + ], + )), ], ); - } } diff --git a/lib/src/generated/platform_constants.dart b/lib/src/generated/platform_constants.dart index 2d978f22a..012075f58 100644 --- a/lib/src/generated/platform_constants.dart +++ b/lib/src/generated/platform_constants.dart @@ -385,7 +385,8 @@ class TxPushRequestPermission { static const String alert = 'alert'; static const String carPlay = 'carPlay'; static const String criticalAlert = 'criticalAlert'; - static const String providesAppNotificationSettings = 'providesAppNotificationSettings'; + static const String providesAppNotificationSettings = + 'providesAppNotificationSettings'; static const String provisional = 'provisional'; static const String announcement = 'announcement'; } @@ -401,7 +402,8 @@ class TxUNNotificationSettings { static const String alertStyle = 'alertStyle'; static const String showPreviewsSetting = 'showPreviewsSetting'; static const String criticalAlertSetting = 'criticalAlertSetting'; - static const String providesAppNotificationSettings = 'providesAppNotificationSettings'; + static const String providesAppNotificationSettings = + 'providesAppNotificationSettings'; static const String announcementSetting = 'announcementSetting'; static const String scheduledDeliverySetting = 'scheduledDeliverySetting'; static const String timeSensitiveSetting = 'timeSensitiveSetting'; diff --git a/lib/src/platform/src/rest/rest.dart b/lib/src/platform/src/rest/rest.dart index 46367b3f2..33c5690f5 100644 --- a/lib/src/platform/src/rest/rest.dart +++ b/lib/src/platform/src/rest/rest.dart @@ -58,11 +58,9 @@ class Rest extends PlatformObject { /// gets stats based on params as a [PaginatedResult] /// /// https://docs.ably.com/client-lib-development-guide/features/#RSC6 - Future> stats([Map params = const {}]) async{ - final message = - await invokeRequest(PlatformMethod.stats,{ - TxTransportKeys.params: params - }); + Future> stats([Map? params]) async { + final message = await invokeRequest( + PlatformMethod.stats, {TxTransportKeys.params: params}); return PaginatedResult.fromAblyMessage( AblyMessage.castFrom(message), ); From f3fb908833fc2486ccc2e6684da5bd0234e6303e Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Tue, 21 Dec 2021 17:44:46 +0000 Subject: [PATCH 42/51] Created StatsEncoder for iOS --- .../codec/encoders/StatsEncoders.swift | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ios/Classes/codec/encoders/StatsEncoders.swift diff --git a/ios/Classes/codec/encoders/StatsEncoders.swift b/ios/Classes/codec/encoders/StatsEncoders.swift new file mode 100644 index 000000000..3a94ff400 --- /dev/null +++ b/ios/Classes/codec/encoders/StatsEncoders.swift @@ -0,0 +1,72 @@ +// +// Created by Ikbal Kaya on 21/12/2021. +// + +import Foundation + +public class StatsEncoders: NSObject { + @objc + public static let encodeStats: (ARTStats) -> [String: Any] = { stats in + [ + TxStats_all: encodeStatMessageTypes(stats.all), + TxStats_apiRequests: encodeStatsMessageTypes(stats.apiRequests), + TxStats_channels:encodeStatsResourceCount(stats.channels), + TxStats_connections:encodeStatsConnectionTypes(stats.connections), + TxStats_inbound:encodeStatsMessageTraffic(stats.inbound), + TxStats_intervalId:stats.intervalId, + TxStats_outbound:encodeStatsMessageTraffic(stats.outbound), + TxStats_persisted:encodeStatsMessageTypes(stats.persisted), + TxStats_tokenRequests: encodeStatsRequestCount(stats.tokenRequests) + ] + } + + static let encodeStatsMessageTypes: (ARTStatsMessageTypes) -> [String: Any] = { types in + [ + TxStatsMessageTypes_all: encodeStatsMessageCount(types.all), + TxStatsMessageTypes_messages: encodeStatsMessageCount(types.messages), + TxStatsMessageTypes_presence: encodeStatsMessageCount(types.presence) + ] + } + + static let encodeStatsMessageCount: (ARTStatsMessageCount) -> [String: Any] = { count in + [ + TxStatsMessageCount_count: count.count, + TxStatsMessageCount_data:count.data + ] + } + + static let encodeStatsRequestCount: (ARTStatsRequestCount) -> [String: Any] = { count in + [ + TxStatsRequestCount_failed: count.failed, + TxStatsRequestCount_refused: count.refused, + TxStatsRequestCount_succeeded: count.succeeded + ] + } + + static let encodeStatsResourceCount: (ARTStatsResourceCount) -> [String: Any] = { count in + [ + TxStatsResourceCount_mean:count.mean, + TxStatsResourceCount_min:count.min, + TxStatsResourceCount_opened:count.opened, + TxStatsResourceCount_peak:count.peak, + TxStatsResourceCount_refused:count.refused + ] + } + + static let encodeStatsConnectionTypes: (ARTStatsConnectionTypes) -> [String: Any] = { types in + [ + TxStatsConnectionTypes_all: encodeStatsResourceCount(types.all), + TxStatsConnectionTypes_plain: encodeStatsResourceCount(types.plain), + TxStatsConnectionTypes_tls: encodeStatsResourceCount(types.tls), + ] + } + + static let encodeStatsMessageTraffic: (ARTStatsMessageTraffic) -> [String: Any] = { types in + [ + TxStatsMessageTraffic_all: encodeStatMessageTypes(types.all), + TxStatsMessageTraffic_realtime: encodeStatMessageTypes(types.realtime), + TxStatsMessageTraffic_rest: encodeStatMessageTypes(types.rest), + TxStatsMessageTraffic_webhook: encodeStatMessageTypes(types.webhook) + ] + } +} \ No newline at end of file From 147c08be6963e36dc005765228ee1536a697d057 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Tue, 21 Dec 2021 17:46:38 +0000 Subject: [PATCH 43/51] Stats encoding mappings in Obj-C --- ios/Classes/codec/AblyFlutterWriter.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/Classes/codec/AblyFlutterWriter.m b/ios/Classes/codec/AblyFlutterWriter.m index 6d7a6126d..b077fd94b 100644 --- a/ios/Classes/codec/AblyFlutterWriter.m +++ b/ios/Classes/codec/AblyFlutterWriter.m @@ -51,6 +51,8 @@ + (UInt8) getType:(id)value{ return CodecTypeRestChannelOptions; } else if ([value isKindOfClass:[ARTCipherParams class]]) { return CodecTypeCipherParams; + } else if([value isKindOfClass:[ARTStats class]]){ + return CodecTypeStats; } return 0; } @@ -71,6 +73,7 @@ + (AblyCodecEncoder) getEncoder:(const NSString*)type { [NSString stringWithFormat:@"%d", CodecTypeUnNotificationSettings]: PushNotificationEncoders.encodeUNNotificationSettings, [NSString stringWithFormat:@"%d", CodecTypeRemoteMessage]: PushNotificationEncoders.encodeRemoteMessage, [NSString stringWithFormat:@"%d", CodecTypeCipherParams]: CryptoCodec.encodeCipherParams, + [NSString stringWithFormat:@"%d", CodecTypeStats]: StatsEncoders.encodeStats, }; return [_handlers objectForKey:[NSString stringWithFormat:@"%@", type]]; } @@ -317,4 +320,5 @@ +(NSString *) encodePresenceAction: (ARTPresenceAction) action { return dictionary; }; + @end From 8a5e998dcf699728c060fb004fa14ad09f40a30c Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Wed, 22 Dec 2021 15:51:17 +0000 Subject: [PATCH 44/51] Fix function calls in StatsEncoders --- ios/Classes/codec/encoders/StatsEncoders.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Classes/codec/encoders/StatsEncoders.swift b/ios/Classes/codec/encoders/StatsEncoders.swift index 3a94ff400..7ab558452 100644 --- a/ios/Classes/codec/encoders/StatsEncoders.swift +++ b/ios/Classes/codec/encoders/StatsEncoders.swift @@ -8,8 +8,8 @@ public class StatsEncoders: NSObject { @objc public static let encodeStats: (ARTStats) -> [String: Any] = { stats in [ - TxStats_all: encodeStatMessageTypes(stats.all), - TxStats_apiRequests: encodeStatsMessageTypes(stats.apiRequests), + TxStats_all: encodeStatsMessageTypes(stats.all), + TxStats_apiRequests: encodeStatsRequestCount(stats.apiRequests), TxStats_channels:encodeStatsResourceCount(stats.channels), TxStats_connections:encodeStatsConnectionTypes(stats.connections), TxStats_inbound:encodeStatsMessageTraffic(stats.inbound), @@ -63,10 +63,10 @@ public class StatsEncoders: NSObject { static let encodeStatsMessageTraffic: (ARTStatsMessageTraffic) -> [String: Any] = { types in [ - TxStatsMessageTraffic_all: encodeStatMessageTypes(types.all), - TxStatsMessageTraffic_realtime: encodeStatMessageTypes(types.realtime), - TxStatsMessageTraffic_rest: encodeStatMessageTypes(types.rest), - TxStatsMessageTraffic_webhook: encodeStatMessageTypes(types.webhook) + TxStatsMessageTraffic_all: encodeStatsMessageTypes(types.all), + TxStatsMessageTraffic_realtime: encodeStatsMessageTypes(types.realtime), + TxStatsMessageTraffic_rest: encodeStatsMessageTypes(types.rest), + TxStatsMessageTraffic_webhook: encodeStatsMessageTypes(types.webhook) ] } -} \ No newline at end of file +} From 29766e9e8b4320252af1c43b86f91acebe03df50 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Wed, 22 Dec 2021 15:52:20 +0000 Subject: [PATCH 45/51] Stats function mapping in Objective-C --- ios/Classes/AblyFlutter.m | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ios/Classes/AblyFlutter.m b/ios/Classes/AblyFlutter.m index c857fca38..dc77aabf9 100644 --- a/ios/Classes/AblyFlutter.m +++ b/ios/Classes/AblyFlutter.m @@ -573,6 +573,21 @@ -(void)reset; }]; }; +static const FlutterHandler _stats = ^void(AblyFlutter *const ably, FlutterMethodCall *const call, const FlutterResult result) { + AblyFlutterMessage *const message = call.arguments; + AblyInstanceStore *const instanceStore = [ably instanceStore]; + + ARTRest *const rest = [instanceStore restFrom:message.message]; + [rest stats:^(ARTPaginatedResult *statsResult, ARTErrorInfo *error) { + if(error){ + result(error); + }else{ + result(statsResult); + } + }]; + +}; + static const FlutterHandler _getNextPage = ^void(AblyFlutter *const ably, FlutterMethodCall *const call, const FlutterResult result) { AblyFlutterMessage *const message = call.arguments; AblyInstanceStore *const instanceStore = [ably instanceStore]; @@ -691,6 +706,7 @@ -(instancetype)initWithChannel:(FlutterMethodChannel *const)channel AblyPlatformMethod_releaseRealtimeChannel: _releaseRealtimeChannel, AblyPlatformMethod_realtimeTime:_realtimeTime, AblyPlatformMethod_realtimeTime:_restTime, + AblyPlatformMethod_stats:_stats, // Push Notifications AblyPlatformMethod_pushActivate: PushHandlers.activate, AblyPlatformMethod_pushRequestPermission: PushHandlers.requestPermission, From a79f96a2f7355ff567044d890f95f7ec89738140 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Wed, 22 Dec 2021 16:05:24 +0000 Subject: [PATCH 46/51] File formattings --- .../codec/encoders/StatsEncoders.swift | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ios/Classes/codec/encoders/StatsEncoders.swift b/ios/Classes/codec/encoders/StatsEncoders.swift index 7ab558452..fd407b8c8 100644 --- a/ios/Classes/codec/encoders/StatsEncoders.swift +++ b/ios/Classes/codec/encoders/StatsEncoders.swift @@ -10,13 +10,13 @@ public class StatsEncoders: NSObject { [ TxStats_all: encodeStatsMessageTypes(stats.all), TxStats_apiRequests: encodeStatsRequestCount(stats.apiRequests), - TxStats_channels:encodeStatsResourceCount(stats.channels), - TxStats_connections:encodeStatsConnectionTypes(stats.connections), - TxStats_inbound:encodeStatsMessageTraffic(stats.inbound), - TxStats_intervalId:stats.intervalId, - TxStats_outbound:encodeStatsMessageTraffic(stats.outbound), - TxStats_persisted:encodeStatsMessageTypes(stats.persisted), - TxStats_tokenRequests: encodeStatsRequestCount(stats.tokenRequests) + TxStats_channels: encodeStatsResourceCount(stats.channels), + TxStats_connections: encodeStatsConnectionTypes(stats.connections), + TxStats_inbound: encodeStatsMessageTraffic(stats.inbound), + TxStats_intervalId: stats.intervalId, + TxStats_outbound: encodeStatsMessageTraffic(stats.outbound), + TxStats_persisted: encodeStatsMessageTypes(stats.persisted), + TxStats_tokenRequests: encodeStatsRequestCount(stats.tokenRequests), ] } @@ -24,14 +24,14 @@ public class StatsEncoders: NSObject { [ TxStatsMessageTypes_all: encodeStatsMessageCount(types.all), TxStatsMessageTypes_messages: encodeStatsMessageCount(types.messages), - TxStatsMessageTypes_presence: encodeStatsMessageCount(types.presence) + TxStatsMessageTypes_presence: encodeStatsMessageCount(types.presence), ] } static let encodeStatsMessageCount: (ARTStatsMessageCount) -> [String: Any] = { count in [ TxStatsMessageCount_count: count.count, - TxStatsMessageCount_data:count.data + TxStatsMessageCount_data: count.data, ] } @@ -39,17 +39,17 @@ public class StatsEncoders: NSObject { [ TxStatsRequestCount_failed: count.failed, TxStatsRequestCount_refused: count.refused, - TxStatsRequestCount_succeeded: count.succeeded + TxStatsRequestCount_succeeded: count.succeeded, ] } static let encodeStatsResourceCount: (ARTStatsResourceCount) -> [String: Any] = { count in [ - TxStatsResourceCount_mean:count.mean, - TxStatsResourceCount_min:count.min, - TxStatsResourceCount_opened:count.opened, - TxStatsResourceCount_peak:count.peak, - TxStatsResourceCount_refused:count.refused + TxStatsResourceCount_mean: count.mean, + TxStatsResourceCount_min: count.min, + TxStatsResourceCount_opened: count.opened, + TxStatsResourceCount_peak: count.peak, + TxStatsResourceCount_refused: count.refused, ] } @@ -66,7 +66,7 @@ public class StatsEncoders: NSObject { TxStatsMessageTraffic_all: encodeStatsMessageTypes(types.all), TxStatsMessageTraffic_realtime: encodeStatsMessageTypes(types.realtime), TxStatsMessageTraffic_rest: encodeStatsMessageTypes(types.rest), - TxStatsMessageTraffic_webhook: encodeStatsMessageTypes(types.webhook) + TxStatsMessageTraffic_webhook: encodeStatsMessageTypes(types.webhook), ] } } From 96b9cc7f3a48a183d2e1fefd644ebe83fc76eab6 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 23 Dec 2021 11:15:10 +0000 Subject: [PATCH 47/51] Fix messageCategory encoding --- .../ably/flutter/plugin/AblyMessageCodec.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java index be6b09550..67a1b85d7 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java @@ -275,19 +275,18 @@ private Map encodeStatsMessageTypes(Stats.MessageTypes messageTy encodeMessageCategory(messageTypes.presence)); return jsonMap; } - // that's StatsMessageCount in Flutter's side + + // This is different in other platform and will correspond to StatsMessageCount for other libraries private Map encodeMessageCategory(Stats.MessageCategory category) { if (category == null) return null; if (category.category == null) return null; final HashMap jsonMap = new HashMap<>(); - // There is a mapping consistencey issue between two, so just assume there is a single message - // for now - for (String key : category.category.keySet()) { - writeValueToJson( - jsonMap, PlatformConstants.TxStatsMessageCount.count, category.category.get(key).count); - writeValueToJson( - jsonMap, PlatformConstants.TxStatsMessageCount.data, category.category.get(key).data); - } + + writeValueToJson( + jsonMap, PlatformConstants.TxStatsMessageCount.count, category.count); + writeValueToJson( + jsonMap, PlatformConstants.TxStatsMessageCount.data, category.data); + return jsonMap; } From b61b0bd202c726d97028de9fc2d8c4de76ff34db Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 23 Dec 2021 11:33:57 +0000 Subject: [PATCH 48/51] File formatting --- .../java/io/ably/flutter/plugin/AblyMessageCodec.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java index 67a1b85d7..fd72cce0c 100644 --- a/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java +++ b/android/src/main/java/io/ably/flutter/plugin/AblyMessageCodec.java @@ -276,16 +276,15 @@ private Map encodeStatsMessageTypes(Stats.MessageTypes messageTy return jsonMap; } - // This is different in other platform and will correspond to StatsMessageCount for other libraries + // This is different in other platform and will correspond to StatsMessageCount for other + // libraries private Map encodeMessageCategory(Stats.MessageCategory category) { if (category == null) return null; if (category.category == null) return null; final HashMap jsonMap = new HashMap<>(); - writeValueToJson( - jsonMap, PlatformConstants.TxStatsMessageCount.count, category.count); - writeValueToJson( - jsonMap, PlatformConstants.TxStatsMessageCount.data, category.data); + writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageCount.count, category.count); + writeValueToJson(jsonMap, PlatformConstants.TxStatsMessageCount.data, category.data); return jsonMap; } From ca03987c443eb0ed39282311a39032ed9918530f Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 23 Dec 2021 12:15:21 +0000 Subject: [PATCH 49/51] Added params to the call in example app and confirmed it's working in Android side --- example/lib/ui/rest_sliver.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/lib/ui/rest_sliver.dart b/example/lib/ui/rest_sliver.dart index 7fffcc6e8..109f35c03 100644 --- a/example/lib/ui/rest_sliver.dart +++ b/example/lib/ui/rest_sliver.dart @@ -94,7 +94,7 @@ class RestSliver extends HookWidget { PaginatedResultViewer( title: 'Stats', subtitle: TextRow('What is it?', 'Realtime stats'), - query: () => rest.stats(), + query: () => rest.stats({ "limit":100, "end":"now" }), builder: (context, stat, _) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ From 38e9ed1e02416c867baec3139ec347a35258b6d3 Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 23 Dec 2021 15:56:33 +0000 Subject: [PATCH 50/51] Added param query builder for stat params --- ios/Classes/AblyFlutter.m | 18 +++++-- .../codec/ARTStatsQuery+ParamBuilder.h | 12 +++++ .../codec/ARTStatsQuery+ParamBuilder.m | 47 +++++++++++++++++++ 3 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 ios/Classes/codec/ARTStatsQuery+ParamBuilder.h create mode 100644 ios/Classes/codec/ARTStatsQuery+ParamBuilder.m diff --git a/ios/Classes/AblyFlutter.m b/ios/Classes/AblyFlutter.m index dc77aabf9..7431bc42a 100644 --- a/ios/Classes/AblyFlutter.m +++ b/ios/Classes/AblyFlutter.m @@ -2,6 +2,7 @@ #import "AblyFlutter.h" #import +#import #import "codec/AblyFlutterReaderWriter.h" #import "AblyFlutterMessage.h" @@ -9,6 +10,7 @@ #import "AblyFlutterStreamHandler.h" #import "AblyStreamsChannel.h" #import "codec/AblyPlatformConstants.h" +#import "ARTStatsQuery+ParamBuilder.h" #define LOG(fmt, ...) NSLog((@"%@:%d " fmt), [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, ##__VA_ARGS__) @@ -574,17 +576,25 @@ -(void)reset; }; static const FlutterHandler _stats = ^void(AblyFlutter *const ably, FlutterMethodCall *const call, const FlutterResult result) { - AblyFlutterMessage *const message = call.arguments; + AblyFlutterMessage *const arguments = call.arguments; AblyInstanceStore *const instanceStore = [ably instanceStore]; + ARTRest *const rest = [instanceStore restFrom:arguments.message]; + AblyFlutterMessage *message = arguments.message; + NSDictionary *paramsDict = message.message; + ARTStatsQuery *query; + if(paramsDict[@"params"]){ + NSDictionary *statsParams = paramsDict[@"params"]; + query = [ARTStatsQuery fromParams:statsParams]; + } - ARTRest *const rest = [instanceStore restFrom:message.message]; - [rest stats:^(ARTPaginatedResult *statsResult, ARTErrorInfo *error) { + NSError *statsError; + [rest stats:query callback:^(ARTPaginatedResult *statsResult, ARTErrorInfo *error) { if(error){ result(error); }else{ result(statsResult); } - }]; + } error:&statsError]; }; diff --git a/ios/Classes/codec/ARTStatsQuery+ParamBuilder.h b/ios/Classes/codec/ARTStatsQuery+ParamBuilder.h new file mode 100644 index 000000000..33e472172 --- /dev/null +++ b/ios/Classes/codec/ARTStatsQuery+ParamBuilder.h @@ -0,0 +1,12 @@ +// +// Created by Ikbal Kaya on 23/12/2021. +// + +#import +#import "ARTStats.h" + +@interface ARTStatsQuery (ParamBuilder) + ++(ARTStatsQuery *)fromParams:(NSDictionary *)params; + +@end \ No newline at end of file diff --git a/ios/Classes/codec/ARTStatsQuery+ParamBuilder.m b/ios/Classes/codec/ARTStatsQuery+ParamBuilder.m new file mode 100644 index 000000000..1e191cdd5 --- /dev/null +++ b/ios/Classes/codec/ARTStatsQuery+ParamBuilder.m @@ -0,0 +1,47 @@ +// +// Created by Ikbal Kaya on 23/12/2021. +// + +#import "ARTStatsQuery+ParamBuilder.h" +#import "ARTNSDate+ARTUtil.h" + + +@implementation ARTStatsQuery (ParamBuilder) ++ (ARTStatsQuery *)fromParams:(NSDictionary *)params { + ARTStatsQuery *query = [[ARTStatsQuery alloc] init]; + id start = params[@"start"]; + if(start && [start isKindOfClass:[NSNumber class]]){ + query.start = [NSDate artDateFromIntegerMs:[start longLongValue]]; + } + id end = params[@"end"]; + if(end && [end isKindOfClass:[NSNumber class]]){ + query.end = [NSDate artDateFromIntegerMs:[end longLongValue]]; + } + id direction = params[@"direction"]; + if(direction && [direction isKindOfClass:[NSString class]]){ + NSString *directionString = [direction stringValue]; + query.direction = [directionString isEqualToString:@"backwards"] ? ARTQueryDirectionBackwards : ARTQueryDirectionForwards; + } + id limit = params[@"limit"]; + if(limit && [limit isKindOfClass:[NSNumber class]]){ + query.limit = (uint16_t) [limit unsignedIntValue]; + } + + id unit = params[@"unit"]; + if(unit && [unit isKindOfClass:[NSString class]]){ + NSString *unitVal = [unit stringValue]; + // minute, hour, day or month, + if ([unitVal isEqualToString:@"minute"]){ + query.unit = ARTStatsGranularityMinute; + }else if ([unitVal isEqualToString:@"hour"]){ + query.unit = ARTStatsGranularityHour; + }else if ([unitVal isEqualToString:@"day"]){ + query.unit = ARTStatsGranularityDay; + }else if ([unitVal isEqualToString:@"month"]){ + query.unit = ARTStatsGranularityMonth; + } + } + return query; +} + +@end \ No newline at end of file From bc81244ee5d106a54f9c47df527c00def58c607d Mon Sep 17 00:00:00 2001 From: ikbalkaya Date: Thu, 23 Dec 2021 15:56:59 +0000 Subject: [PATCH 51/51] file formatting --- example/lib/ui/rest_sliver.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/lib/ui/rest_sliver.dart b/example/lib/ui/rest_sliver.dart index 109f35c03..b1b9caa46 100644 --- a/example/lib/ui/rest_sliver.dart +++ b/example/lib/ui/rest_sliver.dart @@ -94,7 +94,7 @@ class RestSliver extends HookWidget { PaginatedResultViewer( title: 'Stats', subtitle: TextRow('What is it?', 'Realtime stats'), - query: () => rest.stats({ "limit":100, "end":"now" }), + query: () => rest.stats({"limit": 100, "end": "now"}), builder: (context, stat, _) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [