Skip to content

Commit

Permalink
Setup flutter_rust_bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
lbirkert committed Aug 22, 2024
1 parent 56d3606 commit 54ca65c
Show file tree
Hide file tree
Showing 70 changed files with 5,816 additions and 102 deletions.
371 changes: 370 additions & 1 deletion Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ members = [
"qb-daemon",
# Application Clients
"qb-cli",

# Needed for FFI
"qb-mobile/rust",
]

[workspace.package]
Expand Down
12 changes: 0 additions & 12 deletions qb-mobile/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,6 @@ android {
signingConfig = signingConfigs.debug
}
}

sourceSets {
main {
jniLibs.srcDirs += "native"
}
debug {
jniLibs.srcDirs += "native"
}
profile {
jniLibs.srcDirs += "native"
}
}
}

flutter {
Expand Down
8 changes: 2 additions & 6 deletions qb-mobile/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.qb_mobile" >
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>

<application
android:label="qb_mobile"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:extractNativeLibs="true"
tools:replace="android:extractNativeLibs" >
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
3 changes: 3 additions & 0 deletions qb-mobile/flutter_rust_bridge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
rust_input: crate::api
rust_root: rust/
dart_output: lib/src/rust
13 changes: 13 additions & 0 deletions qb-mobile/integration_test/simple_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:qb_mobile/main.dart';
import 'package:qb_mobile/src/rust/frb_generated.dart';
import 'package:integration_test/integration_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUpAll(() async => await RustLib.init());
testWidgets('Can call rust function', (WidgetTester tester) async {
await tester.pumpWidget(const MyApp());
expect(find.textContaining('Result: `Hello, Tom!`'), findsOneWidget);
});
}
187 changes: 108 additions & 79 deletions qb-mobile/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,90 +1,119 @@
import 'package:flutter/material.dart';
import 'package:qb_mobile/service.dart';
// The original content is temporarily commented out to allow generating a self-contained demo - feel free to uncomment later.

void main() async {
WidgetsFlutterBinding.ensureInitialized();
print("kekw");
await initializeService();

runApp(const QuixByteApp());
}
// import 'package:flutter/material.dart';
// import 'package:qb_mobile/service.dart';
//
// void main() async {
// WidgetsFlutterBinding.ensureInitialized();
// print("kekw");
// await initializeService();
//
// runApp(const QuixByteApp());
// }
//
// class QuixByteApp extends StatelessWidget {
// const QuixByteApp({super.key});
//
// // This widget is the root of your application.
// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// title: 'QuixByte Mobile',
// theme: ThemeData(
// // This is the theme of your application.
// //
// // TRY THIS: Try running your application with "flutter run". You'll see
// // the application has a purple toolbar. Then, without quitting the app,
// // try changing the seedColor in the colorScheme below to Colors.green
// // and then invoke "hot reload" (save your changes or press the "hot
// // reload" button in a Flutter-supported IDE, or press "r" if you used
// // the command line to start the app).
// //
// // Notice that the counter didn't reset back to zero; the application
// // state is not lost during the reload. To reset the state, use hot
// // restart instead.
// //
// // This works for code too, not just values: Most code changes can be
// // tested with just a hot reload.
// colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
// useMaterial3: true,
// ),
// home: const QuixByteHomePage(),
// );
// }
// }
//
// class QuixByteHomePage extends StatelessWidget {
// const QuixByteHomePage({super.key});
//
// @override
// Widget build(BuildContext context) {
// // This method is rerun every time setState is called, for instance as done
// // by the _incrementCounter method above.
// //
// // The Flutter framework has been optimized to make rerunning build methods
// // fast, so that you can just rebuild anything that needs updating rather
// // than having to individually change instances of widgets.
// return Scaffold(
// appBar: AppBar(
// // TRY THIS: Try changing the color here to a specific color (to
// // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
// // change color while the other colors stay the same.
// backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// // Here we take the value from the MyHomePage object that was created by
// // the App.build method, and use it to set our appbar title.
// title: const Text("QuixByte Mobile"),
// ),
// body: Center(
// // Center is a layout widget. It takes a single child and positions it
// // in the middle of the parent.
// child: Column(
// // Column is also a layout widget. It takes a list of children and
// // arranges them vertically. By default, it sizes itself to fit its
// // children horizontally, and tries to be as tall as its parent.
// //
// // Column has various properties to control how it sizes itself and
// // how it positions its children. Here we use mainAxisAlignment to
// // center the children vertically; the main axis here is the vertical
// // axis because Columns are vertical (the cross axis would be
// // horizontal).
// //
// // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
// // action in the IDE, or press "p" in the console), to see the
// // wireframe for each widget.
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// FilledButton(onPressed: () {}, child: const Text("Settings")),
// FilledButton(onPressed: () {}, child: const Text("Manage")),
// FilledButton(onPressed: () {}, child: const Text("View Files")),
// ],
// ),
// ),
// );
// }
// }
//

