move all cwtch calls to an interface and an ffi implementation
This commit is contained in:
parent
8d202cfaeb
commit
c1f7556636
|
@ -0,0 +1,14 @@
|
|||
abstract class Cwtch {
|
||||
void Start(String appDir, String torPath) ;
|
||||
|
||||
void SelectProfile(String onion);
|
||||
|
||||
String ACNEvents();
|
||||
String ContactEvents();
|
||||
|
||||
String GetProfiles();
|
||||
String GetContacts(String onion);
|
||||
|
||||
int NumMessages(String profile, String handle);
|
||||
String GetMessage(String profile, String handle, int index);
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:flutter_app/cwtch/cwtch.dart';
|
||||
|
||||
/////////////////////
|
||||
/// Cwtch API ///
|
||||
/////////////////////
|
||||
|
||||
typedef start_cwtch_function = Void Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef StartCwtchFn = void Function(Pointer<Utf8> dir, int len);
|
||||
|
||||
typedef access_cwtch_eventbus_function = Void Function();
|
||||
typedef NextEventFn = void Function();
|
||||
|
||||
typedef get_json_blob_void_function = Pointer<Utf8> Function();
|
||||
typedef GetJsonBlobVoidFn = Pointer<Utf8> Function();
|
||||
|
||||
typedef get_json_blob_string_function = Pointer<Utf8> Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef GetJsonBlobStringFn = Pointer<Utf8> Function(Pointer<Utf8> str,int len);
|
||||
|
||||
//func NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) {
|
||||
typedef get_int_from_str_str_function = Int32 Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef GetIntFromStrStrFn = int Function(Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
|
||||
//func GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char {
|
||||
typedef get_json_blob_from_str_str_int_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int32);
|
||||
typedef GetJsonBlobFromStrStrIntFn = Pointer<Utf8> Function(Pointer<Utf8>, int, Pointer<Utf8>, int, int);
|
||||
|
||||
typedef acn_events_function = Pointer<Utf8> Function();
|
||||
typedef ACNEventsFn = Pointer<Utf8> Function();
|
||||
|
||||
class CwtchFfi implements Cwtch {
|
||||
DynamicLibrary library;
|
||||
|
||||
CwtchFfi() {
|
||||
library = DynamicLibrary.open("libCwtch.so");
|
||||
}
|
||||
|
||||
void Start(String appDir, String torPath) {
|
||||
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("StartCwtch");
|
||||
// ignore: non_constant_identifier_names
|
||||
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
|
||||
StartCwtch(Utf8.toUtf8(appDir), appDir.length);
|
||||
}
|
||||
|
||||
void SelectProfile(String onion) {
|
||||
var selectProfileC = library.lookup<NativeFunction<get_json_blob_string_function>>("SelectProfile");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SelectProfile = selectProfileC.asFunction<GetJsonBlobStringFn>();
|
||||
|
||||
SelectProfile(Utf8.toUtf8(onion), onion.length);
|
||||
}
|
||||
|
||||
String ACNEvents() {
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>(
|
||||
"ACNEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ACNEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
Pointer<Utf8> result = ACNEvents();
|
||||
String event = Utf8.fromUtf8(result);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
String ContactEvents() {
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>(
|
||||
"ContactEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ContactEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
Pointer<Utf8> result = ContactEvents();
|
||||
String event = Utf8.fromUtf8(result);
|
||||
return event;
|
||||
}
|
||||
|
||||
String GetProfiles() {
|
||||
var getProfilesC = library.lookup<NativeFunction<get_json_blob_void_function>>("GetProfiles");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetProfiles = getProfilesC.asFunction<GetJsonBlobVoidFn>();
|
||||
|
||||
Pointer<Utf8> jsonProfilesBytes = GetProfiles();
|
||||
String jsonProfiles = Utf8.fromUtf8(jsonProfilesBytes);
|
||||
return jsonProfiles;
|
||||
}
|
||||
|
||||
String GetContacts(String onion) {
|
||||
var getContactsC = library.lookup<NativeFunction<get_json_blob_string_function>>("GetContacts");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetContacts = getContactsC.asFunction<GetJsonBlobStringFn>();
|
||||
Pointer<Utf8> jsonContactBytes = GetContacts(Utf8.toUtf8(onion), onion.length);
|
||||
String jsonContacts = Utf8.fromUtf8(jsonContactBytes);
|
||||
return jsonContacts;
|
||||
}
|
||||
|
||||
int NumMessages(String profile, String handle) {
|
||||
var numMessagesC = library.lookup<NativeFunction<get_int_from_str_str_function>>("NumMessages");
|
||||
// ignore: non_constant_identifier_names
|
||||
final NumMessages = numMessagesC.asFunction<GetIntFromStrStrFn>();
|
||||
|
||||
int num = NumMessages(Utf8.toUtf8(profile), profile.length, Utf8.toUtf8(handle), handle.length);
|
||||
return num;
|
||||
}
|
||||
|
||||
String GetMessage(String profile, String handle, int index) {
|
||||
var getMessageC = library.lookup<NativeFunction<get_json_blob_from_str_str_int_function>>("GetMessage");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetMessage = getMessageC.asFunction<GetJsonBlobFromStrStrIntFn>();
|
||||
|
||||
Pointer<Utf8> jsonMessageBytes = GetMessage(Utf8.toUtf8(profile), profile.length, Utf8.toUtf8(handle), handle.length, index);
|
||||
String jsonMessage = Utf8.fromUtf8(jsonMessageBytes);
|
||||
return jsonMessage;
|
||||
}
|
||||
}
|
|
@ -1,30 +1,13 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/cwtch/ffi.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'cwtch/cwtch.dart';
|
||||
import 'model.dart';
|
||||
import 'views/profilemgrview.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:io' show Platform;
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'model.dart' as model;
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef start_cwtch_function = Void Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef StartCwtchFn = void Function(Pointer<Utf8> dir, int len);
|
||||
|
||||
typedef access_cwtch_eventbus_function = Void Function();
|
||||
typedef NextEventFn = void Function();
|
||||
|
||||
|
||||
typedef get_json_blob_void_function = Pointer<Utf8> Function();
|
||||
typedef GetJsonBlobVoidFn = Pointer<Utf8> Function();
|
||||
|
||||
typedef get_json_blob_string_function = Pointer<Utf8> Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef GetJsonBlobStringFn = Pointer<Utf8> Function(Pointer<Utf8> str,int len);
|
||||
|
||||
void main() => runApp(Flwtch());
|
||||
|
||||
|
@ -38,7 +21,7 @@ class Flwtch extends StatefulWidget {
|
|||
class FlwtchState extends State<Flwtch> {
|
||||
final TextStyle biggerFont = const TextStyle(fontSize: 18);
|
||||
|
||||
DynamicLibrary library;
|
||||
Cwtch cwtch;
|
||||
AppModel appStatus;
|
||||
|
||||
static const appInfoPlatform = const MethodChannel('test.flutter.dev/applicationInfo');
|
||||
|
@ -70,8 +53,10 @@ class FlwtchState extends State<Flwtch> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
library = DynamicLibrary.open("libCwtch.so");
|
||||
appStatus = AppModel(library: library);
|
||||
|
||||
cwtch = CwtchFfi();
|
||||
|
||||
appStatus = AppModel(cwtch: cwtch);
|
||||
|
||||
String home = "";
|
||||
Map<String, String> envVars = Platform.environment;
|
||||
|
@ -85,13 +70,9 @@ class FlwtchState extends State<Flwtch> {
|
|||
home = androidHomeDirectory;
|
||||
}
|
||||
|
||||
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("StartCwtch");
|
||||
// ignore: non_constant_identifier_names
|
||||
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
|
||||
|
||||
var cwtchDir = path.join(home, ".cwtch/dev/");
|
||||
print("cwtchDir $cwtchDir");
|
||||
StartCwtch(Utf8.toUtf8(cwtchDir), cwtchDir.length);
|
||||
cwtch.Start(cwtchDir, "tor");
|
||||
|
||||
return Provider<FlwtchState>(
|
||||
create: (_) => this,
|
||||
|
|
|
@ -3,6 +3,8 @@ import 'package:ffi/ffi.dart';
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'cwtch/cwtch.dart';
|
||||
|
||||
////////////////////
|
||||
/// UI State ///
|
||||
////////////////////
|
||||
|
@ -28,22 +30,15 @@ class ContactModel {
|
|||
/// ACN ///
|
||||
/////////////
|
||||
|
||||
typedef acn_events_function = Pointer<Utf8> Function();
|
||||
typedef ACNEventsFn = Pointer<Utf8> Function();
|
||||
|
||||
|
||||
class AppModel {
|
||||
final DynamicLibrary library;
|
||||
AppModel({this.library});
|
||||
final Cwtch cwtch;
|
||||
AppModel({this.cwtch});
|
||||
|
||||
Stream<String> contactEvents() async* {
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>(
|
||||
"ContactEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ContactEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
while (true) {
|
||||
Pointer<Utf8> result = ContactEvents();
|
||||
String event = Utf8.fromUtf8(result);
|
||||
String event = cwtch.ContactEvents();
|
||||
if (event != "") {
|
||||
print(event);
|
||||
yield event;
|
||||
|
@ -53,16 +48,9 @@ class AppModel {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Stream<String> torStatus() async* {
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>(
|
||||
"ACNEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ACNEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
while (true) {
|
||||
Pointer<Utf8> result = ACNEvents();
|
||||
String event = Utf8.fromUtf8(result);
|
||||
String event = cwtch.ACNEvents();
|
||||
if (event != "") {
|
||||
yield event;
|
||||
} else {
|
||||
|
@ -71,27 +59,3 @@ class AppModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
/// Cwtch API ///
|
||||
/////////////////////
|
||||
|
||||
typedef start_cwtch_function = Void Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef StartCwtchFn = void Function(Pointer<Utf8> dir, int len);
|
||||
|
||||
typedef access_cwtch_eventbus_function = Void Function();
|
||||
typedef NextEventFn = void Function();
|
||||
|
||||
typedef get_json_blob_void_function = Pointer<Utf8> Function();
|
||||
typedef GetJsonBlobVoidFn = Pointer<Utf8> Function();
|
||||
|
||||
typedef get_json_blob_string_function = Pointer<Utf8> Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef GetJsonBlobStringFn = Pointer<Utf8> Function(Pointer<Utf8> str,int len);
|
||||
|
||||
//func NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) {
|
||||
typedef get_int_from_str_str_function = Int32 Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef GetIntFromStrStrFn = int Function(Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
|
||||
//func GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char {
|
||||
typedef get_json_blob_from_str_str_int_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int32);
|
||||
typedef GetJsonBlobFromStrStrIntFn = Pointer<Utf8> Function(Pointer<Utf8>, int, Pointer<Utf8>, int, int);
|
||||
|
|
|
@ -31,15 +31,10 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
|
||||
|
||||
Widget _buildContactList() {
|
||||
var getContactsC = Provider.of<FlwtchState>(context).library.lookup<NativeFunction<get_json_blob_string_function>>("GetContacts");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetContacts = getContactsC.asFunction<GetJsonBlobStringFn>();
|
||||
|
||||
return StreamBuilder<String>(
|
||||
stream: Provider.of<FlwtchState>(context).appStatus.contactEvents(),
|
||||
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
|
||||
Pointer<Utf8> jsonContactBytes = GetContacts(Utf8.toUtf8(widget.profileOnion), widget.profileOnion.length);
|
||||
String jsonContacts = Utf8.fromUtf8(jsonContactBytes);
|
||||
String jsonContacts = Provider.of<FlwtchState>(context).cwtch.GetContacts(widget.profileOnion);
|
||||
print(jsonContacts);
|
||||
List<dynamic> contacts = jsonDecode(jsonContacts);
|
||||
|
||||
|
|
|
@ -29,32 +29,20 @@ class _MessageViewState extends State<MessageView> {
|
|||
}
|
||||
|
||||
Widget _buildMessageView(BuildContext context) {
|
||||
var numMessagesC = Provider.of<FlwtchState>(context).library.lookup<NativeFunction<get_int_from_str_str_function>>("NumMessages");
|
||||
// ignore: non_constant_identifier_names
|
||||
final NumMessages = numMessagesC.asFunction<GetIntFromStrStrFn>();
|
||||
var getMessageC = Provider.of<FlwtchState>(context).library.lookup<NativeFunction<get_json_blob_from_str_str_int_function>>("GetMessage");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetMessage = getMessageC.asFunction<GetJsonBlobFromStrStrIntFn>();
|
||||
|
||||
_updateMessageCount(context, NumMessages);
|
||||
_updateMessageCount(context);
|
||||
if (timer == null) {
|
||||
timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
|
||||
print("tick");
|
||||
_updateMessageCount(context, NumMessages);
|
||||
_updateMessageCount(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return ProxyProvider0(
|
||||
update: (_, __) => MessageCounter(conversationNumMessages),
|
||||
child: ListView.builder(
|
||||
itemCount: conversationNumMessages,
|
||||
itemBuilder: (context, index) {
|
||||
Pointer<Utf8> jsonMessageBytes = GetMessage(
|
||||
Utf8.toUtf8(widget.profileOnion), widget.profileOnion.length,
|
||||
Utf8.toUtf8(widget.conversationHandle), widget.conversationHandle.length,
|
||||
index);
|
||||
String jsonMessage = Utf8.fromUtf8(jsonMessageBytes);
|
||||
String jsonMessage = Provider.of<FlwtchState>(context).cwtch.GetMessage(widget.profileOnion, widget.conversationHandle, index);
|
||||
//print(jsonMessage);
|
||||
dynamic messageWrapper = jsonDecode(jsonMessage);
|
||||
dynamic message = jsonDecode(messageWrapper['Message']);
|
||||
|
@ -68,18 +56,13 @@ class _MessageViewState extends State<MessageView> {
|
|||
));
|
||||
}
|
||||
|
||||
Future _updateMessageCount(BuildContext context, GetIntFromStrStrFn cfn) async {
|
||||
Future _updateMessageCount(BuildContext context) async {
|
||||
if (!mounted) {
|
||||
if (timer != null && timer.isActive) timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
conversationNumMessages = cfn(
|
||||
Utf8.toUtf8(widget.profileOnion), widget.profileOnion.length,
|
||||
Utf8.toUtf8(widget.conversationHandle),
|
||||
widget.conversationHandle.length,
|
||||
);
|
||||
conversationNumMessages = Provider.of<FlwtchState>(context).cwtch.NumMessages(widget.profileOnion, widget.conversationHandle);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,8 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
}
|
||||
|
||||
if (_profiles.length < 1) {
|
||||
var getProfilesC = Provider.of<FlwtchState>(context).library.lookup<NativeFunction<get_json_blob_void_function>>("GetProfiles");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetProfiles = getProfilesC.asFunction<GetJsonBlobVoidFn>();
|
||||
|
||||
Pointer<Utf8> jsonProfilesBytes = GetProfiles();
|
||||
String jsonProfiles = Utf8.fromUtf8(jsonProfilesBytes);
|
||||
String jsonProfiles = Provider.of<FlwtchState>(context).cwtch.GetProfiles();
|
||||
print(jsonProfiles);
|
||||
|
||||
Map<String, dynamic> profiles = jsonDecode(jsonProfiles);
|
||||
|
@ -84,11 +80,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
subtitle: Text(profile.onion),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
var selectProfileC = Provider.of<FlwtchState>(context, listen:false).library.lookup<NativeFunction<get_json_blob_string_function>>("SelectProfile");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SelectProfile = selectProfileC.asFunction<GetJsonBlobStringFn>();
|
||||
|
||||
SelectProfile(Utf8.toUtf8(profile.onion), profile.onion.length);
|
||||
Provider.of<FlwtchState>(context, listen:false).cwtch.SelectProfile(profile.onion);
|
||||
_pushContactList(profile.onion);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -31,13 +31,4 @@ class _TorStatusState extends State<TorStatusLabel> {
|
|||
},
|
||||
));
|
||||
}
|
||||
|
||||
void _incrementCounter() {
|
||||
setState(() {
|
||||
var nextEventC = Provider.of<FlwtchState>(context).library.lookup<NativeFunction<access_cwtch_eventbus_function>>("NextEvent");
|
||||
// ignore: non_constant_identifier_names
|
||||
final NextEvent = nextEventC.asFunction<NextEventFn>();
|
||||
NextEvent();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue