Skip to content

Commit 720583b

Browse files
committed
Merge branch 'main' into pr-428
# Conflicts: # app/src/main/java/dev/bluehouse/enablevolte/Moder.kt
2 parents 1c2a82e + 68a35e6 commit 720583b

8 files changed

Lines changed: 115 additions & 117 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ English version available [here](https://github.com/kyujin-cho/pixel-volte-patch
6565
### Pixel IMS 애플리케이션 설치
6666

6767
1. 현재 다음 두 가지 방법으로 Pixel IMS 앱을 설치할 수 있습니다.
68-
- [Github Releases](https://github.com/kyujin-cho/pixel-volte-patch/releases/download/1.3.1/dev.bluehouse.enablevolte.apk) 에서 APK 다운로드 후 설치
68+
- [Github Releases](https://github.com/kyujin-cho/pixel-volte-patch/releases/download/1.3.2/dev.bluehouse.enablevolte.apk) 에서 APK 다운로드 후 설치
6969
- [Play Store](https://play.google.com/store/apps/details?id=dev.bluehouse.enablevolte) 에서 다운로드
7070
2. 설치한 애플리케이션을 실행합니다.
7171
3. 다음과 같이 Shizuku 권한을 묻는 팝업 창이 뜰 경우 "모든 경우에 허용" 을 선택합니다.

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ android {
1212
applicationId "dev.bluehouse.enablevolte"
1313
minSdk 28
1414
targetSdk 36
15-
versionCode 15
16-
versionName "1.3.1"
15+
versionCode 16
16+
versionName "1.3.2"
1717

1818
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1919
vectorDrawables {

app/src/main/java/dev/bluehouse/enablevolte/BrokerInstrumentation.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class BrokerInstrumentation : Instrumentation() {
2626
val configurationManager = this.context.getSystemService(CarrierConfigManager::class.java)
2727

2828
try {
29-
configurationManager.overrideConfig(subId, overrideValues, overrideConfigPersistent)
29+
configurationManager.overrideConfig(subId, overrideValues, configPersistent)
3030
} catch (e: NoSuchMethodError) {
3131
configurationManager.overrideConfig(subId, overrideValues)
3232
}

app/src/main/java/dev/bluehouse/enablevolte/Moder.kt

Lines changed: 105 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import android.os.Build.VERSION_CODES
1010
import android.os.Bundle
1111
import android.os.IInterface
1212
import android.os.PersistableBundle
13+
import android.os.ServiceManager
1314
import android.telephony.CarrierConfigManager
1415
import android.telephony.SubscriptionInfo
1516
import android.telephony.TelephonyFrameworkInitializer
@@ -31,7 +32,7 @@ object InterfaceCache {
3132
val cache = HashMap<String, IInterface>()
3233
}
3334

34-
var overrideConfigPersistent by mutableStateOf(true)
35+
var configPersistent by mutableStateOf(true)
3536

3637
open class Moder {
3738
@Suppress("ktlint:standard:property-naming")
@@ -51,43 +52,55 @@ open class Moder {
5152
get() =
5253
ICarrierConfigLoader.Stub.asInterface(
5354
ShizukuBinderWrapper(
54-
TelephonyFrameworkInitializer
55-
.getTelephonyServiceManager()
56-
.carrierConfigServiceRegisterer
57-
.get()!!,
55+
try {
56+
TelephonyFrameworkInitializer
57+
.getTelephonyServiceManager()
58+
.carrierConfigServiceRegisterer
59+
.get()
60+
} catch (_: NoClassDefFoundError) {
61+
ServiceManager.getService(Context.CARRIER_CONFIG_SERVICE)
62+
}!!,
5863
),
5964
)
6065

6166
protected val telephony: ITelephony
6267
get() =
6368
ITelephony.Stub.asInterface(
6469
ShizukuBinderWrapper(
65-
TelephonyFrameworkInitializer
66-
.getTelephonyServiceManager()
67-
.telephonyServiceRegisterer
68-
.get()!!,
70+
try {
71+
TelephonyFrameworkInitializer
72+
.getTelephonyServiceManager()
73+
.telephonyServiceRegisterer
74+
.get()
75+
} catch (_: NoClassDefFoundError) {
76+
ServiceManager.getService(Context.TELEPHONY_SERVICE)
77+
}!!,
6978
),
7079
)
7180

72-
protected val phoneSubInfo: IPhoneSubInfo
81+
protected val phoneSubInfo: IPhoneSubInfo?
7382
get() =
74-
IPhoneSubInfo.Stub.asInterface(
75-
ShizukuBinderWrapper(
76-
TelephonyFrameworkInitializer
77-
.getTelephonyServiceManager()
78-
.phoneSubServiceRegisterer
79-
.get()!!,
80-
),
81-
)
83+
try {
84+
TelephonyFrameworkInitializer
85+
.getTelephonyServiceManager()
86+
.phoneSubServiceRegisterer
87+
.get()
88+
} catch (_: NoClassDefFoundError) {
89+
ServiceManager.getService("iphonesubinfo")
90+
}?.let { IPhoneSubInfo.Stub.asInterface(ShizukuBinderWrapper(it)) }
8291

8392
protected val sub: ISub
8493
get() =
8594
ISub.Stub.asInterface(
8695
ShizukuBinderWrapper(
87-
TelephonyFrameworkInitializer
88-
.getTelephonyServiceManager()
89-
.subscriptionServiceRegisterer
90-
.get()!!,
96+
try {
97+
TelephonyFrameworkInitializer
98+
.getTelephonyServiceManager()
99+
.subscriptionServiceRegisterer
100+
.get()
101+
} catch (_: NoClassDefFoundError) {
102+
ServiceManager.getService("isub")
103+
}!!,
91104
),
92105
)
93106
}
@@ -97,24 +110,41 @@ class CarrierModer(
97110
) : Moder() {
98111
fun getActiveSubscriptionInfoForSimSlotIndex(index: Int): SubscriptionInfo? {
99112
val sub = this.loadCachedInterface { sub }
100-
return sub.getActiveSubscriptionInfoForSimSlotIndex(index, null, null)
113+
return try {
114+
sub.getActiveSubscriptionInfoForSimSlotIndex(index, null, null)
115+
} catch (_: NoSuchMethodError) {
116+
val getActiveSubscriptionInfoForSimSlotIndexMethod =
117+
sub.javaClass.getMethod(
118+
"getActiveSubscriptionInfoForSimSlotIndex",
119+
Int::class.javaPrimitiveType,
120+
String::class.java,
121+
)
122+
(getActiveSubscriptionInfoForSimSlotIndexMethod.invoke(sub, index, null) as? SubscriptionInfo)
123+
}
101124
}
102125

103126
val subscriptions: List<SubscriptionInfo>
104127
get() {
105128
val sub = this.loadCachedInterface { sub }
106129
return try {
107-
sub.getActiveSubscriptionInfoList(null, null, true)
108-
} catch (e: NoSuchMethodError) {
109-
// FIXME: lift up reflect as soon as official source code releases
130+
sub.getActiveSubscriptionInfoList(null, null, true) ?: emptyList()
131+
} catch (_: NoSuchMethodError) {
132+
null
133+
} ?: try {
110134
val getActiveSubscriptionInfoListMethod =
111135
sub.javaClass.getMethod(
112136
"getActiveSubscriptionInfoList",
113137
String::class.java,
114138
String::class.java,
115-
Boolean::class.java,
116139
)
117-
(getActiveSubscriptionInfoListMethod.invoke(sub, null, null, false) as List<SubscriptionInfo>)
140+
(getActiveSubscriptionInfoListMethod.invoke(sub, null, null) as? List<SubscriptionInfo>) ?: emptyList()
141+
} catch (_: NoSuchMethodException) {
142+
val getActiveSubscriptionInfoListMethod =
143+
sub.javaClass.getMethod(
144+
"getActiveSubscriptionInfoList",
145+
String::class.java,
146+
)
147+
(getActiveSubscriptionInfoListMethod.invoke(sub, null) as? List<SubscriptionInfo>) ?: emptyList()
118148
}
119149
}
120150

@@ -137,14 +167,14 @@ class SubscriptionModer(
137167
val subscriptionId: Int,
138168
) : Moder() {
139169
@Suppress("ktlint:standard:property-naming")
140-
private val TAG = "CarrierModer"
170+
private val TAG = "SubscriptionModer"
141171

142172
private fun overrideConfigDirectly(bundle: Bundle?) {
143173
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
144174
val args = bundle?.let(::toPersistableBundle)
145175

146176
try {
147-
iCclInstance.overrideConfig(subscriptionId, args, overrideConfigPersistent)
177+
iCclInstance.overrideConfig(subscriptionId, args, configPersistent)
148178
} catch (e: NoSuchMethodError) {
149179
val overrideConfigMethod =
150180
iCclInstance.javaClass.getMethod(
@@ -153,7 +183,7 @@ class SubscriptionModer(
153183
PersistableBundle::class.java,
154184
)
155185
overrideConfigMethod.invoke(iCclInstance, subscriptionId, args)
156-
if (overrideConfigPersistent) {
186+
if (configPersistent) {
157187
throw e
158188
}
159189
}
@@ -191,15 +221,18 @@ class SubscriptionModer(
191221
val securityPatchDate =
192222
try {
193223
LocalDate.parse(Build.VERSION.SECURITY_PATCH)
194-
} catch (e: DateTimeParseException) {
224+
} catch (_: DateTimeParseException) {
195225
null
196226
}
197227
if (securityPatchDate == null || securityPatchDate.isBefore(LocalDate.of(2025, 10, 1))) {
198228
try {
199229
return this.overrideConfigDirectly(bundle)
200-
} catch (e: SecurityException) {
201-
} catch (e: NoSuchMethodError) {
202-
} catch (e: NoSuchMethodException) {
230+
} catch (_: SecurityException) {
231+
} catch (_: NoSuchMethodError) {
232+
} catch (_: NoSuchMethodException) {
233+
}
234+
if (!configPersistent) {
235+
return
203236
}
204237
}
205238
this.overrideConfigUsingBroker(bundle)
@@ -281,111 +314,76 @@ class SubscriptionModer(
281314

282315
fun restartIMSRegistration() {
283316
val telephony = this.loadCachedInterface { telephony }
284-
val sub = this.loadCachedInterface { sub }
285317
try {
286-
telephony.resetIms(sub.getSlotIndex(this.subscriptionId))
287-
} catch (e: NoSuchMethodError) {
288-
telephony.disableIms(sub.getSlotIndex(this.subscriptionId))
289-
telephony.enableIms(sub.getSlotIndex(this.subscriptionId))
318+
telephony.resetIms(this.simSlotIndex)
319+
} catch (_: NoSuchMethodError) {
320+
telephony.disableIms(this.simSlotIndex)
321+
telephony.enableIms(this.simSlotIndex)
290322
}
291323
}
292324

293-
fun getStringValue(key: String): String? {
325+
fun getStringValue(key: String): String {
294326
Log.d(TAG, "Resolving string value of key $key")
295-
val subscriptionId = this.subscriptionId
296-
if (subscriptionId < 0) {
297-
return ""
298-
}
299-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
300-
301-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
302-
return config.getString(key)
327+
return this.config?.getString(key) ?: ""
303328
}
304329

305330
fun getBooleanValue(key: String): Boolean {
306331
Log.d(TAG, "Resolving boolean value of key $key")
307-
val subscriptionId = this.subscriptionId
308-
if (subscriptionId < 0) {
309-
return false
310-
}
311-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
312-
313-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
314-
return config.getBoolean(key)
332+
return this.config?.getBoolean(key) ?: false
315333
}
316334

317335
fun getIntValue(key: String): Int {
318336
Log.d(TAG, "Resolving integer value of key $key")
319-
val subscriptionId = this.subscriptionId
320-
if (subscriptionId < 0) {
321-
return -1
322-
}
323-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
324-
325-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
326-
return config.getInt(key)
337+
return this.config?.getInt(key) ?: -1
327338
}
328339

329340
fun getLongValue(key: String): Long {
330341
Log.d(TAG, "Resolving long value of key $key")
331-
val subscriptionId = this.subscriptionId
332-
if (subscriptionId < 0) {
333-
return -1
334-
}
335-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
336-
337-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
338-
return config.getLong(key)
342+
return this.config?.getLong(key) ?: -1L
339343
}
340344

341345
fun getBooleanArrayValue(key: String): BooleanArray {
342346
Log.d(TAG, "Resolving boolean array value of key $key")
343-
val subscriptionId = this.subscriptionId
344-
if (subscriptionId < 0) {
345-
return booleanArrayOf()
346-
}
347-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
348-
349-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
350-
return config.getBooleanArray(key) ?: BooleanArray(0)
347+
return this.config?.getBooleanArray(key) ?: BooleanArray(0)
351348
}
352349

353350
fun getIntArrayValue(key: String): IntArray {
354-
Log.d(TAG, "Resolving integer value of key $key")
355-
val subscriptionId = this.subscriptionId
356-
if (subscriptionId < 0) {
357-
return intArrayOf()
358-
}
359-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
360-
361-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
362-
return config.getIntArray(key) ?: IntArray(0)
351+
Log.d(TAG, "Resolving integer array value of key $key")
352+
return this.config?.getIntArray(key) ?: IntArray(0)
363353
}
364354

365355
fun getStringArrayValue(key: String): Array<String> {
366356
Log.d(TAG, "Resolving string array value of key $key")
367-
val subscriptionId = this.subscriptionId
368-
if (subscriptionId < 0) {
369-
return arrayOf()
370-
}
371-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
372-
373-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
374-
return config.getStringArray(key) ?: emptyArray()
357+
return this.config?.getStringArray(key) ?: emptyArray()
375358
}
376359

377360
fun getValue(key: String): Any? {
378361
Log.d(TAG, "Resolving value of key $key")
379-
val subscriptionId = this.subscriptionId
380-
if (subscriptionId < 0) {
381-
return null
382-
}
383-
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
384-
385-
val config = iCclInstance.getConfigForSubIdWithFeature(subscriptionId, iCclInstance.defaultCarrierServicePackageName, "")
386-
return config.get(key)
362+
return this.config?.get(key)
387363
}
388364

365+
protected val config: PersistableBundle?
366+
get() {
367+
if (this.subscriptionId < 0) {
368+
return null
369+
}
370+
val iCclInstance = this.loadCachedInterface { carrierConfigLoader }
371+
return try {
372+
iCclInstance.getConfigForSubIdWithFeature(this.subscriptionId, iCclInstance.defaultCarrierServicePackageName, null)
373+
} catch (_: NoSuchMethodError) {
374+
null
375+
} ?: try {
376+
iCclInstance.getConfigForSubId(this.subscriptionId, iCclInstance.defaultCarrierServicePackageName)
377+
} catch (_: NoSuchMethodError) {
378+
val getConfigForSubIdMethod =
379+
iCclInstance.javaClass.getMethod(
380+
"getConfigForSubId",
381+
Int::class.javaPrimitiveType,
382+
)
383+
(getConfigForSubIdMethod.invoke(iCclInstance, this.subscriptionId) as? PersistableBundle)
384+
}
385+
}
386+
389387
val simSlotIndex: Int
390388
get() = this.loadCachedInterface { sub }.getSlotIndex(subscriptionId)
391389

@@ -433,7 +431,7 @@ class SubscriptionModer(
433431
get() = this.getIntValue(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT)
434432

435433
val carrierName: String
436-
get() = this.loadCachedInterface { telephony }.getSubscriptionCarrierName(this.subscriptionId)
434+
get() = this.loadCachedInterface { telephony }.getSubscriptionCarrierName(this.subscriptionId) ?: ""
437435

438436
val showVoWifiIcon: Boolean
439437
get() = this.getBooleanValue(CarrierConfigManager.KEY_SHOW_WIFI_CALLING_ICON_IN_STATUS_BAR_BOOL)

app/src/main/java/dev/bluehouse/enablevolte/pages/Config.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import dev.bluehouse.enablevolte.components.HeaderText
3535
import dev.bluehouse.enablevolte.components.InfiniteLoadingDialog
3636
import dev.bluehouse.enablevolte.components.RadioSelectPropertyView
3737
import dev.bluehouse.enablevolte.components.UserAgentPropertyView
38-
import dev.bluehouse.enablevolte.overrideConfigPersistent
38+
import dev.bluehouse.enablevolte.configPersistent
3939
import kotlinx.coroutines.Dispatchers
4040
import kotlinx.coroutines.launch
4141
import kotlinx.coroutines.withContext
@@ -148,8 +148,8 @@ fun Config(
148148
InfiniteLoadingDialog()
149149
} else {
150150
Column(modifier = Modifier.padding(Dp(16f)).verticalScroll(scrollState)) {
151-
BooleanPropertyView(label = stringResource(R.string.override_config_persistent), toggled = overrideConfigPersistent) {
152-
overrideConfigPersistent = !overrideConfigPersistent
151+
BooleanPropertyView(label = stringResource(R.string.persist_config), toggled = configPersistent) {
152+
configPersistent = !configPersistent
153153
}
154154

155155
HeaderText(text = stringResource(R.string.feature_toggles))

0 commit comments

Comments
 (0)