Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix setupRemoteVideoEx not call correctly #909

Merged
merged 4 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/src/impl/agora_rtc_engine_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,10 @@ class RtcEngineImpl extends rtc_engine_ex_binding.RtcEngineExImpl
@internal
final MethodChannel engineMethodChannel = const MethodChannel('agora_rtc_ng');

static RtcEngineEx create() {
static RtcEngineEx create({IrisMethodChannel? irisMethodChannel}) {
if (_instance != null) return _instance!;

_instance = RtcEngineImpl._(IrisMethodChannel());
_instance = RtcEngineImpl._(irisMethodChannel ?? IrisMethodChannel());

return _instance!;
}
Expand Down
7 changes: 6 additions & 1 deletion lib/src/impl/video_view_controller_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,12 @@ mixin VideoViewControllerBaseMixin implements VideoViewControllerBase {
mediaPlayerId: canvas.mediaPlayerId,
);
if (canvas.uid != 0) {
await rtcEngine.setupRemoteVideo(videoCanvas);
if (connection != null && rtcEngine is RtcEngineEx) {
await (rtcEngine as RtcEngineEx)
.setupRemoteVideoEx(canvas: videoCanvas, connection: connection!);
} else {
await rtcEngine.setupRemoteVideo(videoCanvas);
}
} else {
await rtcEngine.setupLocalVideo(videoCanvas);
}
Expand Down
4 changes: 3 additions & 1 deletion lib/src/render/video_view_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ class VideoViewController
required this.connection,
this.useFlutterTexture = false,
this.useAndroidSurfaceView = false})
: assert(connection.channelId != null);
: assert(canvas.uid != null && canvas.uid != 0,
'Remote uid can not be null or 0'),
assert(connection.channelId != null);

@override
final RtcEngine rtcEngine;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:flutter/foundation.dart';
import 'package:iris_method_channel/iris_method_channel.dart';

