Skip to content

Commit 7564c75

Browse files
committed
Change-Id: I4ace7833f518e9db622f8ed9f3fc826eb0488650
1 parent c099f13 commit 7564c75

File tree

3 files changed

+160
-30
lines changed

3 files changed

+160
-30
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@
6363
<action android:name="android.provider.Telephony.SMS_DELIVER" />
6464
</intent-filter>
6565
</receiver>
66+
6667
<service
6768
android:name=".services.SmsSendService"
6869
android:exported="true"
6970
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE">
7071
<intent-filter>
7172
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
7273
<category android:name="android.intent.category.DEFAULT" />
74+
7375
<data android:scheme="sms" />
7476
<data android:scheme="smsto" />
7577
<data android:scheme="mms" />
@@ -110,12 +112,14 @@
110112
<activity
111113
android:name=".ui.activity.list.telephony.TelephonyActivity"
112114
android:exported="false">
113-
<!-- Workaround for SMS/MMS handling -->
115+
<!-- SMS/MMS handling -->
114116
<intent-filter>
115117
<action android:name="android.intent.action.SEND" />
116118
<action android:name="android.intent.action.SENDTO" />
119+
117120
<category android:name="android.intent.category.DEFAULT" />
118121
<category android:name="android.intent.category.BROWSABLE" />
122+
119123
<data android:scheme="sms" />
120124
<data android:scheme="smsto" />
121125
<data android:scheme="mms" />
@@ -131,6 +135,20 @@
131135

132136
<category android:name="android.intent.category.LAUNCHER" />
133137
</intent-filter>
138+
139+
<!-- Workaround for Android 14 on certain devices -->
140+
<intent-filter>
141+
<action android:name="android.intent.action.SEND" />
142+
<action android:name="android.intent.action.SENDTO" />
143+
144+
<category android:name="android.intent.category.DEFAULT" />
145+
<category android:name="android.intent.category.BROWSABLE" />
146+
147+
<data android:scheme="sms" />
148+
<data android:scheme="smsto" />
149+
<data android:scheme="mms" />
150+
<data android:scheme="mmsto" />
151+
</intent-filter>
134152
</activity>
135153
</application>
136154
</manifest>

librootservice/src/main/java/com/xayah/databackup/librootservice/RootService.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,28 @@ class RootService {
147147
return getService().closeMemoryFile()
148148
}
149149

