diff options
Diffstat (limited to 'app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt')
-rw-r--r-- | app/src/main/java/moe/yuuta/workmode/ApplicationPickerActivity.kt | 139 |
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 |