starting porting old Java code to Kotlin
Test / test (push) Successful in 7m16s

- no stubs for iOS and macOS yet

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2026-04-26 16:51:32 +02:00
parent b91c8a93db
commit 2847092782
19 changed files with 2489 additions and 19 deletions
@@ -48,10 +48,14 @@ android {
useJUnitPlatform() useJUnitPlatform()
testLogging { testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError" events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false} outputs.upToDateWhen { false }
showStandardStreams = true showStandardStreams = true
} }
} }
} }
}
buildFeatures {
buildConfig = true
}
}
@@ -1,4 +1,4 @@
// Copyright (c) 2026, Org Mars3142 // Copyright (c) 2026, mars3142
// Autogenerated from Pigeon (v26.3.4), do not edit directly. // Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
@@ -34,6 +34,150 @@ private object MessagesPigeonUtils {
) )
} }
} }
fun doubleEquals(a: Double, b: Double): Boolean {
// Normalize -0.0 to 0.0 and handle NaN equality.
return (if (a == 0.0) 0.0 else a) == (if (b == 0.0) 0.0 else b) || (a.isNaN() && b.isNaN())
}
fun floatEquals(a: Float, b: Float): Boolean {
// Normalize -0.0 to 0.0 and handle NaN equality.
return (if (a == 0.0f) 0.0f else a) == (if (b == 0.0f) 0.0f else b) || (a.isNaN() && b.isNaN())
}
fun doubleHash(d: Double): Int {
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
val normalized = if (d == 0.0) 0.0 else d
val bits = java.lang.Double.doubleToLongBits(normalized)
return (bits xor (bits ushr 32)).toInt()
}
fun floatHash(f: Float): Int {
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
val normalized = if (f == 0.0f) 0.0f else f
return java.lang.Float.floatToIntBits(normalized)
}
fun deepEquals(a: Any?, b: Any?): Boolean {
if (a === b) {
return true
}
if (a == null || b == null) {
return false
}
if (a is ByteArray && b is ByteArray) {
return a.contentEquals(b)
}
if (a is IntArray && b is IntArray) {
return a.contentEquals(b)
}
if (a is LongArray && b is LongArray) {
return a.contentEquals(b)
}
if (a is DoubleArray && b is DoubleArray) {
if (a.size != b.size) return false
for (i in a.indices) {
if (!doubleEquals(a[i], b[i])) return false
}
return true
}
if (a is FloatArray && b is FloatArray) {
if (a.size != b.size) return false
for (i in a.indices) {
if (!floatEquals(a[i], b[i])) return false
}
return true
}
if (a is Array<*> && b is Array<*>) {
if (a.size != b.size) return false
for (i in a.indices) {
if (!deepEquals(a[i], b[i])) return false
}
return true
}
if (a is List<*> && b is List<*>) {
if (a.size != b.size) return false
val iterA = a.iterator()
val iterB = b.iterator()
while (iterA.hasNext() && iterB.hasNext()) {
if (!deepEquals(iterA.next(), iterB.next())) return false
}
return true
}
if (a is Map<*, *> && b is Map<*, *>) {
if (a.size != b.size) return false
for (entry in a) {
val key = entry.key
var found = false
for (bEntry in b) {
if (deepEquals(key, bEntry.key)) {
if (deepEquals(entry.value, bEntry.value)) {
found = true
break
} else {
return false
}
}
}
if (!found) return false
}
return true
}
if (a is Double && b is Double) {
return doubleEquals(a, b)
}
if (a is Float && b is Float) {
return floatEquals(a, b)
}
return a == b
}
fun deepHash(value: Any?): Int {
return when (value) {
null -> 0
is ByteArray -> value.contentHashCode()
is IntArray -> value.contentHashCode()
is LongArray -> value.contentHashCode()
is DoubleArray -> {
var result = 1
for (item in value) {
result = 31 * result + doubleHash(item)
}
result
}
is FloatArray -> {
var result = 1
for (item in value) {
result = 31 * result + floatHash(item)
}
result
}
is Array<*> -> {
var result = 1
for (item in value) {
result = 31 * result + deepHash(item)
}
result
}
is List<*> -> {
var result = 1
for (item in value) {
result = 31 * result + deepHash(item)
}
result
}
is Map<*, *> -> {
var result = 0
for (entry in value) {
result += ((deepHash(entry.key) * 31) xor deepHash(entry.value))
}
result
}
is Double -> doubleHash(value)
is Float -> floatHash(value)
else -> value.hashCode()
}
}
} }
/** /**
@@ -47,12 +191,126 @@ class FlutterError (
override val message: String? = null, override val message: String? = null,
val details: Any? = null val details: Any? = null
) : RuntimeException() ) : RuntimeException()
/** Generated class from Pigeon that represents data sent in messages. */
data class App (
val packageName: String,
val appName: String,
val installedBy: String,
val icon: ByteArray
)
{
companion object {
fun fromList(pigeonVar_list: List<Any?>): App {
val packageName = pigeonVar_list[0] as String
val appName = pigeonVar_list[1] as String
val installedBy = pigeonVar_list[2] as String
val icon = pigeonVar_list[3] as ByteArray
return App(packageName, appName, installedBy, icon)
}
}
fun toList(): List<Any?> {
return listOf(
packageName,
appName,
installedBy,
icon,
)
}
override fun equals(other: Any?): Boolean {
if (other == null || other.javaClass != javaClass) {
return false
}
if (this === other) {
return true
}
val other = other as App
return MessagesPigeonUtils.deepEquals(this.packageName, other.packageName) && MessagesPigeonUtils.deepEquals(this.appName, other.appName) && MessagesPigeonUtils.deepEquals(this.installedBy, other.installedBy) && MessagesPigeonUtils.deepEquals(this.icon, other.icon)
}
override fun hashCode(): Int {
var result = javaClass.hashCode()
result = 31 * result + MessagesPigeonUtils.deepHash(this.packageName)
result = 31 * result + MessagesPigeonUtils.deepHash(this.appName)
result = 31 * result + MessagesPigeonUtils.deepHash(this.installedBy)
result = 31 * result + MessagesPigeonUtils.deepHash(this.icon)
return result
}
}
/** Generated class from Pigeon that represents data sent in messages. */
data class Toast (
val app: App,
val message: String,
val timestamp: Long,
val duration: Long
)
{
companion object {
fun fromList(pigeonVar_list: List<Any?>): Toast {
val app = pigeonVar_list[0] as App
val message = pigeonVar_list[1] as String
val timestamp = pigeonVar_list[2] as Long
val duration = pigeonVar_list[3] as Long
return Toast(app, message, timestamp, duration)
}
}
fun toList(): List<Any?> {
return listOf(
app,
message,
timestamp,
duration,
)
}
override fun equals(other: Any?): Boolean {
if (other == null || other.javaClass != javaClass) {
return false
}
if (this === other) {
return true
}
val other = other as Toast
return MessagesPigeonUtils.deepEquals(this.app, other.app) && MessagesPigeonUtils.deepEquals(this.message, other.message) && MessagesPigeonUtils.deepEquals(this.timestamp, other.timestamp) && MessagesPigeonUtils.deepEquals(this.duration, other.duration)
}
override fun hashCode(): Int {
var result = javaClass.hashCode()
result = 31 * result + MessagesPigeonUtils.deepHash(this.app)
result = 31 * result + MessagesPigeonUtils.deepHash(this.message)
result = 31 * result + MessagesPigeonUtils.deepHash(this.timestamp)
result = 31 * result + MessagesPigeonUtils.deepHash(this.duration)
return result
}
}
private open class MessagesPigeonCodec : StandardMessageCodec() { private open class MessagesPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return super.readValueOfType(type, buffer) return when (type) {
129.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
App.fromList(it)
}
}
130.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
Toast.fromList(it)
}
}
else -> super.readValueOfType(type, buffer)
}
} }
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
super.writeValue(stream, value) when (value) {
is App -> {
stream.write(129)
writeValue(stream, value.toList())
}
is Toast -> {
stream.write(130)
writeValue(stream, value.toList())
}
else -> super.writeValue(stream, value)
}
} }
} }
@@ -60,6 +318,13 @@ private open class MessagesPigeonCodec : StandardMessageCodec() {
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface ToasterUtilsApi { interface ToasterUtilsApi {
fun getPlatformName(callback: (Result<String?>) -> Unit) fun getPlatformName(callback: (Result<String?>) -> Unit)
fun getInstalledApps(callback: (Result<List<App>>) -> Unit)
fun getInstalledApp(packageName: String, callback: (Result<App?>) -> Unit)
fun getToasts(packageName: String, callback: (Result<List<Toast>>) -> Unit)
fun getToastFiltered(packageName: String, from: Long, callback: (Result<List<Toast>>) -> Unit)
fun isServiceRunning(callback: (Result<Boolean>) -> Unit)
fun showSettings(callback: (Result<Unit>) -> Unit)
fun exampleToast(callback: (Result<Unit>) -> Unit)
companion object { companion object {
/** The codec used by ToasterUtilsApi. */ /** The codec used by ToasterUtilsApi. */
@@ -88,6 +353,137 @@ interface ToasterUtilsApi {
channel.setMessageHandler(null) channel.setMessageHandler(null)
} }
} }
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApps$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
api.getInstalledApps{ result: Result<List<App>> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(MessagesPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApp$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val packageNameArg = args[0] as String
api.getInstalledApp(packageNameArg) { result: Result<App?> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(MessagesPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToasts$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val packageNameArg = args[0] as String
api.getToasts(packageNameArg) { result: Result<List<Toast>> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(MessagesPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToastFiltered$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val packageNameArg = args[0] as String
val fromArg = args[1] as Long
api.getToastFiltered(packageNameArg, fromArg) { result: Result<List<Toast>> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(MessagesPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.isServiceRunning$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
api.isServiceRunning{ result: Result<Boolean> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(MessagesPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.showSettings$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
api.showSettings{ result: Result<Unit> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
reply.reply(MessagesPigeonUtils.wrapResult(null))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.exampleToast$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
api.exampleToast{ result: Result<Unit> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(MessagesPigeonUtils.wrapError(error))
} else {
reply.reply(MessagesPigeonUtils.wrapResult(null))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
} }
} }
} }
@@ -1,14 +1,20 @@
package org.mars3142 package org.mars3142
import App
import Toast
import ToasterUtilsApi import ToasterUtilsApi
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.FlutterPlugin
class ToasterUtilsPlugin : FlutterPlugin, ToasterUtilsApi { class ToasterUtilsPlugin : FlutterPlugin, ToasterUtilsApi {
companion object { private var context: Context? = null
private const val TAG = "ToasterUtilsPlugin"
}
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
context = binding.applicationContext
ToasterUtilsApi.setUp(binding.binaryMessenger, this) ToasterUtilsApi.setUp(binding.binaryMessenger, this)
} }
@@ -19,4 +25,43 @@ class ToasterUtilsPlugin : FlutterPlugin, ToasterUtilsApi {
override fun getPlatformName(callback: (Result<String?>) -> Unit) { override fun getPlatformName(callback: (Result<String?>) -> Unit) {
callback(Result.success("Android ${android.os.Build.VERSION.RELEASE}")) callback(Result.success("Android ${android.os.Build.VERSION.RELEASE}"))
} }
}
override fun getInstalledApps(callback: (Result<List<App>>) -> Unit) {
callback(Result.success(emptyList()))
}
override fun getInstalledApp(packageName: String, callback: (Result<App?>) -> Unit) {
callback(Result.success(null))
}
override fun getToasts(packageName: String, callback: (Result<List<Toast>>) -> Unit) {
callback(Result.success(emptyList()))
}
override fun getToastFiltered(
packageName: String,
from: Long,
callback: (Result<List<Toast>>) -> Unit
) {
callback(Result.success(emptyList()))
}
override fun isServiceRunning(callback: (Result<Boolean>) -> Unit) {
callback(Result.success(true))
}
override fun showSettings(callback: (Result<Unit>) -> Unit) {
context?.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
callback(Result.success(Unit))
}
override fun exampleToast(callback: (Result<Unit>) -> Unit) {
context?.let { ctx ->
Handler(Looper.getMainLooper()).post {
android.widget.Toast.makeText(ctx, R.string.example_toast, android.widget.Toast.LENGTH_LONG)
.show()
}
}
callback(Result.success(Unit))
}
}
@@ -0,0 +1,31 @@
package org.mars3142.toaster.database
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
class DatabaseHelper(context: Context?) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
companion object {
private const val DATABASE_NAME = "toaster.db3"
private const val DATABASE_VERSION = 1
private const val TAG = "DatabaseHelper"
}
override fun onCreate(db: SQLiteDatabase) {
Log.v(TAG, "create database")
ToasterTable.onCreate(db)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
Log.v(TAG, "Upgrading database from version $oldVersion to $newVersion")
ToasterTable.onUpgrade(db, oldVersion, newVersion)
}
override fun onDowngrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
Log.v(TAG, "Downgrading database from version $oldVersion to $newVersion")
ToasterTable.onDowngrade(db, oldVersion, newVersion)
}
}
@@ -0,0 +1,164 @@
package org.mars3142.toaster.database
import android.content.ContentProvider
import android.content.ContentUris
import android.content.ContentValues
import android.content.UriMatcher
import android.database.Cursor
import android.database.SQLException
import android.database.sqlite.SQLiteQueryBuilder
import android.net.Uri
import android.provider.BaseColumns
import android.util.Log
import io.flutter.BuildConfig
class ToasterProvider : ContentProvider() {
companion object {
const val AUTHORITY: String = "org.mars3142.toaster"
private val TAG = ToasterProvider::class.java.simpleName
private const val TOASTER = 1
private const val TOASTER_ID = 2
private const val PACKAGE = 3
private val toasterMap = hashMapOf<String?, String?>(
BaseColumns._ID to BaseColumns._ID,
ToasterTable.TIMESTAMP to ToasterTable.TIMESTAMP,
ToasterTable.MESSAGE to ToasterTable.MESSAGE,
ToasterTable.PACKAGE to ToasterTable.PACKAGE,
ToasterTable.VERSIONCODE to ToasterTable.VERSIONCODE,
ToasterTable.VERSIONNAME to ToasterTable.VERSIONNAME,
BaseColumns._COUNT to BaseColumns._COUNT,
)
private val packageMap = hashMapOf<String?, String?>(
ToasterTable.PACKAGE to ToasterTable.PACKAGE,
)
private val mUriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
addURI(AUTHORITY, "toaster", TOASTER)
addURI(AUTHORITY, "toaster/#", TOASTER_ID)
addURI(AUTHORITY, "packages", PACKAGE)
}
}
private var dbHelper: DatabaseHelper? = null
override fun onCreate(): Boolean {
dbHelper = DatabaseHelper(context)
return true
}
override fun query(
uri: Uri,
projection: Array<String?>?,
selection: String?,
selectionArgs: Array<String?>?,
sortOrder: String?
): Cursor? {
if (BuildConfig.DEBUG) {
Log.v(TAG, "query: uri=$uri projection=${projection.contentToString()} selection=[$selection] args=${selectionArgs.contentToString()} order=[$sortOrder]")
}
val queryBuilder = SQLiteQueryBuilder()
val effectiveSortOrder = when (mUriMatcher.match(uri)) {
TOASTER -> {
queryBuilder.tables = ToasterTable.TABLENAME
queryBuilder.projectionMap = toasterMap
sortOrder ?: "${ToasterTable.TIMESTAMP} DESC"
}
TOASTER_ID -> {
queryBuilder.tables = ToasterTable.TABLENAME
queryBuilder.projectionMap = toasterMap
queryBuilder.appendWhere("${BaseColumns._ID} = ${uri.lastPathSegment}")
sortOrder
}
PACKAGE -> {
queryBuilder.tables = ToasterTable.TABLENAME
queryBuilder.projectionMap = packageMap
queryBuilder.isDistinct = true
sortOrder ?: "${ToasterTable.PACKAGE} ASC"
}
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
val database = dbHelper?.readableDatabase ?: return null
val cursor = queryBuilder.query(database, projection, selection, selectionArgs, null, null, effectiveSortOrder)
context?.let { cursor?.setNotificationUri(it.contentResolver, uri) }
return cursor
}
override fun getType(uri: Uri): String {
if (BuildConfig.DEBUG) Log.v(TAG, "getType: uri=$uri")
return when (mUriMatcher.match(uri)) {
TOASTER -> ToasterTable.CONTENT_TYPE
TOASTER_ID -> ToasterTable.CONTENT_ITEM_TYPE
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
}
@Synchronized
override fun insert(uri: Uri, initialValues: ContentValues?): Uri? {
if (BuildConfig.DEBUG) Log.v(TAG, "insert: uri=$uri initialValues=[$initialValues]")
if (mUriMatcher.match(uri) != TOASTER) throw IllegalArgumentException("Unknown URI: $uri")
val values = initialValues?.let { ContentValues(it) } ?: ContentValues()
val rowId = dbHelper?.writableDatabase?.insert(ToasterTable.TABLENAME, null, values) ?: 0L
if (rowId > 0) {
context?.contentResolver?.notifyChange(uri, null)
return ContentUris.withAppendedId(ToasterTable.TOASTER_URI, rowId)
}
throw SQLException("Failed to insert row into $uri")
}
@Synchronized
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String?>?): Int {
if (BuildConfig.DEBUG) {
Log.v(TAG, "delete: uri=$uri selection=[$selection] args=${selectionArgs.contentToString()}")
}
val database = dbHelper?.writableDatabase ?: return 0
val count = when (mUriMatcher.match(uri)) {
TOASTER -> database.delete(ToasterTable.TABLENAME, selection, selectionArgs)
TOASTER_ID -> {
val finalWhere = buildString {
append("${BaseColumns._ID} = ${uri.lastPathSegment}")
if (selection != null) append(" AND $selection")
}
database.delete(ToasterTable.TABLENAME, finalWhere, selectionArgs)
}
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
context?.contentResolver?.notifyChange(uri, null)
return count
}
@Synchronized
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<String?>?
): Int {
if (BuildConfig.DEBUG) {
Log.v(TAG, "update: uri=$uri values=[$values] selection=[$selection] args=${selectionArgs.contentToString()}")
}
val database = dbHelper?.writableDatabase ?: return 0
val count = when (mUriMatcher.match(uri)) {
TOASTER -> database.update(ToasterTable.TABLENAME, values, selection, selectionArgs)
TOASTER_ID -> {
val finalWhere = buildString {
append("${BaseColumns._ID} = ${uri.lastPathSegment}")
if (selection != null) append(" AND $selection")
}
database.update(ToasterTable.TABLENAME, values, finalWhere, selectionArgs)
}
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
context?.contentResolver?.notifyChange(uri, null)
return count
}
}
@@ -0,0 +1,52 @@
package org.mars3142.toaster.database
import android.content.ContentResolver
import android.database.SQLException
import android.database.sqlite.SQLiteDatabase
import android.net.Uri
import android.provider.BaseColumns
import androidx.core.net.toUri
object ToasterTable : BaseColumns {
const val TABLENAME: String = "toaster"
const val TIMESTAMP: String = "timestamp"
const val PACKAGE: String = "package"
const val MESSAGE: String = "message"
const val VERSIONCODE: String = "version_code"
const val VERSIONNAME: String = "version_name"
val TOASTER_URI: Uri = "content://${ToasterProvider.AUTHORITY}/toaster".toUri()
val PACKAGE_URI: Uri = "content://${ToasterProvider.AUTHORITY}/packages".toUri()
val CONTENT_TYPE: String = "${ContentResolver.CURSOR_DIR_BASE_TYPE}/vnd.mars3142.content.toaster"
val CONTENT_ITEM_TYPE: String = "${ContentResolver.CURSOR_ITEM_BASE_TYPE}/vnd.mars3142.content.toaster"
fun onCreate(db: SQLiteDatabase) {
db.execSQL(
"""
CREATE TABLE $TABLENAME (${BaseColumns._ID} INTEGER PRIMARY KEY AUTOINCREMENT,
$TIMESTAMP LONG, $PACKAGE TEXT, $MESSAGE TEXT, $VERSIONCODE INTEGER,
$VERSIONNAME TEXT );
"""
)
}
fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
if (newVersion > oldVersion) {
when (oldVersion) {
0 -> try {
db.execSQL("ALTER TABLE $TABLENAME ADD COLUMN $VERSIONCODE INTEGER;")
db.execSQL("ALTER TABLE $TABLENAME ADD COLUMN $VERSIONNAME TEXT;")
} catch (ex: SQLException) {
// upgrade already done
}
else -> {
db.execSQL("DROP TABLE IF EXISTS $TABLENAME")
onCreate(db)
}
}
}
}
@Suppress("UNUSED_PARAMETER")
fun onDowngrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {}
}
@@ -0,0 +1,36 @@
package org.mars3142.toaster.services
import android.accessibilityservice.AccessibilityService
import android.annotation.SuppressLint
import android.app.Notification
import android.content.ContentValues
import android.content.Intent
import android.util.Log
import android.view.accessibility.AccessibilityEvent
import org.mars3142.toaster.database.ToasterTable
@SuppressLint("AccessibilityPolicy")
class ToasterService : AccessibilityService() {
companion object {
private val TAG = ToasterService::class.java.simpleName
}
override fun onAccessibilityEvent(event: AccessibilityEvent) {
if (event.eventType != AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
Log.d(TAG, "Unexpected event type")
return
}
if (event.parcelableData !is Notification) return
val message = event.text.joinToString("\n") { it.toString() }
val cv = ContentValues().apply {
put(ToasterTable.PACKAGE, event.packageName as String?)
put(ToasterTable.MESSAGE, message)
put(ToasterTable.TIMESTAMP, System.currentTimeMillis())
}
contentResolver.insert(ToasterTable.TOASTER_URI, cv)
sendBroadcast(Intent("org.mars3142.toaster.APPWIDGET_UPDATE"))
}
override fun onInterrupt() {}
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="example_toast">This is just an example toast.</string>
</resources>
@@ -1,4 +1,4 @@
// Copyright (c) 2026, Org Mars3142 // Copyright (c) 2026, mars3142
// Autogenerated from Pigeon (v26.3.4), do not edit directly. // Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
// ignore_for_file: unused_import, unused_shown_name // ignore_for_file: unused_import, unused_shown_name
@@ -35,6 +35,178 @@ Object? _extractReplyValueOrThrow(
return replyList.firstOrNull; return replyList.firstOrNull;
} }
bool _deepEquals(Object? a, Object? b) {
if (identical(a, b)) {
return true;
}
if (a is double && b is double) {
if (a.isNaN && b.isNaN) {
return true;
}
return a == b;
}
if (a is List && b is List) {
return a.length == b.length &&
a.indexed
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
}
if (a is Map && b is Map) {
if (a.length != b.length) {
return false;
}
for (final MapEntry<Object?, Object?> entryA in a.entries) {
bool found = false;
for (final MapEntry<Object?, Object?> entryB in b.entries) {
if (_deepEquals(entryA.key, entryB.key)) {
if (_deepEquals(entryA.value, entryB.value)) {
found = true;
break;
} else {
return false;
}
}
}
if (!found) {
return false;
}
}
return true;
}
return a == b;
}
int _deepHash(Object? value) {
if (value is List) {
return Object.hashAll(value.map(_deepHash));
}
if (value is Map) {
int result = 0;
for (final MapEntry<Object?, Object?> entry in value.entries) {
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
}
return result;
}
if (value is double && value.isNaN) {
// Normalize NaN to a consistent hash.
return 0x7FF8000000000000.hashCode;
}
if (value is double && value == 0.0) {
// Normalize -0.0 to 0.0 so they have the same hash code.
return 0.0.hashCode;
}
return value.hashCode;
}
class App {
App({
required this.packageName,
required this.appName,
required this.installedBy,
required this.icon,
});
String packageName;
String appName;
String installedBy;
Uint8List icon;
List<Object?> _toList() {
return <Object?>[
packageName,
appName,
installedBy,
icon,
];
}
Object encode() {
return _toList(); }
static App decode(Object result) {
result as List<Object?>;
return App(
packageName: result[0]! as String,
appName: result[1]! as String,
installedBy: result[2]! as String,
icon: result[3]! as Uint8List,
);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(Object other) {
if (other is! App || other.runtimeType != runtimeType) {
return false;
}
if (identical(this, other)) {
return true;
}
return _deepEquals(packageName, other.packageName) && _deepEquals(appName, other.appName) && _deepEquals(installedBy, other.installedBy) && _deepEquals(icon, other.icon);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}
class Toast {
Toast({
required this.app,
required this.message,
required this.timestamp,
required this.duration,
});
App app;
String message;
int timestamp;
int duration;
List<Object?> _toList() {
return <Object?>[
app,
message,
timestamp,
duration,
];
}
Object encode() {
return _toList(); }
static Toast decode(Object result) {
result as List<Object?>;
return Toast(
app: result[0]! as App,
message: result[1]! as String,
timestamp: result[2]! as int,
duration: result[3]! as int,
);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(Object other) {
if (other is! Toast || other.runtimeType != runtimeType) {
return false;
}
if (identical(this, other)) {
return true;
}
return _deepEquals(app, other.app) && _deepEquals(message, other.message) && _deepEquals(timestamp, other.timestamp) && _deepEquals(duration, other.duration);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}
class _PigeonCodec extends StandardMessageCodec { class _PigeonCodec extends StandardMessageCodec {
@@ -44,6 +216,12 @@ class _PigeonCodec extends StandardMessageCodec {
if (value is int) { if (value is int) {
buffer.putUint8(4); buffer.putUint8(4);
buffer.putInt64(value); buffer.putInt64(value);
} else if (value is App) {
buffer.putUint8(129);
writeValue(buffer, value.encode());
} else if (value is Toast) {
buffer.putUint8(130);
writeValue(buffer, value.encode());
} else { } else {
super.writeValue(buffer, value); super.writeValue(buffer, value);
} }
@@ -52,6 +230,10 @@ class _PigeonCodec extends StandardMessageCodec {
@override @override
Object? readValueOfType(int type, ReadBuffer buffer) { Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) { switch (type) {
case 129:
return App.decode(readValue(buffer)!);
case 130:
return Toast.decode(readValue(buffer)!);
default: default:
return super.readValueOfType(type, buffer); return super.readValueOfType(type, buffer);
} }
@@ -89,4 +271,135 @@ class ToasterUtilsApi {
; ;
return pigeonVar_replyValue as String?; return pigeonVar_replyValue as String?;
} }
Future<List<App>> getInstalledApps() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApps$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<App>();
}
Future<App?> getInstalledApp(String packageName) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApp$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
return pigeonVar_replyValue as App?;
}
Future<List<Toast>> getToasts(String packageName) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToasts$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<Toast>();
}
Future<List<Toast>> getToastFiltered(String packageName, int from) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToastFiltered$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName, from]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<Toast>();
}
Future<bool> isServiceRunning() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.isServiceRunning$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return pigeonVar_replyValue! as bool;
}
Future<void> showSettings() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.showSettings$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
_extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
}
Future<void> exampleToast() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.exampleToast$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
_extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
}
} }
@@ -1 +1 @@
Copyright (c) 2026, Org Mars3142 Copyright (c) 2026, mars3142
@@ -16,4 +16,43 @@ import 'package:pigeon/pigeon.dart';
abstract class ToasterUtilsApi { abstract class ToasterUtilsApi {
@async @async
String? getPlatformName(); String? getPlatformName();
@async
List<App> getInstalledApps();
@async
App? getInstalledApp(String packageName);
@async
List<Toast> getToasts(String packageName);
@async
List<Toast> getToastFiltered(String packageName, int from);
@async
bool isServiceRunning();
@async
void showSettings();
@async
void exampleToast();
}
class App {
const App(this.packageName, this.appName, this.installedBy, this.icon);
final String packageName;
final String appName;
final String installedBy;
final Uint8List icon;
}
class Toast {
const Toast(this.app, this.message, this.timestamp, this.duration);
final App app;
final String message;
final int timestamp;
final int duration;
} }
@@ -1,4 +1,4 @@
// Copyright (c) 2026, Org mars3142 // Copyright (c) 2026, mars3142
// Autogenerated from Pigeon (v26.3.4), do not edit directly. // Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
@@ -65,11 +65,233 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
return value as! T? return value as! T?
} }
private func doubleEqualsMessages(_ lhs: Double, _ rhs: Double) -> Bool {
return (lhs.isNaN && rhs.isNaN) || lhs == rhs
}
private func doubleHashMessages(_ value: Double, _ hasher: inout Hasher) {
if value.isNaN {
hasher.combine(0x7FF8000000000000)
} else {
// Normalize -0.0 to 0.0
hasher.combine(value == 0 ? 0 : value)
}
}
func deepEqualsMessages(_ lhs: Any?, _ rhs: Any?) -> Bool {
let cleanLhs = nilOrValue(lhs) as Any?
let cleanRhs = nilOrValue(rhs) as Any?
switch (cleanLhs, cleanRhs) {
case (nil, nil):
return true
case (nil, _), (_, nil):
return false
case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs:
return true
case is (Void, Void):
return true
case (let lhsArray, let rhsArray) as ([Any?], [Any?]):
guard lhsArray.count == rhsArray.count else { return false }
for (index, element) in lhsArray.enumerated() {
if !deepEqualsMessages(element, rhsArray[index]) {
return false
}
}
return true
case (let lhsArray, let rhsArray) as ([Double], [Double]):
guard lhsArray.count == rhsArray.count else { return false }
for (index, element) in lhsArray.enumerated() {
if !doubleEqualsMessages(element, rhsArray[index]) {
return false
}
}
return true
case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
guard lhsDictionary.count == rhsDictionary.count else { return false }
for (lhsKey, lhsValue) in lhsDictionary {
var found = false
for (rhsKey, rhsValue) in rhsDictionary {
if deepEqualsMessages(lhsKey, rhsKey) {
if deepEqualsMessages(lhsValue, rhsValue) {
found = true
break
} else {
return false
}
}
}
if !found { return false }
}
return true
case (let lhs as Double, let rhs as Double):
return doubleEqualsMessages(lhs, rhs)
case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable):
return lhsHashable == rhsHashable
default:
return false
}
}
func deepHashMessages(value: Any?, hasher: inout Hasher) {
let cleanValue = nilOrValue(value) as Any?
if let cleanValue = cleanValue {
if let doubleValue = cleanValue as? Double {
doubleHashMessages(doubleValue, &hasher)
} else if let valueList = cleanValue as? [Any?] {
for item in valueList {
deepHashMessages(value: item, hasher: &hasher)
}
} else if let valueList = cleanValue as? [Double] {
for item in valueList {
doubleHashMessages(item, &hasher)
}
} else if let valueDict = cleanValue as? [AnyHashable: Any?] {
var result = 0
for (key, value) in valueDict {
var entryKeyHasher = Hasher()
deepHashMessages(value: key, hasher: &entryKeyHasher)
var entryValueHasher = Hasher()
deepHashMessages(value: value, hasher: &entryValueHasher)
result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize())
}
hasher.combine(result)
} else if let hashableValue = cleanValue as? AnyHashable {
hasher.combine(hashableValue)
} else {
hasher.combine(String(describing: cleanValue))
}
} else {
hasher.combine(0)
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct App: Hashable {
var packageName: String
var appName: String
var installedBy: String
var icon: FlutterStandardTypedData
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> App? {
let packageName = pigeonVar_list[0] as! String
let appName = pigeonVar_list[1] as! String
let installedBy = pigeonVar_list[2] as! String
let icon = pigeonVar_list[3] as! FlutterStandardTypedData
return App(
packageName: packageName,
appName: appName,
installedBy: installedBy,
icon: icon
)
}
func toList() -> [Any?] {
return [
packageName,
appName,
installedBy,
icon,
]
}
static func == (lhs: App, rhs: App) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return deepEqualsMessages(lhs.packageName, rhs.packageName) && deepEqualsMessages(lhs.appName, rhs.appName) && deepEqualsMessages(lhs.installedBy, rhs.installedBy) && deepEqualsMessages(lhs.icon, rhs.icon)
}
func hash(into hasher: inout Hasher) {
hasher.combine("App")
deepHashMessages(value: packageName, hasher: &hasher)
deepHashMessages(value: appName, hasher: &hasher)
deepHashMessages(value: installedBy, hasher: &hasher)
deepHashMessages(value: icon, hasher: &hasher)
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct Toast: Hashable {
var app: App
var message: String
var timestamp: Int64
var duration: Int64
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> Toast? {
let app = pigeonVar_list[0] as! App
let message = pigeonVar_list[1] as! String
let timestamp = pigeonVar_list[2] as! Int64
let duration = pigeonVar_list[3] as! Int64
return Toast(
app: app,
message: message,
timestamp: timestamp,
duration: duration
)
}
func toList() -> [Any?] {
return [
app,
message,
timestamp,
duration,
]
}
static func == (lhs: Toast, rhs: Toast) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return deepEqualsMessages(lhs.app, rhs.app) && deepEqualsMessages(lhs.message, rhs.message) && deepEqualsMessages(lhs.timestamp, rhs.timestamp) && deepEqualsMessages(lhs.duration, rhs.duration)
}
func hash(into hasher: inout Hasher) {
hasher.combine("Toast")
deepHashMessages(value: app, hasher: &hasher)
deepHashMessages(value: message, hasher: &hasher)
deepHashMessages(value: timestamp, hasher: &hasher)
deepHashMessages(value: duration, hasher: &hasher)
}
}
private class MessagesPigeonCodecReader: FlutterStandardReader { private class MessagesPigeonCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 129:
return App.fromList(self.readValue() as! [Any?])
case 130:
return Toast.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
}
} }
private class MessagesPigeonCodecWriter: FlutterStandardWriter { private class MessagesPigeonCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? App {
super.writeByte(129)
super.writeValue(value.toList())
} else if let value = value as? Toast {
super.writeByte(130)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
}
} }
private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter {
@@ -90,6 +312,13 @@ class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
/// Generated protocol from Pigeon that represents a handler of messages from Flutter. /// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol ToasterUtilsApi { protocol ToasterUtilsApi {
func getPlatformName(completion: @escaping (Result<String?, Error>) -> Void) func getPlatformName(completion: @escaping (Result<String?, Error>) -> Void)
func getInstalledApps(completion: @escaping (Result<[App], Error>) -> Void)
func getInstalledApp(packageName: String, completion: @escaping (Result<App?, Error>) -> Void)
func getToasts(packageName: String, completion: @escaping (Result<[Toast], Error>) -> Void)
func getToastFiltered(packageName: String, from: Int64, completion: @escaping (Result<[Toast], Error>) -> Void)
func isServiceRunning(completion: @escaping (Result<Bool, Error>) -> Void)
func showSettings(completion: @escaping (Result<Void, Error>) -> Void)
func exampleToast(completion: @escaping (Result<Void, Error>) -> Void)
} }
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@@ -113,5 +342,117 @@ class ToasterUtilsApiSetup {
} else { } else {
getPlatformNameChannel.setMessageHandler(nil) getPlatformNameChannel.setMessageHandler(nil)
} }
let getInstalledAppsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApps\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getInstalledAppsChannel.setMessageHandler { _, reply in
api.getInstalledApps { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getInstalledAppsChannel.setMessageHandler(nil)
}
let getInstalledAppChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApp\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getInstalledAppChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let packageNameArg = args[0] as! String
api.getInstalledApp(packageName: packageNameArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getInstalledAppChannel.setMessageHandler(nil)
}
let getToastsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToasts\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getToastsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let packageNameArg = args[0] as! String
api.getToasts(packageName: packageNameArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getToastsChannel.setMessageHandler(nil)
}
let getToastFilteredChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToastFiltered\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getToastFilteredChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let packageNameArg = args[0] as! String
let fromArg = args[1] as! Int64
api.getToastFiltered(packageName: packageNameArg, from: fromArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getToastFilteredChannel.setMessageHandler(nil)
}
let isServiceRunningChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.isServiceRunning\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
isServiceRunningChannel.setMessageHandler { _, reply in
api.isServiceRunning { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
isServiceRunningChannel.setMessageHandler(nil)
}
let showSettingsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.showSettings\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
showSettingsChannel.setMessageHandler { _, reply in
api.showSettings { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
showSettingsChannel.setMessageHandler(nil)
}
let exampleToastChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.exampleToast\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
exampleToastChannel.setMessageHandler { _, reply in
api.exampleToast { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
exampleToastChannel.setMessageHandler(nil)
}
} }
} }
@@ -1,4 +1,4 @@
// Copyright (c) 2026, Org mars3142 // Copyright (c) 2026, mars3142
// Autogenerated from Pigeon (v26.3.4), do not edit directly. // Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
// ignore_for_file: unused_import, unused_shown_name // ignore_for_file: unused_import, unused_shown_name
@@ -35,6 +35,178 @@ Object? _extractReplyValueOrThrow(
return replyList.firstOrNull; return replyList.firstOrNull;
} }
bool _deepEquals(Object? a, Object? b) {
if (identical(a, b)) {
return true;
}
if (a is double && b is double) {
if (a.isNaN && b.isNaN) {
return true;
}
return a == b;
}
if (a is List && b is List) {
return a.length == b.length &&
a.indexed
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
}
if (a is Map && b is Map) {
if (a.length != b.length) {
return false;
}
for (final MapEntry<Object?, Object?> entryA in a.entries) {
bool found = false;
for (final MapEntry<Object?, Object?> entryB in b.entries) {
if (_deepEquals(entryA.key, entryB.key)) {
if (_deepEquals(entryA.value, entryB.value)) {
found = true;
break;
} else {
return false;
}
}
}
if (!found) {
return false;
}
}
return true;
}
return a == b;
}
int _deepHash(Object? value) {
if (value is List) {
return Object.hashAll(value.map(_deepHash));
}
if (value is Map) {
int result = 0;
for (final MapEntry<Object?, Object?> entry in value.entries) {
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
}
return result;
}
if (value is double && value.isNaN) {
// Normalize NaN to a consistent hash.
return 0x7FF8000000000000.hashCode;
}
if (value is double && value == 0.0) {
// Normalize -0.0 to 0.0 so they have the same hash code.
return 0.0.hashCode;
}
return value.hashCode;
}
class App {
App({
required this.packageName,
required this.appName,
required this.installedBy,
required this.icon,
});
String packageName;
String appName;
String installedBy;
Uint8List icon;
List<Object?> _toList() {
return <Object?>[
packageName,
appName,
installedBy,
icon,
];
}
Object encode() {
return _toList(); }
static App decode(Object result) {
result as List<Object?>;
return App(
packageName: result[0]! as String,
appName: result[1]! as String,
installedBy: result[2]! as String,
icon: result[3]! as Uint8List,
);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(Object other) {
if (other is! App || other.runtimeType != runtimeType) {
return false;
}
if (identical(this, other)) {
return true;
}
return _deepEquals(packageName, other.packageName) && _deepEquals(appName, other.appName) && _deepEquals(installedBy, other.installedBy) && _deepEquals(icon, other.icon);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}
class Toast {
Toast({
required this.app,
required this.message,
required this.timestamp,
required this.duration,
});
App app;
String message;
int timestamp;
int duration;
List<Object?> _toList() {
return <Object?>[
app,
message,
timestamp,
duration,
];
}
Object encode() {
return _toList(); }
static Toast decode(Object result) {
result as List<Object?>;
return Toast(
app: result[0]! as App,
message: result[1]! as String,
timestamp: result[2]! as int,
duration: result[3]! as int,
);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(Object other) {
if (other is! Toast || other.runtimeType != runtimeType) {
return false;
}
if (identical(this, other)) {
return true;
}
return _deepEquals(app, other.app) && _deepEquals(message, other.message) && _deepEquals(timestamp, other.timestamp) && _deepEquals(duration, other.duration);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}
class _PigeonCodec extends StandardMessageCodec { class _PigeonCodec extends StandardMessageCodec {
@@ -44,6 +216,12 @@ class _PigeonCodec extends StandardMessageCodec {
if (value is int) { if (value is int) {
buffer.putUint8(4); buffer.putUint8(4);
buffer.putInt64(value); buffer.putInt64(value);
} else if (value is App) {
buffer.putUint8(129);
writeValue(buffer, value.encode());
} else if (value is Toast) {
buffer.putUint8(130);
writeValue(buffer, value.encode());
} else { } else {
super.writeValue(buffer, value); super.writeValue(buffer, value);
} }
@@ -52,6 +230,10 @@ class _PigeonCodec extends StandardMessageCodec {
@override @override
Object? readValueOfType(int type, ReadBuffer buffer) { Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) { switch (type) {
case 129:
return App.decode(readValue(buffer)!);
case 130:
return Toast.decode(readValue(buffer)!);
default: default:
return super.readValueOfType(type, buffer); return super.readValueOfType(type, buffer);
} }
@@ -89,4 +271,135 @@ class ToasterUtilsApi {
; ;
return pigeonVar_replyValue as String?; return pigeonVar_replyValue as String?;
} }
Future<List<App>> getInstalledApps() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApps$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<App>();
}
Future<App?> getInstalledApp(String packageName) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApp$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
return pigeonVar_replyValue as App?;
}
Future<List<Toast>> getToasts(String packageName) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToasts$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<Toast>();
}
Future<List<Toast>> getToastFiltered(String packageName, int from) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToastFiltered$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName, from]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<Toast>();
}
Future<bool> isServiceRunning() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.isServiceRunning$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return pigeonVar_replyValue! as bool;
}
Future<void> showSettings() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.showSettings$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
_extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
}
Future<void> exampleToast() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.exampleToast$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
_extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
}
} }
@@ -1 +1 @@
Copyright (c) 2026, Org mars3142 Copyright (c) 2026, mars3142
@@ -16,4 +16,43 @@ import 'package:pigeon/pigeon.dart';
abstract class ToasterUtilsApi { abstract class ToasterUtilsApi {
@async @async
String? getPlatformName(); String? getPlatformName();
@async
List<App> getInstalledApps();
@async
App? getInstalledApp(String packageName);
@async
List<Toast> getToasts(String packageName);
@async
List<Toast> getToastFiltered(String packageName, int from);
@async
bool isServiceRunning();
@async
void showSettings();
@async
void exampleToast();
}
class App {
const App(this.packageName, this.appName, this.installedBy, this.icon);
final String packageName;
final String appName;
final String installedBy;
final Uint8List icon;
}
class Toast {
const Toast(this.app, this.message, this.timestamp, this.duration);
final App app;
final String message;
final int timestamp;
final int duration;
} }
@@ -1,4 +1,4 @@
// Copyright (c) 2026, Org mars3142 // Copyright (c) 2026, mars3142
// Autogenerated from Pigeon (v26.3.4), do not edit directly. // Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
// ignore_for_file: unused_import, unused_shown_name // ignore_for_file: unused_import, unused_shown_name
@@ -35,6 +35,178 @@ Object? _extractReplyValueOrThrow(
return replyList.firstOrNull; return replyList.firstOrNull;
} }
bool _deepEquals(Object? a, Object? b) {
if (identical(a, b)) {
return true;
}
if (a is double && b is double) {
if (a.isNaN && b.isNaN) {
return true;
}
return a == b;
}
if (a is List && b is List) {
return a.length == b.length &&
a.indexed
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
}
if (a is Map && b is Map) {
if (a.length != b.length) {
return false;
}
for (final MapEntry<Object?, Object?> entryA in a.entries) {
bool found = false;
for (final MapEntry<Object?, Object?> entryB in b.entries) {
if (_deepEquals(entryA.key, entryB.key)) {
if (_deepEquals(entryA.value, entryB.value)) {
found = true;
break;
} else {
return false;
}
}
}
if (!found) {
return false;
}
}
return true;
}
return a == b;
}
int _deepHash(Object? value) {
if (value is List) {
return Object.hashAll(value.map(_deepHash));
}
if (value is Map) {
int result = 0;
for (final MapEntry<Object?, Object?> entry in value.entries) {
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
}
return result;
}
if (value is double && value.isNaN) {
// Normalize NaN to a consistent hash.
return 0x7FF8000000000000.hashCode;
}
if (value is double && value == 0.0) {
// Normalize -0.0 to 0.0 so they have the same hash code.
return 0.0.hashCode;
}
return value.hashCode;
}
class App {
App({
required this.packageName,
required this.appName,
required this.installedBy,
required this.icon,
});
String packageName;
String appName;
String installedBy;
Uint8List icon;
List<Object?> _toList() {
return <Object?>[
packageName,
appName,
installedBy,
icon,
];
}
Object encode() {
return _toList(); }
static App decode(Object result) {
result as List<Object?>;
return App(
packageName: result[0]! as String,
appName: result[1]! as String,
installedBy: result[2]! as String,
icon: result[3]! as Uint8List,
);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(Object other) {
if (other is! App || other.runtimeType != runtimeType) {
return false;
}
if (identical(this, other)) {
return true;
}
return _deepEquals(packageName, other.packageName) && _deepEquals(appName, other.appName) && _deepEquals(installedBy, other.installedBy) && _deepEquals(icon, other.icon);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}
class Toast {
Toast({
required this.app,
required this.message,
required this.timestamp,
required this.duration,
});
App app;
String message;
int timestamp;
int duration;
List<Object?> _toList() {
return <Object?>[
app,
message,
timestamp,
duration,
];
}
Object encode() {
return _toList(); }
static Toast decode(Object result) {
result as List<Object?>;
return Toast(
app: result[0]! as App,
message: result[1]! as String,
timestamp: result[2]! as int,
duration: result[3]! as int,
);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(Object other) {
if (other is! Toast || other.runtimeType != runtimeType) {
return false;
}
if (identical(this, other)) {
return true;
}
return _deepEquals(app, other.app) && _deepEquals(message, other.message) && _deepEquals(timestamp, other.timestamp) && _deepEquals(duration, other.duration);
}
@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}
class _PigeonCodec extends StandardMessageCodec { class _PigeonCodec extends StandardMessageCodec {
@@ -44,6 +216,12 @@ class _PigeonCodec extends StandardMessageCodec {
if (value is int) { if (value is int) {
buffer.putUint8(4); buffer.putUint8(4);
buffer.putInt64(value); buffer.putInt64(value);
} else if (value is App) {
buffer.putUint8(129);
writeValue(buffer, value.encode());
} else if (value is Toast) {
buffer.putUint8(130);
writeValue(buffer, value.encode());
} else { } else {
super.writeValue(buffer, value); super.writeValue(buffer, value);
} }
@@ -52,6 +230,10 @@ class _PigeonCodec extends StandardMessageCodec {
@override @override
Object? readValueOfType(int type, ReadBuffer buffer) { Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) { switch (type) {
case 129:
return App.decode(readValue(buffer)!);
case 130:
return Toast.decode(readValue(buffer)!);
default: default:
return super.readValueOfType(type, buffer); return super.readValueOfType(type, buffer);
} }
@@ -89,4 +271,135 @@ class ToasterUtilsApi {
; ;
return pigeonVar_replyValue as String?; return pigeonVar_replyValue as String?;
} }
Future<List<App>> getInstalledApps() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApps$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<App>();
}
Future<App?> getInstalledApp(String packageName) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApp$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
return pigeonVar_replyValue as App?;
}
Future<List<Toast>> getToasts(String packageName) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToasts$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<Toast>();
}
Future<List<Toast>> getToastFiltered(String packageName, int from) async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToastFiltered$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[packageName, from]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return (pigeonVar_replyValue! as List<Object?>).cast<Toast>();
}
Future<bool> isServiceRunning() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.isServiceRunning$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: false,
)
;
return pigeonVar_replyValue! as bool;
}
Future<void> showSettings() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.showSettings$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
_extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
}
Future<void> exampleToast() async {
final pigeonVar_channelName = 'dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.exampleToast$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
_extractReplyValueOrThrow(
pigeonVar_replyList,
pigeonVar_channelName,
isNullValid: true,
)
;
}
} }
@@ -1,4 +1,4 @@
// Copyright (c) 2026, Org mars3142 // Copyright (c) 2026, mars3142
// Autogenerated from Pigeon (v26.3.4), do not edit directly. // Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
@@ -65,11 +65,233 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
return value as! T? return value as! T?
} }
private func doubleEqualsMessages(_ lhs: Double, _ rhs: Double) -> Bool {
return (lhs.isNaN && rhs.isNaN) || lhs == rhs
}
private func doubleHashMessages(_ value: Double, _ hasher: inout Hasher) {
if value.isNaN {
hasher.combine(0x7FF8000000000000)
} else {
// Normalize -0.0 to 0.0
hasher.combine(value == 0 ? 0 : value)
}
}
func deepEqualsMessages(_ lhs: Any?, _ rhs: Any?) -> Bool {
let cleanLhs = nilOrValue(lhs) as Any?
let cleanRhs = nilOrValue(rhs) as Any?
switch (cleanLhs, cleanRhs) {
case (nil, nil):
return true
case (nil, _), (_, nil):
return false
case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs:
return true
case is (Void, Void):
return true
case (let lhsArray, let rhsArray) as ([Any?], [Any?]):
guard lhsArray.count == rhsArray.count else { return false }
for (index, element) in lhsArray.enumerated() {
if !deepEqualsMessages(element, rhsArray[index]) {
return false
}
}
return true
case (let lhsArray, let rhsArray) as ([Double], [Double]):
guard lhsArray.count == rhsArray.count else { return false }
for (index, element) in lhsArray.enumerated() {
if !doubleEqualsMessages(element, rhsArray[index]) {
return false
}
}
return true
case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
guard lhsDictionary.count == rhsDictionary.count else { return false }
for (lhsKey, lhsValue) in lhsDictionary {
var found = false
for (rhsKey, rhsValue) in rhsDictionary {
if deepEqualsMessages(lhsKey, rhsKey) {
if deepEqualsMessages(lhsValue, rhsValue) {
found = true
break
} else {
return false
}
}
}
if !found { return false }
}
return true
case (let lhs as Double, let rhs as Double):
return doubleEqualsMessages(lhs, rhs)
case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable):
return lhsHashable == rhsHashable
default:
return false
}
}
func deepHashMessages(value: Any?, hasher: inout Hasher) {
let cleanValue = nilOrValue(value) as Any?
if let cleanValue = cleanValue {
if let doubleValue = cleanValue as? Double {
doubleHashMessages(doubleValue, &hasher)
} else if let valueList = cleanValue as? [Any?] {
for item in valueList {
deepHashMessages(value: item, hasher: &hasher)
}
} else if let valueList = cleanValue as? [Double] {
for item in valueList {
doubleHashMessages(item, &hasher)
}
} else if let valueDict = cleanValue as? [AnyHashable: Any?] {
var result = 0
for (key, value) in valueDict {
var entryKeyHasher = Hasher()
deepHashMessages(value: key, hasher: &entryKeyHasher)
var entryValueHasher = Hasher()
deepHashMessages(value: value, hasher: &entryValueHasher)
result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize())
}
hasher.combine(result)
} else if let hashableValue = cleanValue as? AnyHashable {
hasher.combine(hashableValue)
} else {
hasher.combine(String(describing: cleanValue))
}
} else {
hasher.combine(0)
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct App: Hashable {
var packageName: String
var appName: String
var installedBy: String
var icon: FlutterStandardTypedData
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> App? {
let packageName = pigeonVar_list[0] as! String
let appName = pigeonVar_list[1] as! String
let installedBy = pigeonVar_list[2] as! String
let icon = pigeonVar_list[3] as! FlutterStandardTypedData
return App(
packageName: packageName,
appName: appName,
installedBy: installedBy,
icon: icon
)
}
func toList() -> [Any?] {
return [
packageName,
appName,
installedBy,
icon,
]
}
static func == (lhs: App, rhs: App) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return deepEqualsMessages(lhs.packageName, rhs.packageName) && deepEqualsMessages(lhs.appName, rhs.appName) && deepEqualsMessages(lhs.installedBy, rhs.installedBy) && deepEqualsMessages(lhs.icon, rhs.icon)
}
func hash(into hasher: inout Hasher) {
hasher.combine("App")
deepHashMessages(value: packageName, hasher: &hasher)
deepHashMessages(value: appName, hasher: &hasher)
deepHashMessages(value: installedBy, hasher: &hasher)
deepHashMessages(value: icon, hasher: &hasher)
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct Toast: Hashable {
var app: App
var message: String
var timestamp: Int64
var duration: Int64
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> Toast? {
let app = pigeonVar_list[0] as! App
let message = pigeonVar_list[1] as! String
let timestamp = pigeonVar_list[2] as! Int64
let duration = pigeonVar_list[3] as! Int64
return Toast(
app: app,
message: message,
timestamp: timestamp,
duration: duration
)
}
func toList() -> [Any?] {
return [
app,
message,
timestamp,
duration,
]
}
static func == (lhs: Toast, rhs: Toast) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return deepEqualsMessages(lhs.app, rhs.app) && deepEqualsMessages(lhs.message, rhs.message) && deepEqualsMessages(lhs.timestamp, rhs.timestamp) && deepEqualsMessages(lhs.duration, rhs.duration)
}
func hash(into hasher: inout Hasher) {
hasher.combine("Toast")
deepHashMessages(value: app, hasher: &hasher)
deepHashMessages(value: message, hasher: &hasher)
deepHashMessages(value: timestamp, hasher: &hasher)
deepHashMessages(value: duration, hasher: &hasher)
}
}
private class MessagesPigeonCodecReader: FlutterStandardReader { private class MessagesPigeonCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 129:
return App.fromList(self.readValue() as! [Any?])
case 130:
return Toast.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
}
} }
private class MessagesPigeonCodecWriter: FlutterStandardWriter { private class MessagesPigeonCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? App {
super.writeByte(129)
super.writeValue(value.toList())
} else if let value = value as? Toast {
super.writeByte(130)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
}
} }
private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter {
@@ -90,6 +312,13 @@ class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
/// Generated protocol from Pigeon that represents a handler of messages from Flutter. /// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol ToasterUtilsApi { protocol ToasterUtilsApi {
func getPlatformName(completion: @escaping (Result<String?, Error>) -> Void) func getPlatformName(completion: @escaping (Result<String?, Error>) -> Void)
func getInstalledApps(completion: @escaping (Result<[App], Error>) -> Void)
func getInstalledApp(packageName: String, completion: @escaping (Result<App?, Error>) -> Void)
func getToasts(packageName: String, completion: @escaping (Result<[Toast], Error>) -> Void)
func getToastFiltered(packageName: String, from: Int64, completion: @escaping (Result<[Toast], Error>) -> Void)
func isServiceRunning(completion: @escaping (Result<Bool, Error>) -> Void)
func showSettings(completion: @escaping (Result<Void, Error>) -> Void)
func exampleToast(completion: @escaping (Result<Void, Error>) -> Void)
} }
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@@ -113,5 +342,117 @@ class ToasterUtilsApiSetup {
} else { } else {
getPlatformNameChannel.setMessageHandler(nil) getPlatformNameChannel.setMessageHandler(nil)
} }
let getInstalledAppsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApps\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getInstalledAppsChannel.setMessageHandler { _, reply in
api.getInstalledApps { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getInstalledAppsChannel.setMessageHandler(nil)
}
let getInstalledAppChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getInstalledApp\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getInstalledAppChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let packageNameArg = args[0] as! String
api.getInstalledApp(packageName: packageNameArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getInstalledAppChannel.setMessageHandler(nil)
}
let getToastsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToasts\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getToastsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let packageNameArg = args[0] as! String
api.getToasts(packageName: packageNameArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getToastsChannel.setMessageHandler(nil)
}
let getToastFilteredChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.getToastFiltered\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getToastFilteredChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let packageNameArg = args[0] as! String
let fromArg = args[1] as! Int64
api.getToastFiltered(packageName: packageNameArg, from: fromArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getToastFilteredChannel.setMessageHandler(nil)
}
let isServiceRunningChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.isServiceRunning\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
isServiceRunningChannel.setMessageHandler { _, reply in
api.isServiceRunning { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
isServiceRunningChannel.setMessageHandler(nil)
}
let showSettingsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.showSettings\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
showSettingsChannel.setMessageHandler { _, reply in
api.showSettings { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
showSettingsChannel.setMessageHandler(nil)
}
let exampleToastChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.toaster_utils.ToasterUtilsApi.exampleToast\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
exampleToastChannel.setMessageHandler { _, reply in
api.exampleToast { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
exampleToastChannel.setMessageHandler(nil)
}
} }
} }
@@ -1 +1 @@
Copyright (c) 2026, Org mars3142 Copyright (c) 2026, mars3142
@@ -16,4 +16,43 @@ import 'package:pigeon/pigeon.dart';
abstract class ToasterUtilsApi { abstract class ToasterUtilsApi {
@async @async
String? getPlatformName(); String? getPlatformName();
@async
List<App> getInstalledApps();
@async
App? getInstalledApp(String packageName);
@async
List<Toast> getToasts(String packageName);
@async
List<Toast> getToastFiltered(String packageName, int from);
@async
bool isServiceRunning();
@async
void showSettings();
@async
void exampleToast();
}
class App {
const App(this.packageName, this.appName, this.installedBy, this.icon);
final String packageName;
final String appName;
final String installedBy;
final Uint8List icon;
}
class Toast {
const Toast(this.app, this.message, this.timestamp, this.duration);
final App app;
final String message;
final int timestamp;
final int duration;
} }