Skip to content

Commit

Permalink
fix: fix 'Sending a message before the FlutterEngine has been run.' e…
Browse files Browse the repository at this point in the history
…rror

fix: fix 'Sending a message before the FlutterEngine has been run.' error
  • Loading branch information
littleGnAl authored Aug 15, 2022
1 parent f76a056 commit d0d6fad
Show file tree
Hide file tree
Showing 59 changed files with 2,046 additions and 49 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,20 @@ jobs:
- run: flutter pub get
- run: bash ci/run_android_test.sh

unittest_ios:
name: Run iOS Unit Test
run_test_shard:
name: Run test shard
needs: flutter_codestyle_check
runs-on: macos-11
timeout-minutes: 60
env:
TEST_APP_ID: ${{ secrets.MY_APP_ID }}
steps:
- uses: actions/checkout@v1
- uses: subosito/flutter-action@v1
with:
flutter-version: '2.10.5'
flutter-version: '3.0.1'
- run: flutter pub get
- run: bash ci/run_ios_test.sh
- run: bash ci/run_test_shard.sh

build_android_windows:
name: Build Android on Windows
Expand Down
3 changes: 2 additions & 1 deletion .pubignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
integration_test_app/
tools/
ios/libs
macos/libs
macos/libs
test_shard/
17 changes: 17 additions & 0 deletions ci/run_test_shard.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

set -e
set -x

pushd test_shard/destroy_irisengine_smoke_test
flutter packages get
flutter build ios --no-codesign --simulator --debug
popd

pushd test_shard/destroy_irisengine_smoke_test/ios

bundle install
bundle exec fastlane tests --verbose

popd

5 changes: 5 additions & 0 deletions ios/Classes/AgoraRtcEnginePlugin.mm
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ - (instancetype)init {
return self;
}

- (void)detachFromEngineForRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
[self destroyIrisRtcEngine];
}

- (void)destroyIrisRtcEngine {
[self.flutterIrisEventHandler resetEventHandler:self.irisRtcEngine];
self.irisRtcEngine->SetEventHandler(nil);
self.irisRtcEngine->channel()->SetEventHandler(nil);
delete self.irisRtcEngine;
Expand Down
59 changes: 46 additions & 13 deletions ios/Classes/FlutterIrisEventHandler.mm
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
#import <Foundation/Foundation.h>
#import "FlutterIrisEventHandler.h"
#import <AgoraRtcWrapper/iris_rtc_engine.h>
#include <mutex>

class EventHandler : public agora::iris::IrisEventHandler {

public:
EventHandler(FlutterEventSink eventSink, bool shouldHandleSubProcess = false, bool sub_process = false) : eventSink_(eventSink), sub_process_(sub_process), shouldHandleSubProcess_(shouldHandleSubProcess) {
EventHandler(FlutterEventSink eventSink, bool shouldHandleSubProcess = false, bool sub_process = false) : eventSink_(eventSink), sub_process_(sub_process), shouldHandleSubProcess_(shouldHandleSubProcess), isCleanUp_(false) {
}

void OnEvent(const char *event, const char *data) override {
@autoreleasepool {
if (eventSink_) {
bool subProcess = shouldHandleSubProcess_ && sub_process_;
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithUTF8String:event], @"methodName",
[NSString stringWithUTF8String:data], @"data",
@(subProcess), @"subProcess",
nil];

eventSink_(dic);
}
std::lock_guard<std::mutex> guard(isCleanUpMutex_);

if (isCleanUp_) return;

@try {
if (eventSink_) {
bool subProcess = shouldHandleSubProcess_ && sub_process_;
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithUTF8String:event], @"methodName",
[NSString stringWithUTF8String:data], @"data",
@(subProcess), @"subProcess",
nil];

if (isCleanUp_) return;
eventSink_(dic);
}
} @catch (NSException *e) {
NSLog(@"Error: %@ %@", e, [e userInfo]);
} @finally {
}

}

void OnEvent(const char *event, const char *data, const void *buffer,
unsigned int length) override {
@autoreleasepool {
std::lock_guard<std::mutex> guard(isCleanUpMutex_);

if (isCleanUp_) return;

@try {
FlutterStandardTypedData *bufferApple = [FlutterStandardTypedData
typedDataWithBytes:[[NSData alloc] initWithBytes:buffer
length:length]];
Expand All @@ -37,15 +52,26 @@ void OnEvent(const char *event, const char *data, const void *buffer,
@(subProcess), @"subProcess",
nil];

if (isCleanUp_) return;
eventSink_(dic);
}
} @catch (NSException *e) {
NSLog(@"Error: %@ %@", e, [e userInfo]);
} @finally {
}
}

void setIsCleanUp(bool isCleanUp) {
std::lock_guard<std::mutex> guard(isCleanUpMutex_);
isCleanUp_ = isCleanUp;
}

private:
FlutterEventSink eventSink_;
bool sub_process_;
bool shouldHandleSubProcess_;
bool isCleanUp_ = false;
std::mutex isCleanUpMutex_;
};

@interface FlutterIrisEventHandler ()
Expand Down Expand Up @@ -115,6 +141,13 @@ - (void)setUpEventHandler:(void *)engine eventHandler:(void *)eventHandler {
}

- (void)resetEventHandler:(void *)engine {
if (self.eventHandler) {
self.eventHandler->setIsCleanUp(true);
}
if (self.eventHandlerSub) {
self.eventHandlerSub->setIsCleanUp(true);
}

agora::iris::rtc::IrisRtcEngine *e = (agora::iris::rtc::IrisRtcEngine *)engine;
e->SetEventHandler(nil);
self.eventSink = nil;
Expand Down
2 changes: 2 additions & 0 deletions macos/Classes/AgoraRtcEnginePlugin.mm
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ - (instancetype)init {
}

- (void)dealloc {
[self.eventHandler resetEventHandler:self.engine_main];

if (self.engine_main) {
self.engine_main->SetEventHandler(nil);
self.engine_main->channel()->SetEventHandler(nil);
Expand Down
92 changes: 61 additions & 31 deletions macos/Classes/FlutterIrisEventHandler.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "FlutterIrisEventHandler.h"
#import <AgoraRtcWrapper/iris_rtc_engine.h>
#import <Foundation/Foundation.h>
#include <mutex>

class EventHandler : public agora::iris::IrisEventHandler {
public:
Expand All @@ -10,49 +11,72 @@
shouldHandleSubProcess_(shouldHandleSubProcess) {}

void OnEvent(const char *event, const char *data) override {
@autoreleasepool {
if (eventSink_) {
NSMutableDictionary *dic = [NSMutableDictionary
dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:event],
@"methodName",
[NSString stringWithUTF8String:data],
@"data", nil];

if (shouldHandleSubProcess_) {
[dic setObject:@(sub_process_) forKey:@"subProcess"];
}

eventSink_(dic);
std::lock_guard<std::mutex> guard(isCleanUpMutex_);

if (isCleanUp_) return;

@try {
if (eventSink_) {
NSMutableDictionary *dic = [NSMutableDictionary
dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:event],
@"methodName",
[NSString stringWithUTF8String:data],
@"data", nil];

if (shouldHandleSubProcess_) {
[dic setObject:@(sub_process_) forKey:@"subProcess"];
}

if (isCleanUp_) return;
eventSink_(dic);
}
} @catch (NSException *e) {
NSLog(@"Error: %@ %@", e, [e userInfo]);
} @finally {
}
}
}

void OnEvent(const char *event, const char *data, const void *buffer,
unsigned int length) override {
@autoreleasepool {
FlutterStandardTypedData *bufferApple = [FlutterStandardTypedData
typedDataWithBytes:[[NSData alloc] initWithBytes:buffer
length:length]];
if (eventSink_) {
NSMutableDictionary *dic = [NSMutableDictionary
dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:event],
@"methodName",
[NSString stringWithUTF8String:data],
@"data", bufferApple, @"buffer", nil];

if (shouldHandleSubProcess_) {
[dic setObject:@(sub_process_) forKey:@"subProcess"];
}

eventSink_(dic);
std::lock_guard<std::mutex> guard(isCleanUpMutex_);

if (isCleanUp_) return;

@try {
FlutterStandardTypedData *bufferApple = [FlutterStandardTypedData
typedDataWithBytes:[[NSData alloc] initWithBytes:buffer
length:length]];
if (eventSink_) {
NSMutableDictionary *dic = [NSMutableDictionary
dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:event],
@"methodName",
[NSString stringWithUTF8String:data],
@"data", bufferApple, @"buffer", nil];

if (shouldHandleSubProcess_) {
[dic setObject:@(sub_process_) forKey:@"subProcess"];
}

if (isCleanUp_) return;
eventSink_(dic);
}
} @catch (NSException *e) {
NSLog(@"Error: %@ %@", e, [e userInfo]);
} @finally {
}
}
}

void setIsCleanUp(bool isCleanUp) {
std::lock_guard<std::mutex> guard(isCleanUpMutex_);
isCleanUp_ = isCleanUp;
}

private:
FlutterEventSink eventSink_;
bool sub_process_;
bool shouldHandleSubProcess_;
bool isCleanUp_ = false;
std::mutex isCleanUpMutex_;
};

@interface FlutterIrisEventHandler ()
Expand Down Expand Up @@ -125,6 +149,12 @@ - (void)setUpEventHandler:(void *)engine eventHandler:(void *)eventHandler {
}

- (void)resetEventHandler:(void *)engine {
if (self.eventHandler) {
self.eventHandler->setIsCleanUp(true);
}
if (self.eventHandlerSub) {
self.eventHandlerSub->setIsCleanUp(true);
}
agora::iris::rtc::IrisRtcEngine *e =
(agora::iris::rtc::IrisRtcEngine *)engine;
e->SetEventHandler(nil);
Expand Down
47 changes: 47 additions & 0 deletions test_shard/destroy_irisengine_smoke_test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
30 changes: 30 additions & 0 deletions test_shard/destroy_irisengine_smoke_test/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.

version:
revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
channel: stable

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
- platform: ios
create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
16 changes: 16 additions & 0 deletions test_shard/destroy_irisengine_smoke_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# destroy_irisengine_smoke_test

A new Flutter project.

## Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)

For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
Loading

0 comments on commit d0d6fad

Please sign in to comment.