Skip to content

Commit 2303b39

Browse files
committed
feat: Add last update and last backup info for details page
Change-Id: Iad838f587f88e2be08e7a5f152bd1e662b8a0910
1 parent 8eda2d9 commit 2303b39

File tree

19 files changed

+1692
-191
lines changed

19 files changed

+1692
-191
lines changed

source/app/src/main/res/values-zh-rCN/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<string name="confirm">确定</string>
2121
<string name="cancel">取消</string>
2222
<string name="overlook">总览</string>
23-
<string name="last_backup">上次备份</string>
23+
<string name="last_backup">最近备份</string>
2424
<string name="none">无</string>
2525
<string name="utilities">工具</string>
2626
<string name="activities">活动</string>
@@ -394,4 +394,5 @@
394394
<string name="compression_level">压缩等级</string>
395395
<string name="compression_level_desc">数字越小,压缩速度越快,数字越大,压缩率越高</string>
396396
<string name="args_current_level">当前等级:%1$s</string>
397+
<string name="last_update">最近更新</string>
397398
</resources>

source/app/src/main/res/values-zh-rHK/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<string name="confirm">確定</string>
2121
<string name="cancel">取消</string>
2222
<string name="overlook">概覽</string>
23-
<string name="last_backup">上次備份</string>
23+
<string name="last_backup">最近備份</string>
2424
<string name="none">無</string>
2525
<string name="utilities">工具</string>
2626
<string name="activities">活動</string>
@@ -394,4 +394,5 @@
394394
<string name="compression_level">壓縮等級</string>
395395
<string name="compression_level_desc">數字越小,壓縮速度越快,數字越大,壓縮率越高</string>
396396
<string name="args_current_level">目前等級:%1$s</string>
397+
<string name="last_update">最近更新</string>
397398
</resources>

source/app/src/main/res/values-zh-rTW/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<string name="confirm">確定</string>
2121
<string name="cancel">取消</string>
2222
<string name="overlook">概覽</string>
23-
<string name="last_backup">上次備份</string>
23+
<string name="last_backup">最近備份</string>
2424
<string name="none">無</string>
2525
<string name="utilities">工具</string>
2626
<string name="activities">活動</string>
@@ -394,4 +394,5 @@
394394
<string name="compression_level">壓縮等級</string>
395395
<string name="compression_level_desc">數字越小,壓縮速度越快,數字越大,壓縮率越高</string>
396396
<string name="args_current_level">目前等級:%1$s</string>
397+
<string name="last_update">最近更新</string>
397398
</resources>

source/app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,4 +405,5 @@
405405
<string name="compression_level">Compression level</string>
406406
<string name="compression_level_desc">Lower numbers provide faster compression, higher numbers yield better compression ratios</string>
407407
<string name="args_current_level">Current level: %1$s</string>
408+
<string name="last_update">Last update</string>
408409
</resources>

