From fc0660ca8d5dd98b5a98a32e13896f9553a4311c Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 16 Mar 2020 14:46:36 +0530 Subject: ui: Convert fragment package to Kotlin Signed-off-by: Harsh Shandilya --- .../android/fragment/AppListDialogFragment.kt | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 ui/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.kt (limited to 'ui/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.kt') diff --git a/ui/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.kt new file mode 100644 index 00000000..01dadb08 --- /dev/null +++ b/ui/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.kt @@ -0,0 +1,117 @@ +/* + * Copyright © 2017-2019 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package com.wireguard.android.fragment + +import android.app.Dialog +import android.content.DialogInterface +import android.content.Intent +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.Fragment +import com.wireguard.android.Application +import com.wireguard.android.R +import com.wireguard.android.databinding.AppListDialogFragmentBinding +import com.wireguard.android.model.ApplicationData +import com.wireguard.android.util.ErrorMessages +import com.wireguard.android.util.ObservableKeyedArrayList +import com.wireguard.android.util.ObservableKeyedList +import java9.util.Comparators +import java9.util.function.Function +import java.util.Collections + +class AppListDialogFragment : DialogFragment() { + private val appData: ObservableKeyedList = ObservableKeyedArrayList() + private var currentlyExcludedApps = emptyList() + + private fun loadData() { + val activity = activity ?: return + val pm = activity.packageManager + Application.getAsyncWorker().supplyAsync> { + val launcherIntent = Intent(Intent.ACTION_MAIN, null) + launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER) + val resolveInfos = pm.queryIntentActivities(launcherIntent, 0) + val applicationData: MutableList = ArrayList() + resolveInfos.forEach { + val packageName = it.activityInfo.packageName + applicationData.add(ApplicationData(it.loadIcon(pm), it.loadLabel(pm).toString(), packageName, currentlyExcludedApps.contains(packageName))) + } + + Collections.sort(applicationData, Comparators.comparing(Function { obj: ApplicationData -> obj.name }, java.lang.String.CASE_INSENSITIVE_ORDER)) + applicationData + }.whenComplete { data, throwable -> + if (data != null) { + appData.clear() + appData.addAll(data) + } else { + val error = ErrorMessages.get(throwable) + val message = activity.getString(R.string.error_fetching_apps, error) + Toast.makeText(activity, message, Toast.LENGTH_LONG).show() + dismissAllowingStateLoss() + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val excludedApps = requireArguments().getStringArrayList(KEY_EXCLUDED_APPS) + currentlyExcludedApps = (excludedApps ?: emptyList()) + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val alertDialogBuilder = AlertDialog.Builder(requireActivity()) + alertDialogBuilder.setTitle(R.string.excluded_applications) + val binding = AppListDialogFragmentBinding.inflate(requireActivity().layoutInflater, null, false) + binding.executePendingBindings() + alertDialogBuilder.setView(binding.root) + alertDialogBuilder.setPositiveButton(R.string.set_exclusions) { _, _ -> setExclusionsAndDismiss() } + alertDialogBuilder.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() } + alertDialogBuilder.setNeutralButton(R.string.toggle_all) { _, _ -> } + binding.fragment = this + binding.appData = appData + loadData() + val dialog = alertDialogBuilder.create() + dialog.setOnShowListener { + dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener { + val selectedItems = appData + .filter { obj: ApplicationData -> obj.isExcludedFromTunnel } + + val excludeAll = selectedItems.isEmpty() + appData.forEach { + it.isExcludedFromTunnel = excludeAll + } + } + } + return dialog + } + + private fun setExclusionsAndDismiss() { + val excludedApps: MutableList = ArrayList() + for (data in appData) { + if (data.isExcludedFromTunnel) { + excludedApps.add(data.packageName) + } + } + (targetFragment as AppExclusionListener?)!!.onExcludedAppsSelected(excludedApps) + dismiss() + } + + interface AppExclusionListener { + fun onExcludedAppsSelected(excludedApps: List) + } + + companion object { + private const val KEY_EXCLUDED_APPS = "excludedApps" + fun newInstance(excludedApps: ArrayList?, target: T): AppListDialogFragment where T : Fragment?, T : AppExclusionListener? { + val extras = Bundle() + extras.putStringArrayList(KEY_EXCLUDED_APPS, excludedApps) + val fragment = AppListDialogFragment() + fragment.setTargetFragment(target, 0) + fragment.arguments = extras + return fragment + } + } +} -- cgit v1.2.3-59-g8ed1b