AppDetailsFragment: Add data safety section
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -22,6 +22,8 @@ package com.aurora.store.view.custom.layouts
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.view.isVisible
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.databinding.ViewDevInfoBinding
|
||||
|
||||
@@ -29,6 +31,16 @@ class DevInfoLayout : RelativeLayout {
|
||||
|
||||
private lateinit var binding: ViewDevInfoBinding
|
||||
|
||||
val icon: AppCompatImageView get() = binding.img
|
||||
|
||||
var title: String
|
||||
get() = binding.txtTitle.text.toString()
|
||||
set(value) = setTxtTitle(value)
|
||||
|
||||
var subTitle: String?
|
||||
get() = binding.txtSubtitle.text.toString()
|
||||
set(value) = setTxtSubtitle(value)
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
init(context, null)
|
||||
}
|
||||
@@ -64,8 +76,15 @@ class DevInfoLayout : RelativeLayout {
|
||||
typedArray.recycle()
|
||||
}
|
||||
|
||||
fun setTxtTitle(text: String?) {
|
||||
binding.txtTitle.text = text
|
||||
binding.txtTitle.isVisible = text != null
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setTxtSubtitle(text: String?) {
|
||||
binding.txtSubtitle.text = text
|
||||
binding.txtSubtitle.isVisible = text != null
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import com.aurora.gplayapi.data.models.File
|
||||
import com.aurora.gplayapi.data.models.Review
|
||||
import com.aurora.gplayapi.data.models.StreamBundle
|
||||
import com.aurora.gplayapi.data.models.StreamCluster
|
||||
import com.aurora.gplayapi.data.models.datasafety.EntryType
|
||||
import com.aurora.store.AppStreamStash
|
||||
import com.aurora.store.AuroraApp
|
||||
import com.aurora.store.PermissionType
|
||||
@@ -89,6 +90,7 @@ import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AppDetailsFragment : BaseFragment<FragmentDetailsBinding>() {
|
||||
@@ -264,6 +266,11 @@ class AppDetailsFragment : BaseFragment<FragmentDetailsBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
// Data Safety Report
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewModel.dataSafetyReport.collect { updateDataSafetyViews(it) }
|
||||
}
|
||||
|
||||
// Exodus Privacy Report
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewModel.exodusReport.collect { report ->
|
||||
@@ -687,6 +694,7 @@ class AppDetailsFragment : BaseFragment<FragmentDetailsBinding>() {
|
||||
inflateAppDescription(app)
|
||||
inflateAppRatingAndReviews(app)
|
||||
inflateAppDevInfo(app)
|
||||
inflateAppDataSafety(app)
|
||||
inflateAppPrivacy(app)
|
||||
inflateAppPermission(app)
|
||||
|
||||
@@ -814,6 +822,10 @@ class AppDetailsFragment : BaseFragment<FragmentDetailsBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun inflateAppDataSafety(app: App) {
|
||||
viewModel.fetchAppDataSafetyReport(app.packageName)
|
||||
}
|
||||
|
||||
private fun inflateAppPrivacy(app: App) {
|
||||
viewModel.fetchAppReport(app.packageName)
|
||||
}
|
||||
@@ -953,6 +965,32 @@ class AppDetailsFragment : BaseFragment<FragmentDetailsBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDataSafetyViews(report: DataSafetyReport) {
|
||||
report.entries.groupBy { it.type }.forEach { (type, entries) ->
|
||||
when (type) {
|
||||
EntryType.DATA_COLLECTED -> {
|
||||
binding.layoutDetailsDataSafety.dataCollect.title = HtmlCompat.fromHtml(
|
||||
entries.first().description,
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
).toString()
|
||||
binding.layoutDetailsDataSafety.dataCollect.subTitle =
|
||||
entries.first().subEntries.joinToString(", ") { it.name }.ifBlank { null }
|
||||
}
|
||||
|
||||
EntryType.DATA_SHARED -> {
|
||||
binding.layoutDetailsDataSafety.dataShare.title = HtmlCompat.fromHtml(
|
||||
entries.first().description,
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
).toString()
|
||||
binding.layoutDetailsDataSafety.dataShare.subTitle =
|
||||
entries.first().subEntries.joinToString(", ") { it.name }.ifBlank { null }
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* App Review Helpers */
|
||||
|
||||
private fun addAvgReviews(number: Int, max: Long, rating: Long): RelativeLayout {
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.aurora.gplayapi.data.models.Review
|
||||
import com.aurora.gplayapi.data.models.details.TestingProgramStatus
|
||||
import com.aurora.gplayapi.helpers.AppDetailsHelper
|
||||
import com.aurora.gplayapi.helpers.ReviewsHelper
|
||||
import com.aurora.gplayapi.helpers.web.WebDataSafetyHelper
|
||||
import com.aurora.store.data.model.ExodusReport
|
||||
import com.aurora.store.data.model.Report
|
||||
import com.aurora.store.data.network.HttpClient
|
||||
@@ -28,6 +29,7 @@ import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
import java.lang.reflect.Modifier
|
||||
import javax.inject.Inject
|
||||
import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
|
||||
|
||||
@HiltViewModel
|
||||
class AppDetailsViewModel @Inject constructor(
|
||||
@@ -58,6 +60,10 @@ class AppDetailsViewModel @Inject constructor(
|
||||
private val _userReview = MutableSharedFlow<Review>()
|
||||
val userReview = _userReview.asSharedFlow()
|
||||
|
||||
private val dataSafetyReportStash = mutableMapOf<String, DataSafetyReport>()
|
||||
private val _dataSafetyReport = MutableSharedFlow<DataSafetyReport>()
|
||||
val dataSafetyReport = _dataSafetyReport.asSharedFlow()
|
||||
|
||||
private val exodusReportStash = mutableMapOf<String, Report?>()
|
||||
private val _exodusReport = MutableSharedFlow<Report?>()
|
||||
val exodusReport = _exodusReport.asSharedFlow()
|
||||
@@ -103,6 +109,21 @@ class AppDetailsViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchAppDataSafetyReport(packageName: String) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val report = dataSafetyReportStash.getOrPut(packageName) {
|
||||
WebDataSafetyHelper()
|
||||
.using(httpClient)
|
||||
.fetch(packageName)
|
||||
}
|
||||
_dataSafetyReport.emit(report)
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed to fetch data safety report", exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchAppReport(packageName: String) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user