source/core/data/src/main/kotlin/com/xayah/core/data/repository/AppsRepo.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,14 @@ class AppsRepo @Inject constructor(
279279
},
280280
flags = info.applicationInfo?.flags ?: 0,
281281
firstInstallTime = info.firstInstallTime,
282+
lastUpdateTime = info.lastUpdateTime,
282283
),
283284
extraInfo = PackageExtraInfo(
284285
uid = info.applicationInfo?.uid ?: -1,
285286
hasKeystore = false,
286287
permissions = listOf(),
287288
ssaid = "",
289+
lastBackupTime = 0L,
288290
blocked = false,
289291
activated = false,
290292
firstUpdated = false,
@@ -346,7 +348,7 @@ class AppsRepo @Inject constructor(
346348

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

369+
updateEntity.packageInfo.label = info.applicationInfo?.loadLabel(pm).toString()
370+
updateEntity.packageInfo.versionName = info.versionName ?: ""
371+
updateEntity.packageInfo.versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
372+
info.longVersionCode
373+
} else {
374+
info.versionCode.toLong()
375+
}
376+
updateEntity.packageInfo.flags = info.applicationInfo?.flags ?: 0
377+
updateEntity.packageInfo.firstInstallTime = info.firstInstallTime
378+
updateEntity.packageInfo.lastUpdateTime = info.lastUpdateTime
379+
367380
updateEntity.extraInfo.firstUpdated = true
368381
val uid = info.applicationInfo?.uid ?: -1
369382
updateEntity.extraInfo.uid = uid

source/core/data/src/main/kotlin/com/xayah/core/data/repository/FilesRepo.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class FilesRepo @Inject constructor(
141141
displayBytes = 0,
142142
),
143143
extraInfo = MediaExtraInfo(
144+
lastBackupTime = 0,
144145
blocked = false,
145146
activated = true,
146147
existed = true,
@@ -268,6 +269,7 @@ class FilesRepo @Inject constructor(
268269
displayBytes = 0,
269270
),
270271
extraInfo = MediaExtraInfo(
272+
lastBackupTime = 0,
271273
activated = true,
272274
blocked = false,
273275
existed = true

source/core/data/src/main/kotlin/com/xayah/core/data/repository/MediaRepository.kt

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.xayah.core.data.repository
33
import android.content.Context
44
import com.xayah.core.data.R
55
import com.xayah.core.database.dao.MediaDao
6-
import com.xayah.core.datastore.ConstantUtil
76
import com.xayah.core.model.CompressionType
87
import com.xayah.core.model.DataType
98
import com.xayah.core.model.OpType
@@ -96,44 +95,6 @@ class MediaRepository @Inject constructor(
9695
else -> sortByAlphabetNew(sortType)
9796
}
9897

99-
suspend fun refresh() = run {
100-
// Add default medium for first time
101-
if (mediaDao.count() == 0L) {
102-
ConstantUtil.DefaultMediaList.forEach { (name, path) ->
103-
upsert(
104-
MediaEntity(
105-
id = 0,
106-
indexInfo = MediaIndexInfo(
107-
opType = OpType.BACKUP,
108-
name = name,
109-
compressionType = CompressionType.TAR,
110-
preserveId = 0,
111-
cloud = "",
112-
backupDir = ""
113-
),
114-
mediaInfo = MediaInfo(
115-
path = path,
116-
dataBytes = 0,
117-
displayBytes = 0,
118-
),
119-
extraInfo = MediaExtraInfo(
120-
blocked = false,
121-
activated = true,
122-
existed = true,
123-
),
124-
)
125-
)
126-
}
127-
}
128-
129-
val medium = mediaDao.query(opType = OpType.BACKUP, blocked = false)
130-
medium.forEach { m ->
131-
val size = rootService.calculateSize(m.path)
132-
val existed = rootService.exists(m.path)
133-
mediaDao.upsert(m.copy(mediaInfo = m.mediaInfo.copy(displayBytes = size), extraInfo = m.extraInfo.copy(existed = existed, activated = m.extraInfo.activated && existed)))
134-
}
135-
}
136-
13798
private fun renameDuplicateMedia(name: String): String {
13899
val nameList = name.split("_").toMutableList()
139100
val index = nameList.first().toIntOrNull()
@@ -183,6 +144,7 @@ class MediaRepository @Inject constructor(
183144
displayBytes = 0,
184145
),
185146
extraInfo = MediaExtraInfo(
147+
lastBackupTime = 0,
186148
activated = true,
187149
blocked = false,
188150
existed = true

source/core/data/src/main/kotlin/com/xayah/core/data/repository/PackageRepository.kt

Lines changed: 6 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
11
package com.xayah.core.data.repository
22

3-
import android.annotation.SuppressLint
43
import android.content.Context
5-
import android.content.pm.ApplicationInfo
6-
import android.content.pm.PackageManager
74
import android.os.Build
8-
import android.os.UserHandle
95
import com.xayah.core.data.util.srcDir
106
import com.xayah.core.database.dao.PackageDao
11-
import com.xayah.core.datastore.readCheckKeystore
127
import com.xayah.core.datastore.readCompressionType
13-
import com.xayah.core.datastore.readCustomSUFile
14-
import com.xayah.core.datastore.readIconUpdateTime
15-
import com.xayah.core.datastore.readLoadSystemApps
168
import com.xayah.core.datastore.readReloadDumpApk
17-
import com.xayah.core.datastore.saveIconUpdateTime
189
import com.xayah.core.model.CompressionType
1910
import com.xayah.core.model.DataState
2011
import com.xayah.core.model.DataType
21-
import com.xayah.core.model.DefaultPreserveId
2212
import com.xayah.core.model.OpType
2313
import com.xayah.core.model.SortType
2414
import com.xayah.core.model.database.MediaEntity
@@ -38,7 +28,6 @@ import com.xayah.core.util.DateUtil
3828
import com.xayah.core.util.LogUtil
3929
import com.xayah.core.util.PathUtil
4030
import com.xayah.core.util.command.BaseUtil
41-
import com.xayah.core.util.command.PackageUtil
4231
import com.xayah.core.util.command.Tar
4332
import com.xayah.core.util.iconDir
4433
import com.xayah.core.util.localBackupSaveDir
@@ -79,19 +68,10 @@ class PackageRepository @Inject constructor(
7968

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

82-
private suspend fun getPackage(packageName: String, opType: OpType, userId: Int, preserveId: Long, cloud: String, backupDir: String) =
83-
packageDao.query(packageName, opType, userId, preserveId, cloud, backupDir)
84-
85-
private suspend fun getInstalledPackages(userId: Int) = rootService.getInstalledPackagesAsUser(PackageManager.GET_PERMISSIONS, userId).filter {
86-
// Filter itself
87-
it.packageName != context.packageName
88-
}
89-
9071
fun getKeyPredicateNew(key: String): (PackageEntity) -> Boolean = { p ->
9172
p.packageInfo.label.lowercase().contains(key.lowercase()) || p.packageName.lowercase().contains(key.lowercase())
9273
}
9374

94-
9575
fun getShowSystemAppsPredicate(value: Boolean): (PackageEntity) -> Boolean = { p ->
9676
value || p.isSystemApp.not()
9777
}
@@ -162,121 +142,6 @@ class PackageRepository @Inject constructor(
162142
else -> sortByAlphabetNew(sortType)
163143
}
164144

165-
private suspend fun handlePackage(
166-
pm: PackageManager,
167-
info: android.content.pm.PackageInfo,
168-
checkKeystore: Boolean, userId: Int,
169-
userHandle: UserHandle?,
170-
hasPassedOneDay: Boolean
171-
): PackageEntity {
172-
val permissions = rootService.getPermissions(packageInfo = info)
173-
val uid = info.applicationInfo?.uid ?: -1
174-
val hasKeystore = if (checkKeystore) PackageUtil.hasKeystore(context.readCustomSUFile().first(), uid) else false
175-
val ssaid = rootService.getPackageSsaidAsUser(packageName = info.packageName, uid = uid, userId = userId)
176-
val iconPath = pathUtil.getPackageIconPath(info.packageName, false)
177-
val iconExists = rootService.exists(iconPath)
178-
if (iconExists.not() || (iconExists && hasPassedOneDay)) {
179-
runCatching {
180-
val icon = info.applicationInfo!!.loadIcon(pm)
181-
BaseUtil.writeIcon(icon = icon, dst = iconPath)
182-
}.withLog()
183-
}
184-
val packageInfo = PackageInfo(
185-
label = info.applicationInfo?.loadLabel(pm).toString(),
186-
versionName = info.versionName ?: "",
187-
versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
188-
info.longVersionCode
189-
} else {
190-
info.versionCode.toLong()
191-
},
192-
flags = info.applicationInfo?.flags ?: 0,
193-
firstInstallTime = info.firstInstallTime,
194-
)
195-
val extraInfo = PackageExtraInfo(
196-
uid = uid,
197-
hasKeystore = hasKeystore,
198-
permissions = permissions,
199-
ssaid = ssaid,
200-
blocked = false,
201-
activated = false,
202-
firstUpdated = true,
203-
enabled = true,
204-
)
205-
val indexInfo = PackageIndexInfo(
206-
opType = OpType.BACKUP,
207-
packageName = info.packageName,
208-
userId = userId,
209-
compressionType = context.readCompressionType().first(),
210-
preserveId = DefaultPreserveId,
211-
cloud = "",
212-
backupDir = ""
213-
)
214-
val packageEntity =
215-
getPackage(packageName = info.packageName, opType = OpType.BACKUP, userId = userId, preserveId = DefaultPreserveId, cloud = "", backupDir = "")
216-
?: PackageEntity(
217-
id = 0,
218-
indexInfo = indexInfo,
219-
packageInfo = packageInfo,
220-
extraInfo = extraInfo,
221-
dataStates = PackageDataStates(),
222-
storageStats = PackageStorageStats(),
223-
dataStats = PackageDataStats(),
224-
displayStats = PackageDataStats(),
225-
)
226-
// Update if exists.
227-
packageEntity.apply {
228-
this.packageInfo = packageInfo
229-
this.extraInfo.uid = uid
230-
this.extraInfo.hasKeystore = hasKeystore
231-
this.extraInfo.permissions = permissions
232-
this.extraInfo.ssaid = ssaid
233-
}
234-
if (userHandle != null) {
235-
rootService.queryStatsForPackage(info, userHandle).also { stats ->
236-
if (stats != null) {
237-
packageEntity.apply {
238-
this.storageStats.appBytes = stats.appBytes
239-
this.storageStats.cacheBytes = stats.cacheBytes
240-
this.storageStats.dataBytes = stats.dataBytes
241-
this.storageStats.externalCacheBytes = stats.externalCacheBytes
242-
}
243-
}
244-
}
245-
}
246-
return packageEntity
247-
}
248-
249-
@SuppressLint("StringFormatInvalid")
250-
suspend fun refresh() = run {
251-
val checkKeystore = context.readCheckKeystore().first()
252-
val loadSystemApps = context.readLoadSystemApps().first()
253-
val pm = context.packageManager
254-
val userInfoList = rootService.getUsers()
255-
for (userInfo in userInfoList) {
256-
val userId = userInfo.id
257-
val userHandle = rootService.getUserHandle(userId)
258-
val installedPackages = getInstalledPackages(userId)
259-
val installedPackagesCount = (installedPackages.size - 1).coerceAtLeast(1)
260-
261-
// Get 1/10 of total count.
262-
val epoch: Int = ((installedPackagesCount + 1) / 10).coerceAtLeast(1)
263-
264-
// Update packages' info.
265-
BaseUtil.mkdirs(context.iconDir())
266-
val iconUpdateTime = context.readIconUpdateTime().first()
267-
val now = DateUtil.getTimestamp()
268-
val hasPassedOneDay = DateUtil.getNumberOfDaysPassed(iconUpdateTime, now) >= 1
269-
if (hasPassedOneDay) context.saveIconUpdateTime(now)
270-
installedPackages.forEachIndexed { index, info ->
271-
val isSystemApp = ((info.applicationInfo?.flags ?: 0) and ApplicationInfo.FLAG_SYSTEM) != 0
272-
if (loadSystemApps || isSystemApp.not()) {
273-
val packageEntity = handlePackage(pm, info, checkKeystore, userId, userHandle, hasPassedOneDay)
274-
upsert(packageEntity)
275-
}
276-
}
277-
}
278-
}
279-
280145
fun getDataSrcDir(dataType: DataType, userId: Int) = dataType.srcDir(userId)
281146

282147
fun getDataSrc(srcDir: String, packageName: String) = "$srcDir/$packageName"
@@ -736,12 +601,14 @@ class PackageRepository @Inject constructor(
736601
versionCode = 0,
737602
flags = 0,
738603
firstInstallTime = 0,
604+
lastUpdateTime = 0,
739605
),
740606
extraInfo = PackageExtraInfo(
741607
uid = -1,
742608
hasKeystore = false,
743609
permissions = listOf(),
744610
ssaid = "",
611+
lastBackupTime = 0,
745612
blocked = false,
746613
activated = false,
747614
firstUpdated = true,
@@ -936,6 +803,7 @@ class PackageRepository @Inject constructor(
936803
displayBytes = 0L,
937804
),
938805
extraInfo = MediaExtraInfo(
806+
lastBackupTime = 0L,
939807
blocked = false,
940808
activated = false,
941809
existed = true,
@@ -1075,12 +943,14 @@ class PackageRepository @Inject constructor(
1075943
versionCode = 0,
1076944
flags = 0,
1077945
firstInstallTime = 0,
946+
lastUpdateTime = 0,
1078947
),
1079948
extraInfo = PackageExtraInfo(
1080949
uid = -1,
1081950
hasKeystore = false,
1082951
permissions = listOf(),
1083952
ssaid = "",
953+
lastBackupTime = 0,
1084954
blocked = false,
1085955
activated = false,
1086956
firstUpdated = true,
@@ -1291,6 +1161,7 @@ class PackageRepository @Inject constructor(
12911161
displayBytes = 0L,
12921162
),
12931163
extraInfo = MediaExtraInfo(
1164+
lastBackupTime = 0L,
12941165
blocked = false,
12951166
activated = false,
12961167
existed = true,

0 commit comments

Comments
 (0)