implement gomobile interface for start and parial work on GetProfiles
This commit is contained in:
parent
c1f7556636
commit
c2aa0dfb4a
|
@ -0,0 +1,46 @@
|
|||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import io.flutter.plugin.common.MethodChannel.Result
|
||||
import androidx.annotation.NonNull
|
||||
import android.content.Context
|
||||
|
||||
//import libCwtch.LibCwtch
|
||||
|
||||
/* References:
|
||||
more detailed kotlin / flutter method channel example:
|
||||
https://stablekernel.com/article/flutter-platform-channels-quick-start/
|
||||
|
||||
kotlin / flutter plugin:
|
||||
https://github.com/flutter/samples -- experimental/federated_plugin/federated_plugin
|
||||
*/
|
||||
/*
|
||||
class FederatedPlugin : FlutterPlugin, MethodCallHandler {
|
||||
private lateinit var channel: MethodChannel
|
||||
private var context: Context? = null
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "cwtch")
|
||||
channel.setMethodCallHandler(this)
|
||||
context = flutterPluginBinding.applicationContext
|
||||
}
|
||||
|
||||
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||
when (call.method) {
|
||||
"Start" -> {
|
||||
val appDir = (call.arguments as? String) ?: "";
|
||||
val tor = (call.arguments as? String) ?: "tor";
|
||||
result.success(LibCwtch.Start(appDir, tor))
|
||||
?: result.error("Failed to start cwtch", "", null);
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel.setMethodCallHandler(null)
|
||||
context = null
|
||||
}
|
||||
|
||||
}*/
|
|
@ -4,37 +4,55 @@ import io.flutter.embedding.android.FlutterActivity
|
|||
import androidx.annotation.NonNull
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import io.flutter.plugin.common.MethodChannel.Result
|
||||
import android.content.pm.PackageManager
|
||||
|
||||
import android.util.Log
|
||||
|
||||
import cwtch.Cwtch
|
||||
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
|
||||
private val CHANNEL = "test.flutter.dev/applicationInfo"
|
||||
private val CALL_NATIVE_LIB_DIR = "getNativeLibDir"
|
||||
private val CHANNEL_APP_INFO = "test.flutter.dev/applicationInfo"
|
||||
private val CALL_APP_INFO = "getNativeLibDir"
|
||||
|
||||
private val CHANNEL_CWTCH = "cwtch"
|
||||
|
||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
|
||||
// Note: this method is invoked on the main thread.
|
||||
call, result ->
|
||||
if (call.method == CALL_NATIVE_LIB_DIR) {
|
||||
val nativeLibDir = getNativeLibDir()
|
||||
// Note: this method is invoked on the main thread.
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_APP_INFO).setMethodCallHandler { call, result -> handleAppInfo(call, result) }
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_CWTCH).setMethodCallHandler { call, result -> handleCwtch(call, result) }
|
||||
}
|
||||
|
||||
if (nativeLibDir != "") {
|
||||
result.success(nativeLibDir)
|
||||
} else {
|
||||
result.error("UNAVAILABLE", "nativeLibDir not available.", null)
|
||||
}
|
||||
} else {
|
||||
result.notImplemented()
|
||||
}
|
||||
private fun handleAppInfo(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||
when (call.method) {
|
||||
CALL_APP_INFO -> result.success(getNativeLibDir())
|
||||
?: result.error("Unavailable", "nativeLibDir not available", null);
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNativeLibDir(): String {
|
||||
|
||||
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
|
||||
"com.example.flutter_app", // Must be app name
|
||||
PackageManager.GET_SHARED_LIBRARY_FILES)
|
||||
return ainfo.nativeLibraryDir
|
||||
}
|
||||
|
||||
private fun handleCwtch(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||
when (call.method) {
|
||||
"Start" -> {
|
||||
Log.i("MainActivity.kt", "handleAppInfo Start")
|
||||
val appDir = (call.argument("appDir") as? String) ?: "";
|
||||
val torPath = (call.argument("torPath") as? String) ?: "tor";
|
||||
Log.i("MainActivity.kt", " appDir: '" + appDir + "' torPath: '" + torPath + "'")
|
||||
Cwtch.startCwtch(appDir, torPath)
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -1,12 +1,12 @@
|
|||
abstract class Cwtch {
|
||||
void Start(String appDir, String torPath) ;
|
||||
void Start();
|
||||
|
||||
void SelectProfile(String onion);
|
||||
|
||||
String ACNEvents();
|
||||
String ContactEvents();
|
||||
|
||||
String GetProfiles();
|
||||
Future<String> GetProfiles();
|
||||
String GetContacts(String onion);
|
||||
|
||||
int NumMessages(String profile, String handle);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:flutter_app/cwtch/cwtch.dart';
|
||||
|
@ -7,8 +9,8 @@ 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 start_cwtch_function = Void Function(Pointer<Utf8> str, Int32 length, Pointer<Utf8> str2, Int32 length2);
|
||||
typedef StartCwtchFn = void Function(Pointer<Utf8> dir, int len, Pointer<Utf8> tor, int torLen);
|
||||
|
||||
typedef access_cwtch_eventbus_function = Void Function();
|
||||
typedef NextEventFn = void Function();
|
||||
|
@ -37,15 +39,25 @@ class CwtchFfi implements Cwtch {
|
|||
library = DynamicLibrary.open("libCwtch.so");
|
||||
}
|
||||
|
||||
void Start(String appDir, String torPath) {
|
||||
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("StartCwtch");
|
||||
void Start() {
|
||||
String home = "";
|
||||
Map<String, String> envVars = Platform.environment;
|
||||
if (Platform.isLinux) {
|
||||
home = envVars['HOME'];
|
||||
} else if (Platform.isWindows) {
|
||||
home = envVars['UserProfile'];
|
||||
}
|
||||
var cwtchDir = path.join(home, ".cwtch/dev/");
|
||||
print("cwtchDir $cwtchDir");
|
||||
|
||||
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("c_StartCwtch");
|
||||
// ignore: non_constant_identifier_names
|
||||
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
|
||||
StartCwtch(Utf8.toUtf8(appDir), appDir.length);
|
||||
StartCwtch(Utf8.toUtf8(cwtchDir), cwtchDir.length, Utf8.toUtf8(""), 0);
|
||||
}
|
||||
|
||||
void SelectProfile(String onion) {
|
||||
var selectProfileC = library.lookup<NativeFunction<get_json_blob_string_function>>("SelectProfile");
|
||||
var selectProfileC = library.lookup<NativeFunction<get_json_blob_string_function>>("c_SelectProfile");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SelectProfile = selectProfileC.asFunction<GetJsonBlobStringFn>();
|
||||
|
||||
|
@ -54,7 +66,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
String ACNEvents() {
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>(
|
||||
"ACNEvents");
|
||||
"c_ACNEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ACNEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
|
@ -66,7 +78,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
String ContactEvents() {
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>(
|
||||
"ContactEvents");
|
||||
"c_ContactEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ContactEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
|
@ -75,8 +87,8 @@ class CwtchFfi implements Cwtch {
|
|||
return event;
|
||||
}
|
||||
|
||||
String GetProfiles() {
|
||||
var getProfilesC = library.lookup<NativeFunction<get_json_blob_void_function>>("GetProfiles");
|
||||
Future<String> GetProfiles() async {
|
||||
var getProfilesC = library.lookup<NativeFunction<get_json_blob_void_function>>("c_GetProfiles");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetProfiles = getProfilesC.asFunction<GetJsonBlobVoidFn>();
|
||||
|
||||
|
@ -86,7 +98,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
String GetContacts(String onion) {
|
||||
var getContactsC = library.lookup<NativeFunction<get_json_blob_string_function>>("GetContacts");
|
||||
var getContactsC = library.lookup<NativeFunction<get_json_blob_string_function>>("c_GetContacts");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetContacts = getContactsC.asFunction<GetJsonBlobStringFn>();
|
||||
Pointer<Utf8> jsonContactBytes = GetContacts(Utf8.toUtf8(onion), onion.length);
|
||||
|
@ -95,7 +107,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
int NumMessages(String profile, String handle) {
|
||||
var numMessagesC = library.lookup<NativeFunction<get_int_from_str_str_function>>("NumMessages");
|
||||
var numMessagesC = library.lookup<NativeFunction<get_int_from_str_str_function>>("c_NumMessages");
|
||||
// ignore: non_constant_identifier_names
|
||||
final NumMessages = numMessagesC.asFunction<GetIntFromStrStrFn>();
|
||||
|
||||
|
@ -104,7 +116,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
String GetMessage(String profile, String handle, int index) {
|
||||
var getMessageC = library.lookup<NativeFunction<get_json_blob_from_str_str_int_function>>("GetMessage");
|
||||
var getMessageC = library.lookup<NativeFunction<get_json_blob_from_str_str_int_function>>("c_GetMessage");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetMessage = getMessageC.asFunction<GetJsonBlobFromStrStrIntFn>();
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'dart:async';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'cwtch.dart';
|
||||
|
||||
/*
|
||||
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
||||
|
||||
/// It uses [FederatedPluginInterface]
|
||||
Future startCwtch() async {
|
||||
return await FederatedPluginInterface.instance.startCwtch();
|
||||
}
|
||||
*/
|
||||
|
||||
class CwtchGomobile implements Cwtch {
|
||||
static const appInfoPlatform = const MethodChannel('test.flutter.dev/applicationInfo');
|
||||
static const cwtchPlatform = const MethodChannel('cwtch');
|
||||
|
||||
var androidLibraryDir = "";
|
||||
var androidHomeDirectory = "";
|
||||
|
||||
CwtchGomobile() {
|
||||
print("CwtchGomobile()");
|
||||
/*getApplicationDocumentsDirectory().then((directory) =>
|
||||
{
|
||||
print("androidHomeDir = $directory"),
|
||||
androidHomeDirectory = directory.path
|
||||
});
|
||||
|
||||
appInfoPlatform.invokeMethod('getNativeLibDir').then((value) =>
|
||||
{
|
||||
print("nativeLibraryDir = $value"),
|
||||
androidLibraryDir = value
|
||||
});*/
|
||||
}
|
||||
|
||||
void Start() async {
|
||||
var androidHome = getApplicationDocumentsDirectory();
|
||||
var androidLibDir = appInfoPlatform.invokeMethod('getNativeLibDir');
|
||||
|
||||
var cwtchDir = path.join((await androidHome).path, ".cwtch/dev/");
|
||||
String torPath = path.join(await androidLibDir, "libtor.so");
|
||||
print("gomobile.dart: Start($cwtchDir, $torPath)");
|
||||
cwtchPlatform.invokeMethod("Start", {"appDir": cwtchDir, "torPath": torPath});
|
||||
}
|
||||
|
||||
void SelectProfile(String onion) {
|
||||
}
|
||||
|
||||
String ACNEvents() {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
String ContactEvents() {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
Future<String> GetProfiles() {
|
||||
return cwtchPlatform.invokeMethod("GetProfiles");
|
||||
}
|
||||
|
||||
String GetContacts(String onion) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
int NumMessages(String profile, String handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String GetMessage(String profile, String handle, int index) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/cwtch/ffi.dart';
|
||||
import 'package:flutter_app/cwtch/gomobile.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'cwtch/cwtch.dart';
|
||||
import 'model.dart';
|
||||
|
@ -24,55 +25,23 @@ class FlwtchState extends State<Flwtch> {
|
|||
Cwtch cwtch;
|
||||
AppModel appStatus;
|
||||
|
||||
static const appInfoPlatform = const MethodChannel('test.flutter.dev/applicationInfo');
|
||||
var androidLibraryDir = "";
|
||||
var androidHomeDirectory = "";
|
||||
|
||||
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
getApplicationDocumentsDirectory().then((directory) =>
|
||||
{
|
||||
setState(() {
|
||||
print("androidHomeDir = $directory");
|
||||
androidHomeDirectory = directory.path;
|
||||
})
|
||||
});
|
||||
|
||||
appInfoPlatform.invokeMethod('getNativeLibDir').then((value) =>
|
||||
{
|
||||
setState(() {
|
||||
print("nativeLibraryDir = $value");
|
||||
androidLibraryDir = value;
|
||||
})
|
||||
});
|
||||
cwtch = CwtchGomobile();
|
||||
} else {
|
||||
cwtch = CwtchFfi();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
cwtch = CwtchFfi();
|
||||
|
||||
appStatus = AppModel(cwtch: cwtch);
|
||||
|
||||
String home = "";
|
||||
Map<String, String> envVars = Platform.environment;
|
||||
if (Platform.isMacOS) {
|
||||
home = envVars['HOME'];
|
||||
} else if (Platform.isLinux) {
|
||||
home = envVars['HOME'];
|
||||
} else if (Platform.isWindows) {
|
||||
home = envVars['UserProfile'];
|
||||
} else if (Platform.isAndroid) {
|
||||
home = androidHomeDirectory;
|
||||
}
|
||||
|
||||
var cwtchDir = path.join(home, ".cwtch/dev/");
|
||||
print("cwtchDir $cwtchDir");
|
||||
cwtch.Start(cwtchDir, "tor");
|
||||
cwtch.Start();
|
||||
|
||||
return Provider<FlwtchState>(
|
||||
create: (_) => this,
|
||||
|
|
Loading…
Reference in New Issue