From 7bed3c558b1222655f88dabd052894e2769bd613 Mon Sep 17 00:00:00 2001 From: frknkrc44 Date: Sat, 13 Jul 2024 10:44:47 +0300 Subject: [PATCH 1/6] feat: Add pre API 26 support --- source/app/src/main/AndroidManifest.xml | 2 + source/app/src/main/ic_launcher-playstore.png | Bin 14863 -> 20267 bytes .../res/drawable/ic_launcher_foreground.xml | 183 +++++++-------- .../ic_launcher.xml | 5 +- .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1604 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 1054 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 2122 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 3064 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 4210 bytes .../data/repository/DirectoryRepository.kt | 5 +- .../core/data/repository/PackageRepository.kt | 2 +- .../core/network/client/FTPClientImpl.kt | 12 +- .../core/network/client/SFTPClientImpl.kt | 4 +- .../core/network/client/SMBClientImpl.kt | 4 +- .../core/network/client/WebDAVClientImpl.kt | 4 +- .../core/rootservice/IRemoteRootService.aidl | 3 +- .../parcelables/StorageStatsParcelable.aidl | 2 + .../rootservice/impl/RemoteRootServiceImpl.kt | 216 ++++++++++++++---- .../rootservice/parcelables/PathParcelable.kt | 5 +- .../parcelables/StorageStatsParcelable.kt | 47 ++++ .../rootservice/service/RemoteRootService.kt | 9 +- .../kotlin/com/xayah/core/util/DateUtil.kt | 21 +- .../kotlin/com/xayah/core/util/HashUtil.kt | 14 +- .../com/xayah/core/util/NotificationUtil.kt | 36 ++- .../kotlin/com/xayah/core/util/PathUtil.kt | 11 +- .../com/xayah/core/util/command/BaseUtil.kt | 6 +- source/gradle/libs.versions.toml | 6 +- 27 files changed, 407 insertions(+), 190 deletions(-) rename source/app/src/main/res/{mipmap-anydpi => mipmap-anydpi-v26}/ic_launcher.xml (75%) create mode 100644 source/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 source/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 source/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 source/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 source/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.aidl create mode 100644 source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.kt diff --git a/source/app/src/main/AndroidManifest.xml b/source/app/src/main/AndroidManifest.xml index a8223ef450..181c2cfdcc 100644 --- a/source/app/src/main/AndroidManifest.xml +++ b/source/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + j}t`Q}+gi=Lo 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 Xqt^U9Tq8+`F^z-~B0{Qy4{-km_S;?E literal 14863 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 Cq`)fx diff --git a/source/app/src/main/res/drawable/ic_launcher_foreground.xml b/source/app/src/main/res/drawable/ic_launcher_foreground.xml index 682eea297a..daafe49e47 100644 --- a/source/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/source/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,93 +1,98 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 75% rename from source/app/src/main/res/mipmap-anydpi/ic_launcher.xml rename to source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 0648fb47f9..7353dbd1fd 100644 --- a/source/app/src/main/res/mipmap-anydpi/ic_launcher.xml +++ b/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,5 @@ - - - + + \ No newline at end of file diff --git a/source/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..7984add040fcffb960514645cbdc5d9ff39267df GIT binary patch literal 1604 zcmV-K2D|xENk&FI1^@t8MM6+kP&iC51^@srN5Byf6^DYhZKRq%?0t6(B4PqEnkpKf zbA|+NZClHfSJBJ>5t;X;Jy3$X>u3m>yTkW)fq!q-_t5NhghNCT6yQ$AA{<&E`!ZZo zLiZA^jtM6sV%tcPqRv06PvHH9V|eh`cic#lA}8~=e9)A$POEKOmfzhCtt8*TB8Nz( zvjUamlH4WzKQq_>x{f^z+qR8F^}PwME6CNh|NNVyEmzwZ+cmar+qU&*48r`cAvYqpnpx7R3a zBq@!S!5i|pL;o4MjiksqEi=4<$KG`V*}cG!G~tGBpqMCcTJ}TODjRCk5c|SbSNQ5F z?eKo_86RHm($_J}vrwVCRH#o2_grhQgNzAgVP15X%!ef1=zRmActU1|TiuGjT_#DW zpB5W9b5wao3V>{MTU5H#PrC_MuF;2_r_N`*Oysu1ge%p`BL~1##+gvrKe3fu`w*3J zrgW^eHkgXoGdk9i+i``Kz=(hm0Qf5eh6Nz{gQUe5;PhsjJ7;IR{}_PVmwbH;4A9G? zkQf03M<{?GsR93xOwRKBxz&xu&|sgzQIuROYkPUudwK-8{kWN=CMV7%5*$+^>l=$9 zz}rI^%b!zTTeYp#+S$azX|AcsnI(l+LO@7<0SyjI5Qxq}?;whf+oH5~PHzSV>+Qw* z#t9{~5{vl<*pQF)xcEbJXLDNtFg^2+A3s{CAtndONl3~6;@zF-=0uORhCH1J000p* zQ-6AU^d8LOrRcd)Co}bQHdEN!7C$nln>kgD=Urzo6>C=(f6~Y&Y4pnxPq}_<#S-ZW zk|hA}&HBdSDKaSHD^_et%u&z60(6E`qqh~SR|a`RbV&yN!-z8^=G#4md%F9rzw`jHDY@|4ia|143v$yDygO-a^C^s#< z5*Q%_;IUD6N8Q}$?&|U!d#%_CS#Lat4YQytKS!i2He&tppi5VQ!8PbqiOlooOPT&V zBceRE;tI!cW1<7r9xRRCChGMWsTJkRAkyludw>v{n>TOfGBiu@-JUuXbaUO7p2{Q{ z^hN#zspn*7qN$R2KYUhg9Wo_bb`nu(#@Nf*Ypc7HY>>kqSu&MnlBk5ZnBr3^F5VjD zbLi6&*{c}<_yzVNT5Unq7XWgN=A8_t;{}734(;n~=Fpc-HzS+rsu|B4k>ANDIYomu z%VKYE)Q|no-gMa_J_38S(9ZaT_!;~^IF}(}XnYRpY-blI|NhF2H(7O};G0Y0v5Ay9 zc^5@~MSn6#rE!)&BYEOIHJFXn3e`J`v4Ige#l<7O{3ddDW3t;uzVb-9afYcj&llfg zxJbLyTAN6vd1$pcS+g0Qg_q(IvgQg4V5!$mk6qO0?&V;84&eY15v?{^_8c&Wm*V8l z#qlvd)$T7+?`(bs002P&VQ-lWfb~0iIs6gPYIC~rGX#U|mCU(VDJJBZ12nsf$ir0@ zsZ|_s^)lF})wV)D2qt-Kqpg@Ta_r@7Mz)y>#HB$~kb1o@c&>FR7{!XAVNsl$8+da? zv@_`Lka|lc^xb4VHt{3L6W314lO_Be=cV}Cdml35W6CwB+G-l6R6AK_bhG5@3|pxr zBq%YPIF1XrxP$uBq2AsdE>W@;l1YfsYZqMYxTq_9j^WH%&YY}T{iWGo=QaD=c-|Ke ziT|9rFLGO*|G@TG6|tvutR**?D(@NHd(ED5izyF1q==(QX1=ia=A~?RT~EFIyg~YyNS9m zC@Ap``L@ze1TZWw2n2vAKrZII8*$@%Ol@&W8sVpm2>MDM5%k^qzo)VTY2BIQlo9^+ z|KGuMAc%|rAOk=G2m>Slk^m{?eJufmOdx+SS^%&?7e>H~WBT!wcXzbTZuLPBkD+22 CP7k*L literal 0 HcmV?d00001 diff --git a/source/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..b01c4c728088026bee90332d5c0098310ecfc0ce GIT binary patch literal 1054 zcmV+(1mXKqNk&E%1ONb6MM6+kP&iBq1ONapFTe{B{|7gcB*j+lzW4b{-+#kUV%C_p z+<+TNl47g+SbN~Wx95BPO!=hommba(oZ7ZsEAzacg98lUUj!Z))C}5Rk>6X8YTH`g z?DvJ4lTk8^i&#K0)C#DCYN&*Y!4Wfa13*B690VlDKqotMl6?BVRIsubt z>Lg53ha^N&Q-_cwLrA0wNeGgV^+<*!2uTPN)F7IGB-Mrxl39<`A*=FtUez!GVSced-^ z&bo&&r^Uz+cDI8$Ek=fn5d@3@GDeu=Vg!s4Fy=Uf?Yy(y4raz?-q|jDBM5U?2-7`6 zn1IyT%nLyn8Nvt{!Wh611_%NYFbNYdtFwmx8Cu#bF==Gu0G%Pe=q;LN4L+@ z*TKQE%zFICs#d>Q|GM{l^1ohhFVEkn+skmX?CKxq&xkFp+Wzl<-{1C6Pe%h@KORt4<+A06^4F}(WCf!zs~Fb4dcA>G zNpiZNECKZzx!IYg!r@IDkI-t?2Sj?ynDM( z9Nf9DSZ*jtN{8sN1IhpeX7PY%AK?m80QIK!r=#8Zv1Q+( z;m&|@p}u3f1r9J8GTwA#a|*)vr1ayiK`j82hffV^>o{lJ^x$c;%qbworlwm>>m>k; z4Dc)wy3CH?rZ@nNG9UM*-6zdx0L((SnWLH@6`@Jgv4&o=2I(^)n&|=^L@Y}w@d_I4 zeIf=^Kz8|gboI~~929}m&|k<76HDVnCy&Kyr70-k;XhX4Qo literal 0 HcmV?d00001 diff --git a/source/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..37137ed60962a576f5908682d91e874d1e157673 GIT binary patch literal 2122 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 Gl%xQIe%rzT literal 0 HcmV?d00001 diff --git a/source/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..28fa6010d80522b5dd9b7ca90f42e44e5cccb4e1 GIT binary patch literal 4210 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 IWR1EA01qbkqyPW_ literal 0 HcmV?d00001 diff --git a/source/core/data/src/main/kotlin/com/xayah/core/data/repository/DirectoryRepository.kt b/source/core/data/src/main/kotlin/com/xayah/core/data/repository/DirectoryRepository.kt index 1ef27c4f4f..885a96718b 100644 --- a/source/core/data/src/main/kotlin/com/xayah/core/data/repository/DirectoryRepository.kt +++ b/source/core/data/src/main/kotlin/com/xayah/core/data/repository/DirectoryRepository.kt @@ -45,9 +45,8 @@ class DirectoryRepository @Inject constructor( val customDirList = mutableListOf() pathList.forEach { pathString -> if (pathString.isNotEmpty()) { - val path = Paths.get(pathString) - val parent = path.parent.pathString - val child = path.name + val parent = PathUtil.getParentPath(pathString) + val child = PathUtil.getFileName(pathString) // Custom storage val dir = DirectoryUpsertEntity( diff --git a/source/core/data/src/main/kotlin/com/xayah/core/data/repository/PackageRepository.kt b/source/core/data/src/main/kotlin/com/xayah/core/data/repository/PackageRepository.kt index cacb5a8bde..4f262a65f3 100644 --- a/source/core/data/src/main/kotlin/com/xayah/core/data/repository/PackageRepository.kt +++ b/source/core/data/src/main/kotlin/com/xayah/core/data/repository/PackageRepository.kt @@ -300,7 +300,7 @@ class PackageRepository @Inject constructor( this.storageStats.appBytes = stats.appBytes this.storageStats.cacheBytes = stats.cacheBytes this.storageStats.dataBytes = stats.dataBytes - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) this.storageStats.externalCacheBytes = stats.externalCacheBytes + this.storageStats.externalCacheBytes = stats.externalCacheBytes } } } diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt index 725d0e878a..7e88127955 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt @@ -11,6 +11,7 @@ import com.xayah.core.network.util.getExtraEntity import com.xayah.core.rootservice.parcelables.PathParcelable import com.xayah.core.util.GsonUtil import com.xayah.core.util.LogUtil +import com.xayah.core.util.PathUtil import com.xayah.core.util.toPathList import com.xayah.core.util.withMainContext import com.xayah.libpickyou.parcelables.DirChildrenParcelable @@ -28,6 +29,8 @@ import java.io.OutputStream import java.nio.file.Paths import javax.security.auth.login.LoginException import kotlin.io.path.Path +import kotlin.io.path.absolute +import kotlin.io.path.name import kotlin.io.path.pathString class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra) : CloudClient { @@ -88,7 +91,7 @@ class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) = withClient { client -> - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "$dst/$name" log { "upload: $src to $dstPath" } val srcFile = File(src) @@ -102,7 +105,7 @@ class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) = withClient { client -> - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "$dst/$name" log { "download: $src to $dstPath" } val dstFile = File(dstPath) @@ -133,8 +136,9 @@ class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra val srcPath = Path(src) srcFile = client.mlistFile(src) if (srcFile == null) { - srcFile = client.listFiles(runCatching { srcPath.parent.pathString }.getOrElse { "." }) - .firstOrNull { it.name == srcPath.fileName.pathString } + srcFile = client.listFiles(runCatching { PathUtil.getParentPath(srcPath.pathString) }.getOrElse { "." }) + .firstOrNull { it.name == srcPath.pathString.substring( + srcPath.pathString.lastIndexOf('/') + 1) } } } if (srcFile != null) { diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt index 474473b10e..87c1094055 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt @@ -109,7 +109,7 @@ class SFTPClientImpl(private val entity: CloudEntity, private val extra: SFTPExt } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) { - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "$dst/$name" log { "upload: $src to $dstPath" } val dstFile = openFile(dstPath) @@ -126,7 +126,7 @@ class SFTPClientImpl(private val entity: CloudEntity, private val extra: SFTPExt } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) { - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "${dst}/$name" log { "download: $src to $dstPath" } val dstFile = File(dstPath) diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt index bc3f3468d4..783271a169 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt @@ -200,7 +200,7 @@ class SMBClientImpl(private val entity: CloudEntity, private val extra: SMBExtra } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) = run { - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "$dst/$name" log { "upload: $src to $dstPath" } val dstFile = openFile(dstPath) @@ -216,7 +216,7 @@ class SMBClientImpl(private val entity: CloudEntity, private val extra: SMBExtra } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) = run { - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "$dst/$name" log { "download: $src to $dstPath" } val dstOutputStream = File(dstPath).outputStream() diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt index 56f797a6e0..8a800a3472 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt @@ -72,7 +72,7 @@ class WebDAVClientImpl(private val entity: CloudEntity) : CloudClient { } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) = withClient { client -> - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "${getPath(dst)}/$name" log { "upload: $src to $dstPath" } val srcFile = File(src) @@ -80,7 +80,7 @@ class WebDAVClientImpl(private val entity: CloudEntity) : CloudClient { } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) = withClient { client -> - val name = Paths.get(src).fileName + val name = src.substring(src.lastIndexOf('/') + 1) val dstPath = "${dst}/$name" log { "download: ${getPath(src)} to $dstPath" } val dstOutputStream = File(dstPath).outputStream() diff --git a/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/IRemoteRootService.aidl b/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/IRemoteRootService.aidl index 55291feb3d..0b7814d92e 100644 --- a/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/IRemoteRootService.aidl +++ b/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/IRemoteRootService.aidl @@ -1,6 +1,7 @@ package com.xayah.core.rootservice; import com.xayah.core.rootservice.parcelables.StatFsParcelable; +import com.xayah.core.rootservice.parcelables.StorageStatsParcelable; interface IRemoteRootService { StatFsParcelable readStatFs(String path); @@ -28,7 +29,7 @@ interface IRemoteRootService { boolean queryInstalled(String packageName, int userId); int getPackageUid(String packageName, int userId); UserHandle getUserHandle(int userId); - StorageStats queryStatsForPackage(in PackageInfo packageInfo, in UserHandle user); + StorageStatsParcelable queryStatsForPackage(in PackageInfo packageInfo, in UserHandle user); List getUsers(); ParcelFileDescriptor walkFileTree(String path); PackageInfo getPackageArchiveInfo(String path); diff --git a/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.aidl b/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.aidl new file mode 100644 index 0000000000..f259a7adcd --- /dev/null +++ b/source/core/rootservice/src/main/aidl/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.aidl @@ -0,0 +1,2 @@ +package com.xayah.core.rootservice.parcelables; +parcelable StorageStatsParcelable; \ No newline at end of file diff --git a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt index 0ad6a13c88..75cf9262ca 100644 --- a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt +++ b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt @@ -1,8 +1,8 @@ package com.xayah.core.rootservice.impl +import android.annotation.TargetApi import android.app.ActivityManagerHidden import android.app.ActivityThread -import android.app.usage.StorageStats import android.app.usage.StorageStatsManager import android.content.Context import android.content.pm.PackageInfo @@ -25,11 +25,13 @@ import com.xayah.core.hiddenapi.castTo import com.xayah.core.rootservice.IRemoteRootService import com.xayah.core.rootservice.parcelables.PathParcelable import com.xayah.core.rootservice.parcelables.StatFsParcelable +import com.xayah.core.rootservice.parcelables.StorageStatsParcelable import com.xayah.core.rootservice.util.ExceptionUtil.tryOn import com.xayah.core.rootservice.util.ExceptionUtil.tryWithBoolean import com.xayah.core.rootservice.util.SsaidUtil import com.xayah.core.util.FileUtil import com.xayah.core.util.HashUtil +import com.xayah.core.util.PathUtil import com.xayah.core.util.command.BaseUtil.setAllPermissions import java.io.File import java.io.IOException @@ -51,12 +53,12 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { private var systemContext: Context private var packageManager: PackageManager private var packageManagerHidden: PackageManagerHidden - private var storageStatsManager: StorageStatsManager private var userManager: UserManagerHidden private var activityManager: ActivityManagerHidden private fun getSystemContext(): Context = ActivityThread.systemMain().systemContext + @TargetApi(Build.VERSION_CODES.O) private fun getStorageStatsManager(): StorageStatsManager = systemContext.getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager private fun getUserManager(): UserManagerHidden = UserManagerHidden.get(systemContext).castTo() @@ -86,7 +88,6 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { systemContext = getSystemContext() packageManager = systemContext.packageManager packageManagerHidden = packageManager.castTo() - storageStatsManager = getStorageStatsManager() userManager = getUserManager() activityManager = getActivityManager() } @@ -180,30 +181,54 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { override fun clearEmptyDirectoriesRecursively(path: String) = synchronized(lock) { tryOn { - Files.walkFileTree(Paths.get(path), object : SimpleFileVisitor() { - override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult { - if (dir != null && attrs != null) { - if (Files.isDirectory(dir) && Files.list(dir).count() == 0L) { - // Empty dir - Files.delete(dir) - } - } - return FileVisitResult.CONTINUE - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + clearEmptyDirectoriesRecursivelyAPI26(path) + } else { + clearEmptyDirectoriesRecursivelyPRE26(path) + } + } + } - override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult { - return FileVisitResult.CONTINUE - } + private fun clearEmptyDirectoriesRecursivelyPRE26(path: String) { + val dir = File(path) + if (dir.isDirectory) { + val items = dir.listFiles() - override fun visitFileFailed(file: Path?, exc: IOException?): FileVisitResult { - return FileVisitResult.CONTINUE + if (items!!.isEmpty()) { + dir.delete() + } else { + for (item: File in items) { + clearEmptyDirectoriesRecursivelyPRE26(item.absolutePath) } + } + } + } - override fun postVisitDirectory(dir: Path?, exc: IOException?): FileVisitResult { - return FileVisitResult.CONTINUE + @TargetApi(Build.VERSION_CODES.O) + private fun clearEmptyDirectoriesRecursivelyAPI26(path: String) { + Files.walkFileTree(Paths.get(path), object : SimpleFileVisitor() { + override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult { + if (dir != null && attrs != null) { + if (Files.isDirectory(dir) && Files.list(dir).count() == 0L) { + // Empty dir + Files.delete(dir) + } } - }) - } + return FileVisitResult.CONTINUE + } + + override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult { + return FileVisitResult.CONTINUE + } + + override fun visitFileFailed(file: Path?, exc: IOException?): FileVisitResult { + return FileVisitResult.CONTINUE + } + + override fun postVisitDirectory(dir: Path?, exc: IOException?): FileVisitResult { + return FileVisitResult.CONTINUE + } + }) } override fun setAllPermissions(src: String): Unit = synchronized(lock) { File(src).setAllPermissions() } @@ -278,10 +303,68 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { UserHandleHidden.of(userId) } - override fun queryStatsForPackage(packageInfo: PackageInfo, user: UserHandle): StorageStats? = synchronized(lock) { + private fun queryStatsForPackagePRE26(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable { + fun getUserId(user: UserHandle): Int { + val userStr = user.toString() + // "UserHandle{" + mHandle + "}" -> mHandle + return userStr.substring(userStr.indexOf("{") + 1, userStr.length - 1).toInt() + } + + fun treeWalkerDirSize(path: String): Long { + val file = File(path) + if (!file.exists()) { + return 0 + } + + var ret: Long = 0 + + if (file.isFile) { + ret += file.length() + } else if (file.isDirectory) { + for (item in file.listFiles()!!) { + ret += treeWalkerDirSize(item.absolutePath) + } + } + + return ret + } + + val userDir = PathUtil.getPackageUserDir(getUserId(user)) + val pkgCacheDir = "$userDir/${packageInfo.packageName}/cache" + val pkgCodeCacheDir = "$userDir/${packageInfo.packageName}/code_cache" + val pkgDataDir = "$userDir/${packageInfo.packageName}" + + val pkgCacheDirSize = treeWalkerDirSize(pkgCacheDir) + treeWalkerDirSize(pkgCodeCacheDir) + val pkgDataDirSize = treeWalkerDirSize(pkgDataDir) - pkgCacheDirSize + + return StorageStatsParcelable( + treeWalkerDirSize(packageInfo.applicationInfo.sourceDir), + pkgCacheDirSize, + pkgDataDirSize, + 0, + ) + } + + @TargetApi(Build.VERSION_CODES.O) + fun queryStatsForPackageAPI26(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable { + val stats = getStorageStatsManager().queryStatsForPackage(packageInfo.applicationInfo.storageUuid, packageInfo.packageName, user) + + return StorageStatsParcelable( + stats.appBytes, + stats.cacheBytes, + stats.dataBytes, + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { stats.externalCacheBytes } else { 0 }, + ) + } + + override fun queryStatsForPackage(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable? = synchronized(lock) { tryOn( block = { - storageStatsManager.queryStatsForPackage(packageInfo.applicationInfo.storageUuid, packageInfo.packageName, user) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + queryStatsForPackageAPI26(packageInfo, user) + } else { + queryStatsForPackagePRE26(packageInfo, user) + } }, onException = { null @@ -301,41 +384,76 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { } override fun walkFileTree(path: String): ParcelFileDescriptor = synchronized(lock) { - writeToParcel { parcel -> - parcel.writeTypedList( - tryOn( - block = { - val pathParcelableList = mutableListOf() - Files.walkFileTree(Paths.get(path), object : SimpleFileVisitor() { - override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult { - return FileVisitResult.CONTINUE - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + walkFileTreeAPI26(path) + } else { + walkFileTreePRE26(path) + } + } - override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult { - if (file != null && attrs != null) { - pathParcelableList.add(PathParcelable(file.pathString)) - } - return FileVisitResult.CONTINUE - } + private fun walkFileTreePRE26(path: String): ParcelFileDescriptor { + fun treeWalker(path: String): List { + val parcelables = ArrayList() - override fun visitFileFailed(file: Path?, exc: IOException?): FileVisitResult { - return FileVisitResult.CONTINUE - } + val file = File(path) + if (file.isFile) { + parcelables.add(PathParcelable(file.absolutePath)) + } else if (file.isDirectory) { + for (item in file.listFiles()!!) { + parcelables.addAll(treeWalker(item.absolutePath)) + } + } - override fun postVisitDirectory(dir: Path?, exc: IOException?): FileVisitResult { - return FileVisitResult.CONTINUE - } - }) - pathParcelableList - }, + return parcelables + } + + return writeToParcel { parcel -> + parcel.writeTypedList( + tryOn( + block = { treeWalker(path) }, onException = { listOf() - } + }, ) ) } } + @TargetApi(Build.VERSION_CODES.O) + private fun walkFileTreeAPI26(path: String): ParcelFileDescriptor = writeToParcel { parcel -> + parcel.writeTypedList( + tryOn( + block = { + val pathParcelableList = mutableListOf() + Files.walkFileTree(Paths.get(path), object : SimpleFileVisitor() { + override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult { + return FileVisitResult.CONTINUE + } + + override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult { + if (file != null && attrs != null) { + pathParcelableList.add(PathParcelable(file.pathString)) + } + return FileVisitResult.CONTINUE + } + + override fun visitFileFailed(file: Path?, exc: IOException?): FileVisitResult { + return FileVisitResult.CONTINUE + } + + override fun postVisitDirectory(dir: Path?, exc: IOException?): FileVisitResult { + return FileVisitResult.CONTINUE + } + }) + pathParcelableList + }, + onException = { + listOf() + } + ) + ) + } + override fun getPackageArchiveInfo(path: String): PackageInfo? = synchronized(lock) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { systemContext.packageManager.getPackageArchiveInfo(path, PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong()))?.apply { diff --git a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/PathParcelable.kt b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/PathParcelable.kt index 269a407dd8..37e826f7ae 100644 --- a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/PathParcelable.kt +++ b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/PathParcelable.kt @@ -12,11 +12,10 @@ class PathParcelable() : Parcelable { var extension: String = "" constructor(pathString: String) : this() { - val path = Paths.get(pathString) this.pathList = pathString.split("/") this.pathString = pathString - this.nameWithoutExtension = path.fileName.pathString.split(".").first() - this.extension = path.fileName.pathString.replace("${nameWithoutExtension}.", "") + this.nameWithoutExtension = pathList.last().split(".").first() + this.extension = pathList.last().replace("${nameWithoutExtension}.", "") } constructor(parcel: Parcel) : this() { diff --git a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.kt b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.kt new file mode 100644 index 0000000000..f9f80df66b --- /dev/null +++ b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/parcelables/StorageStatsParcelable.kt @@ -0,0 +1,47 @@ +package com.xayah.core.rootservice.parcelables + +import android.os.Parcel +import android.os.Parcelable + +class StorageStatsParcelable() : Parcelable { + var appBytes: Long = 0L + var cacheBytes: Long = 0L + var dataBytes: Long = 0L + var externalCacheBytes: Long = 0L + + constructor(appBytes: Long, cacheBytes: Long, dateBytes: Long, externalCacheBytes: Long): this() { + this.appBytes = appBytes + this.cacheBytes = cacheBytes + this.dataBytes = dateBytes + this.externalCacheBytes = externalCacheBytes + } + + constructor(parcel: Parcel) : this() { + appBytes = parcel.readLong() + cacheBytes = parcel.readLong() + dataBytes = parcel.readLong() + externalCacheBytes = parcel.readLong() + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeLong(appBytes) + parcel.writeLong(cacheBytes) + parcel.writeLong(dataBytes) + parcel.writeLong(externalCacheBytes) + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): StorageStatsParcelable { + return StorageStatsParcelable(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + +} \ No newline at end of file diff --git a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt index 0a1c381ccb..5d94f54506 100644 --- a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt +++ b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt @@ -1,6 +1,5 @@ package com.xayah.core.rootservice.service -import android.app.usage.StorageStats import android.content.ComponentName import android.content.Context import android.content.Intent @@ -18,6 +17,7 @@ import com.xayah.core.rootservice.IRemoteRootService import com.xayah.core.rootservice.impl.RemoteRootServiceImpl import com.xayah.core.rootservice.parcelables.PathParcelable import com.xayah.core.rootservice.parcelables.StatFsParcelable +import com.xayah.core.rootservice.parcelables.StorageStatsParcelable import com.xayah.core.rootservice.util.ExceptionUtil.tryOnScope import com.xayah.core.rootservice.util.withMainContext import com.xayah.core.util.GsonUtil @@ -124,11 +124,6 @@ class RemoteRootService(private val context: Context) { val msg = "Service is null, trying to bind: $retries." log { msg } bindService() - } else if (mService!!.asBinder().isBinderAlive.not()) { - mService = null - val msg = "Service is dead, trying to bind: $retries." - log { msg } - bindService() } else { mService!! } @@ -262,7 +257,7 @@ class RemoteRootService(private val context: Context) { suspend fun getUserHandle(userId: Int): UserHandle? = runCatching { getService().getUserHandle(userId) }.onFailure(onFailure).getOrNull() - suspend fun queryStatsForPackage(packageInfo: PackageInfo, user: UserHandle): StorageStats? = + suspend fun queryStatsForPackage(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable? = runCatching { getService().queryStatsForPackage(packageInfo, user) }.onFailure(onFailure).getOrNull() suspend fun getUsers(): List = runCatching { getService().users }.onFailure(onFailure).getOrElse { listOf() } diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt index e02ed17707..c3a54344d2 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt @@ -1,6 +1,8 @@ package com.xayah.core.util +import android.annotation.TargetApi import android.content.Context +import android.os.Build import android.text.format.DateUtils import java.text.SimpleDateFormat import java.time.Instant @@ -9,6 +11,7 @@ import java.time.ZoneId import java.time.temporal.ChronoUnit import java.util.Date import java.util.Locale +import java.util.concurrent.TimeUnit import kotlin.math.abs @@ -62,19 +65,23 @@ object DateUtil { return String.format(format, count) } + fun getNumberOfDaysPassed(date1: Long, date2: Long): Long { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + getNumberOfDaysPassedAPI26(date1, date2) + } else { + getNumberOfDaysPassedPRE26(date1, date2) + } + } + + private fun getNumberOfDaysPassedPRE26(date1: Long, date2: Long) = TimeUnit.MILLISECONDS.toDays(abs(date2 - date1)) /** * @see packages/apps/Messaging/src/com/android/messaging/util/Dates.java */ - fun getNumberOfDaysPassed(date1: Long, date2: Long): Long { + @TargetApi(Build.VERSION_CODES.O) + private fun getNumberOfDaysPassedAPI26(date1: Long, date2: Long): Long { val dateTime1 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date1), ZoneId.systemDefault()) val dateTime2 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date2), ZoneId.systemDefault()) return abs(ChronoUnit.DAYS.between(dateTime2, dateTime1)) } - - fun getNumberOfHoursPassed(date1: Long, date2: Long): Long { - val dateTime1 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date1), ZoneId.systemDefault()) - val dateTime2 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date2), ZoneId.systemDefault()) - return abs(ChronoUnit.HOURS.between(dateTime2, dateTime1)) - } } diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt index 0515bfbc44..1aab6df7f3 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt @@ -1,9 +1,21 @@ package com.xayah.core.util +import android.annotation.TargetApi +import android.os.Build import org.apache.commons.codec.digest.DigestUtils +import java.io.FileInputStream import java.nio.file.Files import java.nio.file.Paths object HashUtil { - fun calculateMD5(src: String) = DigestUtils.md5Hex(Files.newInputStream(Paths.get(src))) + fun calculateMD5(src: String): String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + calculateMD5API26(src) + } else { + calculateMD5PRE26(src) + } + + private fun calculateMD5PRE26(src: String) = DigestUtils.md5Hex(FileInputStream(src)) + + @TargetApi(Build.VERSION_CODES.O) + private fun calculateMD5API26(src: String) = DigestUtils.md5Hex(Files.newInputStream(Paths.get(src))) } diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt index 497a9945c9..b9811dcc57 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt @@ -8,6 +8,7 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.net.Uri import android.os.Build import android.provider.Settings import android.provider.Settings.EXTRA_APP_PACKAGE @@ -35,7 +36,7 @@ object NotificationUtil { fun requestPermissions(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { ActivityCompat.requestPermissions(context.getActivity(), arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1) - } else { + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { runCatching { val intent = Intent() intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS) @@ -46,6 +47,15 @@ object NotificationUtil { }.onFailure { Toast.makeText(context, context.getString(R.string.grant_ntfy_perm_manually), Toast.LENGTH_SHORT).show() } + } else { + runCatching { + val intent = Intent().apply { + setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + addCategory(Intent.CATEGORY_DEFAULT) + setData(Uri.parse("package:${context.packageName}")) + } + context.startActivity(intent) + } } } @@ -53,13 +63,25 @@ object NotificationUtil { val pendingIntent: PendingIntent = context.packageManager.getLaunchIntentForPackage(context.packageName).let { intent -> PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) } - val channel = NotificationChannel(ForegroundServiceChannelId, ForegroundServiceChannelName, NotificationManager.IMPORTANCE_LOW).apply { - description = ForegroundServiceChannelDesc - } - val notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - notificationManager.createNotificationChannel(channel) - Notification.Builder(context, ForegroundServiceChannelId).setContentIntent(pendingIntent).build() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = NotificationChannel( + ForegroundServiceChannelId, + ForegroundServiceChannelName, + NotificationManager.IMPORTANCE_LOW + ).apply { + description = ForegroundServiceChannelDesc + } + val notificationManager: NotificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(channel) + + Notification.Builder(context, ForegroundServiceChannelId) + .setContentIntent(pendingIntent).build() + } else { + @Suppress("DEPRECATION") + Notification.Builder(context).setContentIntent(pendingIntent).build() + } } fun getProgressNotificationBuilder(context: Context) = diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt index df173847ed..e7bdbd355e 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt @@ -7,9 +7,7 @@ import com.xayah.core.util.command.SELinux import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking -import java.nio.file.Paths import javax.inject.Inject -import kotlin.io.path.pathString const val LogRelativeDir = "log" const val IconRelativeDir = "icon" @@ -38,8 +36,13 @@ class PathUtil @Inject constructor( @ApplicationContext private val context: Context, ) { companion object { - fun getParentPath(path: String): String = Paths.get(path).parent.pathString - fun getFileName(path: String): String = Paths.get(path).fileName.pathString + fun getParentPath(path: String): String { + assert(path.contains('/') && path != "/") { "Path doesn't have any parent" } + val child = path.substring(path.lastIndexOf('/')) + return path.replace(child, "", false) + } + + fun getFileName(path: String): String = path.substring(path.lastIndexOf('/') + 1) // Paths for processing. @SuppressLint("SdCardPath") diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt index 3c1e713edc..b8e760d42d 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt @@ -124,12 +124,14 @@ object BaseUtil { } suspend fun kill(context: Context, vararg keys: String) { + execute("echo \$PATH", shell = getNewShell(context), timeout = -1) + // ps -A | grep -w $key1 | grep -w $key2 | ... | awk 'NF>1{print $2}' | xargs kill -9 val keysArg = keys.map { "| grep -w $it" }.toTypedArray() execute( - "ps -A", + "busybox ps -A", *keysArg, - "| awk 'NF>1{print ${USD}2}'", + "| cut -f2 -d' '", "| xargs kill -9", shell = getNewShell(context), timeout = -1 diff --git a/source/gradle/libs.versions.toml b/source/gradle/libs.versions.toml index 86977c51b6..a64f80ddd6 100644 --- a/source/gradle/libs.versions.toml +++ b/source/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] # config compileSdk = "34" -minSdk = "26" +minSdk = "24" targetSdk = "34" # __(API)_(feature)___(version)_(abi) # TODO: Feature bit is no longer useful, drop when next api releases @@ -17,7 +17,7 @@ appcompat = "1.7.0" androidx-test-ext-junit = "1.1.5" espresso-core = "3.5.1" junit = "4.13.2" -compose-bom = "2024.05.00" +compose-bom = "2024.06.00" core-ktx = "1.13.1" core-splashscreen = "1.0.1" gson = "2.10.1" @@ -27,7 +27,7 @@ hilt-navigation-compose = "1.2.0" navigation-compose = "2.7.7" okhttp = "4.12.0" retrofit = "2.9.0" -libsu = "PR182-SNAPSHOT" # TODO Force enable the latest libsu +libsu = "6.0.0" # TODO Force enable the latest libsu zip4j = "2.11.5" kotlinx-coroutines-core-jvm = "1.8.0" room = "2.6.1" From 71f4bed3daecf93b6c9a10588e71895219c64c54 Mon Sep 17 00:00:00 2001 From: Xayah Date: Sun, 14 Jul 2024 10:54:25 +0800 Subject: [PATCH 2/6] refactor: Modify codes Change-Id: I898b6743a704fcea2128ac3dab04bd01e9829d77 --- source/app/src/main/ic_launcher-playstore.png | Bin 20267 -> 25834 bytes .../res/drawable/ic_launcher_foreground.xml | 179 +++++++++--------- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 1604 -> 1932 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 3670 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 1054 -> 1372 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 2490 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 2122 -> 2614 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 5120 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 3064 -> 3746 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 7974 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 4210 -> 5154 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 11010 bytes .../java/android/os/UserHandleHidden.java | 4 + .../core/network/client/FTPClientImpl.kt | 14 +- .../core/network/client/SFTPClientImpl.kt | 6 +- .../core/network/client/SMBClientImpl.kt | 6 +- .../core/network/client/WebDAVClientImpl.kt | 6 +- .../rootservice/impl/RemoteRootServiceImpl.kt | 128 ++++++------- .../rootservice/service/RemoteRootService.kt | 5 + .../kotlin/com/xayah/core/util/DateUtil.kt | 9 +- .../kotlin/com/xayah/core/util/FileUtil.kt | 29 ++- .../kotlin/com/xayah/core/util/HashUtil.kt | 8 +- .../com/xayah/core/util/NotificationUtil.kt | 8 +- .../kotlin/com/xayah/core/util/PathUtil.kt | 15 +- .../com/xayah/core/util/command/BaseUtil.kt | 9 +- 27 files changed, 226 insertions(+), 211 deletions(-) create mode 100644 source/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 source/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 source/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 source/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 source/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 source/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/source/app/src/main/ic_launcher-playstore.png b/source/app/src/main/ic_launcher-playstore.png index 9be4656a374290d8f519a1fc0e624b75967dd7cf..1af026ff6659c9d0b5e63d6468565b984eebccd1 100644 GIT binary patch literal 25834 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 literal 20267 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 Xqt^U9Tq8+`F^z-~B0{Qy4{-km_S;?E diff --git a/source/app/src/main/res/drawable/ic_launcher_foreground.xml b/source/app/src/main/res/drawable/ic_launcher_foreground.xml index daafe49e47..1c52454b4e 100644 --- a/source/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/source/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -3,96 +3,91 @@ android:height="108dp" android:viewportWidth="432" android:viewportHeight="432"> - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 7353dbd1fd..0648fb47f9 100644 --- a/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,6 @@ - - + + + \ No newline at end of file diff --git a/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..0648fb47f9 --- /dev/null +++ b/source/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/source/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-hdpi/ic_launcher.webp index 7984add040fcffb960514645cbdc5d9ff39267df..84d6ab69f93a496371bf6e746afacb6747b99c04 100644 GIT binary patch literal 1932 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 CP7k*L diff --git a/source/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/source/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..d8de8a5704c366cd601bdf0da750aba41ea89766 GIT binary patch literal 3670 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 literal 0 HcmV?d00001 diff --git a/source/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-mdpi/ic_launcher.webp index b01c4c728088026bee90332d5c0098310ecfc0ce..0e2910eccc9c999e03538bdafb1487913c8f5693 100644 GIT binary patch literal 1372 zcmV-i1*7^>Nk&Fg1pok7MM6+kP&iCT1pojqFTe{B6^DVeZ5sc!_iKoV3Ft(57;QM! zwmoY;PaHN-(Q$%}wlxR6_YMeON5wrwC0?O5D&{(~I<|IfcUZ62L-fO>Mf#)PF^8 z+cwPTIJbEO&WmFM`q+d4TPb%8s5NS&`P1rm7@X_&Sy2q2}caLUc$*o)4IAD#tH1fciJk3-38Y>W^kk6mM{ zjRwm;^}PG$tY7 zU`vBd4Y8D)5Rejaa>%ThdWkXw6a~l&R3ASjPf0x_eH(5I5aqBjk@T^&AT4I7O6b+_ zmDMNA$V<^|(GCNKnA>w^Mw&HaE}|kGpqDImjH(af961T`Qc_h2q=gi$^Q2%?gc)M9 zDdBopiuai*hLK)@37M*%>yMh(sw_bx(hC#^B8@n+0sxr+0yQ?L{imxS85J;=Q6b+} zj$u!EmS&V7i#bJ3Nn%PAawJ~uN555Xn75`yds_F0`}#?ilB&R*O@AOM;N*}q05Bs< z*#F%9PF<@NI2!(KwxeOunTE*LhYsn(#{fRNh~_xYKaObt5Mqh$CUn=$g0x9TxuB&J z9LrLq)QP40JAtb9^+jf_l_+KaZldbU`r5UX=DqHH zpxzc$j>>}e6ho1bBBhXb7$9ek@9~nx3;?*o*3EwWlWAjdP0LGX-pl?U)N2y_jC1D_ zxO~lR^*BzxAqMacy2T0Pi!Zy$e*9$s1S{rRk5c(mD<5l}XBou>>cw%z|I$~jilGYI zFo*GHT;Jq0eU&+(fZ&>HT-yfld93C;ktbwS+r-ukxf(Ukl?l*mf73@bg=39ADRKhv z&VBXFF+|Vv699O&(Q>AqM3FTd50>GgKzt6D_wKSA{^Ys6`vVC3G-_tvnnOkiJWb&9 z=eg5w*Q%owOTwo^4>Hq&EA@>JEpHH>y|0h-U1RCwXk1 z5)>31%Q>d0{jZPrB)ieSRbz8ZnITKFZbDbCgnnZP(b-M^RzzT}L<1IRwf@)s+52$6 zx<`3pwFXqgu_cblEZs8!{0{v@@GFAu(b{`=xvpN1%{^A+i<)z?&^WOLDBQ*U=QI7? z{-;#nJO`4_#wWB~3B%q#XzY|o;-tyD_qJEDVZlgukN}}SJWGZ}@Fc?ZKjrW!S zagEXlpw0iTSD2o|Q1da9cuzH6-yl!l!^TH$xQ?cOH@H_A<|P3Y>vtG>uBo&=rV?mp e`3)m|sW|)&z!4x5pn+XIu2Ioq5Ws>ha84j0`K$E+ literal 1054 zcmV+(1mXKqNk&E%1ONb6MM6+kP&iBq1ONapFTe{B{|7gcB*j+lzW4b{-+#kUV%C_p z+<+TNl47g+SbN~Wx95BPO!=hommba(oZ7ZsEAzacg98lUUj!Z))C}5Rk>6X8YTH`g z?DvJ4lTk8^i&#K0)C#DCYN&*Y!4Wfa13*B690VlDKqotMl6?BVRIsubt z>Lg53ha^N&Q-_cwLrA0wNeGgV^+<*!2uTPN)F7IGB-Mrxl39<`A*=FtUez!GVSced-^ z&bo&&r^Uz+cDI8$Ek=fn5d@3@GDeu=Vg!s4Fy=Uf?Yy(y4raz?-q|jDBM5U?2-7`6 zn1IyT%nLyn8Nvt{!Wh611_%NYFbNYdtFwmx8Cu#bF==Gu0G%Pe=q;LN4L+@ z*TKQE%zFICs#d>Q|GM{l^1ohhFVEkn+skmX?CKxq&xkFp+Wzl<-{1C6Pe%h@KORt4<+A06^4F}(WCf!zs~Fb4dcA>G zNpiZNECKZzx!IYg!r@IDkI-t?2Sj?ynDM( z9Nf9DSZ*jtN{8sN1IhpeX7PY%AK?m80QIK!r=#8Zv1Q+( z;m&|@p}u3f1r9J8GTwA#a|*)vr1ayiK`j82hffV^>o{lJ^x$c;%qbworlwm>>m>k; z4Dc)wy3CH?rZ@nNG9UM*-6zdx0L((SnWLH@6`@Jgv4&o=2I(^)n&|=^L@Y}w@d_I4 zeIf=^Kz8|gboI~~929}m&|k<76HDVnCy&Kyr70-k;XhX4Qo diff --git a/source/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/source/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1e9c991531d59b8e15867f94b85213153f296702 GIT binary patch literal 2490 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 diff --git a/source/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/source/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..6ffdee30bd675bd08e3f768b486240db812b404c GIT binary patch literal 5120 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 M(<%a_9Vtlx09@oE>i_@% literal 3064 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 Gl%xQIe%rzT diff --git a/source/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/source/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..bdb4e30efbac0adfdbdaefb99a703f8583ca694b GIT binary patch literal 7974 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 literal 0 HcmV?d00001 diff --git a/source/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/source/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index 28fa6010d80522b5dd9b7ca90f42e44e5cccb4e1..ce25e0e1cd981f818ae77ffa71860a86641ac2b1 100644 GIT binary patch literal 5154 zcmV+-6y57mNk&E*6aWBMMM6+kP&iBt6aWA(zrZgLHHYH1Z5(<3u~V<#Ga@E{J<9EC z1@QRDT9C4^9b+v`|G(O8llRb7UR=9lSTQp*gPEBngCy%(EHjgs44S?Py668t=N_GN zx=U|i8RldajZ$W2N8^mVbLNz+%xI?E$|(lQOinbqcgozly{j-MhM8Y@Rc>z;PF_G< zm#Z>4%$z99*>=L5RWoJq{8!~Va3^%iT*c$jm|b$CFf%hV6vNESNmpGlT8;n!h9u4J zZM(;|+P2+YHG7IK-*^*B0>GvXWK}s2)2`4Y$%*Yy-Nv@9Dj&-UEq9k#n}IT*2Dsp zxQ+@q)LF!=VNPURxwULZkINQr hD){%vGqI+VCGOBCfuHlxS8vV-nHqZsk3aZ12 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 QgF{1=9+wJ0Wg}e#08=B06951J literal 4210 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 IWR1EA01qbkqyPW_ diff --git a/source/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/source/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..5ec0d60a758418691c31292adccba118233b9654 GIT binary patch literal 11010 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 z%0A6mNHe}A0)CP8?@#5wdLH)ff%3iq%ev_!!f={mdS`Cb3GvH;a zm-VSuR26PMvOaiTE|<7P8t6sk896Pdufg4QjN$2}YwKI6v3iziB z(I7)SP|kG%3X($hmaF|Oz@e3f?nlrM`T+Crs~#9hqf@0FncsjUhyeAPQ9S_i$LaE~vUj^%hzAO?yWOp9*@ahd^zioIsYJ^TADSGF{e!VTgp=zg9gCYht>Av5*^0V_=`6TkPcD}mFul06_EiaH0=T(BCV&h+&sNqH0G+2a6aWAK literal 0 HcmV?d00001 diff --git a/source/core/hiddenapi/src/main/java/android/os/UserHandleHidden.java b/source/core/hiddenapi/src/main/java/android/os/UserHandleHidden.java index 187e7a0b59..adc50c4bb6 100644 --- a/source/core/hiddenapi/src/main/java/android/os/UserHandleHidden.java +++ b/source/core/hiddenapi/src/main/java/android/os/UserHandleHidden.java @@ -10,4 +10,8 @@ public class UserHandleHidden { public static UserHandle of(int userId) { throw new RuntimeException("Stub!"); } + + public int getIdentifier() { + throw new RuntimeException("Stub!"); + } } diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt index 7e88127955..0a8b846a95 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/FTPClientImpl.kt @@ -26,11 +26,7 @@ import java.io.FileInputStream import java.io.IOException import java.io.InputStream import java.io.OutputStream -import java.nio.file.Paths import javax.security.auth.login.LoginException -import kotlin.io.path.Path -import kotlin.io.path.absolute -import kotlin.io.path.name import kotlin.io.path.pathString class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra) : CloudClient { @@ -91,7 +87,7 @@ class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) = withClient { client -> - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "$dst/$name" log { "upload: $src to $dstPath" } val srcFile = File(src) @@ -105,7 +101,7 @@ class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) = withClient { client -> - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "$dst/$name" log { "download: $src to $dstPath" } val dstFile = File(dstPath) @@ -133,12 +129,10 @@ class FTPClientImpl(private val entity: CloudEntity, private val extra: FTPExtra private fun listFile(src: String): FTPFile { var srcFile: FTPFile? = null withClient { client -> - val srcPath = Path(src) srcFile = client.mlistFile(src) if (srcFile == null) { - srcFile = client.listFiles(runCatching { PathUtil.getParentPath(srcPath.pathString) }.getOrElse { "." }) - .firstOrNull { it.name == srcPath.pathString.substring( - srcPath.pathString.lastIndexOf('/') + 1) } + srcFile = client.listFiles(runCatching { PathUtil.getParentPath(src) }.getOrElse { "." }) + .firstOrNull { it.name == PathUtil.getFileName(src) } } } if (srcFile != null) { diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt index 87c1094055..3c1d44cdbe 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt @@ -11,6 +11,7 @@ import com.xayah.core.network.util.getExtraEntity import com.xayah.core.rootservice.parcelables.PathParcelable import com.xayah.core.util.GsonUtil import com.xayah.core.util.LogUtil +import com.xayah.core.util.PathUtil import com.xayah.core.util.toPathList import com.xayah.core.util.withMainContext import com.xayah.libpickyou.parcelables.DirChildrenParcelable @@ -27,7 +28,6 @@ import net.schmizz.sshj.userauth.password.PasswordFinder import net.schmizz.sshj.userauth.password.Resource import java.io.File import java.io.FileOutputStream -import java.nio.file.Paths import kotlin.io.path.pathString @@ -109,7 +109,7 @@ class SFTPClientImpl(private val entity: CloudEntity, private val extra: SFTPExt } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) { - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "$dst/$name" log { "upload: $src to $dstPath" } val dstFile = openFile(dstPath) @@ -126,7 +126,7 @@ class SFTPClientImpl(private val entity: CloudEntity, private val extra: SFTPExt } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) { - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "${dst}/$name" log { "download: $src to $dstPath" } val dstFile = File(dstPath) diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt index 783271a169..def59beaa8 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt @@ -30,6 +30,7 @@ import com.xayah.core.network.util.getExtraEntity import com.xayah.core.rootservice.parcelables.PathParcelable import com.xayah.core.util.GsonUtil import com.xayah.core.util.LogUtil +import com.xayah.core.util.PathUtil import com.xayah.core.util.SymbolUtil import com.xayah.core.util.toPathList import com.xayah.core.util.withLog @@ -41,7 +42,6 @@ import com.xayah.libpickyou.ui.model.PickerType import java.io.File import java.io.FileInputStream import java.io.IOException -import java.nio.file.Paths import kotlin.io.path.pathString @@ -200,7 +200,7 @@ class SMBClientImpl(private val entity: CloudEntity, private val extra: SMBExtra } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) = run { - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "$dst/$name" log { "upload: $src to $dstPath" } val dstFile = openFile(dstPath) @@ -216,7 +216,7 @@ class SMBClientImpl(private val entity: CloudEntity, private val extra: SMBExtra } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) = run { - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "$dst/$name" log { "download: $src to $dstPath" } val dstOutputStream = File(dstPath).outputStream() diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt index 8a800a3472..fc5f72fbed 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt @@ -6,6 +6,7 @@ import com.xayah.core.model.database.CloudEntity import com.xayah.core.network.R import com.xayah.core.rootservice.parcelables.PathParcelable import com.xayah.core.util.LogUtil +import com.xayah.core.util.PathUtil import com.xayah.core.util.toPathList import com.xayah.core.util.withMainContext import com.xayah.libpickyou.parcelables.DirChildrenParcelable @@ -15,7 +16,6 @@ import com.xayah.libpickyou.ui.model.PickerType import com.xayah.libsardine.impl.OkHttpSardine import okhttp3.OkHttpClient import java.io.File -import java.nio.file.Paths import java.util.concurrent.TimeUnit import kotlin.io.path.pathString @@ -72,7 +72,7 @@ class WebDAVClientImpl(private val entity: CloudEntity) : CloudClient { } override fun upload(src: String, dst: String, onUploading: (read: Long, total: Long) -> Unit) = withClient { client -> - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "${getPath(dst)}/$name" log { "upload: $src to $dstPath" } val srcFile = File(src) @@ -80,7 +80,7 @@ class WebDAVClientImpl(private val entity: CloudEntity) : CloudClient { } override fun download(src: String, dst: String, onDownloading: (written: Long, total: Long) -> Unit) = withClient { client -> - val name = src.substring(src.lastIndexOf('/') + 1) + val name = PathUtil.getFileName(src) val dstPath = "${dst}/$name" log { "download: ${getPath(src)} to $dstPath" } val dstOutputStream = File(dstPath).outputStream() diff --git a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt index 75cf9262ca..4bf6625c6d 100644 --- a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt +++ b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/impl/RemoteRootServiceImpl.kt @@ -182,30 +182,30 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { override fun clearEmptyDirectoriesRecursively(path: String) = synchronized(lock) { tryOn { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - clearEmptyDirectoriesRecursivelyAPI26(path) + clearEmptyDirectoriesRecursivelyApi26(path) } else { - clearEmptyDirectoriesRecursivelyPRE26(path) + clearEmptyDirectoriesRecursivelyApi24(path) } } } - private fun clearEmptyDirectoriesRecursivelyPRE26(path: String) { + private fun clearEmptyDirectoriesRecursivelyApi24(path: String) { val dir = File(path) if (dir.isDirectory) { - val items = dir.listFiles() - - if (items!!.isEmpty()) { - dir.delete() - } else { - for (item: File in items) { - clearEmptyDirectoriesRecursivelyPRE26(item.absolutePath) + dir.listFiles()?.also { items -> + if (items.isEmpty()) { + dir.delete() + } else { + items.forEach { + clearEmptyDirectoriesRecursivelyApi24(it.absolutePath) + } } } } } @TargetApi(Build.VERSION_CODES.O) - private fun clearEmptyDirectoriesRecursivelyAPI26(path: String) { + private fun clearEmptyDirectoriesRecursivelyApi26(path: String) { Files.walkFileTree(Paths.get(path), object : SimpleFileVisitor() { override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult { if (dir != null && attrs != null) { @@ -303,50 +303,40 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { UserHandleHidden.of(userId) } - private fun queryStatsForPackagePRE26(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable { - fun getUserId(user: UserHandle): Int { - val userStr = user.toString() - // "UserHandle{" + mHandle + "}" -> mHandle - return userStr.substring(userStr.indexOf("{") + 1, userStr.length - 1).toInt() - } - - fun treeWalkerDirSize(path: String): Long { - val file = File(path) - if (!file.exists()) { - return 0 - } - - var ret: Long = 0 - - if (file.isFile) { - ret += file.length() - } else if (file.isDirectory) { - for (item in file.listFiles()!!) { - ret += treeWalkerDirSize(item.absolutePath) - } - } - - return ret - } - - val userDir = PathUtil.getPackageUserDir(getUserId(user)) - val pkgCacheDir = "$userDir/${packageInfo.packageName}/cache" - val pkgCodeCacheDir = "$userDir/${packageInfo.packageName}/code_cache" - val pkgDataDir = "$userDir/${packageInfo.packageName}" - - val pkgCacheDirSize = treeWalkerDirSize(pkgCacheDir) + treeWalkerDirSize(pkgCodeCacheDir) - val pkgDataDirSize = treeWalkerDirSize(pkgDataDir) - pkgCacheDirSize - + private fun queryStatsForPackageApi24(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable { + val userHandle: UserHandleHidden = user.castTo() + // https://cs.android.com/android/platform/superproject/+/android-8.0.0_r51:frameworks/base/services/core/java/com/android/server/pm/Installer.java;l=225 + // https://cs.android.com/android/platform/superproject/+/android-8.0.0_r51:frameworks/native/cmds/installd/InstalldNativeService.cpp;l=1340 + // https://cs.android.com/android/platform/superproject/+/android-8.0.0_r51:frameworks/base/services/usage/java/com/android/server/usage/StorageStatsService.java;l=439 + // https://cs.android.com/android/platform/superproject/+/android-8.0.0_r51:frameworks/base/core/java/android/app/usage/StorageStats.java;l=31 + val userDir = "${PathUtil.getPackageUserDir(userHandle.identifier)}/${packageInfo.packageName}" + val userCacheDir = "$userDir/cache" + val userCodeCacheDir = "$userDir}/code_cache" + val dataDir = "${PathUtil.getPackageDataDir(userHandle.identifier)}/${packageInfo.packageName}" + val dataCacheDir = "$dataDir/cache" + val dataCodeCacheDir = "$dataDir}/code_cache" + val obbDir = "${PathUtil.getPackageObbDir(userHandle.identifier)}/${packageInfo.packageName}" + val obbCacheDir = "$obbDir/cache" + val obbCodeCacheDir = "$obbDir}/code_cache" + val mediaDir = "${PathUtil.getPackageMediaDir(userHandle.identifier)}/${packageInfo.packageName}" + val mediaCacheDir = "$mediaDir/cache" + val mediaCodeCacheDir = "$mediaDir}/code_cache" + + val cacheDirSize = FileUtil.calculateSize(userCacheDir) + FileUtil.calculateSize(userCodeCacheDir) + + FileUtil.calculateSize(dataCacheDir) + FileUtil.calculateSize(dataCodeCacheDir) + + FileUtil.calculateSize(obbCacheDir) + FileUtil.calculateSize(obbCodeCacheDir) + + FileUtil.calculateSize(mediaCacheDir) + FileUtil.calculateSize(mediaCodeCacheDir) + val dataDirSize = FileUtil.calculateSize(userDir) + FileUtil.calculateSize(dataDir) + FileUtil.calculateSize(obbDir) + FileUtil.calculateSize(mediaDir) - cacheDirSize return StorageStatsParcelable( - treeWalkerDirSize(packageInfo.applicationInfo.sourceDir), - pkgCacheDirSize, - pkgDataDirSize, + FileUtil.calculateSize(PathUtil.getParentPath(packageInfo.applicationInfo.sourceDir)), + cacheDirSize, + dataDirSize, 0, ) } @TargetApi(Build.VERSION_CODES.O) - fun queryStatsForPackageAPI26(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable { + fun queryStatsForPackageApi26(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable { val stats = getStorageStatsManager().queryStatsForPackage(packageInfo.applicationInfo.storageUuid, packageInfo.packageName, user) return StorageStatsParcelable( @@ -358,18 +348,13 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { } override fun queryStatsForPackage(packageInfo: PackageInfo, user: UserHandle): StorageStatsParcelable? = synchronized(lock) { - tryOn( - block = { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - queryStatsForPackageAPI26(packageInfo, user) - } else { - queryStatsForPackagePRE26(packageInfo, user) - } - }, - onException = { - null + runCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + queryStatsForPackageApi26(packageInfo, user) + } else { + queryStatsForPackageApi24(packageInfo, user) } - ) + }.getOrNull() } override fun getUsers(): List = synchronized(lock) { @@ -385,32 +370,29 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { override fun walkFileTree(path: String): ParcelFileDescriptor = synchronized(lock) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - walkFileTreeAPI26(path) + walkFileTreeApi26(path) } else { - walkFileTreePRE26(path) + walkFileTreeApi24(path) } } - private fun walkFileTreePRE26(path: String): ParcelFileDescriptor { - fun treeWalker(path: String): List { - val parcelables = ArrayList() - + private fun walkFileTreeApi24(path: String): ParcelFileDescriptor { + fun walkFileTreeRecursively(path: String): List { + val pathParcelableList = mutableListOf() val file = File(path) if (file.isFile) { - parcelables.add(PathParcelable(file.absolutePath)) + pathParcelableList.add(PathParcelable(file.absolutePath)) } else if (file.isDirectory) { for (item in file.listFiles()!!) { - parcelables.addAll(treeWalker(item.absolutePath)) + pathParcelableList.addAll(walkFileTreeRecursively(item.absolutePath)) } } - - return parcelables + return pathParcelableList } - return writeToParcel { parcel -> parcel.writeTypedList( tryOn( - block = { treeWalker(path) }, + block = { walkFileTreeRecursively(path) }, onException = { listOf() }, @@ -420,7 +402,7 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() { } @TargetApi(Build.VERSION_CODES.O) - private fun walkFileTreeAPI26(path: String): ParcelFileDescriptor = writeToParcel { parcel -> + private fun walkFileTreeApi26(path: String): ParcelFileDescriptor = writeToParcel { parcel -> parcel.writeTypedList( tryOn( block = { diff --git a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt index 5d94f54506..651b9c8343 100644 --- a/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt +++ b/source/core/rootservice/src/main/kotlin/com/xayah/core/rootservice/service/RemoteRootService.kt @@ -124,6 +124,11 @@ class RemoteRootService(private val context: Context) { val msg = "Service is null, trying to bind: $retries." log { msg } bindService() + } else if (mService!!.asBinder().isBinderAlive.not()) { + mService = null + val msg = "Service is dead, trying to bind: $retries." + log { msg } + bindService() } else { mService!! } diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt index c3a54344d2..e72e28bd37 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/DateUtil.kt @@ -14,7 +14,6 @@ import java.util.Locale import java.util.concurrent.TimeUnit import kotlin.math.abs - object DateUtil { private const val SECOND_IN_MILLIS: Long = 1000 private const val MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60 @@ -67,19 +66,19 @@ object DateUtil { fun getNumberOfDaysPassed(date1: Long, date2: Long): Long { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - getNumberOfDaysPassedAPI26(date1, date2) + getNumberOfDaysPassedApi26(date1, date2) } else { - getNumberOfDaysPassedPRE26(date1, date2) + getNumberOfDaysPassedApi24(date1, date2) } } - private fun getNumberOfDaysPassedPRE26(date1: Long, date2: Long) = TimeUnit.MILLISECONDS.toDays(abs(date2 - date1)) + private fun getNumberOfDaysPassedApi24(date1: Long, date2: Long) = TimeUnit.MILLISECONDS.toDays(abs(date2 - date1)) /** * @see packages/apps/Messaging/src/com/android/messaging/util/Dates.java */ @TargetApi(Build.VERSION_CODES.O) - private fun getNumberOfDaysPassedAPI26(date1: Long, date2: Long): Long { + private fun getNumberOfDaysPassedApi26(date1: Long, date2: Long): Long { val dateTime1 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date1), ZoneId.systemDefault()) val dateTime2 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date2), ZoneId.systemDefault()) return abs(ChronoUnit.DAYS.between(dateTime2, dateTime1)) diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/FileUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/FileUtil.kt index fc2abffd68..d45ef27b90 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/FileUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/FileUtil.kt @@ -1,5 +1,7 @@ package com.xayah.core.util +import android.annotation.TargetApi +import android.os.Build import java.io.File import java.io.IOException import java.nio.file.FileVisitResult @@ -16,6 +18,31 @@ object FileUtil { }.getOrElse { listOf() } fun calculateSize(path: String): Long = run { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + calculateSizeApi26(path) + } else { + calculateSizeApi24(path) + } + } + + private fun calculateSizeApi24(path: String): Long { + val file = File(path) + if (!file.exists()) { + return 0 + } + var size: Long = 0 + if (file.isFile) { + size += file.length() + } else if (file.isDirectory) { + for (item in file.listFiles()!!) { + size += calculateSizeApi24(item.absolutePath) + } + } + return size + } + + @TargetApi(Build.VERSION_CODES.O) + private fun calculateSizeApi26(path: String): Long { val size = AtomicLong(0) runCatching { Files.walkFileTree(Paths.get(path), object : SimpleFileVisitor() { @@ -39,7 +66,7 @@ object FileUtil { } }) } - size.get() + return size.get() } fun deleteRecursively(path: String): Boolean = runCatching { File(path).deleteRecursively() }.getOrElse { false } diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt index 1aab6df7f3..84144529a6 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/HashUtil.kt @@ -9,13 +9,13 @@ import java.nio.file.Paths object HashUtil { fun calculateMD5(src: String): String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - calculateMD5API26(src) + calculateMD5Api26(src) } else { - calculateMD5PRE26(src) + calculateMD5Api24(src) } - private fun calculateMD5PRE26(src: String) = DigestUtils.md5Hex(FileInputStream(src)) + private fun calculateMD5Api24(src: String) = DigestUtils.md5Hex(FileInputStream(src)) @TargetApi(Build.VERSION_CODES.O) - private fun calculateMD5API26(src: String) = DigestUtils.md5Hex(Files.newInputStream(Paths.get(src))) + private fun calculateMD5Api26(src: String) = DigestUtils.md5Hex(Files.newInputStream(Paths.get(src))) } diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt index b9811dcc57..2259adebe9 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/NotificationUtil.kt @@ -1,7 +1,6 @@ package com.xayah.core.util import android.Manifest -import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent @@ -75,13 +74,8 @@ object NotificationUtil { val notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) - - Notification.Builder(context, ForegroundServiceChannelId) - .setContentIntent(pendingIntent).build() - } else { - @Suppress("DEPRECATION") - Notification.Builder(context).setContentIntent(pendingIntent).build() } + NotificationCompat.Builder(context, ForegroundServiceChannelId).setContentIntent(pendingIntent).build() } fun getProgressNotificationBuilder(context: Context) = diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt index e7bdbd355e..621324673a 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/PathUtil.kt @@ -36,13 +36,22 @@ class PathUtil @Inject constructor( @ApplicationContext private val context: Context, ) { companion object { + /** + * Returns the parent path, or empty string if this path does not have a parent. + */ fun getParentPath(path: String): String { - assert(path.contains('/') && path != "/") { "Path doesn't have any parent" } + if (path.contains('/').not() || path == "/") return "" val child = path.substring(path.lastIndexOf('/')) - return path.replace(child, "", false) + return path.replace(child, "") } - fun getFileName(path: String): String = path.substring(path.lastIndexOf('/') + 1) + /** + * Returns the name of the file or directory denoted by this path, or empty string if this path has zero elements. + */ + fun getFileName(path: String): String { + if (path.isEmpty()) return "" + return path.substring(path.lastIndexOf('/') + 1) + } // Paths for processing. @SuppressLint("SdCardPath") diff --git a/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt b/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt index b8e760d42d..ef50a66d33 100644 --- a/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt +++ b/source/core/util/src/main/kotlin/com/xayah/core/util/command/BaseUtil.kt @@ -45,6 +45,7 @@ private class EnvInitializer : Shell.Initializer() { .add("set -o pipefail") // Ensure that the exit code of each command is correct. .add("alias tar=${QUOTE}busybox tar$QUOTE") .add("alias awk=${QUOTE}busybox awk$QUOTE") + .add("alias ps=${QUOTE}busybox ps$QUOTE") .exec() } } @@ -124,14 +125,12 @@ object BaseUtil { } suspend fun kill(context: Context, vararg keys: String) { - execute("echo \$PATH", shell = getNewShell(context), timeout = -1) - - // ps -A | grep -w $key1 | grep -w $key2 | ... | awk 'NF>1{print $2}' | xargs kill -9 + // ps -A | grep -w $key1 | grep -w $key2 | ... | awk 'NF>1{print $1}' | xargs kill -9 val keysArg = keys.map { "| grep -w $it" }.toTypedArray() execute( - "busybox ps -A", + "ps -A", *keysArg, - "| cut -f2 -d' '", + "| awk 'NF>1{print ${USD}1}'", "| xargs kill -9", shell = getNewShell(context), timeout = -1 From 84165823219d1173ab883d8b4312ac24a6d7b95f Mon Sep 17 00:00:00 2001 From: Xayah Date: Sun, 14 Jul 2024 11:01:57 +0800 Subject: [PATCH 3/6] fix: Lint error Change-Id: Id73058e7143bf137b1e5c5526661c4134531e6f7 --- .../java/com/android/providers/settings/SettingsStateApi31.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/core/systemapi/src/main/java/com/android/providers/settings/SettingsStateApi31.java b/source/core/systemapi/src/main/java/com/android/providers/settings/SettingsStateApi31.java index 1082d7a8db..c15ad98bc6 100644 --- a/source/core/systemapi/src/main/java/com/android/providers/settings/SettingsStateApi31.java +++ b/source/core/systemapi/src/main/java/com/android/providers/settings/SettingsStateApi31.java @@ -16,6 +16,7 @@ package com.android.providers.settings; +import android.annotation.TargetApi; import android.os.Build; import android.os.FileUtils; import android.os.Handler; @@ -66,6 +67,7 @@ * the same lock to grab the current state to write to disk. *

*/ +@TargetApi(Build.VERSION_CODES.S) public class SettingsStateApi31 implements SettingsState { private static final boolean DEBUG = false; private static final boolean DEBUG_PERSISTENCE = false; From fa05c4432a7eae6b146ac5a9436d63630c2f4a74 Mon Sep 17 00:00:00 2001 From: Xayah Date: Sun, 14 Jul 2024 12:51:39 +0800 Subject: [PATCH 4/6] feat: Update libpickyou Change-Id: Ieecd715229c4c77fd6575e88065982812ab30520 --- source/app/src/main/AndroidManifest.xml | 2 -- .../kotlin/com/xayah/core/network/client/FTPClientImpl.kt | 3 +-- .../kotlin/com/xayah/core/network/client/SFTPClientImpl.kt | 3 +-- .../kotlin/com/xayah/core/network/client/SMBClientImpl.kt | 3 +-- .../com/xayah/core/network/client/WebDAVClientImpl.kt | 3 +-- source/gradle/libs.versions.toml | 6 +++--- 6 files changed, 7 insertions(+), 13 deletions(-) diff --git a/source/app/src/main/AndroidManifest.xml b/source/app/src/main/AndroidManifest.xml index 181c2cfdcc..a8223ef450 100644 --- a/source/app/src/main/AndroidManifest.xml +++ b/source/app/src/main/AndroidManifest.xml @@ -2,8 +2,6 @@ - - runCatching { mkdirRecursively(handleOriginalPath("$parent/$child")) }.isSuccess } diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt index 3c1d44cdbe..c7cb9b2882 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SFTPClientImpl.kt @@ -28,7 +28,6 @@ import net.schmizz.sshj.userauth.password.PasswordFinder import net.schmizz.sshj.userauth.password.Resource import java.io.File import java.io.FileOutputStream -import kotlin.io.path.pathString class SFTPClientImpl(private val entity: CloudEntity, private val extra: SFTPExtra) : CloudClient { @@ -221,7 +220,7 @@ class SFTPClientImpl(private val entity: CloudEntity, private val extra: SFTPExt connect() PickYouLauncher.apply { val prefix = "${context.getString(R.string.cloud)}:" - sTraverseBackend = { listFiles(it.pathString.replaceFirst(prefix, ".")) } + sTraverseBackend = { listFiles(it.replaceFirst(prefix, ".")) } sMkdirsBackend = { parent, child -> runCatching { mkdirRecursively(handleOriginalPath("$parent/$child")) }.isSuccess } diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt index def59beaa8..c697e61e98 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/SMBClientImpl.kt @@ -42,7 +42,6 @@ import com.xayah.libpickyou.ui.model.PickerType import java.io.File import java.io.FileInputStream import java.io.IOException -import kotlin.io.path.pathString class SMBClientImpl(private val entity: CloudEntity, private val extra: SMBExtra) : CloudClient { @@ -343,7 +342,7 @@ class SMBClientImpl(private val entity: CloudEntity, private val extra: SMBExtra connect() PickYouLauncher.apply { val prefix = "${context.getString(R.string.cloud)}:" - sTraverseBackend = { listFiles(it.pathString.replaceFirst(prefix, "")) } + sTraverseBackend = { listFiles(it.replaceFirst(prefix, "")) } sMkdirsBackend = { parent, child -> val (_, target) = handleOriginalPath("$parent/$child") runCatching { mkdirRecursively(target) }.isSuccess diff --git a/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt b/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt index fc5f72fbed..8da9579f31 100644 --- a/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt +++ b/source/core/network/src/main/kotlin/com/xayah/core/network/client/WebDAVClientImpl.kt @@ -17,7 +17,6 @@ import com.xayah.libsardine.impl.OkHttpSardine import okhttp3.OkHttpClient import java.io.File import java.util.concurrent.TimeUnit -import kotlin.io.path.pathString class WebDAVClientImpl(private val entity: CloudEntity) : CloudClient { private var client: OkHttpSardine? = null @@ -191,7 +190,7 @@ class WebDAVClientImpl(private val entity: CloudEntity) : CloudClient { connect() PickYouLauncher.apply { val prefix = "${context.getString(R.string.cloud)}:" - sTraverseBackend = { listFiles(it.pathString.replaceFirst(prefix, "")) } + sTraverseBackend = { listFiles(it.replaceFirst(prefix, "")) } sMkdirsBackend = { parent, child -> runCatching { mkdirRecursively(handleOriginalPath("$parent/$child")) }.isSuccess } diff --git a/source/gradle/libs.versions.toml b/source/gradle/libs.versions.toml index a64f80ddd6..bbe0890b74 100644 --- a/source/gradle/libs.versions.toml +++ b/source/gradle/libs.versions.toml @@ -17,7 +17,7 @@ appcompat = "1.7.0" androidx-test-ext-junit = "1.1.5" espresso-core = "3.5.1" junit = "4.13.2" -compose-bom = "2024.06.00" +compose-bom = "2024.05.00" core-ktx = "1.13.1" core-splashscreen = "1.0.1" gson = "2.10.1" @@ -27,7 +27,7 @@ hilt-navigation-compose = "1.2.0" navigation-compose = "2.7.7" okhttp = "4.12.0" retrofit = "2.9.0" -libsu = "6.0.0" # TODO Force enable the latest libsu +libsu = "PR182-SNAPSHOT" # TODO Force enable the latest libsu zip4j = "2.11.5" kotlinx-coroutines-core-jvm = "1.8.0" room = "2.6.1" @@ -37,7 +37,7 @@ palette = "1.0.0" google-services = "4.3.15" # Pinned: https://github.com/firebase/firebase-android-sdk/issues/4693#issuecomment-1765778239 firebase-crashlytics-gradle = "2.9.9" # Workaround: https://github.com/xamarin/GooglePlayServicesComponents/issues/642#issuecomment-1221520982 firebase-bom = "32.7.0" -pickyou = "2.1.7" +pickyou = "2.1.8" datastore-preferences = "1.1.1" serialization-protobuf = "1.6.0" apache-commons = "3.10.0" From 1a9728f2172d5f563dafe25ad5bc066b6746865c Mon Sep 17 00:00:00 2001 From: Xayah Date: Sun, 14 Jul 2024 20:50:12 +0800 Subject: [PATCH 5/6] fix: Set tmp files context before uploading Change-Id: I7a0dd1452fb188588ef8854fc671572e5efedbfb --- .../kotlin/com/xayah/core/data/repository/CloudRepository.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/core/data/src/main/kotlin/com/xayah/core/data/repository/CloudRepository.kt b/source/core/data/src/main/kotlin/com/xayah/core/data/repository/CloudRepository.kt index 2a2002fd77..473e54da83 100644 --- a/source/core/data/src/main/kotlin/com/xayah/core/data/repository/CloudRepository.kt +++ b/source/core/data/src/main/kotlin/com/xayah/core/data/repository/CloudRepository.kt @@ -42,6 +42,7 @@ class CloudRepository @Inject constructor( var isSuccess = true val out = mutableListOf() + PathUtil.setFilesDirSELinux(context) runCatching { client.upload(src = src, dst = dstDir, onUploading = onUploading) From 147f395f75e1f131bf62757b7a3aa61991b06ed2 Mon Sep 17 00:00:00 2001 From: Xayah Date: Sun, 14 Jul 2024 21:50:06 +0800 Subject: [PATCH 6/6] fix: Hide auto theme option from sdk 24 to sdk 28 Change-Id: Ia08410042f3c375424d162e9bea73806e8f096d9 --- .../com/xayah/core/model/util/ModelUtil.kt | 3 +- .../com/xayah/feature/main/settings/Item.kt | 50 ++++++++++++------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/source/core/model/src/main/kotlin/com/xayah/core/model/util/ModelUtil.kt b/source/core/model/src/main/kotlin/com/xayah/core/model/util/ModelUtil.kt index cac168db97..8f9f2ab99f 100644 --- a/source/core/model/src/main/kotlin/com/xayah/core/model/util/ModelUtil.kt +++ b/source/core/model/src/main/kotlin/com/xayah/core/model/util/ModelUtil.kt @@ -1,5 +1,6 @@ package com.xayah.core.model.util +import android.os.Build import com.xayah.core.model.CompressionType import com.xayah.core.model.KillAppOption import com.xayah.core.model.LZ4_SUFFIX @@ -53,7 +54,7 @@ fun SelectionType.Companion.of(name: String?): SelectionType = runCatching { SelectionType.valueOf(name!!.uppercase()) }.getOrDefault(SelectionType.DEFAULT) fun ThemeType.Companion.of(name: String?): ThemeType = - runCatching { ThemeType.valueOf(name!!.uppercase()) }.getOrDefault(ThemeType.AUTO) + runCatching { ThemeType.valueOf(name!!.uppercase()) }.getOrDefault(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) ThemeType.AUTO else ThemeType.LIGHT_THEME) fun SmbAuthMode.Companion.indexOf(index: Int): SmbAuthMode = when (index) { 1 -> SmbAuthMode.GUEST diff --git a/source/feature/main/settings/src/main/kotlin/com/xayah/feature/main/settings/Item.kt b/source/feature/main/settings/src/main/kotlin/com/xayah/feature/main/settings/Item.kt index 5990ac57e9..b1cd007e25 100644 --- a/source/feature/main/settings/src/main/kotlin/com/xayah/feature/main/settings/Item.kt +++ b/source/feature/main/settings/src/main/kotlin/com/xayah/feature/main/settings/Item.kt @@ -1,5 +1,6 @@ package com.xayah.feature.main.settings +import android.os.Build import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -22,23 +23,38 @@ fun DarkThemeSelectable() { val context = LocalContext.current val dialogState = LocalSlotScope.current!!.dialogSlot val items = remember { - listOf( - DialogRadioItem( - enum = ThemeType.AUTO, - title = StringResourceToken.fromStringId(R.string.theme_auto), - desc = StringResourceToken.fromStringId(R.string.theme_auto_desc), - ), - DialogRadioItem( - enum = ThemeType.LIGHT_THEME, - title = StringResourceToken.fromStringId(R.string.theme_light), - desc = StringResourceToken.fromStringId(R.string.theme_light_desc), - ), - DialogRadioItem( - enum = ThemeType.DARK_THEME, - title = StringResourceToken.fromStringId(R.string.theme_dark), - desc = StringResourceToken.fromStringId(R.string.theme_dark_desc), - ), - ) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + listOf( + DialogRadioItem( + enum = ThemeType.AUTO, + title = StringResourceToken.fromStringId(R.string.theme_auto), + desc = StringResourceToken.fromStringId(R.string.theme_auto_desc), + ), + DialogRadioItem( + enum = ThemeType.LIGHT_THEME, + title = StringResourceToken.fromStringId(R.string.theme_light), + desc = StringResourceToken.fromStringId(R.string.theme_light_desc), + ), + DialogRadioItem( + enum = ThemeType.DARK_THEME, + title = StringResourceToken.fromStringId(R.string.theme_dark), + desc = StringResourceToken.fromStringId(R.string.theme_dark_desc), + ), + ) + } else { + listOf( + DialogRadioItem( + enum = ThemeType.LIGHT_THEME, + title = StringResourceToken.fromStringId(R.string.theme_light), + desc = StringResourceToken.fromStringId(R.string.theme_light_desc), + ), + DialogRadioItem( + enum = ThemeType.DARK_THEME, + title = StringResourceToken.fromStringId(R.string.theme_dark), + desc = StringResourceToken.fromStringId(R.string.theme_dark_desc), + ), + ) + } } val currentType by observeCurrentTheme() val currentIndex by remember(currentType) { mutableIntStateOf(items.indexOfFirst { it.enum == currentType }) }