nx: support multi-share API

pulsejet/aio-hw-docs
Varun Patil 2023-11-13 22:37:19 -08:00
parent 183de24e62
commit 680322d916
2 changed files with 56 additions and 34 deletions

View File

@ -55,8 +55,7 @@ class NativeX(private val mCtx: MainActivity) {
val IMAGE_FULL = Regex("^/image/full/[0-9a-f]+$") val IMAGE_FULL = Regex("^/image/full/[0-9a-f]+$")
val SHARE_URL = Regex("^/api/share/url/.+$") val SHARE_URL = Regex("^/api/share/url/.+$")
val SHARE_BLOB = Regex("^/api/share/blob/.+$") val SHARE_BLOB = Regex("^/api/share/blobs$")
val SHARE_LOCAL = Regex("^/api/share/local/[0-9a-f]+$")
val CONFIG_ALLOW_MEDIA = Regex("^/api/config/allow_media/\\d+$") val CONFIG_ALLOW_MEDIA = Regex("^/api/config/allow_media/\\d+$")
} }
@ -113,6 +112,12 @@ class NativeX(private val mCtx: MainActivity) {
dlService!!.queue(url, filename) dlService!!.queue(url, filename)
} }
@JavascriptInterface
fun setShareBlobs(objects: String?) {
if (objects == null) return;
dlService!!.setShareBlobs(JSONArray(objects))
}
@JavascriptInterface @JavascriptInterface
fun playVideo(auid: String, fileid: Long, urlsArray: String) { fun playVideo(auid: String, fileid: Long, urlsArray: String) {
mCtx.threadPool.submit { mCtx.threadPool.submit {
@ -250,9 +255,7 @@ class NativeX(private val mCtx: MainActivity) {
} else if (path.matches(API.SHARE_URL)) { } else if (path.matches(API.SHARE_URL)) {
makeResponse(dlService!!.shareUrl(URLDecoder.decode(parts[4], "UTF-8"))) makeResponse(dlService!!.shareUrl(URLDecoder.decode(parts[4], "UTF-8")))
} else if (path.matches(API.SHARE_BLOB)) { } else if (path.matches(API.SHARE_BLOB)) {
makeResponse(dlService!!.shareBlobFromUrl(URLDecoder.decode(parts[4], "UTF-8"))) makeResponse(dlService!!.shareBlobs())
} else if (path.matches(API.SHARE_LOCAL)) {
makeResponse(dlService!!.shareLocal(parts[4]))
} else if (path.matches(API.CONFIG_ALLOW_MEDIA)) { } else if (path.matches(API.CONFIG_ALLOW_MEDIA)) {
permissions.setAllowMedia(true) permissions.setAllowMedia(true)
if (permissions.requestMediaPermissionSync()) { if (permissions.requestMediaPermissionSync()) {

View File

@ -6,14 +6,15 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Environment import android.os.Environment
import android.webkit.CookieManager import android.webkit.CookieManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.collection.ArrayMap import androidx.collection.ArrayMap
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import org.json.JSONArray
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
@UnstableApi class DownloadService(private val mActivity: AppCompatActivity, private val query: TimelineQuery) { @UnstableApi class DownloadService(private val mActivity: AppCompatActivity, private val query: TimelineQuery) {
private val mDownloads: MutableMap<Long, () -> Unit> = ArrayMap() private val mDownloads: MutableMap<Long, () -> Unit> = ArrayMap()
private var mShareBlobs: JSONArray? = null
/** /**
* Callback when download is complete * Callback when download is complete
@ -31,8 +32,6 @@ import java.util.concurrent.CountDownLatch
return return
} }
} }
Toast.makeText(mActivity, "Download Complete", Toast.LENGTH_SHORT).show()
} }
} }
@ -77,48 +76,68 @@ import java.util.concurrent.CountDownLatch
} }
/** /**
* Share a URL as a blob * Share the blobs from URLs already set by setShareBlobs
* @param url The URL to share
* @return True if the URL was shared * @return True if the URL was shared
*/ */
@Throws(Exception::class) @Throws(Exception::class)
fun shareBlobFromUrl(url: String): Boolean { fun shareBlobs(): Boolean {
val id = queue(url, "") if (mShareBlobs == null) throw Exception("No blobs to share")
val latch = CountDownLatch(1)
// All URIs to share including remote and local files
val uris = ArrayList<Uri>()
val dlIds = ArrayList<Long>()
// Process all objects to share
for (i in 0 until mShareBlobs!!.length()) {
val obj = mShareBlobs!!.getJSONObject(i)
// If AUID is found, then look for local file
val auid = obj.getString("auid")
if (auid != "") {
val sysImgs = query.getSystemImagesByAUIDs(listOf(auid))
if (sysImgs.isNotEmpty()) {
uris.add(sysImgs[0].uri)
continue
}
}
// Queue a download for remote files
dlIds.add(queue(obj.getString("href"), ""))
}
// Wait for all downloads to complete
val latch = CountDownLatch(dlIds.size)
synchronized(mDownloads) { synchronized(mDownloads) {
mDownloads.put(id, fun() { latch.countDown() }) for (dlId in dlIds) {
mDownloads.put(dlId, fun() { latch.countDown() })
}
} }
latch.await() latch.await()
// Get the URI of the downloaded file // Get the URI of the downloaded file
for (id in dlIds) {
val sUri = getDownloadedFileURI(id) ?: throw Exception("Failed to download file") val sUri = getDownloadedFileURI(id) ?: throw Exception("Failed to download file")
val uri = Uri.parse(sUri) uris.add(Uri.parse(sUri))
}
// Create sharing intent // Create sharing intent
val intent = Intent(Intent.ACTION_SEND) val intent = Intent(Intent.ACTION_SEND_MULTIPLE)
intent.type = mActivity.contentResolver.getType(uri) intent.type = "*/*"
intent.putExtra(Intent.EXTRA_STREAM, uri) intent.putExtra(Intent.EXTRA_STREAM, uris)
mActivity.startActivity(Intent.createChooser(intent, null)) mActivity.startActivity(Intent.createChooser(intent, null))
// Reset the blobs
mShareBlobs = null
return true return true
} }
/** /**
* Share a local image * Set the blobs to share
* @param auid The AUID of the image to share * @param objects The blobs to share
* @return True if the image was shared
*/ */
@Throws(Exception::class) fun setShareBlobs(objects: JSONArray) {
fun shareLocal(auid: String): Boolean { mShareBlobs = objects
val sysImgs = query.getSystemImagesByAUIDs(listOf(auid))
if (sysImgs.isEmpty()) throw Exception("Image not found locally")
val uri = sysImgs[0].uri
val intent = Intent(Intent.ACTION_SEND)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.type = mActivity.contentResolver.getType(uri)
intent.putExtra(Intent.EXTRA_STREAM, uri)
mActivity.startActivity(Intent.createChooser(intent, null))
return true
} }
/** /**