diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 51650e8ed..e9b6c9b32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,6 +37,9 @@ jobs: integration_test_android: name: Run Flutter Android Integration Tests needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: macos-11 timeout-minutes: 60 env: @@ -48,7 +51,7 @@ jobs: java-version: '11' - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - name: run flutter android integration tests uses: reactivecircus/android-emulator-runner@v2.21.0 with: @@ -60,6 +63,9 @@ jobs: integration_test_ios: name: Run Flutter iOS Integration Tests needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: macos-11 timeout-minutes: 60 env: @@ -68,7 +74,7 @@ jobs: - uses: actions/checkout@v1 - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - uses: futureware-tech/simulator-action@v1 with: model: 'iPhone 13 Pro Max' @@ -77,6 +83,9 @@ jobs: integration_test_macos: name: Run Flutter macOS Integration Tests needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: macos-11 timeout-minutes: 60 env: @@ -85,13 +94,16 @@ jobs: - uses: actions/checkout@v1 - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - run: flutter config --enable-macos-desktop - run: bash ci/run_flutter_macos_integration_test.sh integration_test_windows: name: Run Flutter Windows Integration Tests needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: windows-2019 timeout-minutes: 60 env: @@ -100,7 +112,7 @@ jobs: - uses: actions/checkout@v1 - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - run: flutter config --enable-windows-desktop - run: bash ci/run_flutter_macos_integration_test.sh @@ -136,6 +148,9 @@ jobs: build_android_windows: name: Build Android on Windows needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: windows-2019 steps: - uses: actions/checkout@v1 @@ -144,7 +159,7 @@ jobs: java-version: '11' - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - run: flutter pub get - name: Run flutter build apk run: flutter build apk @@ -153,6 +168,9 @@ jobs: build_android_ubuntu: name: Build Android on Ubuntu needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 @@ -161,7 +179,7 @@ jobs: java-version: '11' - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - run: flutter pub get - name: Run flutter build apk run: flutter build apk @@ -170,13 +188,16 @@ jobs: build_ios: name: Build iOS needs: flutter_codestyle_check + strategy: + matrix: + version: ['2.10.5', '3.0.0'] runs-on: macos-11 timeout-minutes: 60 steps: - uses: actions/checkout@v1 - uses: subosito/flutter-action@v1 with: - flutter-version: '2.10.5' + flutter-version: ${{ matrix.version }} - run: flutter pub get - name: Run flutter build ios --no-codesign run: flutter build ios --no-codesign diff --git a/README.md b/README.md index 7388b888d..606209e87 100644 --- a/README.md +++ b/README.md @@ -136,9 +136,9 @@ as [Custom Audio Source and Renderer](https://docs.agora.io/en/Video/custom_audi Please note that you should not call the [RtcEngine.destroy](https://docs.agora.io/en/Video/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#afb808cdc9025a77af7dd2bce98311bfe)/[AgoraRtcEngineKit.destroy](https://docs.agora.io/en/Video/API%20Reference/oc/Classes/AgoraRtcEngineKit.html#//api/name/destroy) function on Android/iOS code, because it will affect the [RtcEngine](https://github.com/AgoraIO/Agora-Flutter-SDK/blob/master/lib/src/rtc_engine.dart) on the Flutter side. To see how to use `RtcEnginePlugin`, please check the custom audio source example: -Android: [CustomAudioPlugin.kt](https://github.com/AgoraIO/Agora-Flutter-SDK/blob/master/example/android/app/src/main/kotlin/io/agora/agora_rtc_engine_example/custom_audio_source/CustomAudioPlugin.kt) +Android: [CustomCaptureAudioPlugin.kt](https://github.com/AgoraIO/Agora-Flutter-SDK/blob/master/example/android/app/src/main/kotlin/io/agora/agora_rtc_engine_example/custom_capture_audio/CustomCaptureAudioPlugin.kt) -iOS: [CustmoAudioSourcePlugin.swift](https://github.com/AgoraIO/Agora-Flutter-SDK/blob/master/example/ios/Runner/CustomAudioSource/CustmoAudioSourcePlugin.swift) +iOS: [CustomCaptureAudioPlugin.swift](https://github.com/AgoraIO/Agora-Flutter-SDK/blob/master/example/ios/Runner/CustomCaptureAudio/CustomCaptureAudioPlugin.swift) ## API Reference Resources diff --git a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraPlatformView.kt b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraPlatformView.kt index 6ca0b2f8b..0b6501c2b 100644 --- a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraPlatformView.kt +++ b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraPlatformView.kt @@ -16,35 +16,39 @@ private class PlatformViewApiTypeCallApiMethodCallHandler( ) : CallApiMethodCallHandler(irisRtcEngine) { override fun callApi(apiType: Int, params: String?, sb: StringBuffer): Int { platformView.updateView() - return irisRtcEngine.callApi(apiType, params, platformView.getIrisRenderView(), sb) + return platformView.getIrisRenderView()?.let { + irisRtcEngine.callApi(apiType, params, platformView.getIrisRenderView(), sb) + } ?: -1 } } // We should ensure not doing some leak in constructor @Suppress("LeakingThis") abstract class AgoraPlatformView( - private val context: Context, + private val context: Context?, messenger: BinaryMessenger, viewId: Int, args: Map<*, *>?, - private val irisRtcEngine: IrisRtcEngine + irisRtcEngine: IrisRtcEngine ) : PlatformView, MethodChannel.MethodCallHandler { - private val parentView: FrameLayout = FrameLayout(context) + private var parentView: FrameLayout? = null - private var platformView: View + private var platformView: View? = null - private val channel: MethodChannel + private var channel: MethodChannel? = null - private val callApiMethodCallHandler: CallApiMethodCallHandler = - PlatformViewApiTypeCallApiMethodCallHandler(irisRtcEngine, this) + private var callApiMethodCallHandler: CallApiMethodCallHandler? = null init { - platformView = createView(context.applicationContext) - parentView.addView(platformView) + parentView = context?.let { FrameLayout(context) } + platformView = createView(context) + parentView?.addView(platformView) channel = MethodChannel(messenger, "${channelName}_$viewId") - channel.setMethodCallHandler(this) + channel?.setMethodCallHandler(this) + + callApiMethodCallHandler = PlatformViewApiTypeCallApiMethodCallHandler(irisRtcEngine, this) args?.apply { for ((key, value) in entries) { @@ -54,28 +58,27 @@ abstract class AgoraPlatformView( } fun updateView() { - parentView.removeAllViews() - platformView = createView(context.applicationContext) - parentView.addView(platformView) + parentView?.removeAllViews() + platformView = createView(context) + parentView?.addView(platformView) } - abstract fun createView(context: Context): View + abstract fun createView(context: Context?): View? protected abstract val channelName: String - fun getIrisRenderView(): View { + fun getIrisRenderView(): View? { return platformView } - override fun getView(): View { + override fun getView(): View? { return parentView } override fun dispose() { - channel.setMethodCallHandler(null) } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { - callApiMethodCallHandler.onMethodCall(call, result) + callApiMethodCallHandler?.onMethodCall(call, result) } } diff --git a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraRtcEnginePlugin.kt b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraRtcEnginePlugin.kt index 8e2f36b42..7ee3b5eb0 100644 --- a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraRtcEnginePlugin.kt +++ b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraRtcEnginePlugin.kt @@ -260,6 +260,6 @@ class AgoraRtcEnginePlugin : FlutterPlugin, MethodCallHandler, EventChannel.Stre } return@getAssetAbsolutePath } - result.error(IllegalArgumentException::class.simpleName, null, null) + result.error(IllegalArgumentException::class.simpleName ?: "IllegalArgumentException", "The parameter should not be null", null) } } diff --git a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraSurfaceViewFactory.kt b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraSurfaceViewFactory.kt index 093885fe2..8c9c96c24 100644 --- a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraSurfaceViewFactory.kt +++ b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraSurfaceViewFactory.kt @@ -1,14 +1,10 @@ package io.agora.agora_rtc_engine import android.content.Context -import android.view.SurfaceView import android.view.View -import android.widget.FrameLayout import io.agora.iris.rtc.IrisRtcEngine import io.agora.rtc.RtcEngine import io.flutter.plugin.common.BinaryMessenger -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory @@ -17,9 +13,9 @@ class AgoraSurfaceViewFactory( private val messenger: BinaryMessenger, private val irisRtcEngine: IrisRtcEngine ) : PlatformViewFactory(StandardMessageCodec.INSTANCE) { - override fun create(context: Context, viewId: Int, args: Any?): PlatformView { + override fun create(context: Context?, viewId: Int, args: Any?): PlatformView { return AgoraPlatformViewSurface( - context.applicationContext, + context, messenger, viewId, args as? Map<*, *>, @@ -29,39 +25,17 @@ private val irisRtcEngine: IrisRtcEngine } class AgoraPlatformViewSurface( - context: Context, + context: Context?, messenger: BinaryMessenger, viewId: Int, args: Map<*, *>?, irisRtcEngine: IrisRtcEngine ) : AgoraPlatformView(context, messenger, viewId, args, irisRtcEngine) { - override fun createView(context: Context): View { - return RtcEngine.CreateRendererView(context) + override fun createView(context: Context?): View? { + return context?.let { + RtcEngine.CreateTextureView(context) + } } override val channelName: String get() = "agora_rtc_engine/surface_view" - - override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { - when (call.method) { - "setZOrderOnTop" -> { - val surfaceView = getIrisRenderView() as SurfaceView - val parentView = view as FrameLayout - parentView.removeView(surfaceView) - surfaceView.setZOrderOnTop((call.argument("onTop"))!!) - parentView.addView(surfaceView) - result.success(null) - } - "setZOrderMediaOverlay" -> { - val surfaceView = getIrisRenderView() as SurfaceView - val parentView = view as FrameLayout - parentView.removeView(surfaceView) - surfaceView.setZOrderMediaOverlay((call.argument("isMediaOverlay"))!!) - parentView.addView(surfaceView) - result.success(null) - } - else -> { - super.onMethodCall(call, result) - } - } - } } diff --git a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraTextureViewFactory.kt b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraTextureViewFactory.kt index 83afca3a4..840620538 100644 --- a/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraTextureViewFactory.kt +++ b/android/src/main/kotlin/io/agora/agora_rtc_engine/AgoraTextureViewFactory.kt @@ -14,9 +14,9 @@ class AgoraTextureViewFactory( private val irisRtcEngine: IrisRtcEngine ) : PlatformViewFactory(StandardMessageCodec.INSTANCE) { - override fun create(context: Context, viewId: Int, args: Any?): PlatformView { + override fun create(context: Context?, viewId: Int, args: Any?): PlatformView { return AgoraPlatformViewTexture( - context.applicationContext, + context, messenger, viewId, args as? Map<*, *>, @@ -26,14 +26,13 @@ class AgoraTextureViewFactory( } class AgoraPlatformViewTexture( - context: Context, + context: Context?, messenger: BinaryMessenger, viewId: Int, args: Map<*, *>?, irisRtcEngine: IrisRtcEngine ) : AgoraPlatformView(context, messenger, viewId, args, irisRtcEngine) { - override fun createView(context: Context): View { - - return RtcEngine.CreateTextureView(context) + override fun createView(context: Context?): View? { + return context?.let { RtcEngine.CreateTextureView(context) } } override val channelName: String diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index bf611fa3e..808c63f58 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -47,5 +47,7 @@ io.flutter.embedded_views_preview + CADisableMinimumFrameDurationOnPhone + diff --git a/example/lib/examples/advanced/enable_virtualbackground/enable_virtualbackground.dart b/example/lib/examples/advanced/enable_virtualbackground/enable_virtualbackground.dart index f91567d75..b3e13820c 100644 --- a/example/lib/examples/advanced/enable_virtualbackground/enable_virtualbackground.dart +++ b/example/lib/examples/advanced/enable_virtualbackground/enable_virtualbackground.dart @@ -188,7 +188,8 @@ class _State extends State { return Expanded( child: Stack( children: [ - const rtc_local_view.SurfaceView(), + const rtc_local_view.SurfaceView( + ), Align( alignment: Alignment.topLeft, child: SingleChildScrollView( diff --git a/example/lib/examples/advanced/index.dart b/example/lib/examples/advanced/index.dart index f785cbd83..86a532ef4 100644 --- a/example/lib/examples/advanced/index.dart +++ b/example/lib/examples/advanced/index.dart @@ -40,4 +40,5 @@ final advanced = [ 'widget': const EnableVirtualBackground() }, {'name': 'MediaRecorder', 'widget': const MediaRecorder()}, + ]; diff --git a/example/lib/examples/advanced/stream_message/stream_message.dart b/example/lib/examples/advanced/stream_message/stream_message.dart index 14b78406b..19840e639 100644 --- a/example/lib/examples/advanced/stream_message/stream_message.dart +++ b/example/lib/examples/advanced/stream_message/stream_message.dart @@ -215,7 +215,7 @@ class _State extends State { width: 120, child: rtc_remote_view.SurfaceView( uid: uid, - channelId: config.channelId, + channelId: _channelIdController.text, ), ) : SizedBox( @@ -223,7 +223,7 @@ class _State extends State { width: 120, child: rtc_remote_view.TextureView( uid: uid, - channelId: config.channelId, + channelId: _channelIdController.text, ), )); })); diff --git a/example/linux/.gitignore b/example/linux/.gitignore index d3896c984..3c7337d8c 100644 --- a/example/linux/.gitignore +++ b/example/linux/.gitignore @@ -1 +1,4 @@ flutter/ephemeral +flutter/generated_plugins.cmake +flutter/generated_plugin_registrant.h +flutter/generated_plugin_registrant.cc diff --git a/example/linux/flutter/generated_plugin_registrant.cc b/example/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index e71a16d23..000000000 --- a/example/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,11 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - - -void fl_register_plugins(FlPluginRegistry* registry) { -} diff --git a/example/linux/flutter/generated_plugin_registrant.h b/example/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/example/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/example/linux/flutter/generated_plugins.cmake b/example/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 51436ae8c..000000000 --- a/example/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) diff --git a/example/windows/.gitignore b/example/windows/.gitignore index d492d0d98..8faa5fab1 100644 --- a/example/windows/.gitignore +++ b/example/windows/.gitignore @@ -1,4 +1,7 @@ flutter/ephemeral/ +flutter/generated_plugin_registrant.h +flutter/generated_plugin_registrant.cc +flutter/generated_plugins.cmake # Visual Studio user-specific files. *.suo diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index f9eb73595..000000000 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,14 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include - -void RegisterPlugins(flutter::PluginRegistry* registry) { - AgoraRtcEnginePluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("AgoraRtcEnginePlugin")); -} diff --git a/example/windows/flutter/generated_plugin_registrant.h b/example/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index dc139d85a..000000000 --- a/example/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake deleted file mode 100644 index bee76c9f8..000000000 --- a/example/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - agora_rtc_engine -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) diff --git a/integration_test_app/integration_test/agora_rtc_engine_api_test.dart b/integration_test_app/integration_test/agora_rtc_engine_api_test.dart index eacfdca9f..4f39be3a1 100644 --- a/integration_test_app/integration_test/agora_rtc_engine_api_test.dart +++ b/integration_test_app/integration_test/agora_rtc_engine_api_test.dart @@ -1579,7 +1579,16 @@ void main() { rtcEngine = await _createEngine(); - await rtcEngine.getEffectDuration('/path'); + fakeIrisEngine.mockCallApiReturnCode( + ApiTypeEngine.kEngineGetEffectDuration.index, + jsonEncode({ + 'filePath': '/path', + }), + 10, + ); + + final ret = await rtcEngine.getEffectDuration('/path'); + expect(ret, 10); fakeIrisEngine.expectCalledApi( ApiTypeEngine.kEngineGetEffectDuration.index, @@ -2560,8 +2569,18 @@ void main() { fakeIrisEngine = FakeIrisRtcEngine(); await fakeIrisEngine.initialize(); - rtcEngine = await _createEngine(); final DataStreamConfig config = DataStreamConfig(true, true); + + fakeIrisEngine.mockCallApiReturnCode( + ApiTypeEngine.kEngineCreateDataStream.index, + jsonEncode({ + 'config': config.toJson(), + }), + 10, + ); + + rtcEngine = await _createEngine(); + await rtcEngine.createDataStreamWithConfig(config); fakeIrisEngine.expectCalledApi( @@ -3157,6 +3176,12 @@ void main() { fakeIrisEngine = FakeIrisRtcEngine(); await fakeIrisEngine.initialize(); + fakeIrisEngine.mockCallApiResult( + ApiTypeEngine.kEngineGetCameraMaxZoomFactor.index, + jsonEncode({}), + "1.0", + ); + rtcEngine = await _createEngine(); await rtcEngine.getCameraMaxZoomFactor(); @@ -3176,8 +3201,14 @@ void main() { fakeIrisEngine = FakeIrisRtcEngine(); await fakeIrisEngine.initialize(); + fakeIrisEngine.mockCallApiReturnCode( + ApiTypeEngine.kEngineIsCameraAutoFocusFaceModeSupported.index, + jsonEncode({}), + 1); + rtcEngine = await _createEngine(); - await rtcEngine.isCameraAutoFocusFaceModeSupported(); + final isSupported = await rtcEngine.isCameraAutoFocusFaceModeSupported(); + expect(isSupported, true); fakeIrisEngine.expectCalledApi( ApiTypeEngine.kEngineIsCameraAutoFocusFaceModeSupported.index, @@ -3195,8 +3226,14 @@ void main() { fakeIrisEngine = FakeIrisRtcEngine(); await fakeIrisEngine.initialize(); + fakeIrisEngine.mockCallApiReturnCode( + ApiTypeEngine.kEngineIsCameraExposurePositionSupported.index, + jsonEncode({}), + 1); + rtcEngine = await _createEngine(); - await rtcEngine.isCameraExposurePositionSupported(); + final isSupported = await rtcEngine.isCameraExposurePositionSupported(); + expect(isSupported, true); fakeIrisEngine.expectCalledApi( ApiTypeEngine.kEngineIsCameraExposurePositionSupported.index, @@ -3214,8 +3251,12 @@ void main() { fakeIrisEngine = FakeIrisRtcEngine(); await fakeIrisEngine.initialize(); + fakeIrisEngine.mockCallApiReturnCode( + ApiTypeEngine.kEngineIsCameraFocusSupported.index, jsonEncode({}), 1); + rtcEngine = await _createEngine(); - await rtcEngine.isCameraFocusSupported(); + final isSupported = await rtcEngine.isCameraFocusSupported(); + expect(isSupported, true); fakeIrisEngine.expectCalledApi( ApiTypeEngine.kEngineIsCameraFocusSupported.index, @@ -3225,6 +3266,29 @@ void main() { skip: !(Platform.isAndroid || Platform.isIOS), ); + testWidgets( + 'isCameraTorchSupported', + (WidgetTester tester) async { + app.main(); + await tester.pumpAndSettle(); + fakeIrisEngine = FakeIrisRtcEngine(); + await fakeIrisEngine.initialize(); + + fakeIrisEngine.mockCallApiReturnCode( + ApiTypeEngine.kEngineIsCameraTorchSupported.index, jsonEncode({}), 1); + + rtcEngine = await _createEngine(); + final isSupported = await rtcEngine.isCameraTorchSupported(); + expect(isSupported, true); + + fakeIrisEngine.expectCalledApi( + ApiTypeEngine.kEngineIsCameraTorchSupported.index, + jsonEncode({}), + ); + }, + skip: !(Platform.isAndroid || Platform.isIOS), + ); + testWidgets( 'isCameraZoomSupported', (WidgetTester tester) async { diff --git a/ios/Classes/AgoraSurfaceViewFactory.mm b/ios/Classes/AgoraSurfaceViewFactory.mm index 0ffc9e5fa..a7e6b302b 100644 --- a/ios/Classes/AgoraSurfaceViewFactory.mm +++ b/ios/Classes/AgoraSurfaceViewFactory.mm @@ -103,7 +103,6 @@ - (instancetype)initWith:(NSObject *)messenger - (void)dealloc { [self removeObserver:self.parentView forKeyPath:[self observerForKeyPath] context:nil]; - [self.methodChannel setMethodCallHandler:nil]; } - (UIView *)getIrisRenderView { diff --git a/ios/Classes/AgoraTextureViewFactory.mm b/ios/Classes/AgoraTextureViewFactory.mm index bc73d8d40..d079bee4b 100644 --- a/ios/Classes/AgoraTextureViewFactory.mm +++ b/ios/Classes/AgoraTextureViewFactory.mm @@ -132,7 +132,6 @@ - (void)dealloc { } - (void)destroy { - [self.channel setMethodCallHandler:nil]; self.renderer->DisableVideoFrameBuffer(self.delegate); [self.textureRegistry unregisterTexture:self.textureId]; } diff --git a/lib/src/impl/rtc_ender_view_impl.dart b/lib/src/impl/rtc_ender_view_impl.dart index c0d1f6bba..9e2a87476 100644 --- a/lib/src/impl/rtc_ender_view_impl.dart +++ b/lib/src/impl/rtc_ender_view_impl.dart @@ -53,21 +53,24 @@ class RtcSurfaceViewState extends State { @override Widget build(BuildContext context) { if (defaultTargetPlatform == TargetPlatform.android) { + const viewType = 'AgoraSurfaceView'; + final creationParams = { + ..._creationParams, + 'setZOrderOnTop': { + 'onTop': widget.zOrderOnTop, + }, + 'setZOrderMediaOverlay': { + 'isMediaOverlay': widget.zOrderMediaOverlay, + }, + }; + return GestureDetector( behavior: HitTestBehavior.opaque, child: AndroidView( - viewType: 'AgoraSurfaceView', + viewType: viewType, onPlatformViewCreated: _onPlatformViewCreated, hitTestBehavior: PlatformViewHitTestBehavior.transparent, - creationParams: { - ..._creationParams, - 'setZOrderOnTop': { - 'onTop': widget.zOrderOnTop, - }, - 'setZOrderMediaOverlay': { - 'isMediaOverlay': widget.zOrderMediaOverlay, - }, - }, + creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), gestureRecognizers: widget.gestureRecognizers, ), @@ -134,14 +137,6 @@ class RtcSurfaceViewState extends State { _setMirrorMode(); } } - if (defaultTargetPlatform == TargetPlatform.android) { - if (oldWidget.zOrderOnTop != widget.zOrderOnTop) { - _setZOrderOnTop(); - } - if (oldWidget.zOrderMediaOverlay != widget.zOrderMediaOverlay) { - _setZOrderMediaOverlay(); - } - } } @override @@ -199,18 +194,6 @@ class RtcSurfaceViewState extends State { }); } - void _setZOrderOnTop() { - _channels[_id]?.invokeMethod('setZOrderOnTop', { - 'onTop': widget.zOrderOnTop, - }); - } - - void _setZOrderMediaOverlay() { - _channels[_id]?.invokeMethod('setZOrderMediaOverlay', { - 'isMediaOverlay': widget.zOrderMediaOverlay, - }); - } - Future _onPlatformViewCreated(int id) async { _id = id; if (!_channels.containsKey(id)) { diff --git a/lib/src/impl/rtc_engine_impl.dart b/lib/src/impl/rtc_engine_impl.dart index 1cf8acc8a..41f9ec6e0 100644 --- a/lib/src/impl/rtc_engine_impl.dart +++ b/lib/src/impl/rtc_engine_impl.dart @@ -886,7 +886,7 @@ class RtcEngineImpl with MediaRecorderImplMixin implements RtcEngine { return _invokeMethod('callApi', { 'apiType': ApiTypeEngine.kEngineIsCameraAutoFocusFaceModeSupported.index, 'params': jsonEncode({}), - }); + }).then((v) => v == 1 ? true : false); } @override @@ -894,7 +894,7 @@ class RtcEngineImpl with MediaRecorderImplMixin implements RtcEngine { return _invokeMethod('callApi', { 'apiType': ApiTypeEngine.kEngineIsCameraExposurePositionSupported.index, 'params': jsonEncode({}), - }); + }).then((v) => v == 1 ? true : false); } @override @@ -902,7 +902,7 @@ class RtcEngineImpl with MediaRecorderImplMixin implements RtcEngine { return _invokeMethod('callApi', { 'apiType': ApiTypeEngine.kEngineIsCameraFocusSupported.index, 'params': jsonEncode({}), - }); + }).then((v) => v == 1 ? true : false); } @override @@ -910,7 +910,7 @@ class RtcEngineImpl with MediaRecorderImplMixin implements RtcEngine { return _invokeMethod('callApi', { 'apiType': ApiTypeEngine.kEngineIsCameraTorchSupported.index, 'params': jsonEncode({}), - }); + }).then((v) => v == 1 ? true : false); } @override diff --git a/macos/Classes/AgoraTextureViewFactory.mm b/macos/Classes/AgoraTextureViewFactory.mm index cbc85914a..10b0e52fa 100644 --- a/macos/Classes/AgoraTextureViewFactory.mm +++ b/macos/Classes/AgoraTextureViewFactory.mm @@ -127,7 +127,6 @@ - (void)dealloc { } - (void)destroy { - [self.channel setMethodCallHandler:nil]; self.renderer->DisableVideoFrameBuffer(self.delegate); [self.textureRegistry unregisterTexture:self.textureId]; } diff --git a/pubspec.yaml b/pubspec.yaml index a7f53d468..a1e37207c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ homepage: https://www.agora.io repository: https://github.com/AgoraIO/Flutter-SDK environment: sdk: '>=2.12.0 <3.0.0' - flutter: '>=1.12.13+hotfix.6' + flutter: '>=2.0.0' dependencies: flutter: sdk: flutter