class QuixByteApp extends StatelessWidget {
const QuixByteApp({super.key});
import 'package:flutter/material.dart';
import 'package:qb_mobile/src/rust/api/simple.dart';
import 'package:qb_mobile/src/rust/frb_generated.dart';

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QuixByte Mobile',
theme: ThemeData(
// This is the theme of your application.
//
// TRY THIS: Try running your application with "flutter run". You'll see
// the application has a purple toolbar. Then, without quitting the app,
// try changing the seedColor in the colorScheme below to Colors.green
// and then invoke "hot reload" (save your changes or press the "hot
// reload" button in a Flutter-supported IDE, or press "r" if you used
// the command line to start the app).
//
// Notice that the counter didn't reset back to zero; the application
// state is not lost during the reload. To reset the state, use hot
// restart instead.
//
// This works for code too, not just values: Most code changes can be
// tested with just a hot reload.
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const QuixByteHomePage(),
);
}
Future<void> main() async {
await RustLib.init();
runApp(const MyApp());
}

class QuixByteHomePage extends StatelessWidget {
const QuixByteHomePage({super.key});
class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// TRY THIS: Try changing the color here to a specific color (to
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
// change color while the other colors stay the same.
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: const Text("QuixByte Mobile"),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
//
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
// action in the IDE, or press "p" in the console), to see the
// wireframe for each widget.
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FilledButton(onPressed: () {}, child: const Text("Settings")),
FilledButton(onPressed: () {}, child: const Text("Manage")),
FilledButton(onPressed: () {}, child: const Text("View Files")),
],
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('flutter_rust_bridge quickstart')),
body: Center(
child: Text(
'Action: Call Rust `greet("Tom")`\nResult: `${greet(name: "Tom")}`'),
),
),
);
Expand Down
9 changes: 5 additions & 4 deletions qb-mobile/lib/service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'package:process/process.dart';
import 'package:flutter/material.dart';
import 'package:flutter_background_service/flutter_background_service.dart';


const ProcessManager processManager = LocalProcessManager();

Future<void> initializeService() async {
Expand Down Expand Up @@ -63,12 +62,14 @@ void onStart(ServiceInstance service) async {
//await copyBinary('qb-daemon-$abi', file);
//}

final fileProc = await processManager.run(['ls', '-la', '/data/app/com.example.qb_mobile.apk']);
final fileProc = await processManager
.run(['ls', '-la', '/data/app/com.example.qb_mobile.apk']);
print(fileProc.stdout);
print(fileProc.stderr);

final file = File('');
final process = await processManager.run([file.path, '--no-ipc --std'], runInShell: true);
final process = await processManager
.run([file.path, '--no-ipc --std'], runInShell: true);
print(process.stderr);
process.stdout.listen((data) {
print("recv: $data");
Expand Down Expand Up @@ -96,7 +97,7 @@ void onStart(ServiceInstance service) async {
// final src = await rootBundle.load("assets/bin/$srcBin");
// await dst.writeAsBytes(src.buffer.asUint8List(src.offsetInBytes, src.lengthInBytes));
// print(src.lengthInBytes);
//
//
// final chmodProc = await processManager.run(['chmod', '+x', dst.path], runInShell: true);
// print(chmodProc.stdout);
// print(chmodProc.stderr);
Expand Down
10 changes: 10 additions & 0 deletions qb-mobile/lib/src/rust/api/simple.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This file is automatically generated, so please do not edit it.
// Generated by `flutter_rust_bridge`@ 2.3.0.

// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import

import '../frb_generated.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';

String greet({required String name}) =>
RustLib.instance.api.crateApiSimpleGreet(name: name);
Loading

0 comments on commit 54ca65c

Please sign in to comment.