This commit is contained in:
Thibault Deckers 2022-10-03 19:35:18 +02:00
parent 76162e0d2f
commit 9659580203
4 changed files with 84 additions and 74 deletions

View file

@ -3,6 +3,7 @@ package deckers.thibault.aves
import android.app.Notification import android.app.Notification
import android.app.PendingIntent import android.app.PendingIntent
import android.app.Service import android.app.Service
import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.* import android.os.*
import android.util.Log import android.util.Log
@ -21,7 +22,7 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
class AnalysisService : MethodChannel.MethodCallHandler, Service() { class AnalysisService : Service() {
private var flutterEngine: FlutterEngine? = null private var flutterEngine: FlutterEngine? = null
private var backgroundChannel: MethodChannel? = null private var backgroundChannel: MethodChannel? = null
private var serviceLooper: Looper? = null private var serviceLooper: Looper? = null
@ -30,35 +31,13 @@ class AnalysisService : MethodChannel.MethodCallHandler, Service() {
override fun onCreate() { override fun onCreate() {
Log.i(LOG_TAG, "Create analysis service") Log.i(LOG_TAG, "Create analysis service")
val context = this
runBlocking { runBlocking {
FlutterUtils.initFlutterEngine(context, SHARED_PREFERENCES_KEY, CALLBACK_HANDLE_KEY) { FlutterUtils.initFlutterEngine(this@AnalysisService, SHARED_PREFERENCES_KEY, CALLBACK_HANDLE_KEY) {
flutterEngine = it flutterEngine = it
} }
} }
val messenger = flutterEngine!!.dartExecutor initChannels(this)
// channels for analysis
// dart -> platform -> dart
// - need Context
MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(this))
MethodChannel(messenger, GeocodingHandler.CHANNEL).setMethodCallHandler(GeocodingHandler(this))
MethodChannel(messenger, MediaStoreHandler.CHANNEL).setMethodCallHandler(MediaStoreHandler(this))
MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(this))
MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(this))
// result streaming: dart -> platform ->->-> dart
// - need Context
StreamsChannel(messenger, ImageByteStreamHandler.CHANNEL).setStreamHandlerFactory { args -> ImageByteStreamHandler(this, args) }
StreamsChannel(messenger, MediaStoreStreamHandler.CHANNEL).setStreamHandlerFactory { args -> MediaStoreStreamHandler(this, args) }
// channel for service management
backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL).apply {
setMethodCallHandler(context)
}
HandlerThread("Analysis service handler", Process.THREAD_PRIORITY_BACKGROUND).apply { HandlerThread("Analysis service handler", Process.THREAD_PRIORITY_BACKGROUND).apply {
start() start()
@ -94,7 +73,36 @@ class AnalysisService : MethodChannel.MethodCallHandler, Service() {
return START_NOT_STICKY return START_NOT_STICKY
} }
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { private fun detachAndStop() {
analysisServiceBinder.detach()
stopSelf()
}
private fun initChannels(context: Context) {
val messenger = flutterEngine!!.dartExecutor
// channels for analysis
// dart -> platform -> dart
// - need Context
MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(context))
MethodChannel(messenger, GeocodingHandler.CHANNEL).setMethodCallHandler(GeocodingHandler(context))
MethodChannel(messenger, MediaStoreHandler.CHANNEL).setMethodCallHandler(MediaStoreHandler(context))
MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(context))
MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(context))
// result streaming: dart -> platform ->->-> dart
// - need Context
StreamsChannel(messenger, ImageByteStreamHandler.CHANNEL).setStreamHandlerFactory { args -> ImageByteStreamHandler(context, args) }
StreamsChannel(messenger, MediaStoreStreamHandler.CHANNEL).setStreamHandlerFactory { args -> MediaStoreStreamHandler(context, args) }
// channel for service management
backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL).apply {
setMethodCallHandler { call, result -> onMethodCall(call, result) }
}
}
private fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) { when (call.method) {
"initialized" -> { "initialized" -> {
Log.d(LOG_TAG, "background channel is ready") Log.d(LOG_TAG, "background channel is ready")
@ -119,11 +127,6 @@ class AnalysisService : MethodChannel.MethodCallHandler, Service() {
} }
} }
private fun detachAndStop() {
analysisServiceBinder.detach()
stopSelf()
}
private fun buildNotification(title: String? = null, message: String? = null): Notification { private fun buildNotification(title: String? = null, message: String? = null): Notification {
val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT

View file

@ -3,7 +3,6 @@ package deckers.thibault.aves
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
class HomeWidgetSettingsActivity : MainActivity() { class HomeWidgetSettingsActivity : MainActivity() {
@ -26,7 +25,7 @@ class HomeWidgetSettingsActivity : MainActivity() {
} }
val messenger = flutterEngine!!.dartExecutor val messenger = flutterEngine!!.dartExecutor
MethodChannel(messenger, CHANNEL).setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> MethodChannel(messenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) { when (call.method) {
"configure" -> { "configure" -> {
result.success(null) result.success(null)

View file

@ -15,7 +15,6 @@ import deckers.thibault.aves.utils.ContextUtils.resourceUri
import deckers.thibault.aves.utils.FlutterUtils import deckers.thibault.aves.utils.FlutterUtils
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.util.* import java.util.*
@ -74,8 +73,8 @@ class SearchSuggestionsProvider : ContentProvider() {
} }
val messenger = flutterEngine!!.dartExecutor val messenger = flutterEngine!!.dartExecutor
val backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL) val backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL).apply {
backgroundChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> setMethodCallHandler { call, result ->
when (call.method) { when (call.method) {
"initialized" -> { "initialized" -> {
Log.d(LOG_TAG, "background channel is ready") Log.d(LOG_TAG, "background channel is ready")
@ -84,6 +83,7 @@ class SearchSuggestionsProvider : ContentProvider() {
else -> result.notImplemented() else -> result.notImplemented()
} }
} }
}
try { try {
return suspendCoroutine { cont -> return suspendCoroutine { cont ->

View file

@ -1,5 +1,6 @@
package deckers.thibault.aves package deckers.thibault.aves
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@ -16,50 +17,22 @@ import deckers.thibault.aves.channel.streams.ImageByteStreamHandler
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.getParcelableExtraCompat import deckers.thibault.aves.utils.getParcelableExtraCompat
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
class WallpaperActivity : FlutterActivity() { class WallpaperActivity : FlutterActivity() {
private lateinit var intentDataMap: MutableMap<String, Any?> private lateinit var intentDataMap: MutableMap<String, Any?>
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i(LOG_TAG, "onCreate intent=$intent") Log.i(LOG_TAG, "onCreate intent=$intent")
intent.extras?.takeUnless { it.isEmpty }?.let { intent.extras?.takeUnless { it.isEmpty }?.let {
Log.i(LOG_TAG, "onCreate intent extras=$it") Log.i(LOG_TAG, "onCreate intent extras=$it")
} }
super.onCreate(savedInstanceState)
val messenger = flutterEngine!!.dartExecutor
// dart -> platform -> dart
// - need Context
MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(this))
MethodChannel(messenger, EmbeddedDataHandler.CHANNEL).setMethodCallHandler(EmbeddedDataHandler(this))
MethodChannel(messenger, MediaFetchBytesHandler.CHANNEL, AvesByteSendingMethodCodec.INSTANCE).setMethodCallHandler(MediaFetchBytesHandler(context))
MethodChannel(messenger, MediaFetchObjectHandler.CHANNEL).setMethodCallHandler(MediaFetchObjectHandler(this))
MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(this))
MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(this))
// - need ContextWrapper
MethodChannel(messenger, AccessibilityHandler.CHANNEL).setMethodCallHandler(AccessibilityHandler(this))
MethodChannel(messenger, WallpaperHandler.CHANNEL).setMethodCallHandler(WallpaperHandler(this))
// - need Activity
MethodChannel(messenger, WindowHandler.CHANNEL).setMethodCallHandler(ActivityWindowHandler(this))
// result streaming: dart -> platform ->->-> dart
// - need Context
StreamsChannel(messenger, ImageByteStreamHandler.CHANNEL).setStreamHandlerFactory { args -> ImageByteStreamHandler(this, args) }
// intent handling
// detail fetch: dart -> platform
intentDataMap = extractIntentData(intent) intentDataMap = extractIntentData(intent)
MethodChannel(messenger, MainActivity.INTENT_CHANNEL).setMethodCallHandler { call, result ->
when (call.method) { initChannels(this)
"getIntentData" -> {
result.success(intentDataMap)
intentDataMap.clear()
}
}
}
} }
override fun onStart() { override fun onStart() {
@ -76,6 +49,41 @@ class WallpaperActivity : FlutterActivity() {
} }
} }
private fun initChannels(activity: Activity) {
val messenger = flutterEngine!!.dartExecutor
// dart -> platform -> dart
// - need Context
MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(activity))
MethodChannel(messenger, EmbeddedDataHandler.CHANNEL).setMethodCallHandler(EmbeddedDataHandler(activity))
MethodChannel(messenger, MediaFetchBytesHandler.CHANNEL, AvesByteSendingMethodCodec.INSTANCE).setMethodCallHandler(MediaFetchBytesHandler(activity))
MethodChannel(messenger, MediaFetchObjectHandler.CHANNEL).setMethodCallHandler(MediaFetchObjectHandler(activity))
MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(activity))
MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(activity))
// - need ContextWrapper
MethodChannel(messenger, AccessibilityHandler.CHANNEL).setMethodCallHandler(AccessibilityHandler(activity))
MethodChannel(messenger, WallpaperHandler.CHANNEL).setMethodCallHandler(WallpaperHandler(activity))
// - need Activity
MethodChannel(messenger, WindowHandler.CHANNEL).setMethodCallHandler(ActivityWindowHandler(activity))
// result streaming: dart -> platform ->->-> dart
// - need Context
StreamsChannel(messenger, ImageByteStreamHandler.CHANNEL).setStreamHandlerFactory { args -> ImageByteStreamHandler(activity, args) }
// intent handling
// detail fetch: dart -> platform
MethodChannel(messenger, MainActivity.INTENT_CHANNEL).setMethodCallHandler { call, result -> onMethodCall(call, result) }
}
private fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"getIntentData" -> {
result.success(intentDataMap)
intentDataMap.clear()
}
}
}
private fun extractIntentData(intent: Intent?): MutableMap<String, Any?> { private fun extractIntentData(intent: Intent?): MutableMap<String, Any?> {
when (intent?.action) { when (intent?.action) {
Intent.ACTION_ATTACH_DATA, Intent.ACTION_SET_WALLPAPER -> { Intent.ACTION_ATTACH_DATA, Intent.ACTION_SET_WALLPAPER -> {