aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/shell/Pickers.kt
blob: f54ef874527b7f00ebb310cea8387a32712befe0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package org.meshbay.client.shell

import android.app.Activity
import android.content.Intent
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicInteger

/**
 * A system picker (folder, save-as, open) started from a bridge worker and
 * waited on there — the bridge never blocks the UI thread, and the page gets
 * its answer as the reply to the call that asked.
 */
class Pickers(private val activity: Activity) {
    private class Waiting { val done = CountDownLatch(1); @Volatile var result: Intent? = null }

    private val waiting = ConcurrentHashMap<Int, Waiting>()
    private val codes = AtomicInteger(4000)

    /** The result intent, or null when the person dismissed the picker. */
    fun run(intent: Intent): Intent? {
        val code = codes.incrementAndGet()
        val w = Waiting()
        waiting[code] = w
        activity.runOnUiThread {
            try { activity.startActivityForResult(intent, code) }
            catch (e: android.content.ActivityNotFoundException) { waiting.remove(code); w.done.countDown() }
        }
        w.done.await()
        return w.result
    }

    /** From Activity.onActivityResult; true when the code was one of ours. */
    fun deliver(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
        val w = waiting.remove(requestCode) ?: return false
        w.result = if (resultCode == Activity.RESULT_OK) data ?: Intent() else null
        w.done.countDown()
        return true
    }
}