aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt')
-rw-r--r--app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt139
1 files changed, 80 insertions, 59 deletions
diff --git a/app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt b/app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt
index a5e3d0c..736fb0a 100644
--- a/app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt
+++ b/app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt
@@ -3,8 +3,8 @@ package moe.yuuta.workmode
import android.app.Activity
import android.content.Context
import android.content.Intent
-import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
+import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.LruCache
@@ -25,23 +25,32 @@ import moe.yuuta.workmode.async.Async
import moe.yuuta.workmode.async.Callback
import moe.yuuta.workmode.async.Runnable
import moe.yuuta.workmode.async.StoppableGroup
-import moe.yuuta.workmode.utils.Utils
+import moe.yuuta.workmode.suspend.AsyncSuspender
+import moe.yuuta.workmode.suspend.data.TransferableSuspendedApp
+import java.util.*
+import java.util.concurrent.CompletableFuture
import java.util.stream.Collectors
class ApplicationPickerActivity : AppCompatActivity() {
companion object {
- const val EXTRA_SELECTED_PACKAGE_NAME = "moe.yuuta.workmode.ApplicationPickerActivity.EXTRA_SELECTED_PACKAGE_NAME"
+ const val EXTRA_SELECTED_PACKAGES = "moe.yuuta.workmode.ApplicationPickerActivity.EXTRA_SELECTED_PACKAGES"
}
private val logger: Logger = XLog.tag("ApplicationPickerActivity").build()
private lateinit var mAdapter: Adapter
- private val mStoppableGroup: StoppableGroup = StoppableGroup()
+ private lateinit var mLoadAppsFuture: CompletableFuture<List<TransferableSuspendedApp>>
private lateinit var mProgressBar: ProgressBar
private lateinit var fab: FloatingActionButton
- private fun setResultAndFinish(packageNames: Array<String>?) {
- setResult(if (packageNames == null) Activity.RESULT_CANCELED else Activity.RESULT_OK,
- Intent().putExtra(EXTRA_SELECTED_PACKAGE_NAME, packageNames ?: arrayOf()))
+ private fun setResultAndFinish(packages: List<TransferableSuspendedApp>?) {
+ val selected = arrayListOf<TransferableSuspendedApp>()
+ selected.addAll(packages ?: listOf())
+ selected.stream()
+ .forEach {
+ it.trimData()
+ }
+ setResult(if (packages == null) Activity.RESULT_CANCELED else Activity.RESULT_OK,
+ Intent().putExtra(EXTRA_SELECTED_PACKAGES, selected))
finish()
}
@@ -56,7 +65,14 @@ class ApplicationPickerActivity : AppCompatActivity() {
mAdapter = Adapter()
recyclerView.adapter = mAdapter
fab.setOnClickListener {
- setResultAndFinish(mAdapter.checked.toTypedArray())
+ setResultAndFinish(mAdapter.data.stream()
+ .filter {
+ return@filter it.selected
+ }
+ .map {
+ return@map it.packageInfo
+ }
+ .collect(Collectors.toList()))
}
load()
}
@@ -72,43 +88,40 @@ class ApplicationPickerActivity : AppCompatActivity() {
}
private fun load() {
- mStoppableGroup.add(Async.beginTask(object : Runnable<List<SelectedApp>> {
- override fun run(): List<SelectedApp> {
- val selected = intent.getStringArrayExtra(EXTRA_SELECTED_PACKAGE_NAME) ?: arrayOf()
- return packageManager.getInstalledApplications(0)
- .stream()
- .filter(Utils.buildGeneralApplicationInfoFilter(this@ApplicationPickerActivity))
- .sorted(ApplicationInfo.DisplayNameComparator(packageManager))
- .map {
- return@map SelectedApp(it.packageName, selected.contains(it.packageName))
- }
- .collect(Collectors.toList())
- }
- }, object : Callback<List<SelectedApp>> {
- override fun onStart() {
- mProgressBar.visibility = View.VISIBLE
- fab.visibility = View.GONE
- }
-
- override fun onStop(success: Boolean, result: List<SelectedApp>?, e: Throwable?) {
- mProgressBar.visibility = View.GONE
- fab.visibility = View.VISIBLE
- if (success && result != null) {
- display(result)
- } else {
- Toast.makeText(this@ApplicationPickerActivity,
+ if (::mLoadAppsFuture.isInitialized && !mLoadAppsFuture.isDone) {
+ mLoadAppsFuture.cancel(true)
+ }
+ mLoadAppsFuture = AsyncSuspender(this).getInstalledApplicationsAcrossUser(0)
+ mProgressBar.visibility = View.VISIBLE
+ fab.visibility = View.GONE
+ mLoadAppsFuture
+ .handle { result, e ->
+ runOnUiThread {
+ mProgressBar.visibility = View.GONE
+ fab.visibility = View.VISIBLE
+ if (e == null && result != null) {
+ val selected = intent.getParcelableArrayListExtra(EXTRA_SELECTED_PACKAGES) ?: listOf<TransferableSuspendedApp>()
+ logger.d("Selected: $selected")
+ if (BuildConfig.DEBUG) logger.d("Installed: $result")
+ display(result.stream()
+ .map {
+ return@map SelectedApp(it, selected.any { a -> return@any a.essentiallyEqual(it) })
+ }
+ .collect(Collectors.toList()))
+ } else {
+ Toast.makeText(this@ApplicationPickerActivity,
R.string.error_load_applications, Toast.LENGTH_LONG)
.show()
- if (e != null) {
- logger.e("Load applications", e)
- } else {
- logger.e("Cannot load applications (no stacktrace)")
+ if (e != null) {
+ logger.e("Load applications", e)
+ } else {
+ logger.e("Cannot load applications (no stacktrace)")
+ }
+ // Not sure if the toast will dismiss immediately
+ // setResultAndFinish()
}
- // Not sure if the toast will dismiss immediately
- // setResultAndFinish()
}
}
- }))
}
private fun display(result: List<SelectedApp>) {
@@ -125,12 +138,14 @@ class ApplicationPickerActivity : AppCompatActivity() {
mAdapter.data[oldItemPosition] ==
result[newItemPosition]
})
- mAdapter.data = result
+ mAdapter.data = result.toMutableList()
diff.dispatchUpdatesTo(mAdapter)
}
override fun onDestroy() {
- mStoppableGroup.stop()
+ if (::mLoadAppsFuture.isInitialized && !mLoadAppsFuture.isDone) {
+ mLoadAppsFuture.cancel(true)
+ }
mAdapter.destroy()
super.onDestroy()
}
@@ -139,8 +154,7 @@ class ApplicationPickerActivity : AppCompatActivity() {
private val mIconMemoryCaches: LruCache<String, Drawable> =
LruCache(Runtime.getRuntime().maxMemory().toInt() / 5)
private val mStoppableGroup: StoppableGroup = StoppableGroup()
- internal var data: List<SelectedApp> = listOf()
- internal val checked: MutableSet<String> = mutableSetOf()
+ internal var data: MutableList<SelectedApp> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH =
VH(LayoutInflater.from(parent.context).inflate(R.layout.item_application_select, parent, false))
@@ -150,30 +164,37 @@ class ApplicationPickerActivity : AppCompatActivity() {
override fun onBindViewHolder(holder: VH, position: Int) {
val context = holder.itemView.context
val packageInfo = data[position]
- val icon = getIconFromMemoryCache(packageInfo.packageName)
+ val icon = if (packageInfo.packageInfo.icon != null) BitmapDrawable(context.resources,
+ packageInfo.packageInfo.icon)
+ else getIconFromMemoryCache(packageInfo.packageInfo.packageName)
if (icon != null) {
holder.icon.setImageDrawable(icon)
} else {
- loadIcon(packageInfo.packageName, holder.itemView.context, holder.icon)
+ loadIcon(packageInfo.packageInfo.packageName, holder.itemView.context, holder.icon)
}
- holder.title.text = context
- .packageManager
- .getApplicationLabel(
- context.packageManager.getApplicationInfo(packageInfo.packageName, 0)
- )
- if (packageInfo.selected) checked.add(packageInfo.packageName)
- else checked.remove(packageInfo.packageName)
- holder.checkBox.isChecked = checked.contains(packageInfo.packageName)
+ holder.title.text = if (packageInfo.packageInfo.label != null) packageInfo.packageInfo.label
+ else context
+ .packageManager
+ .getApplicationLabel(
+ context.packageManager.getApplicationInfo(packageInfo.packageInfo.packageName, 0)
+ )
+ holder.summary.text = context.getString(R.string.app_list_user_template, packageInfo.packageInfo.userId)
+ holder.checkBox.isChecked = packageInfo.selected
holder.checkBox.setOnClickListener {
- val selected = holder.checkBox.isChecked
- if (selected) checked.add(packageInfo.packageName)
- else checked.remove(packageInfo.packageName)
+ packageInfo.selected = holder.checkBox.isChecked
+ Collections.replaceAll(data,
+ data.stream()
+ .filter { return@filter it.packageInfo == packageInfo.packageInfo }
+ .findFirst()
+ .get(),
+ packageInfo)
}
}
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
internal val icon: ImageView = itemView.findViewById(android.R.id.icon)
internal val title: TextView = itemView.findViewById(android.R.id.title)
+ internal val summary: TextView = itemView.findViewById(android.R.id.summary)
internal val checkBox: CheckBox = itemView.findViewById(android.R.id.checkbox)
}
@@ -217,6 +238,6 @@ class ApplicationPickerActivity : AppCompatActivity() {
}
private data class SelectedApp(
- val packageName: String,
- val selected: Boolean
+ val packageInfo: TransferableSuspendedApp,
+ var selected: Boolean
) \ No newline at end of file