Skip to content

Commit

Permalink
feat: Add last update and last backup info for details page
Browse files Browse the repository at this point in the history
Change-Id: Iad838f587f88e2be08e7a5f152bd1e662b8a0910
  • Loading branch information
XayahSuSuSu committed Jan 11, 2025
1 parent 8eda2d9 commit 2303b39
Show file tree
Hide file tree
Showing 19 changed files with 1,692 additions and 191 deletions.
3 changes: 2 additions & 1 deletion source/app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<string name="confirm">确定</string>
<string name="cancel">取消</string>
<string name="overlook">总览</string>
<string name="last_backup">上次备份</string>
<string name="last_backup">最近备份</string>
<string name="none">无</string>
<string name="utilities">工具</string>
<string name="activities">活动</string>
Expand Down Expand Up @@ -394,4 +394,5 @@
<string name="compression_level">压缩等级</string>
<string name="compression_level_desc">数字越小,压缩速度越快,数字越大,压缩率越高</string>
<string name="args_current_level">当前等级:%1$s</string>
<string name="last_update">最近更新</string>
</resources>
3 changes: 2 additions & 1 deletion source/app/src/main/res/values-zh-rHK/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<string name="confirm">確定</string>
<string name="cancel">取消</string>
<string name="overlook">概覽</string>
<string name="last_backup">上次備份</string>
<string name="last_backup">最近備份</string>
<string name="none">無</string>
<string name="utilities">工具</string>
<string name="activities">活動</string>
Expand Down Expand Up @@ -394,4 +394,5 @@
<string name="compression_level">壓縮等級</string>
<string name="compression_level_desc">數字越小,壓縮速度越快,數字越大,壓縮率越高</string>
<string name="args_current_level">目前等級:%1$s</string>
<string name="last_update">最近更新</string>
</resources>
3 changes: 2 additions & 1 deletion source/app/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<string name="confirm">確定</string>
<string name="cancel">取消</string>
<string name="overlook">概覽</string>
<string name="last_backup">上次備份</string>
<string name="last_backup">最近備份</string>
<string name="none">無</string>
<string name="utilities">工具</string>
<string name="activities">活動</string>
Expand Down Expand Up @@ -394,4 +394,5 @@
<string name="compression_level">壓縮等級</string>
<string name="compression_level_desc">數字越小,壓縮速度越快,數字越大,壓縮率越高</string>
<string name="args_current_level">目前等級:%1$s</string>
<string name="last_update">最近更新</string>
</resources>
1 change: 1 addition & 0 deletions source/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -405,4 +405,5 @@
<string name="compression_level">Compression level</string>
<string name="compression_level_desc">Lower numbers provide faster compression, higher numbers yield better compression ratios</string>
<string name="args_current_level">Current level: %1$s</string>
<string name="last_update">Last update</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,14 @@ class AppsRepo @Inject constructor(
},
flags = info.applicationInfo?.flags ?: 0,
firstInstallTime = info.firstInstallTime,
lastUpdateTime = info.lastUpdateTime,
),
extraInfo = PackageExtraInfo(
uid = info.applicationInfo?.uid ?: -1,
hasKeystore = false,
permissions = listOf(),
ssaid = "",
lastBackupTime = 0L,
blocked = false,
activated = false,
firstUpdated = false,
Expand Down Expand Up @@ -346,7 +348,7 @@ class AppsRepo @Inject constructor(

private suspend fun updateApp(pm: PackageManager, pkg: PackageEntity, userId: Int, userHandle: UserHandle?): PackageUpdateEntity? {
val info = rootService.getPackageInfoAsUser(pkg.packageName, PackageManager.GET_PERMISSIONS, userId)
val updateEntity = PackageUpdateEntity(pkg.id, pkg.extraInfo, pkg.storageStats)
val updateEntity = PackageUpdateEntity(pkg.id, pkg.packageInfo, pkg.extraInfo, pkg.storageStats)
if (info != null) {
runCatching {
val iconPath: String
Expand All @@ -364,6 +366,17 @@ class AppsRepo @Inject constructor(
}
}.withLog()

updateEntity.packageInfo.label = info.applicationInfo?.loadLabel(pm).toString()
updateEntity.packageInfo.versionName = info.versionName ?: ""
updateEntity.packageInfo.versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
info.longVersionCode
} else {
info.versionCode.toLong()
}
updateEntity.packageInfo.flags = info.applicationInfo?.flags ?: 0
updateEntity.packageInfo.firstInstallTime = info.firstInstallTime
updateEntity.packageInfo.lastUpdateTime = info.lastUpdateTime

updateEntity.extraInfo.firstUpdated = true
val uid = info.applicationInfo?.uid ?: -1
updateEntity.extraInfo.uid = uid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class FilesRepo @Inject constructor(
displayBytes = 0,
),
extraInfo = MediaExtraInfo(
lastBackupTime = 0,
blocked = false,
activated = true,
existed = true,
Expand Down Expand Up @@ -268,6 +269,7 @@ class FilesRepo @Inject constructor(
displayBytes = 0,
),
extraInfo = MediaExtraInfo(
lastBackupTime = 0,
activated = true,
blocked = false,
existed = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.xayah.core.data.repository
import android.content.Context
import com.xayah.core.data.R
import com.xayah.core.database.dao.MediaDao
import com.xayah.core.datastore.ConstantUtil
import com.xayah.core.model.CompressionType
import com.xayah.core.model.DataType
import com.xayah.core.model.OpType
Expand Down Expand Up @@ -96,44 +95,6 @@ class MediaRepository @Inject constructor(
else -> sortByAlphabetNew(sortType)
}

suspend fun refresh() = run {
// Add default medium for first time
if (mediaDao.count() == 0L) {
ConstantUtil.DefaultMediaList.forEach { (name, path) ->
upsert(
MediaEntity(
id = 0,
indexInfo = MediaIndexInfo(
opType = OpType.BACKUP,
name = name,
compressionType = CompressionType.TAR,
preserveId = 0,
cloud = "",
backupDir = ""
),
mediaInfo = MediaInfo(
path = path,
dataBytes = 0,
displayBytes = 0,
),
extraInfo = MediaExtraInfo(
blocked = false,
activated = true,
existed = true,
),
)
)
}
}

val medium = mediaDao.query(opType = OpType.BACKUP, blocked = false)
medium.forEach { m ->
val size = rootService.calculateSize(m.path)
val existed = rootService.exists(m.path)
mediaDao.upsert(m.copy(mediaInfo = m.mediaInfo.copy(displayBytes = size), extraInfo = m.extraInfo.copy(existed = existed, activated = m.extraInfo.activated && existed)))
}
}

private fun renameDuplicateMedia(name: String): String {
val nameList = name.split("_").toMutableList()
val index = nameList.first().toIntOrNull()
Expand Down Expand Up @@ -183,6 +144,7 @@ class MediaRepository @Inject constructor(
displayBytes = 0,
),
extraInfo = MediaExtraInfo(
lastBackupTime = 0,
activated = true,
blocked = false,
existed = true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
package com.xayah.core.data.repository

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.UserHandle
import com.xayah.core.data.util.srcDir
import com.xayah.core.database.dao.PackageDao
import com.xayah.core.datastore.readCheckKeystore
import com.xayah.core.datastore.readCompressionType
import com.xayah.core.datastore.readCustomSUFile
import com.xayah.core.datastore.readIconUpdateTime
import com.xayah.core.datastore.readLoadSystemApps
import com.xayah.core.datastore.readReloadDumpApk
import com.xayah.core.datastore.saveIconUpdateTime
import com.xayah.core.model.CompressionType
import com.xayah.core.model.DataState
import com.xayah.core.model.DataType
import com.xayah.core.model.DefaultPreserveId
import com.xayah.core.model.OpType
import com.xayah.core.model.SortType
import com.xayah.core.model.database.MediaEntity
Expand All @@ -38,7 +28,6 @@ import com.xayah.core.util.DateUtil
import com.xayah.core.util.LogUtil
import com.xayah.core.util.PathUtil
import com.xayah.core.util.command.BaseUtil
import com.xayah.core.util.command.PackageUtil
import com.xayah.core.util.command.Tar
import com.xayah.core.util.iconDir
import com.xayah.core.util.localBackupSaveDir
Expand Down Expand Up @@ -79,19 +68,10 @@ class PackageRepository @Inject constructor(

fun getArchiveDst(dstDir: String, dataType: DataType, ct: CompressionType) = "${dstDir}/${dataType.type}.${ct.suffix}"

private suspend fun getPackage(packageName: String, opType: OpType, userId: Int, preserveId: Long, cloud: String, backupDir: String) =
packageDao.query(packageName, opType, userId, preserveId, cloud, backupDir)

private suspend fun getInstalledPackages(userId: Int) = rootService.getInstalledPackagesAsUser(PackageManager.GET_PERMISSIONS, userId).filter {
// Filter itself
it.packageName != context.packageName
}

fun getKeyPredicateNew(key: String): (PackageEntity) -> Boolean = { p ->
p.packageInfo.label.lowercase().contains(key.lowercase()) || p.packageName.lowercase().contains(key.lowercase())
}


fun getShowSystemAppsPredicate(value: Boolean): (PackageEntity) -> Boolean = { p ->
value || p.isSystemApp.not()
}
Expand Down Expand Up @@ -162,121 +142,6 @@ class PackageRepository @Inject constructor(
else -> sortByAlphabetNew(sortType)
}

private suspend fun handlePackage(
pm: PackageManager,
info: android.content.pm.PackageInfo,
checkKeystore: Boolean, userId: Int,
userHandle: UserHandle?,
hasPassedOneDay: Boolean
): PackageEntity {
val permissions = rootService.getPermissions(packageInfo = info)
val uid = info.applicationInfo?.uid ?: -1
val hasKeystore = if (checkKeystore) PackageUtil.hasKeystore(context.readCustomSUFile().first(), uid) else false
val ssaid = rootService.getPackageSsaidAsUser(packageName = info.packageName, uid = uid, userId = userId)
val iconPath = pathUtil.getPackageIconPath(info.packageName, false)
val iconExists = rootService.exists(iconPath)
if (iconExists.not() || (iconExists && hasPassedOneDay)) {
runCatching {
val icon = info.applicationInfo!!.loadIcon(pm)
BaseUtil.writeIcon(icon = icon, dst = iconPath)
}.withLog()
}
val packageInfo = PackageInfo(
label = info.applicationInfo?.loadLabel(pm).toString(),
versionName = info.versionName ?: "",
versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
info.longVersionCode
} else {
info.versionCode.toLong()
},
flags = info.applicationInfo?.flags ?: 0,
firstInstallTime = info.firstInstallTime,
)
val extraInfo = PackageExtraInfo(
uid = uid,
hasKeystore = hasKeystore,
permissions = permissions,
ssaid = ssaid,
blocked = false,
activated = false,
firstUpdated = true,
enabled = true,
)
val indexInfo = PackageIndexInfo(
opType = OpType.BACKUP,
packageName = info.packageName,
userId = userId,
compressionType = context.readCompressionType().first(),
preserveId = DefaultPreserveId,
cloud = "",
backupDir = ""
)
val packageEntity =
getPackage(packageName = info.packageName, opType = OpType.BACKUP, userId = userId, preserveId = DefaultPreserveId, cloud = "", backupDir = "")
?: PackageEntity(
id = 0,
indexInfo = indexInfo,
packageInfo = packageInfo,
extraInfo = extraInfo,
dataStates = PackageDataStates(),
storageStats = PackageStorageStats(),
dataStats = PackageDataStats(),
displayStats = PackageDataStats(),
)
// Update if exists.
packageEntity.apply {
this.packageInfo = packageInfo
this.extraInfo.uid = uid
this.extraInfo.hasKeystore = hasKeystore
this.extraInfo.permissions = permissions
this.extraInfo.ssaid = ssaid
}
if (userHandle != null) {
rootService.queryStatsForPackage(info, userHandle).also { stats ->
if (stats != null) {
packageEntity.apply {
this.storageStats.appBytes = stats.appBytes
this.storageStats.cacheBytes = stats.cacheBytes
this.storageStats.dataBytes = stats.dataBytes
this.storageStats.externalCacheBytes = stats.externalCacheBytes
}
}
}
}
return packageEntity
}

@SuppressLint("StringFormatInvalid")
suspend fun refresh() = run {
val checkKeystore = context.readCheckKeystore().first()
val loadSystemApps = context.readLoadSystemApps().first()
val pm = context.packageManager
val userInfoList = rootService.getUsers()
for (userInfo in userInfoList) {
val userId = userInfo.id
val userHandle = rootService.getUserHandle(userId)
val installedPackages = getInstalledPackages(userId)
val installedPackagesCount = (installedPackages.size - 1).coerceAtLeast(1)

// Get 1/10 of total count.
val epoch: Int = ((installedPackagesCount + 1) / 10).coerceAtLeast(1)

// Update packages' info.
BaseUtil.mkdirs(context.iconDir())
val iconUpdateTime = context.readIconUpdateTime().first()
val now = DateUtil.getTimestamp()
val hasPassedOneDay = DateUtil.getNumberOfDaysPassed(iconUpdateTime, now) >= 1
if (hasPassedOneDay) context.saveIconUpdateTime(now)
installedPackages.forEachIndexed { index, info ->
val isSystemApp = ((info.applicationInfo?.flags ?: 0) and ApplicationInfo.FLAG_SYSTEM) != 0
if (loadSystemApps || isSystemApp.not()) {
val packageEntity = handlePackage(pm, info, checkKeystore, userId, userHandle, hasPassedOneDay)
upsert(packageEntity)
}
}
}
}

fun getDataSrcDir(dataType: DataType, userId: Int) = dataType.srcDir(userId)

fun getDataSrc(srcDir: String, packageName: String) = "$srcDir/$packageName"
Expand Down Expand Up @@ -736,12 +601,14 @@ class PackageRepository @Inject constructor(
versionCode = 0,
flags = 0,
firstInstallTime = 0,
lastUpdateTime = 0,
),
extraInfo = PackageExtraInfo(
uid = -1,
hasKeystore = false,
permissions = listOf(),
ssaid = "",
lastBackupTime = 0,
blocked = false,
activated = false,
firstUpdated = true,
Expand Down Expand Up @@ -936,6 +803,7 @@ class PackageRepository @Inject constructor(
displayBytes = 0L,
),
extraInfo = MediaExtraInfo(
lastBackupTime = 0L,
blocked = false,
activated = false,
existed = true,
Expand Down Expand Up @@ -1075,12 +943,14 @@ class PackageRepository @Inject constructor(
versionCode = 0,
flags = 0,
firstInstallTime = 0,
lastUpdateTime = 0,
),
extraInfo = PackageExtraInfo(
uid = -1,
hasKeystore = false,
permissions = listOf(),
ssaid = "",
lastBackupTime = 0,
blocked = false,
activated = false,
firstUpdated = true,
Expand Down Expand Up @@ -1291,6 +1161,7 @@ class PackageRepository @Inject constructor(
displayBytes = 0L,
),
extraInfo = MediaExtraInfo(
lastBackupTime = 0L,
blocked = false,
activated = false,
existed = true,
Expand Down
Loading

0 comments on commit 2303b39

Please sign in to comment.