2021-06-24 23:10:45 +00:00
|
|
|
package im.cwtch.flwtch
|
|
|
|
|
|
|
|
import android.app.*
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Intent
|
|
|
|
import android.graphics.BitmapFactory
|
|
|
|
import android.graphics.Color
|
|
|
|
import android.os.Build
|
|
|
|
import android.util.Log
|
|
|
|
import androidx.annotation.RequiresApi
|
|
|
|
import androidx.core.app.NotificationCompat
|
|
|
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
|
|
|
import androidx.work.*
|
|
|
|
import cwtch.Cwtch
|
|
|
|
import io.flutter.FlutterInjector
|
|
|
|
import org.json.JSONObject
|
|
|
|
|
2021-09-27 19:53:21 +00:00
|
|
|
import java.nio.file.Files
|
|
|
|
import java.nio.file.Paths
|
|
|
|
import java.nio.file.StandardCopyOption
|
|
|
|
import android.net.Uri
|
2021-06-24 23:10:45 +00:00
|
|
|
|
|
|
|
class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|
|
|
CoroutineWorker(context, parameters) {
|
|
|
|
private val notificationManager =
|
|
|
|
context.getSystemService(Context.NOTIFICATION_SERVICE) as
|
|
|
|
NotificationManager
|
|
|
|
|
|
|
|
private var notificationID: MutableMap<String, Int> = mutableMapOf()
|
|
|
|
private var notificationIDnext: Int = 1
|
|
|
|
|
|
|
|
override suspend fun doWork(): Result {
|
|
|
|
val method = inputData.getString(KEY_METHOD)
|
|
|
|
?: return Result.failure()
|
|
|
|
val args = inputData.getString(KEY_ARGS)
|
|
|
|
?: return Result.failure()
|
|
|
|
// Mark the Worker as important
|
|
|
|
val progress = "Cwtch is keeping Tor running in the background"//todo:translate
|
|
|
|
setForeground(createForegroundInfo(progress))
|
|
|
|
return handleCwtch(method, args)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun getNotificationID(profile: String, contact: String): Int {
|
|
|
|
val k = "$profile $contact"
|
|
|
|
if (!notificationID.containsKey(k)) {
|
|
|
|
notificationID[k] = notificationIDnext++
|
|
|
|
}
|
|
|
|
return notificationID[k] ?: -1
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun handleCwtch(method: String, args: String): Result {
|
|
|
|
val a = JSONObject(args)
|
|
|
|
when (method) {
|
|
|
|
"Start" -> {
|
|
|
|
Log.i("FlwtchWorker.kt", "handleAppInfo Start")
|
|
|
|
val appDir = (a.get("appDir") as? String) ?: ""
|
|
|
|
val torPath = (a.get("torPath") as? String) ?: "tor"
|
|
|
|
Log.i("FlwtchWorker.kt", "appDir: '$appDir' torPath: '$torPath'")
|
|
|
|
|
|
|
|
if (Cwtch.startCwtch(appDir, torPath) != 0.toLong()) return Result.failure()
|
|
|
|
|
|
|
|
Log.i("FlwtchWorker.kt", "startCwtch success, starting coroutine AppbusEvent loop...")
|
2021-09-30 00:16:00 +00:00
|
|
|
val downloadIDs = mutableMapOf<String, Int>()
|
2021-06-24 23:10:45 +00:00
|
|
|
while(true) {
|
|
|
|
val evt = MainActivity.AppbusEvent(Cwtch.getAppBusEvent())
|
|
|
|
if (evt.EventType == "NewMessageFromPeer" || evt.EventType == "NewMessageFromGroup") {
|
|
|
|
val data = JSONObject(evt.Data)
|
2021-06-29 18:49:29 +00:00
|
|
|
val handle = if (evt.EventType == "NewMessageFromPeer") data.getString("RemotePeer") else data.getString("GroupID");
|
2021-06-25 00:59:54 +00:00
|
|
|
if (data["RemotePeer"] != data["ProfileOnion"]) {
|
|
|
|
|
|
|
|
|
2021-06-29 18:49:29 +00:00
|
|
|
|
2022-02-08 17:35:25 +00:00
|
|
|
val notification = data["notification"]
|
2021-06-25 00:59:54 +00:00
|
|
|
|
2022-02-08 16:32:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2022-02-08 17:35:25 +00:00
|
|
|
if (notification == "SimpleEvent") {
|
|
|
|
val channelId =
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
createMessageNotificationChannel("Cwtch", "Cwtch")
|
|
|
|
} else {
|
|
|
|
// If earlier version channel ID is not used
|
|
|
|
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
|
|
|
""
|
|
|
|
}
|
|
|
|
|
|
|
|
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
|
|
|
intent.action = Intent.ACTION_RUN
|
|
|
|
intent.putExtra("EventType", "NotificationClicked")
|
|
|
|
}
|
|
|
|
|
|
|
|
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
|
|
|
.setContentTitle("Cwtch")
|
|
|
|
.setContentText("New message")//todo: translate
|
|
|
|
.setSmallIcon(R.mipmap.knott_transparent)
|
|
|
|
.setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
|
|
|
.setAutoCancel(true)
|
|
|
|
.build()
|
|
|
|
|
|
|
|
notificationManager.notify(getNotificationID("Cwtch", "Cwtch"), newNotification)
|
|
|
|
} else if (notification == "ContactInfo") {
|
|
|
|
val channelId =
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
createMessageNotificationChannel(handle, handle)
|
|
|
|
} else {
|
|
|
|
// If earlier version channel ID is not used
|
|
|
|
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
|
|
|
""
|
|
|
|
}
|
|
|
|
val loader = FlutterInjector.instance().flutterLoader()
|
|
|
|
val key = loader.getLookupKeyForAsset("assets/" + data.getString("Picture"))//"assets/profiles/001-centaur.png")
|
|
|
|
val fh = applicationContext.assets.open(key)
|
|
|
|
|
|
|
|
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
|
|
|
intent.action = Intent.ACTION_RUN
|
|
|
|
intent.putExtra("EventType", "NotificationClicked")
|
|
|
|
intent.putExtra("ProfileOnion", data.getString("ProfileOnion"))
|
|
|
|
intent.putExtra("Handle", handle)
|
|
|
|
}
|
|
|
|
|
|
|
|
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
|
|
|
.setContentTitle(data.getString("Nick"))
|
|
|
|
.setContentText("New message")//todo: translate
|
|
|
|
.setLargeIcon(BitmapFactory.decodeStream(fh))
|
|
|
|
.setSmallIcon(R.mipmap.knott_transparent)
|
|
|
|
.setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
|
|
|
.setAutoCancel(true)
|
|
|
|
.build()
|
|
|
|
|
|
|
|
notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), handle), newNotification)
|
2022-02-08 16:32:05 +00:00
|
|
|
}
|
|
|
|
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2021-09-30 00:16:00 +00:00
|
|
|
} else if (evt.EventType == "FileDownloadProgressUpdate") {
|
|
|
|
try {
|
|
|
|
val data = JSONObject(evt.Data);
|
|
|
|
val fileKey = data.getString("FileKey");
|
|
|
|
val title = data.getString("NameSuggestion");
|
|
|
|
val progress = data.getString("Progress").toInt();
|
|
|
|
val progressMax = data.getString("FileSizeInChunks").toInt();
|
|
|
|
if (!downloadIDs.containsKey(fileKey)) {
|
|
|
|
downloadIDs.put(fileKey, downloadIDs.count());
|
|
|
|
}
|
|
|
|
var dlID = downloadIDs.get(fileKey);
|
|
|
|
if (dlID == null) {
|
|
|
|
dlID = 0;
|
|
|
|
}
|
2021-11-04 22:31:50 +00:00
|
|
|
if (progress >= 0) {
|
|
|
|
val channelId =
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
createDownloadNotificationChannel(fileKey, fileKey)
|
|
|
|
} else {
|
|
|
|
// If earlier version channel ID is not used
|
|
|
|
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
|
|
|
""
|
|
|
|
};
|
|
|
|
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
|
|
|
.setOngoing(true)
|
|
|
|
.setContentTitle("Downloading")//todo: translate
|
|
|
|
.setContentText(title)
|
|
|
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
|
|
|
.setProgress(progressMax, progress, false)
|
|
|
|
.setSound(null)
|
|
|
|
//.setSilent(true)
|
|
|
|
.build();
|
|
|
|
notificationManager.notify(dlID, newNotification);
|
|
|
|
}
|
2021-09-30 00:16:00 +00:00
|
|
|
} catch (e: Exception) {
|
2021-12-10 19:51:19 +00:00
|
|
|
Log.d("FlwtchWorker->FileDownloadProgressUpdate", e.toString() + " :: " + e.getStackTrace());
|
2021-09-30 00:16:00 +00:00
|
|
|
}
|
2021-09-27 19:53:21 +00:00
|
|
|
} else if (evt.EventType == "FileDownloaded") {
|
2021-12-10 19:51:19 +00:00
|
|
|
Log.d("FlwtchWorker", "file downloaded!");
|
2021-09-27 19:53:21 +00:00
|
|
|
val data = JSONObject(evt.Data);
|
|
|
|
val tempFile = data.getString("TempFile");
|
2021-09-30 00:16:00 +00:00
|
|
|
val fileKey = data.getString("FileKey");
|
2021-12-15 01:13:13 +00:00
|
|
|
if (tempFile != "" && tempFile != data.getString("FilePath")) {
|
2021-09-27 19:53:21 +00:00
|
|
|
val filePath = data.getString("FilePath");
|
|
|
|
Log.i("FlwtchWorker", "moving "+tempFile+" to "+filePath);
|
|
|
|
val sourcePath = Paths.get(tempFile);
|
|
|
|
val targetUri = Uri.parse(filePath);
|
|
|
|
val os = this.applicationContext.getContentResolver().openOutputStream(targetUri);
|
|
|
|
val bytesWritten = Files.copy(sourcePath, os);
|
2021-12-10 19:51:19 +00:00
|
|
|
Log.d("FlwtchWorker", "copied " + bytesWritten.toString() + " bytes");
|
2021-09-27 19:53:21 +00:00
|
|
|
if (bytesWritten != 0L) {
|
|
|
|
os?.flush();
|
|
|
|
os?.close();
|
|
|
|
Files.delete(sourcePath);
|
|
|
|
}
|
|
|
|
}
|
2021-09-30 00:16:00 +00:00
|
|
|
if (downloadIDs.containsKey(fileKey)) {
|
|
|
|
notificationManager.cancel(downloadIDs.get(fileKey)?:0);
|
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Intent().also { intent ->
|
|
|
|
intent.action = "im.cwtch.flwtch.broadcast.SERVICE_EVENT_BUS"
|
|
|
|
intent.putExtra("EventType", evt.EventType)
|
|
|
|
intent.putExtra("Data", evt.Data)
|
|
|
|
intent.putExtra("EventID", evt.EventID)
|
|
|
|
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(intent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"ReconnectCwtchForeground" -> {
|
|
|
|
Cwtch.reconnectCwtchForeground()
|
|
|
|
}
|
|
|
|
"CreateProfile" -> {
|
|
|
|
val nick = (a.get("nick") as? String) ?: ""
|
|
|
|
val pass = (a.get("pass") as? String) ?: ""
|
|
|
|
Cwtch.createProfile(nick, pass)
|
|
|
|
}
|
|
|
|
"LoadProfiles" -> {
|
|
|
|
val pass = (a.get("pass") as? String) ?: ""
|
|
|
|
Cwtch.loadProfiles(pass)
|
|
|
|
}
|
2021-12-19 20:44:04 +00:00
|
|
|
"ChangePassword" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val pass = (a.get("OldPass") as? String) ?: ""
|
|
|
|
val passNew = (a.get("NewPass") as? String) ?: ""
|
|
|
|
val passNew2 = (a.get("NewPassAgain") as? String) ?: ""
|
|
|
|
Cwtch.changePassword(profile, pass, passNew, passNew2)
|
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
"GetMessage" -> {
|
2021-12-03 19:28:10 +00:00
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val conversation = a.getInt("conversation").toLong()
|
|
|
|
val indexI = a.getInt("index").toLong()
|
2021-12-10 19:51:19 +00:00
|
|
|
Log.d("FlwtchWorker", "Cwtch GetMessage " + profile + " " + conversation.toString() + " " + indexI.toString())
|
2021-12-03 19:28:10 +00:00
|
|
|
return Result.success(Data.Builder().putString("result", Cwtch.getMessage(profile, conversation, indexI)).build())
|
|
|
|
}
|
|
|
|
"GetMessageByID" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val conversation = a.getInt("conversation").toLong()
|
|
|
|
val id = a.getInt("id").toLong()
|
|
|
|
return Result.success(Data.Builder().putString("result", Cwtch.getMessageByID(profile, conversation, id)).build())
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2021-07-05 19:31:16 +00:00
|
|
|
"GetMessageByContentHash" -> {
|
2021-12-03 19:28:10 +00:00
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-07-05 19:31:16 +00:00
|
|
|
val contentHash = (a.get("contentHash") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
return Result.success(Data.Builder().putString("result", Cwtch.getMessagesByContentHash(profile, conversation, contentHash)).build())
|
2021-07-05 19:31:16 +00:00
|
|
|
}
|
2021-12-03 19:28:10 +00:00
|
|
|
"UpdateMessageAttribute" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val conversation = a.getInt("conversation").toLong()
|
|
|
|
val channel = a.getInt("chanenl").toLong()
|
|
|
|
val midx = a.getInt("midx").toLong()
|
|
|
|
val key = (a.get("key") as? String) ?: ""
|
|
|
|
val value = (a.get("value") as? String) ?: ""
|
|
|
|
Cwtch.setMessageAttribute(profile, conversation, channel, midx, key, value)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2021-12-03 19:28:10 +00:00
|
|
|
"AcceptConversation" -> {
|
2021-06-24 23:10:45 +00:00
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
|
|
|
Cwtch.acceptConversation(profile, conversation)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
|
|
|
"BlockContact" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
|
|
|
Cwtch.blockContact(profile, conversation)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2022-01-06 21:54:25 +00:00
|
|
|
"UnblockContact" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val conversation = a.getInt("conversation").toLong()
|
|
|
|
Cwtch.unblockContact(profile, conversation)
|
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
"SendMessage" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-06-24 23:10:45 +00:00
|
|
|
val message = (a.get("message") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.sendMessage(profile, conversation, message)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
|
|
|
"SendInvitation" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2022-01-07 03:08:18 +00:00
|
|
|
val target = a.getInt("target").toLong()
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.sendInvitation(profile, conversation, target)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2021-09-27 19:53:21 +00:00
|
|
|
"ShareFile" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-09-27 19:53:21 +00:00
|
|
|
val filepath = (a.get("filepath") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.shareFile(profile, conversation, filepath)
|
2021-09-27 19:53:21 +00:00
|
|
|
}
|
|
|
|
"DownloadFile" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-09-27 19:53:21 +00:00
|
|
|
val filepath = (a.get("filepath") as? String) ?: ""
|
|
|
|
val manifestpath = (a.get("manifestpath") as? String) ?: ""
|
|
|
|
val filekey = (a.get("filekey") as? String) ?: ""
|
2021-10-01 14:52:49 +00:00
|
|
|
// FIXME: Prevent spurious calls by Intent
|
|
|
|
if (profile != "") {
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.downloadFile(profile, conversation, filepath, manifestpath, filekey)
|
2021-10-01 14:52:49 +00:00
|
|
|
}
|
2021-09-27 19:53:21 +00:00
|
|
|
}
|
2021-09-29 20:31:01 +00:00
|
|
|
"CheckDownloadStatus" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val fileKey = (a.get("fileKey") as? String) ?: ""
|
|
|
|
Cwtch.checkDownloadStatus(profile, fileKey)
|
|
|
|
}
|
2021-11-04 22:31:50 +00:00
|
|
|
"VerifyOrResumeDownload" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-11-04 22:31:50 +00:00
|
|
|
val fileKey = (a.get("fileKey") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.verifyOrResumeDownload(profile, conversation, fileKey)
|
2021-11-04 22:31:50 +00:00
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
"SendProfileEvent" -> {
|
|
|
|
val onion = (a.get("onion") as? String) ?: ""
|
|
|
|
val jsonEvent = (a.get("jsonEvent") as? String) ?: ""
|
|
|
|
Cwtch.sendProfileEvent(onion, jsonEvent)
|
|
|
|
}
|
|
|
|
"SendAppEvent" -> {
|
|
|
|
val jsonEvent = (a.get("jsonEvent") as? String) ?: ""
|
|
|
|
Cwtch.sendAppEvent(jsonEvent)
|
|
|
|
}
|
|
|
|
"ResetTor" -> {
|
|
|
|
Cwtch.resetTor()
|
|
|
|
}
|
|
|
|
"ImportBundle" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val bundle = (a.get("bundle") as? String) ?: ""
|
|
|
|
Cwtch.importBundle(profile, bundle)
|
|
|
|
}
|
|
|
|
"CreateGroup" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val server = (a.get("server") as? String) ?: ""
|
2021-06-30 00:17:42 +00:00
|
|
|
val groupName = (a.get("groupName") as? String) ?: ""
|
2021-06-24 23:10:45 +00:00
|
|
|
Cwtch.createGroup(profile, server, groupName)
|
|
|
|
}
|
|
|
|
"DeleteProfile" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val pass = (a.get("pass") as? String) ?: ""
|
|
|
|
Cwtch.deleteProfile(profile, pass)
|
|
|
|
}
|
2021-08-27 20:46:13 +00:00
|
|
|
"ArchiveConversation" -> {
|
2021-06-24 23:10:45 +00:00
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2022-01-06 23:46:49 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.archiveConversation(profile, conversation)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2021-12-03 19:28:10 +00:00
|
|
|
"DeleteConversation" -> {
|
2021-06-24 23:10:45 +00:00
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2022-01-06 23:46:49 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.deleteContact(profile, conversation)
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
2021-10-14 01:24:07 +00:00
|
|
|
"SetProfileAttribute" -> {
|
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
|
|
|
val key = (a.get("Key") as? String) ?: ""
|
|
|
|
val v = (a.get("Val") as? String) ?: ""
|
|
|
|
Cwtch.setProfileAttribute(profile, key, v)
|
|
|
|
}
|
2021-12-03 19:28:10 +00:00
|
|
|
"SetConversationAttribute" -> {
|
2021-10-14 01:24:07 +00:00
|
|
|
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
2022-01-06 23:46:49 +00:00
|
|
|
val conversation = a.getInt("conversation").toLong()
|
2021-10-14 01:24:07 +00:00
|
|
|
val key = (a.get("Key") as? String) ?: ""
|
|
|
|
val v = (a.get("Val") as? String) ?: ""
|
2021-12-03 19:28:10 +00:00
|
|
|
Cwtch.setConversationAttribute(profile, conversation, key, v)
|
2021-10-14 01:24:07 +00:00
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
"Shutdown" -> {
|
|
|
|
Cwtch.shutdownCwtch();
|
|
|
|
return Result.success()
|
|
|
|
}
|
2021-10-14 01:24:07 +00:00
|
|
|
"LoadServers" -> {
|
|
|
|
val password = (a.get("Password") as? String) ?: ""
|
|
|
|
Cwtch.loadServers(password)
|
|
|
|
}
|
|
|
|
"CreateServer" -> {
|
|
|
|
val password = (a.get("Password") as? String) ?: ""
|
2021-10-29 23:37:02 +00:00
|
|
|
val desc = (a.get("Description") as? String) ?: ""
|
2021-11-02 04:45:27 +00:00
|
|
|
val autostart = (a.get("Autostart") as? Boolean) ?: false
|
2021-10-29 23:37:02 +00:00
|
|
|
Cwtch.createServer(password, desc, autostart)
|
2021-10-14 01:24:07 +00:00
|
|
|
}
|
|
|
|
"DeleteServer" -> {
|
|
|
|
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
|
|
|
val password = (a.get("Password") as? String) ?: ""
|
|
|
|
Cwtch.deleteServer(serverOnion, password)
|
|
|
|
}
|
|
|
|
"LaunchServers" -> {
|
|
|
|
Cwtch.launchServers()
|
|
|
|
}
|
|
|
|
"LaunchServer" -> {
|
|
|
|
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
|
|
|
Cwtch.launchServer(serverOnion)
|
|
|
|
}
|
2021-11-02 02:29:58 +00:00
|
|
|
"StopServer" -> {
|
2021-10-14 01:24:07 +00:00
|
|
|
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
2021-11-02 04:45:27 +00:00
|
|
|
Cwtch.stopServer(serverOnion)
|
2021-10-14 01:24:07 +00:00
|
|
|
}
|
2021-11-02 02:29:58 +00:00
|
|
|
"StopServers" -> {
|
2021-11-02 04:45:27 +00:00
|
|
|
Cwtch.stopServers()
|
2021-10-14 01:24:07 +00:00
|
|
|
}
|
2021-11-02 02:29:58 +00:00
|
|
|
"DestroyServers" -> {
|
|
|
|
Cwtch.destroyServers()
|
|
|
|
}
|
2021-10-29 23:37:02 +00:00
|
|
|
"SetServerAttribute" -> {
|
|
|
|
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
|
|
|
val key = (a.get("Key") as? String) ?: ""
|
|
|
|
val v = (a.get("Val") as? String) ?: ""
|
|
|
|
Cwtch.setServerAttribute(serverOnion, key, v)
|
|
|
|
}
|
2021-12-03 19:28:10 +00:00
|
|
|
else -> {
|
|
|
|
Log.i("FlwtchWorker", "unknown command: " + method);
|
|
|
|
return Result.failure()
|
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
}
|
|
|
|
return Result.success()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates an instance of ForegroundInfo which can be used to update the
|
|
|
|
// ongoing notification.
|
|
|
|
private fun createForegroundInfo(progress: String): ForegroundInfo {
|
|
|
|
val id = "flwtch"
|
|
|
|
val title = "Flwtch"
|
|
|
|
val cancel = "Shut down"//todo: translate
|
|
|
|
val channelId =
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
createForegroundNotificationChannel(id, id)
|
|
|
|
} else {
|
|
|
|
// If earlier version channel ID is not used
|
|
|
|
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
|
|
|
""
|
|
|
|
}
|
|
|
|
|
2021-06-25 00:59:54 +00:00
|
|
|
val cancelIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
|
|
|
intent.action = Intent.ACTION_RUN
|
|
|
|
intent.putExtra("EventType", "ShutdownClicked")
|
|
|
|
}
|
2021-06-24 23:10:45 +00:00
|
|
|
|
|
|
|
val notification = NotificationCompat.Builder(applicationContext, channelId)
|
|
|
|
.setContentTitle(title)
|
|
|
|
.setTicker(title)
|
|
|
|
.setContentText(progress)
|
2021-07-15 20:03:57 +00:00
|
|
|
.setSmallIcon(R.mipmap.knott_transparent)
|
2021-06-24 23:10:45 +00:00
|
|
|
.setOngoing(true)
|
|
|
|
// Add the cancel action to the notification which can
|
|
|
|
// be used to cancel the worker
|
2021-07-02 23:27:09 +00:00
|
|
|
.addAction(android.R.drawable.ic_delete, cancel, PendingIntent.getActivity(applicationContext, 2, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
2021-06-24 23:10:45 +00:00
|
|
|
.build()
|
|
|
|
|
|
|
|
return ForegroundInfo(101, notification)
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequiresApi(Build.VERSION_CODES.O)
|
|
|
|
private fun createForegroundNotificationChannel(channelId: String, channelName: String): String{
|
|
|
|
val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE)
|
|
|
|
chan.lightColor = Color.MAGENTA
|
|
|
|
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
|
|
|
notificationManager.createNotificationChannel(chan)
|
|
|
|
return channelId
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequiresApi(Build.VERSION_CODES.O)
|
|
|
|
private fun createMessageNotificationChannel(channelId: String, channelName: String): String{
|
|
|
|
val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
|
|
|
|
chan.lightColor = Color.MAGENTA
|
|
|
|
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
|
|
|
notificationManager.createNotificationChannel(chan)
|
|
|
|
return channelId
|
|
|
|
}
|
|
|
|
|
2021-09-30 00:16:00 +00:00
|
|
|
@RequiresApi(Build.VERSION_CODES.O)
|
|
|
|
private fun createDownloadNotificationChannel(channelId: String, channelName: String): String{
|
|
|
|
val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW)
|
|
|
|
chan.lightColor = Color.MAGENTA
|
|
|
|
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
|
|
|
notificationManager.createNotificationChannel(chan)
|
|
|
|
return channelId
|
|
|
|
}
|
|
|
|
|
2021-06-24 23:10:45 +00:00
|
|
|
companion object {
|
|
|
|
const val KEY_METHOD = "KEY_METHOD"
|
|
|
|
const val KEY_ARGS = "KEY_ARGS"
|
|
|
|
}
|
|
|
|
}
|