1+ package de.psdev.devdrawer.profiles
2+
3+ import android.content.pm.PackageManager
4+ import android.os.Bundle
5+ import android.view.LayoutInflater
6+ import android.view.View
7+ import android.view.ViewGroup
8+ import androidx.core.view.isVisible
9+ import androidx.lifecycle.lifecycleScope
10+ import androidx.navigation.fragment.navArgs
11+ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
12+ import com.google.firebase.ktx.Firebase
13+ import com.google.firebase.perf.ktx.performance
14+ import dagger.hilt.android.AndroidEntryPoint
15+ import de.psdev.devdrawer.appwidget.toAppInfo
16+ import de.psdev.devdrawer.appwidget.toPackageHashInfo
17+ import de.psdev.devdrawer.database.DevDrawerDatabase
18+ import de.psdev.devdrawer.database.FilterType
19+ import de.psdev.devdrawer.database.PackageFilter
20+ import de.psdev.devdrawer.databinding.AppSignatureChooserBottomSheetDialogFragmentBinding
21+ import de.psdev.devdrawer.receivers.UpdateReceiver
22+ import de.psdev.devdrawer.utils.awaitSubmit
23+ import de.psdev.devdrawer.utils.trace
24+ import kotlinx.coroutines.Dispatchers
25+ import kotlinx.coroutines.launch
26+ import kotlinx.coroutines.withContext
27+ import mu.KLogging
28+ import javax.inject.Inject
29+
30+ @AndroidEntryPoint
31+ class AppSignatureChooserBottomSheetDialogFragment : BottomSheetDialogFragment () {
32+ companion object : KLogging ()
33+
34+ @Inject
35+ lateinit var devDrawerDatabase: DevDrawerDatabase
36+
37+ private var _binding : AppSignatureChooserBottomSheetDialogFragmentBinding ? = null
38+ private val binding get() = _binding !!
39+
40+ private val navArgs: AppSignatureChooserBottomSheetDialogFragmentArgs by navArgs()
41+
42+ private val onAppClickListener: AppInfoActionListener = { appInfo ->
43+ lifecycleScope.launch {
44+ val packageFilter = PackageFilter (
45+ filter = appInfo.signatureSha256,
46+ type = FilterType .SIGNATURE ,
47+ description = appInfo.name,
48+ profileId = navArgs.widgetProfileId
49+ )
50+ devDrawerDatabase.packageFilterDao().insert(packageFilter)
51+ UpdateReceiver .send(requireContext())
52+ dismiss()
53+ }
54+ }
55+ private val appAdapter = AppListAdapter (onAppClickListener)
56+
57+ override fun onCreateView (
58+ inflater : LayoutInflater ,
59+ container : ViewGroup ? ,
60+ savedInstanceState : Bundle ?
61+ ): View = AppSignatureChooserBottomSheetDialogFragmentBinding .inflate(inflater).also {
62+ _binding = it
63+ }.root
64+
65+ @Suppress(" DEPRECATION" )
66+ override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
67+ super .onViewCreated(view, savedInstanceState)
68+ with (binding) {
69+ btnClose.setOnClickListener { dismiss() }
70+ recyclerApps.adapter = appAdapter
71+ lifecycleScope.launchWhenResumed {
72+ withContext(Dispatchers .IO ) {
73+ val filters = devDrawerDatabase.packageFilterDao().findAllByProfile(navArgs.widgetProfileId)
74+ val context = requireContext()
75+ val packageManager = context.packageManager
76+ val installedPackages = Firebase .performance.trace(" widget_profile_packages" ) {
77+ packageManager.getInstalledPackages(PackageManager .GET_SIGNATURES )
78+ .asSequence()
79+ .map { it.toPackageHashInfo() }
80+ .distinctBy { it.signatureHashSha256 }
81+ .filter { hashInfo -> filters.none { it.type == FilterType .SIGNATURE && it.filter == hashInfo.signatureHashSha256 } }
82+ .mapNotNull { it.toAppInfo(context) }
83+ .sortedBy { it.name }
84+ .toList()
85+ }
86+ logger.warn { " Installed packages: $installedPackages " }
87+ withContext(Dispatchers .Main ) {
88+ appAdapter.awaitSubmit(installedPackages)
89+ progress.hide()
90+ recyclerApps.isVisible = true
91+ }
92+ }
93+ }
94+ }
95+ }
96+
97+ override fun onDestroyView () {
98+ binding.recyclerApps.adapter = null
99+ super .onDestroyView()
100+ }
101+ }
0 commit comments