Skip to content

Commit

Permalink
use pigeon to generate platform channels
Browse files Browse the repository at this point in the history
  • Loading branch information
nullxception committed Jun 9, 2023
1 parent 3e74911 commit 65d1792
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.chaldeaprjkt.boorusphere

import StorageUtil
import android.os.Environment

class AndroidStorageUtil : StorageUtil {
override fun getStoragePath(): String {
val file = Environment.getExternalStorageDirectory()
return file.absolutePath
}

override fun getDownloadPath(): String {
val file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
return file.absolutePath
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
package io.chaldeaprjkt.boorusphere

import android.os.Environment
import androidx.annotation.NonNull
import StorageUtil
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
val channelPath = "${BuildConfig.APPLICATION_ID}/path"
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
channelPath
).setMethodCallHandler { call, result ->
if (call.method == "getDownload") {
result.success(downloadPath.absolutePath)
} else {
result.notImplemented()
}
}
}

@Suppress("DEPRECATION")
private val downloadPath get() =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
StorageUtil.setUp(flutterEngine.dartExecutor.binaryMessenger, AndroidStorageUtil())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Autogenerated from Pigeon (v9.2.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon


import android.util.Log
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MessageCodec
import io.flutter.plugin.common.StandardMessageCodec
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer

private fun wrapResult(result: Any?): List<Any?> {
return listOf(result)
}

private fun wrapError(exception: Throwable): List<Any?> {
if (exception is FlutterError) {
return listOf(
exception.code,
exception.message,
exception.details
)
} else {
return listOf(
exception.javaClass.simpleName,
exception.toString(),
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
)
}
}

/**
* Error class for passing custom error details to Flutter via a thrown PlatformException.
* @property code The error code.
* @property message The error message.
* @property details The error details. Must be a datatype supported by the api codec.
*/
class FlutterError (
val code: String,
override val message: String? = null,
val details: Any? = null
) : Throwable()
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface StorageUtil {
fun getStoragePath(): String
fun getDownloadPath(): String

companion object {
/** The codec used by StorageUtil. */
val codec: MessageCodec<Any?> by lazy {
StandardMessageCodec()
}
/** Sets up an instance of `StorageUtil` to handle messages through the `binaryMessenger`. */
@Suppress("UNCHECKED_CAST")
fun setUp(binaryMessenger: BinaryMessenger, api: StorageUtil?) {
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.StorageUtil.getStoragePath", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
var wrapped: List<Any?>
try {
wrapped = listOf<Any?>(api.getStoragePath())
} catch (exception: Throwable) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.StorageUtil.getDownloadPath", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
var wrapped: List<Any?>
try {
wrapped = listOf<Any?>(api.getDownloadPath())
} catch (exception: Throwable) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
74 changes: 74 additions & 0 deletions lib/pigeon/storage_util.pi.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Autogenerated from Pigeon (v9.2.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import

import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;

import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';

class StorageUtil {
/// Constructor for [StorageUtil]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
StorageUtil({BinaryMessenger? binaryMessenger})
: _binaryMessenger = binaryMessenger;
final BinaryMessenger? _binaryMessenger;

static const MessageCodec<Object?> codec = StandardMessageCodec();

Future<String> getStoragePath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.StorageUtil.getStoragePath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as String?)!;
}
}

Future<String> getDownloadPath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.StorageUtil.getDownloadPath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as String?)!;
}
}
}
5 changes: 2 additions & 3 deletions lib/presentation/provider/shared_storage_handle.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:boorusphere/pigeon/storage_util.pi.dart';
import 'package:media_scanner/media_scanner.dart';
import 'package:path/path.dart' as p;
import 'package:permission_handler/permission_handler.dart';
Expand All @@ -14,8 +14,7 @@ SharedStorageHandle sharedStorageHandle(SharedStorageHandleRef ref) {
}

Future<SharedStorageHandle> provideSharedStorageHandle() async {
const channel = MethodChannel('io.chaldeaprjkt.boorusphere/path');
final downloadPath = await channel.invokeMethod('getDownload');
final downloadPath = await StorageUtil().getDownloadPath();
return SharedStorageHandle(downloadPath: downloadPath);
}

Expand Down
15 changes: 15 additions & 0 deletions pigeons/storage_util.pi.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:pigeon/pigeon.dart';

@ConfigurePigeon(
PigeonOptions(
dartOut: 'lib/pigeon/storage_util.pi.dart',
kotlinOut:
'android/app/src/main/kotlin/io/chaldeaprjkt/boorusphere/pigeon/StorageUtil.pi.kt',
kotlinOptions: KotlinOptions(errorClassName: 'StorageUtilException'),
),
)
@HostApi()
abstract class StorageUtil {
String getStoragePath();
String getDownloadPath();
}
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.4.0"
pigeon:
dependency: "direct dev"
description:
name: pigeon
sha256: "6b270420d0808903f4c2d848aa96f8c12e6275b15989270f24e552939642212f"
url: "https://pub.dev"
source: hosted
version: "9.2.5"
pigment:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ dev_dependencies:
json_serializable: ^6.7.0
mocktail: ^0.3.0
riverpod_generator: ^2.0.0
pigeon: ^9.2.5

flutter_icons:
android: true
Expand Down
17 changes: 16 additions & 1 deletion tool/grind.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ Future<void> genlang() async {
await Pub.runAsync('slang', runOptions: utf8Opt);
}

@Task('Generate pigeon bindings')
Future<void> pigeons() async {
final files = Directory('pigeons')
.listSync(recursive: true)
.where((x) => x is File && x.path.endsWith('.pi.dart'))
.map((x) => x.path);

await Pub.runAsync('pigeon',
arguments: [
'--input',
...files,
],
runOptions: utf8Opt);
}

@Task('Build APKs')
@Depends(clean, sync, gencode, genlang)
Future<void> buildapk() async {
Expand All @@ -95,7 +110,7 @@ Future<void> checkfmt() async {
.where((x) =>
x is File &&
x.path.endsWith('.dart') &&
!x.path.contains(RegExp(r'\.(g|gr|freezed)\.dart$')))
!x.path.contains(RegExp(r'\.(freezed|g|gr|pi)\.dart$')))
.map((x) => x.path);

await runAsync(
Expand Down

0 comments on commit 65d1792

Please sign in to comment.