Skip to content

Commit

Permalink
Add vendor props and fetch them from build.prop
Browse files Browse the repository at this point in the history
  • Loading branch information
AxelBlaz3 committed Nov 8, 2023
1 parent 07d8e94 commit dc9a496
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ package org.pixysos.updater.core.data.model
data class PixysBuildProperty(
val device: String? = null,
val releaseType: String? = null,
val buildEdition: String? = null
val buildEdition: String? = null,
val securityPatchDate: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,9 @@ interface BuildPropertiesRepository {
* Returns the build variant. Can be either "vanilla" or "gapps".
*/
fun getBuildEdition(): String?

/**
* Returns the security patch date.
*/
fun getSecurityPatchDate(): String?
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.pixysos.updater.core.data.repository
import android.os.SystemProperties
import org.pixysos.updater.BuildConfig
import org.pixysos.updater.core.data.model.PixysBuildProperty
import java.text.SimpleDateFormat
import java.util.Locale
import javax.inject.Inject

/**
Expand All @@ -15,15 +17,32 @@ class PixysBuildPropertiesRepository @Inject constructor(
get() = PixysBuildProperty(
device = getDeviceCodename(),
releaseType = getReleaseType(),
buildEdition = getBuildEdition()
buildEdition = getBuildEdition(),
securityPatchDate = getSecurityPatchDate()
)

override fun getDeviceCodename(): String? =
SystemProperties.get(BuildConfig.PROP_DEVICE, "N/A")
override fun getDeviceCodename(): String {
val device = SystemProperties.get(BuildConfig.PROP_VENDOR_DEVICE, "N/A")
val model = SystemProperties.get(BuildConfig.PROP_VENDOR_MODEL, "N/A")

if (device == "N/A" || model == "N/A") {
return "N/A"
}

return "$model ($device)"
}

override fun getReleaseType(): String? =
SystemProperties.get(BuildConfig.PROP_RELEASE_TYPE, "unofficial")

override fun getBuildEdition(): String? =
SystemProperties.get(BuildConfig.PROP_BUILD_EDITION, "N/A")

override fun getSecurityPatchDate(): String? {
val securityPatchDateString =
SystemProperties.get(BuildConfig.PROP_SECURITY_PATCH_LEVEL, "N/A")
val securityPatchDate =
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(securityPatchDateString)
return SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault()).format(securityPatchDate)
}
}
155 changes: 84 additions & 71 deletions app/src/main/java/org/pixysos/updater/feature/updates/UpdatesScreen.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.pixysos.updater.feature.updates

import android.util.Log
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedContent
Expand All @@ -12,9 +11,6 @@ import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
Expand All @@ -28,9 +24,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
Expand All @@ -41,7 +34,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
Expand All @@ -51,6 +43,7 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.pixysos.updater.R
import org.pixysos.updater.core.data.model.PixysBuildProperty
import org.pixysos.updater.core.designsystem.component.UpdaterTopAppBar
import org.pixysos.updater.core.designsystem.theme.GreenLooksGood

Expand All @@ -61,7 +54,7 @@ fun UpdatesScreen(
viewModel: UpdatesViewModel = hiltViewModel()
) {
val updatesUiState: UpdatesUiState by viewModel.uiState.collectAsStateWithLifecycle()
val scrollState = rememberScrollState()
val deviceInfoSummaryList = viewModel.deviceSummaryList
val connection = rememberNestedScrollInteropConnection()

Scaffold(
Expand All @@ -72,14 +65,23 @@ fun UpdatesScreen(
)
},
floatingActionButton = {
ExtendedFloatingActionButton(onClick = { /*TODO*/ }, modifier = Modifier.windowInsetsPadding(
WindowInsets.navigationBars)) {
Image(painter = painterResource(id = R.drawable.ic_sync), contentDescription = stringResource(
R.string.check_for_updates_content_desc
),
ExtendedFloatingActionButton(
onClick = { /*TODO*/ }, modifier = Modifier.windowInsetsPadding(
WindowInsets.navigationBars
)
) {
Image(
painter = painterResource(id = R.drawable.ic_sync),
contentDescription = stringResource(
R.string.check_for_updates_content_desc
),
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface)
)
Text(text = stringResource(R.string.check_updates), style = MaterialTheme.typography.labelLarge, modifier = Modifier.padding(start = 16.dp))
Text(
text = stringResource(R.string.check_updates),
style = MaterialTheme.typography.labelLarge,
modifier = Modifier.padding(start = 16.dp)
)
}
}
) { padding ->
Expand All @@ -93,12 +95,16 @@ fun UpdatesScreen(
is UpdatesUiState.Error -> {

}

is UpdatesUiState.Success -> {
UpdateStatusCard(title = stringResource(id = R.string.looks_good), summary = stringResource(
id = R.string.no_updates_available,
),
updateFound = true)
UpdateStatusCard(
title = stringResource(id = R.string.looks_good), summary = stringResource(
id = R.string.no_updates_available,
),
updateFound = true
)
}

else -> {
UpdateStatusCard(
title = stringResource(id = R.string.looks_good),
Expand All @@ -109,7 +115,14 @@ fun UpdatesScreen(
}

DeviceInformationSection(
modifier = Modifier.padding(top = 24.dp)
modifier = Modifier.padding(top = 24.dp),
deviceInfoList = deviceInfoSummaryList.mapIndexed { i, summary ->
DeviceInformation(
title = deviceInfoTitles[i],
iconRes = deviceInfoIcons[i],
summary = summary
)
}
)
}
}
Expand Down Expand Up @@ -137,27 +150,35 @@ fun UpdateStatusCard(
modifier = modifier,
shape = MaterialTheme.shapes.large,
) {
Row (modifier = Modifier.padding(24.dp),
verticalAlignment = Alignment.CenterVertically) {
Row(
modifier = Modifier.padding(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(id = R.drawable.ic_verified_user),
contentDescription = "Security update good",
colorFilter = ColorFilter.tint(color = GreenLooksGood.copy(alpha = if (updateFound) 1f else alpha)),
modifier = Modifier.size(40.dp)
)
Column (
Column(
modifier = Modifier
.padding(start = 16.dp)
.weight(1f),
verticalArrangement = Arrangement.Center
) {
AnimatedContent(targetState = title, label = "Title change animation") { targetTitle ->
AnimatedContent(
targetState = title,
label = "Title change animation"
) { targetTitle ->
Text(
text = targetTitle,
style = MaterialTheme.typography.headlineSmall
)
}
AnimatedContent(targetState = summary, label = "Summary change animation") { targetSummary ->
AnimatedContent(
targetState = summary,
label = "Summary change animation"
) { targetSummary ->
Text(
text = targetSummary,
style = MaterialTheme.typography.bodyLarge,
Expand All @@ -171,63 +192,48 @@ fun UpdateStatusCard(
}


@Composable
fun NoUpdatesAvailable(
modifier: Modifier = Modifier
) {
Card(
modifier = modifier,
shape = MaterialTheme.shapes.large,
) {
Row (modifier = Modifier.padding(24.dp),
verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(id = R.drawable.ic_security_update_good),
modifier = Modifier
.clip(CircleShape)
.background(MaterialTheme.colorScheme.background)
.padding(12.dp)
.size(32.dp),
contentDescription = "Security update good",
colorFilter = ColorFilter.tint(color = GreenLooksGood)
)
Column (
modifier = Modifier
.padding(start = 16.dp)
.weight(1f),
verticalArrangement = Arrangement.Center
) {
Text(text = stringResource(id = R.string.looks_good), style = MaterialTheme.typography.headlineSmall)
Text(text = stringResource(id = R.string.no_updates_available), style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.paddingFromBaseline(top = 12.dp), color = MaterialTheme.colorScheme.outline)
}
}
}
}
data class DeviceInformation(
@StringRes val title: Int,
@DrawableRes val iconRes: Int,
val summary: String
)

data class StatusInfo(@StringRes val title: Int, @DrawableRes val iconRes: Int, val summary: String)
val informationItems: List<StatusInfo> = listOf(
StatusInfo(title = R.string.security_update, R.drawable.ic_shield, "Update from October 05, 2023"),
StatusInfo(title = R.string.device, R.drawable.ic_smartphone, "Pixel 7"),
StatusInfo(title = R.string.pixys_version, R.drawable.ic_perm_device_information, "7.x.x"),
val deviceInfoTitles = listOf(
R.string.security_update,
R.string.device,
R.string.pixys_version
)

val deviceInfoIcons = listOf(
R.drawable.ic_shield,
R.drawable.ic_smartphone,
R.drawable.ic_perm_device_information
)

@Composable
fun DeviceInformationSection(
modifier: Modifier = Modifier,
deviceInfoList: List<DeviceInformation>
) {
LazyColumn(
modifier = modifier,
contentPadding = PaddingValues(top = 24.dp, start = 8.dp)
) {
item {
Text(text = stringResource(R.string.device_information), modifier = Modifier.padding(bottom = 16.dp))
Text(
text = stringResource(R.string.device_information),
modifier = Modifier.padding(bottom = 16.dp)
)
}
items(informationItems) { statusInfo ->
items(deviceInfoList) { deviceInfo ->
DeviceInformationElement(
modifier = Modifier.padding(vertical = 8.dp),
titleRes = statusInfo.title,
summary = statusInfo.summary,
iconRes = statusInfo.iconRes
titleRes = deviceInfo.title,
summary = if (deviceInfo.title != R.string.security_update) deviceInfo.summary else stringResource(
id = R.string.update_from,
deviceInfo.summary
),
iconRes = deviceInfo.iconRes
)
}
}
Expand All @@ -241,9 +247,16 @@ fun DeviceInformationElement(
summary: String,
contentDescription: String? = null
) {
Row (verticalAlignment = Alignment.CenterVertically) {
Image(painter = painterResource(id = iconRes), contentDescription = contentDescription, colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary))
Column(modifier = modifier.padding(start = 24.dp), verticalArrangement = Arrangement.Center) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(id = iconRes),
contentDescription = contentDescription,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary)
)
Column(
modifier = modifier.padding(start = 24.dp),
verticalArrangement = Arrangement.Center
) {
Text(stringResource(id = titleRes), style = MaterialTheme.typography.titleLarge)
Text(
summary,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package org.pixysos.updater.feature.updates
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import org.pixysos.updater.core.data.model.PixysBuildProperty
import org.pixysos.updater.core.data.model.UpdatePackage
import org.pixysos.updater.core.data.repository.BuildPropertiesRepository
import org.pixysos.updater.core.data.repository.UpdatesRepository
Expand All @@ -27,6 +30,19 @@ class UpdatesViewModel @Inject constructor(
started = SharingStarted.WhileSubscribed(5_000),
initialValue = UpdatesUiState.Loading
)

private val _buildProperty: MutableStateFlow<PixysBuildProperty> = MutableStateFlow(buildPropertiesRepository.buildProperty)
val buildProperty: StateFlow<PixysBuildProperty>
get() = _buildProperty.asStateFlow()

val deviceSummaryList: List<String>
get() = _buildProperty.value.let { property ->
listOf(
property.securityPatchDate!!,
property.device!!,
property.releaseType!!
)
}
}

sealed interface UpdatesUiState {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
<string name="check_for_updates_content_desc">Check for updates</string>
<string name="check_updates">Check updates</string>
<string name="device_information">Device Information</string>
<string name="update_from">Update from %1$s</string>
</resources>
7 changes: 6 additions & 1 deletion secrets.default.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
BASE_URL="https://api.pixysos.com/ota/v1/"
ANDROID_VERSION_NAME="twelve"

# Device properties
# Device properties.
PROP_DEVICE="ro.pixys.device"
PROP_RELEASE_TYPE="ro.pixys.releasetype"
PROP_BUILD_EDITION="ro.pixys.edition"

# Vendor properties.
PROP_VENDOR_MODEL="ro.product.vendor.model"
PROP_VENDOR_DEVICE="ro.product.vendor.device"
PROP_SECURITY_PATCH_LEVEL="ro.build.version.security_patch"

0 comments on commit dc9a496

Please sign in to comment.