@@ -10,6 +10,7 @@ import android.os.Build.VERSION_CODES
1010import android.os.Bundle
1111import android.os.IInterface
1212import android.os.PersistableBundle
13+ import android.os.ServiceManager
1314import android.telephony.CarrierConfigManager
1415import android.telephony.SubscriptionInfo
1516import 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
3637open 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 )
0 commit comments