Merge branch 'newPeer' of git.openprivacy.ca:flutter/flutter_app into erinnplods

This commit is contained in:
erinn 2021-02-09 17:36:25 -08:00
commit 267b331614
5 changed files with 80 additions and 12 deletions

View File

@ -0,0 +1,21 @@
import '../model.dart';
// Class that handles libcwtch-go events (received either via ffi with an isolate or gomobile over a method channel from kotlin)
// Takes Notifiers and triggers them on appropriate events
class CwtchNotifier {
ProfileListState profileCN;
CwtchNotifier(ProfileListState pcn) {
profileCN = pcn;
}
void handleMessage(String type, dynamic data) {
switch (type) {
case "NewPeer":
profileCN.add(ProfileInfoState(onion: data["Identity"], nickname: data["name"], imagePath: data["picture"]));
break;
default:
print("unhandled gomobile appbus event: ${type}");
}
}
}

View File

@ -1,10 +1,15 @@
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'package:flutter_app/cwtch/cwtchNotifier.dart';
import 'package:path/path.dart' as path;
import 'package:ffi/ffi.dart';
import 'package:flutter_app/cwtch/cwtch.dart';
import '../model.dart';
/////////////////////
/// Cwtch API ///
/////////////////////
@ -44,9 +49,12 @@ typedef ACNEventsFn = Pointer<Utf8> Function();
class CwtchFfi implements Cwtch {
DynamicLibrary library;
CwtchNotifier cwtchNotifier;
Isolate cwtchIsolate;
CwtchFfi() {
CwtchFfi(CwtchNotifier _cwtchNotifier) {
library = DynamicLibrary.open("libCwtch.so");
cwtchNotifier = _cwtchNotifier;
}
Future<void> Start() async {
@ -64,6 +72,43 @@ class CwtchFfi implements Cwtch {
// ignore: non_constant_identifier_names
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
StartCwtch(Utf8.toUtf8(cwtchDir), cwtchDir.length, Utf8.toUtf8(""), 0);
// Spawn an isolate to listen to events from libcwtch-go and then dispatch them when received on main thread to cwtchNotifier
var _receivePort = ReceivePort();
cwtchIsolate = await Isolate.spawn(_checkAppbusEvents, _receivePort.sendPort);
_receivePort.listen((message) {
var env = jsonDecode(message);
cwtchNotifier.handleMessage(env["EventType"], env["Data"]);
});
}
// Called on object being disposed to (presumably on app close) to close the isolate that's listening to libcwtch-go events
@override
void dispose() {
if (cwtchIsolate != null) {
cwtchIsolate.kill();
}
}
// Entry point for an isolate to listen to a stream of events pulled from libcwtch-go and return them on the sendPort
static void _checkAppbusEvents(SendPort sendPort) async {
var stream = pollAppbusEvents();
await for (var value in stream) {
sendPort.send(value);
}
}
// Steam of appbus events. Call blocks in libcwtch-go GetAppbusEvent. Static so the isolate can use it
static Stream<String> pollAppbusEvents() async* {
var library = DynamicLibrary.open("libCwtch.so");
var getAppbusEventC = library.lookup<NativeFunction<acn_events_function>>("c_GetAppBusEvent");
final GetAppbusEvent = getAppbusEventC.asFunction<ACNEventsFn>();
while (true) {
Pointer<Utf8> result = GetAppbusEvent();
String event = Utf8.fromUtf8(result);
yield event;
}
}
// ignore: non_constant_identifier_names

View File

@ -8,6 +8,7 @@ import 'dart:async';
import 'package:path/path.dart' as path;
import 'cwtch.dart';
import 'cwtchNotifier.dart';
/*
TODO: make a reusable plugin for other flutter apps
@ -28,14 +29,15 @@ class CwtchGomobile implements Cwtch {
Future<String> androidLibraryDir;
Future<Directory> androidHomeDirectory;
ProfileListState profileCN;
CwtchNotifier cwtchNotifier;
CwtchGomobile(ProfileListState profs) {
CwtchGomobile(CwtchNotifier _cwtchNotifier) {
print("gomobile.dart: CwtchGomobile()");
profileCN = profs;
cwtchNotifier = _cwtchNotifier;
androidHomeDirectory = getApplicationDocumentsDirectory();
androidLibraryDir = appInfoPlatform.invokeMethod('getNativeLibDir');
// Method channel to receive libcwtch-go events via Kotlin and dispatch them to _handleAppbusEvent (sends to cwtchNotifier)
final appbusEventChannel = MethodChannel(appbusEventChannelName);
appbusEventChannel.setMethodCallHandler(this._handleAppbusEvent);
}
@ -48,15 +50,12 @@ class CwtchGomobile implements Cwtch {
cwtchPlatform.invokeMethod("Start", {"appDir": cwtchDir, "torPath": torPath});
}
// Handle libcwtch-go events (received via kotlin) and dispatch to the cwtchNotifier
Future<void> _handleAppbusEvent(MethodCall call) async {
final String json = call.arguments;
var obj = jsonDecode(json);
switch (call.method) {
case "NewPeer":
profileCN.add(ProfileInfoState(onion: obj["Identity"], nickname: obj["ProfileName"], imagePath: obj["Path"]));
break;
default: print("unhandled gomobile appbus event: $call");
}
cwtchNotifier.handleMessage(call.method, obj);
}
void SelectProfile(String onion) {

View File

@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_app/views/triplecolview.dart';
import 'package:provider/provider.dart';
import 'cwtch/cwtch.dart';
import 'cwtch/cwtchNotifier.dart';
import 'model.dart';
import 'views/profilemgrview.dart';
import 'views/splashView.dart';
@ -36,11 +37,12 @@ class FlwtchState extends State<Flwtch> {
super.initState();
cwtchInit = false;
profs = ProfileListState();
var cwtchNotifier = new CwtchNotifier(profs);
if (Platform.isAndroid) {
cwtch = CwtchGomobile(profs);
cwtch = CwtchGomobile(cwtchNotifier);
} else {
cwtch = CwtchFfi();
cwtch = CwtchFfi(cwtchNotifier);
}
cwtch.Start().then((val) {

View File

@ -83,6 +83,7 @@ add_custom_command(
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
linux-x64 ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"