feat(android): stream the connection info

This commit is contained in:
ksenia312
2024-02-04 17:11:25 +01:00
parent 66a79eb4ba
commit 90c2908496
7 changed files with 94 additions and 20 deletions
@@ -289,4 +289,28 @@ class NearbyServiceManager(private var context: Context) {
handler.removeCallbacks(postCallback) handler.removeCallbacks(postCallback)
} }
} }
var connectionInfoHandler = object : EventChannel.StreamHandler {
private var handler: Handler = Handler(Looper.getMainLooper())
private var eventSink: EventChannel.EventSink? = null
val postCallback = object : Runnable {
override fun run() {
handler.post { eventSink?.success(receiver.wifiInfo?.toJsonString()) }
handler.postDelayed(this, 1000)
}
}
override fun onListen(arguments: Any?, sink: EventChannel.EventSink?) {
onCancel(null)
eventSink = sink
Logger.d("Listen connection info")
handler.postDelayed(postCallback, 1000)
}
override fun onCancel(p0: Any?) {
Logger.d("Kill last process connection info")
eventSink = null
handler.removeCallbacks(postCallback)
}
}
} }
@@ -17,6 +17,7 @@ import kotlinx.coroutines.launch
const val CHANNEL_NAME = "nearby_service" const val CHANNEL_NAME = "nearby_service"
const val PEERS_CHANNEL_NAME = "nearby_service_peers" const val PEERS_CHANNEL_NAME = "nearby_service_peers"
const val CONNECTED_DEVICE_CHANNEL_NAME = "nearby_service_connected_device" const val CONNECTED_DEVICE_CHANNEL_NAME = "nearby_service_connected_device"
const val CONNECTION_INFO_CHANNEL_NAME = "nearby_service_connection_info"
/** /**
* Plugin for creating connections in the Wi-fi Direct scope. * Plugin for creating connections in the Wi-fi Direct scope.
@@ -27,6 +28,7 @@ class NearbyServicePlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
private lateinit var manager: NearbyServiceManager private lateinit var manager: NearbyServiceManager
private lateinit var peersChannel: EventChannel private lateinit var peersChannel: EventChannel
private lateinit var connectedDeviceChannel: EventChannel private lateinit var connectedDeviceChannel: EventChannel
private lateinit var connectionInfoChannel: EventChannel
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
@@ -157,6 +159,9 @@ class NearbyServicePlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
connectedDeviceChannel = EventChannel(binaryMessenger, CONNECTED_DEVICE_CHANNEL_NAME) connectedDeviceChannel = EventChannel(binaryMessenger, CONNECTED_DEVICE_CHANNEL_NAME)
connectedDeviceChannel.setStreamHandler(manager.connectedDeviceInfoHandler) connectedDeviceChannel.setStreamHandler(manager.connectedDeviceInfoHandler)
connectionInfoChannel = EventChannel(binaryMessenger, CONNECTION_INFO_CHANNEL_NAME)
connectionInfoChannel.setStreamHandler(manager.connectionInfoHandler)
} }
+40 -19
View File
@@ -46,27 +46,30 @@ class MyApp extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.fromLTRB(16, 20, 16, 0), padding: const EdgeInsets.fromLTRB(16, 10, 16, 10),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Platform: ${service.platformVersion}\n' 'Platform: ${service.platformVersion}, Model: ${service.platformModel}',
'Model: ${service.platformModel}',
), ),
if (service.currentDeviceInfo != null) if (service.currentDeviceInfo != null)
Text( Text(
'Device Name: ${service.currentDeviceInfo!.displayName}' 'Device Name: ${service.currentDeviceInfo!.displayName} ${Platform.isIOS ? '\nDevice ID: ${service.currentDeviceInfo!.id}' : ''}',
'${Platform.isIOS ? '\nDevice ID: ${service.currentDeviceInfo!.id}' : ''}',
), ),
Text(
'Communication channel state: ${service.communicationChannelState.previewName}\n',
),
if (Platform.isIOS) if (Platform.isIOS)
Text( Text(
'You are ${service.isIOSBrowser ? 'going to find your friend' : 'waiting for another user to connect'}', 'You are ${service.isIOSBrowser ? 'going to find your friend' : 'waiting for another user to connect'}',
), ),
Text( if (Platform.isAndroid &&
'Communication channel state: ${service.communicationChannelState.previewName}', service.isAndroidGroupOwner != null)
) Text(
'You ${service.isAndroidGroupOwner! ? 'are' : 'are not'} a group owner',
),
], ],
), ),
), ),
@@ -201,8 +204,7 @@ class AppService extends ChangeNotifier {
StreamSubscription? peersSubscription; StreamSubscription? peersSubscription;
StreamSubscription? connectedDeviceSubscription; StreamSubscription? connectedDeviceSubscription;
StreamSubscription? connectionInfoSubscription;
final _filesAccepts = <String, Future<bool?>>{};
@override @override
void dispose() { void dispose() {
@@ -218,8 +220,8 @@ class AppService extends ChangeNotifier {
return _nearbyService.ios?.isBrowser.value ?? false; return _nearbyService.ios?.isBrowser.value ?? false;
} }
bool get isAndroidGroupOwner { bool? get isAndroidGroupOwner {
return Platform.isAndroid && (connectionAndroidInfo?.isGroupOwner ?? false); return connectionAndroidInfo?.isGroupOwner;
} }
Future<void> getPlatformInfo() async { Future<void> getPlatformInfo() async {
@@ -287,6 +289,7 @@ class AppService extends ChangeNotifier {
final result = await _nearbyService.discover(); final result = await _nearbyService.discover();
if (result) { if (result) {
updateState(AppState.discoveringPeers); updateState(AppState.discoveringPeers);
startListeningConnectionInfo();
} }
} catch (e) { } catch (e) {
if (kDebugMode) { if (kDebugMode) {
@@ -325,15 +328,36 @@ class AppService extends ChangeNotifier {
} }
Future<void> stopListeningPeers() async { Future<void> stopListeningPeers() async {
peersSubscription?.cancel(); await peersSubscription?.cancel();
peers = null; peers = null;
updateState(AppState.discoveringPeers); updateState(AppState.discoveringPeers);
} }
Future<void> stopListeningConnectionInfo() async {
await connectionInfoSubscription?.cancel();
connectionInfoSubscription = null;
}
Future<void> connect(NearbyDevice device) async { Future<void> connect(NearbyDevice device) async {
try { try {
await _nearbyService.connect(device); await _nearbyService.connect(device);
connectionAndroidInfo = await _nearbyService.android?.getConnectionInfo(); } catch (e) {
if (kDebugMode) {
print(e);
}
}
notifyListeners();
}
void startListeningConnectionInfo() {
try {
connectionInfoSubscription =
_nearbyService.android?.getConnectionInfoStream().listen(
(event) async {
connectionAndroidInfo = event;
notifyListeners();
},
);
} catch (e) { } catch (e) {
if (kDebugMode) { if (kDebugMode) {
print(e); print(e);
@@ -468,10 +492,6 @@ class AppService extends ChangeNotifier {
); );
} }
void setFileAcceptFuture(String id, Future<bool?> future) {
_filesAccepts[id] = future;
}
Future<void> disconnect(NearbyDevice device) async { Future<void> disconnect(NearbyDevice device) async {
try { try {
await _nearbyService.disconnect(device); await _nearbyService.disconnect(device);
@@ -488,6 +508,7 @@ class AppService extends ChangeNotifier {
Future<void> stopListeningAll() async { Future<void> stopListeningAll() async {
await stopListeningConnectedDevice(); await stopListeningConnectedDevice();
await stopListeningPeers(); await stopListeningPeers();
await stopListeningConnectionInfo();
await stopDiscovery(); await stopDiscovery();
} }
@@ -817,7 +838,7 @@ class _ConnectedBody extends StatelessWidget {
else else
Text( Text(
'Connecting socket.. ' 'Connecting socket.. '
'${service.isAndroidGroupOwner ? "Waiting a client for connect" : "Waiting a connection"}', '${service.isAndroidGroupOwner != null ? service.isAndroidGroupOwner! ? "Waiting a client for connect" : "Waiting a server for connect" : "Waiting a connection"}',
) )
], ],
), ),
@@ -126,6 +126,14 @@ class NearbyAndroidService extends NearbyService {
return NearbyServiceAndroidPlatform.instance.getConnectionInfo(); return NearbyServiceAndroidPlatform.instance.getConnectionInfo();
} }
///
/// Streams [NearbyConnectionAndroidInfo] -
/// information about the connection information.
///
Stream<NearbyConnectionAndroidInfo?> getConnectionInfoStream() {
return NearbyServiceAndroidPlatform.instance.getConnectionInfoStream();
}
void _requireAndroidDevice(NearbyDevice device) { void _requireAndroidDevice(NearbyDevice device) {
assert( assert(
device is NearbyAndroidDevice, device is NearbyAndroidDevice,
@@ -54,4 +54,10 @@ abstract class NearbyServiceAndroidPlatform extends PlatformInterface {
Future<bool> disconnect(String deviceAddress) { Future<bool> disconnect(String deviceAddress) {
throw UnimplementedError('disconnect() has not been implemented.'); throw UnimplementedError('disconnect() has not been implemented.');
} }
Stream<NearbyConnectionAndroidInfo?> getConnectionInfoStream() {
throw UnimplementedError(
'getConnectionInfoStream() has not been implemented.',
);
}
} }
@@ -64,4 +64,14 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
)) ?? )) ??
false; false;
} }
@override
Stream<NearbyConnectionAndroidInfo?> getConnectionInfoStream() {
const connectedDeviceChannel = EventChannel(
"nearby_service_connection_info",
);
return connectedDeviceChannel.receiveBroadcastStream().map(
(e) => NearbyConnectionInfoMapper.mapToInfo(e),
);
}
} }
+1 -1
View File
@@ -31,8 +31,8 @@ class FilesSocket {
final NearbyMessageFilesContent content; final NearbyMessageFilesContent content;
final void Function(String) onDestroy; final void Function(String) onDestroy;
final NearbyServiceFilesListener? listener; final NearbyServiceFilesListener? listener;
final WebSocket _socket; final WebSocket _socket;
final _files = <NearbyFile>[]; final _files = <NearbyFile>[];
final _bytesTable = <String, List<int>>{'0': []}; final _bytesTable = <String, List<int>>{'0': []};
final _futures = <Future>[]; final _futures = <Future>[];