150-
fun readTextByDescriptor(path: String): String {
151-
var text = ""
152-
try {
153-
val fileDescriptor = readByDescriptor(path)
154-
val fileInputStream = FileInputStream(fileDescriptor.fileDescriptor)
155-
text = String(fileInputStream.readBytes())
156-
closeMemoryFile()
157-
} catch (_: Exception) {
158-
}
159-
return text
150+
private fun readFromParcel(pfd: ParcelFileDescriptor, onRead: (Parcel) -> Unit) = run {
151+
val stream = ParcelFileDescriptor.AutoCloseInputStream(pfd)
152+
val bytes = stream.readBytes()
153+
val parcel = Parcel.obtain()
154+
155+
parcel.unmarshall(bytes, 0, bytes.size)
156+
parcel.setDataPosition(0)
157+
158+
onRead(parcel)
159+
160+
parcel.recycle()
160161
}
161162

163+
fun readTextByDescriptor(path: String): String = runCatching {
164+
val pfd = getService().readByDescriptor(path)
165+
var text: String? = null
166+
readFromParcel(pfd) {
167+
text = it.readString()
168+
}
169+
text ?: ""
170+
}.getOrElse { "" }
171+
162172
fun readBytesByDescriptor(path: String): ByteArray {
163173
var bytes = ByteArray(0)
164174
try {

librootservice/src/main/java/com/xayah/databackup/librootservice/service/RemoteRootServiceImpl.kt

Lines changed: 121 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import android.content.Context
88
import android.content.pm.*
99
import android.content.pm.PackageManager.PackageInfoFlags
1010
import android.os.*
11+
import com.topjohnwu.superuser.ShellUtils
1112
import com.xayah.databackup.libhiddenapi.HiddenApiBypassUtil
1213
import com.xayah.databackup.librootservice.IRemoteRootService
1314
import com.xayah.databackup.librootservice.parcelables.StatFsParcelable
@@ -31,6 +32,32 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
3132

3233
private lateinit var memoryFile: MemoryFile
3334

35+
companion object {
36+
const val ParcelTmpFilePath = "/data/local/tmp"
37+
const val ParcelTmpFileName = "data_backup_tmp"
38+
}
39+
40+
init {
41+
/**
42+
* If [ParcelTmpFilePath] has incorrect SELinux context, the transaction will get failed:
43+
* Fatal Exception: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died, but this could also be caused by running out of binder buffe
44+
* Correct SELinux context should be: u:object_r:shell_data_file:s0
45+
*
46+
* If [ParcelTmpFilePath] doesn't exist, the transaction will failed:
47+
* pfd must not be null
48+
*/
49+
ShellUtils.fastCmd(
50+
"""
51+
mkdir "$ParcelTmpFilePath/"
52+
""".trimIndent()
53+
)
54+
ShellUtils.fastCmd(
55+
"""
56+
chcon -hR "u:object_r:shell_data_file:s0" "$ParcelTmpFilePath/"
57+
""".trimIndent()
58+
)
59+
}
60+
3461
/**
3562
* 获取systemContext
3663
*/
@@ -136,7 +163,10 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
136163
return FileVisitResult.CONTINUE
137164
}
138165

139-
override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult {
166+
override fun preVisitDirectory(
167+
dir: Path?,
168+
attrs: BasicFileAttributes?
169+
): FileVisitResult {
140170
return FileVisitResult.CONTINUE
141171
}
142172

@@ -153,6 +183,22 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
153183
return size.get()
154184
}
155185

186+
private fun writeToParcel(onWrite: (Parcel) -> Unit) = run {
187+
val parcel = Parcel.obtain()
188+
parcel.setDataPosition(0)
189+
190+
onWrite(parcel)
191+
192+
val tmp = File(ParcelTmpFilePath, ParcelTmpFileName)
193+
tmp.createNewFile()
194+
tmp.writeBytes(parcel.marshall())
195+
val pfd = ParcelFileDescriptor.open(tmp, ParcelFileDescriptor.MODE_READ_WRITE)
196+
tmp.deleteRecursively()
197+
198+
parcel.recycle()
199+
pfd
200+
}
201+
156202
override fun readText(path: String): String {
157203
return try {
158204
val file = File(path)
@@ -173,11 +219,9 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
173219

174220
override fun readByDescriptor(path: String): ParcelFileDescriptor {
175221
synchronized(this) {
176-
val bytes = File(path).readBytes()
177-
memoryFile = MemoryFile("memoryFileDataBackupRead", bytes.size).apply {
178-
writeBytes(bytes, 0, 0, bytes.size)
222+
return writeToParcel { parcel ->
223+
parcel.writeString(runCatching { File(path).readText() }.getOrElse { "" })
179224
}
180-
return ParcelFileDescriptor.dup(MemoryFileHidden.getFileDescriptor(memoryFile))
181225
}
182226
}
183227

@@ -272,7 +316,11 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
272316
override fun offerInstalledPackagesAsUser(flags: Int, userId: Int): Boolean {
273317
return try {
274318
packageInfoQueue.clear()
275-
PackageManagerHidden.getInstalledPackagesAsUser(systemContext.packageManager, flags, userId).forEach {
319+
PackageManagerHidden.getInstalledPackagesAsUser(
320+
systemContext.packageManager,
321+
flags,
322+
userId
323+
).forEach {
276324
packageInfoQueue.offer(it)
277325
}
278326
true
@@ -301,8 +349,16 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
301349
val packages = mutableListOf<PackageInfo>()
302350
try {
303351
for (userId in UserManagerHidden.getUsers(userManager = userManager).toMutableList()) {
304-
PackageManagerHidden.getInstalledPackagesAsUser(systemContext.packageManager, 0, userId.id).forEach {
305-
if (PackageManagerHidden.isPackageSuspended(systemContext.packageManager, it.packageName))
352+
PackageManagerHidden.getInstalledPackagesAsUser(
353+
systemContext.packageManager,
354+
0,
355+
userId.id
356+
).forEach {
357+
if (PackageManagerHidden.isPackageSuspended(
358+
systemContext.packageManager,
359+
it.packageName
360+
)
361+
)
306362
packages.add(it)
307363
}
308364
}
@@ -312,15 +368,23 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
312368
}
313369

314370
override fun getPackageArchiveInfo(path: String): PackageInfo? {
315-
return systemContext.packageManager.getPackageArchiveInfo(path, PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong()))?.apply {
371+
return systemContext.packageManager.getPackageArchiveInfo(
372+
path,
373+
PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong())
374+
)?.apply {
316375
applicationInfo?.sourceDir = path
317376
applicationInfo?.publicSourceDir = path
318377
}
319378
}
320379

321380
override fun queryInstalled(packageName: String, userId: Int): Boolean {
322381
return try {
323-
PackageManagerHidden.getPackageInfoAsUser(systemContext.packageManager, packageName, 0, userId)
382+
PackageManagerHidden.getPackageInfoAsUser(
383+
systemContext.packageManager,
384+
packageName,
385+
0,
386+
userId
387+
)
324388
true
325389
} catch (_: Exception) {
326390
false
@@ -335,9 +399,18 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
335399
)
336400
}
337401

338-
override fun grantRuntimePermission(packageName: String, permName: String, userId: Int): Boolean {
402+
override fun grantRuntimePermission(
403+
packageName: String,
404+
permName: String,
405+
userId: Int
406+
): Boolean {
339407
return try {
340-
PackageManagerHidden.grantRuntimePermission(systemContext.packageManager, packageName, permName, getUserHandle(userId))
408+
PackageManagerHidden.grantRuntimePermission(
409+
systemContext.packageManager,
410+
packageName,
411+
permName,
412+
getUserHandle(userId)
413+
)
341414
true
342415
} catch (_: Exception) {
343416
false
@@ -347,7 +420,12 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
347420
override fun displayPackageFilePath(packageName: String, userId: Int): List<String> {
348421
return try {
349422
val list = mutableListOf<String>()
350-
val packageInfo = PackageManagerHidden.getPackageInfoAsUser(systemContext.packageManager, packageName, 0, userId)
423+
val packageInfo = PackageManagerHidden.getPackageInfoAsUser(
424+
systemContext.packageManager,
425+
packageName,
426+
0,
427+
userId
428+
)
351429
list.add(packageInfo.applicationInfo.sourceDir)
352430
val splitSourceDirs = packageInfo.applicationInfo.splitSourceDirs
353431
if (splitSourceDirs != null && splitSourceDirs.isNotEmpty())
@@ -361,7 +439,14 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
361439

362440
override fun setPackagesSuspended(packageNames: Array<String>, suspended: Boolean): Boolean {
363441
return try {
364-
PackageManagerHidden.setPackagesSuspended(systemContext.packageManager, packageNames, suspended, null, null, null)
442+
PackageManagerHidden.setPackagesSuspended(
443+
systemContext.packageManager,
444+
packageNames,
445+
suspended,
446+
null,
447+
null,
448+
null
449+
)
365450
true
366451
} catch (_: Exception) {
367452
false
@@ -370,7 +455,12 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
370455

371456
override fun getPackageUid(packageName: String, userId: Int): Int {
372457
return try {
373-
val packageInfo = PackageManagerHidden.getPackageInfoAsUser(systemContext.packageManager, packageName, 0, userId)
458+
val packageInfo = PackageManagerHidden.getPackageInfoAsUser(
459+
systemContext.packageManager,
460+
packageName,
461+
0,
462+
userId
463+
)
374464
packageInfo.applicationInfo.uid
375465
} catch (_: Exception) {
376466
-1
@@ -379,18 +469,30 @@ class RemoteRootServiceImpl : IRemoteRootService.Stub() {
379469

380470
override fun getPackageLongVersionCode(packageName: String, userId: Int): Long {
381471
return try {
382-
val packageInfo = PackageManagerHidden.getPackageInfoAsUser(systemContext.packageManager, packageName, 0, userId)
472+
val packageInfo = PackageManagerHidden.getPackageInfoAsUser(
473+
systemContext.packageManager,
474+
packageName,
475+
0,
476+
userId
477+
)
383478
packageInfo.longVersionCode
384479
} catch (_: Exception) {
385480
-1L
386481
}
387482
}
388483

389-
override fun setApplicationEnabledSetting(packageName: String, newState: Int, flags: Int, userId: Int) {
390-
IPackageManager.Stub.asInterface(serviceManager).setApplicationEnabledSetting(packageName, newState, flags, userId, null)
484+
override fun setApplicationEnabledSetting(
485+
packageName: String,
486+
newState: Int,
487+
flags: Int,
488+
userId: Int
489+
) {
490+
IPackageManager.Stub.asInterface(serviceManager)
491+
.setApplicationEnabledSetting(packageName, newState, flags, userId, null)
391492
}
392493

393494
override fun getApplicationEnabledSetting(packageName: String, userId: Int): Int {
394-
return IPackageManager.Stub.asInterface(serviceManager).getApplicationEnabledSetting(packageName, userId)
495+
return IPackageManager.Stub.asInterface(serviceManager)
496+
.getApplicationEnabledSetting(packageName, userId)
395497
}
396498
}

0 commit comments

Comments
 (0)