class FakeIrisMethodChannel extends IrisMethodChannel {
final List<IrisMethodCall> methodCallQueue = [];

@override
Future<void> initilize(NativeBindingsProvider provider) async {}

@override
Future<CallApiResult> invokeMethod(IrisMethodCall methodCall) async {
methodCallQueue.add(methodCall);
return CallApiResult(data: {'result': 0}, irisReturnCode: 0);
}

@override
int getNativeHandle() {
return 100;
}

@override
VoidCallback addHotRestartListener(HotRestartListener listener) {
return () {};
}

@override
void removeHotRestartListener(HotRestartListener listener) {}

@override
Future<void> dispose() async {}

void reset() {
methodCallQueue.clear();
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import 'dart:convert';
import 'dart:io';

import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:agora_rtc_engine/src/impl/agora_rtc_engine_impl.dart';
import '../fake/fake_iris_method_channel.dart';

class _RenderViewWidget extends StatefulWidget {
const _RenderViewWidget({
Key? key,
required this.builder,
required this.rtcEngine,
}) : super(key: key);

final Function(BuildContext context, RtcEngine engine) builder;

final RtcEngine rtcEngine;

@override
State<_RenderViewWidget> createState() => _RenderViewWidgetState();
}
Expand Down Expand Up @@ -41,7 +47,7 @@ class _RenderViewWidgetState extends State<_RenderViewWidget> {
String engineAppId = const String.fromEnvironment('TEST_APP_ID',
defaultValue: '<YOUR_APP_ID>');

_engine = createAgoraRtcEngine();
_engine = widget.rtcEngine;
await _engine.initialize(RtcEngineContext(
appId: engineAppId,
areaCode: AreaCode.areaCodeGlob.value(),
Expand Down Expand Up @@ -75,7 +81,12 @@ void testCases() {
testWidgets(
'Show local AgoraVideoView after RtcEngine.initialize',
(WidgetTester tester) async {
final irisMethodChannel = FakeIrisMethodChannel();
final rtcEngine =
RtcEngineImpl.create(irisMethodChannel: irisMethodChannel);

await tester.pumpWidget(_RenderViewWidget(
rtcEngine: rtcEngine,
builder: (context, engine) {
return SizedBox(
height: 100,
Expand All @@ -90,6 +101,8 @@ void testCases() {
},
));

await tester.pumpAndSettle(const Duration(milliseconds: 5000));
// pumpAndSettle again to ensure the `AgoraVideoView` shown
await tester.pumpAndSettle(const Duration(milliseconds: 5000));

if (defaultTargetPlatform == TargetPlatform.android) {
Expand All @@ -100,11 +113,132 @@ void testCases() {
expect(find.byType(UiKitView), findsOneWidget);
}

final setupLocalVideoCalls = irisMethodChannel.methodCallQueue
.where((e) => e.funcName == 'RtcEngine_setupLocalVideo')
.toList();

final jsonMap2 = jsonDecode(setupLocalVideoCalls[0].params);
expect(jsonMap2['canvas']['view'] != 0, isTrue);

await tester.pumpWidget(Container());
await tester.pumpAndSettle(const Duration(milliseconds: 5000));

expect(find.byType(AgoraVideoView), findsNothing);
},
skip: !(Platform.isAndroid || Platform.isIOS),
);

testWidgets(
'Switch local/remote AgoraVideoView with RtcConnection',
(WidgetTester tester) async {
final irisMethodChannel = FakeIrisMethodChannel();
final rtcEngine =
RtcEngineImpl.create(irisMethodChannel: irisMethodChannel);

await tester.pumpWidget(_RenderViewWidget(
rtcEngine: rtcEngine,
builder: (context, engine) {
return Column(
children: [
SizedBox(
height: 100,
width: 100,
child: AgoraVideoView(
controller: VideoViewController(
rtcEngine: engine,
canvas: const VideoCanvas(uid: 0),
),
),
),
SizedBox(
height: 100,
width: 100,
child: AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: engine,
canvas: const VideoCanvas(uid: 1000),
connection: const RtcConnection(
channelId: 'switch_video_view',
localUid: 1000,
),
),
),
)
],
);
},
));

await tester.pumpAndSettle(const Duration(milliseconds: 5000));
// pumpAndSettle again to ensure the `AgoraVideoView` shown
await tester.pumpAndSettle(const Duration(milliseconds: 5000));

if (defaultTargetPlatform == TargetPlatform.android) {
expect(find.byType(AndroidView), findsNWidgets(2));
}

if (defaultTargetPlatform == TargetPlatform.iOS) {
expect(find.byType(UiKitView), findsNWidgets(2));
}

// Clear the methodCall records
irisMethodChannel.reset();

await tester.pumpWidget(_RenderViewWidget(
rtcEngine: rtcEngine,
builder: (context, engine) {
return Column(
children: [
SizedBox(
height: 100,
width: 100,
child: AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: engine,
canvas: const VideoCanvas(uid: 1000),
connection: const RtcConnection(
channelId: 'switch_video_view',
localUid: 1000,
),
),
),
),
SizedBox(
height: 100,
width: 100,
child: AgoraVideoView(
controller: VideoViewController(
rtcEngine: engine,
canvas: const VideoCanvas(uid: 0),
),
),
)
],
);
},
));

await tester.pumpAndSettle(const Duration(milliseconds: 5000));
if (defaultTargetPlatform == TargetPlatform.android) {
expect(find.byType(AndroidView), findsNWidgets(2));
}
if (defaultTargetPlatform == TargetPlatform.iOS) {
expect(find.byType(UiKitView), findsNWidgets(2));
}

final setupRemoteVideoExCalls = irisMethodChannel.methodCallQueue
.where((e) => e.funcName == 'RtcEngineEx_setupRemoteVideoEx')
.toList();

final jsonMap1 = jsonDecode(setupRemoteVideoExCalls[0].params);
expect(jsonMap1['canvas']['view'] == 0, isTrue);

final jsonMap2 = jsonDecode(setupRemoteVideoExCalls[1].params);
expect(jsonMap2['canvas']['view'] != 0, isTrue);

await tester.pumpWidget(Container());
await tester.pumpAndSettle(const Duration(milliseconds: 5000));
},
skip: !(Platform.isAndroid || Platform.isIOS),
);
}