Loading flags/misc.aconfig +11 −0 Original line number Diff line number Diff line package: "com.android.internal.telephony.flags" container: "system" # OWNER=linggm TARGET=24Q3 flag { name: "combine_ril_death_handle" namespace: "telephony" description: "Upon radio service death, combine its handling to prevent race condition" bug:"319612362" metadata { purpose: PURPOSE_BUGFIX } } # OWNER=tjstuart TARGET=24Q3 flag { name: "do_not_override_precise_label" Loading src/java/com/android/internal/telephony/PhoneFactory.java +2 −2 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ public class PhoneFactory { Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i])); sCommandsInterfaces[i] = new RIL(context, RadioAccessFamily.getRafFromNetworkType(networkModes[i]), cdmaSubscription, i); cdmaSubscription, i, featureFlags); } if (numPhones > 0) { Loading Loading @@ -312,7 +312,7 @@ public class PhoneFactory { for (int i = prevActiveModemCount; i < activeModemCount; i++) { sCommandsInterfaces[i] = new RIL(context, RadioAccessFamily.getRafFromNetworkType( RILConstants.PREFERRED_NETWORK_MODE), cdmaSubscription, i); cdmaSubscription, i, sFeatureFlags); sPhones[i] = createPhone(context, i); if (context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_IMS)) { Loading src/java/com/android/internal/telephony/RIL.java +126 −40 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.cdma.CdmaInformationRecords; import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo; import com.android.internal.telephony.emergency.EmergencyConstants; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; import com.android.internal.telephony.imsphone.ImsCallInfo; import com.android.internal.telephony.metrics.ModemRestartStats; Loading Loading @@ -221,6 +222,8 @@ public class RIL extends BaseCommands implements CommandsInterface { public static final int MAX_SERVICE_IDX = HAL_SERVICE_IMS; @NonNull private final FeatureFlags mFeatureFlags; /** * An array of sets that records if services are disabled in the HAL for a specific phone ID * slot to avoid further getService requests for that service. See XXX_SERVICE for the indices. Loading Loading @@ -384,6 +387,20 @@ public class RIL extends BaseCommands implements CommandsInterface { case EVENT_AIDL_PROXY_DEAD: int aidlService = msg.arg1; long msgCookie = (long) msg.obj; if (mFeatureFlags.combineRilDeathHandle()) { if (msgCookie == mServiceCookies.get(aidlService).get()) { riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msgCookie + ", service = " + serviceToString(aidlService) + ", cookie = " + mServiceCookies.get(aidlService)); mIsRadioProxyInitialized = false; resetProxyAndRequestList(aidlService); // Remove duplicate death message to avoid duplicate reset. mRilHandler.removeMessages(EVENT_AIDL_PROXY_DEAD); } else { riljLog("Ignore stale EVENT_AIDL_PROXY_DEAD for service " + serviceToString(aidlService)); } } else { riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msgCookie + ", service = " + serviceToString(aidlService) + ", cookie = " + mServiceCookies.get(aidlService)); Loading @@ -391,6 +408,7 @@ public class RIL extends BaseCommands implements CommandsInterface { mIsRadioProxyInitialized = false; resetProxyAndRequestList(aidlService); } } break; } } Loading Loading @@ -434,10 +452,16 @@ public class RIL extends BaseCommands implements CommandsInterface { public void serviceDied(long cookie) { // Deal with service going away riljLog("serviceDied"); if (mFeatureFlags.combineRilDeathHandle()) { mRilHandler.sendMessageAtFrontOfQueue(mRilHandler.obtainMessage( EVENT_RADIO_PROXY_DEAD, HAL_SERVICE_RADIO, 0 /* ignored arg2 */, cookie)); } else { mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, HAL_SERVICE_RADIO, 0 /* ignored arg2 */, cookie)); } } } private final class BinderServiceDeathRecipient implements IBinder.DeathRecipient { private IBinder mBinder; Loading Loading @@ -467,24 +491,49 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void binderDied() { riljLog("Service " + serviceToString(mService) + " has died."); if (mFeatureFlags.combineRilDeathHandle()) { mRilHandler.sendMessageAtFrontOfQueue(mRilHandler.obtainMessage( EVENT_AIDL_PROXY_DEAD, mService, 0 /* ignored arg2 */, mServiceCookies.get(mService).get())); } else { mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_AIDL_PROXY_DEAD, mService, 0 /* ignored arg2 */, mServiceCookies.get(mService).get())); } unlinkToDeath(); } } private synchronized void resetProxyAndRequestList(int service) { /** * Reset services. If one of the AIDL service is reset, all the other AIDL services will be * reset as well. * @param service The service to reset. */ private synchronized void resetProxyAndRequestList(@HalService int service) { if (service == HAL_SERVICE_RADIO) { mRadioProxy = null; // Increment the cookie so that death notification can be ignored mServiceCookies.get(service).incrementAndGet(); } else { mServiceProxies.get(service).clear(); if (mFeatureFlags.combineRilDeathHandle()) { // Reset all aidl services. for (int i = MIN_SERVICE_IDX; i <= MAX_SERVICE_IDX; i++) { if (i == HAL_SERVICE_RADIO) continue; if (mServiceProxies.get(i) == null) { // This should only happen in tests riljLoge("Null service proxy for service " + serviceToString(i)); continue; } mServiceProxies.get(i).clear(); // Increment the cookie so that death notification can be ignored mServiceCookies.get(i).incrementAndGet(); } } else { mServiceProxies.get(service).clear(); // Increment the cookie so that death notification can be ignored mServiceCookies.get(service).incrementAndGet(); } } // TODO: If a service doesn't exist or is unimplemented, it shouldn't cause the radio to // become unavailable for all other services setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE, true /* forceNotifyRegistrants */); RILRequest.resetSerial(); Loading @@ -493,10 +542,23 @@ public class RIL extends BaseCommands implements CommandsInterface { if (service == HAL_SERVICE_RADIO) { getRadioProxy(); } else { if (mFeatureFlags.combineRilDeathHandle()) { // Reset all aidl services. for (int i = MIN_SERVICE_IDX; i <= MAX_SERVICE_IDX; i++) { if (i == HAL_SERVICE_RADIO) continue; if (mServiceProxies.get(i) == null) { // This should only happen in tests riljLoge("Null service proxy for service " + serviceToString(i)); continue; } getRadioServiceProxy(i); } } else { getRadioServiceProxy(service); } } } /** * Request to enable/disable the mock modem service. Loading @@ -512,10 +574,6 @@ public class RIL extends BaseCommands implements CommandsInterface { mMockModem = null; mMockModem = new MockModem(mContext, serviceName, mPhoneId); if (mMockModem == null) { riljLoge("MockModem create fail."); return false; } // Disable HIDL service if (mRadioProxy != null) { Loading Loading @@ -552,11 +610,17 @@ public class RIL extends BaseCommands implements CommandsInterface { if (serviceBound) { mIsRadioProxyInitialized = false; if (mFeatureFlags.combineRilDeathHandle()) { // Reset both hidl and aidl proxies. resetProxyAndRequestList(HAL_SERVICE_RADIO); resetProxyAndRequestList(HAL_SERVICE_DATA); } else { for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { resetProxyAndRequestList(service); } } } } if ((serviceName == null) || (!serviceBound)) { if (serviceBound) riljLog("Unbinding to MockModemService"); Loading @@ -581,9 +645,17 @@ public class RIL extends BaseCommands implements CommandsInterface { mHalVersion.put(service, RADIO_HAL_VERSION_UNSUPPORTED); } } if (!mFeatureFlags.combineRilDeathHandle()) { resetProxyAndRequestList(service); } } if (mFeatureFlags.combineRilDeathHandle()) { // Reset both hidl and aidl proxies. Must be after cleaning mocked halVersion, // otherwise an aidl service will be incorrectly considered as disabled. resetProxyAndRequestList(HAL_SERVICE_RADIO); resetProxyAndRequestList(HAL_SERVICE_DATA); } } } return serviceBound; Loading Loading @@ -990,6 +1062,22 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public synchronized void onSlotActiveStatusChange(boolean active) { mIsRadioProxyInitialized = false; if (mFeatureFlags.combineRilDeathHandle()) { if (active) { for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { // Try to connect to RIL services and set response functions. if (service == HAL_SERVICE_RADIO) { getRadioProxy(); } else { getRadioServiceProxy(service); } } } else { // Reset both hidl and aidl proxies resetProxyAndRequestList(HAL_SERVICE_RADIO); resetProxyAndRequestList(HAL_SERVICE_DATA); } } else { for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { if (active) { // Try to connect to RIL services and set response functions. Loading @@ -1003,23 +1091,21 @@ public class RIL extends BaseCommands implements CommandsInterface { } } } } //***** Constructors @UnsupportedAppUsage public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription) { this(context, allowedNetworkTypes, cdmaSubscription, null); } @UnsupportedAppUsage public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId) { this(context, allowedNetworkTypes, cdmaSubscription, instanceId, null); public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId, @NonNull FeatureFlags flags) { this(context, allowedNetworkTypes, cdmaSubscription, instanceId, null, flags); } @VisibleForTesting public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId, SparseArray<RadioServiceProxy> proxies) { SparseArray<RadioServiceProxy> proxies, @NonNull FeatureFlags flags) { super(context); mFeatureFlags = flags; if (RILJ_LOGD) { riljLog("RIL: init allowedNetworkTypes=" + allowedNetworkTypes + " cdmaSubscription=" + cdmaSubscription + ")"); Loading src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java +5 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,11 @@ public class SatelliteSOSMessageRecommender extends Handler { return; } if (hasMessages(EVENT_EMERGENCY_CALL_STARTED)) { logd("onEmergencyCallStarted: Ignoring due to ongoing event:"); return; } /* * Right now, assume that the device is connected to satellite via carrier within hysteresis * time. However, this might not be correct when the monitoring timer expires. Thus, we Loading src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +5 −0 Original line number Diff line number Diff line Loading @@ -4724,6 +4724,11 @@ public class SubscriptionManagerService extends ISub.Stub { "config_satellite_sim_spn_identifier", ""); } log("isSatelliteSpn: overlaySpn=" + overlaySpn + ", spn=" + spn); if (TextUtils.isEmpty(spn) || TextUtils.isEmpty(overlaySpn)) { return false; } return TextUtils.equals(spn, overlaySpn); } Loading Loading
flags/misc.aconfig +11 −0 Original line number Diff line number Diff line package: "com.android.internal.telephony.flags" container: "system" # OWNER=linggm TARGET=24Q3 flag { name: "combine_ril_death_handle" namespace: "telephony" description: "Upon radio service death, combine its handling to prevent race condition" bug:"319612362" metadata { purpose: PURPOSE_BUGFIX } } # OWNER=tjstuart TARGET=24Q3 flag { name: "do_not_override_precise_label" Loading
src/java/com/android/internal/telephony/PhoneFactory.java +2 −2 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ public class PhoneFactory { Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i])); sCommandsInterfaces[i] = new RIL(context, RadioAccessFamily.getRafFromNetworkType(networkModes[i]), cdmaSubscription, i); cdmaSubscription, i, featureFlags); } if (numPhones > 0) { Loading Loading @@ -312,7 +312,7 @@ public class PhoneFactory { for (int i = prevActiveModemCount; i < activeModemCount; i++) { sCommandsInterfaces[i] = new RIL(context, RadioAccessFamily.getRafFromNetworkType( RILConstants.PREFERRED_NETWORK_MODE), cdmaSubscription, i); cdmaSubscription, i, sFeatureFlags); sPhones[i] = createPhone(context, i); if (context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_IMS)) { Loading
src/java/com/android/internal/telephony/RIL.java +126 −40 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.cdma.CdmaInformationRecords; import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo; import com.android.internal.telephony.emergency.EmergencyConstants; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; import com.android.internal.telephony.imsphone.ImsCallInfo; import com.android.internal.telephony.metrics.ModemRestartStats; Loading Loading @@ -221,6 +222,8 @@ public class RIL extends BaseCommands implements CommandsInterface { public static final int MAX_SERVICE_IDX = HAL_SERVICE_IMS; @NonNull private final FeatureFlags mFeatureFlags; /** * An array of sets that records if services are disabled in the HAL for a specific phone ID * slot to avoid further getService requests for that service. See XXX_SERVICE for the indices. Loading Loading @@ -384,6 +387,20 @@ public class RIL extends BaseCommands implements CommandsInterface { case EVENT_AIDL_PROXY_DEAD: int aidlService = msg.arg1; long msgCookie = (long) msg.obj; if (mFeatureFlags.combineRilDeathHandle()) { if (msgCookie == mServiceCookies.get(aidlService).get()) { riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msgCookie + ", service = " + serviceToString(aidlService) + ", cookie = " + mServiceCookies.get(aidlService)); mIsRadioProxyInitialized = false; resetProxyAndRequestList(aidlService); // Remove duplicate death message to avoid duplicate reset. mRilHandler.removeMessages(EVENT_AIDL_PROXY_DEAD); } else { riljLog("Ignore stale EVENT_AIDL_PROXY_DEAD for service " + serviceToString(aidlService)); } } else { riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msgCookie + ", service = " + serviceToString(aidlService) + ", cookie = " + mServiceCookies.get(aidlService)); Loading @@ -391,6 +408,7 @@ public class RIL extends BaseCommands implements CommandsInterface { mIsRadioProxyInitialized = false; resetProxyAndRequestList(aidlService); } } break; } } Loading Loading @@ -434,10 +452,16 @@ public class RIL extends BaseCommands implements CommandsInterface { public void serviceDied(long cookie) { // Deal with service going away riljLog("serviceDied"); if (mFeatureFlags.combineRilDeathHandle()) { mRilHandler.sendMessageAtFrontOfQueue(mRilHandler.obtainMessage( EVENT_RADIO_PROXY_DEAD, HAL_SERVICE_RADIO, 0 /* ignored arg2 */, cookie)); } else { mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, HAL_SERVICE_RADIO, 0 /* ignored arg2 */, cookie)); } } } private final class BinderServiceDeathRecipient implements IBinder.DeathRecipient { private IBinder mBinder; Loading Loading @@ -467,24 +491,49 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void binderDied() { riljLog("Service " + serviceToString(mService) + " has died."); if (mFeatureFlags.combineRilDeathHandle()) { mRilHandler.sendMessageAtFrontOfQueue(mRilHandler.obtainMessage( EVENT_AIDL_PROXY_DEAD, mService, 0 /* ignored arg2 */, mServiceCookies.get(mService).get())); } else { mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_AIDL_PROXY_DEAD, mService, 0 /* ignored arg2 */, mServiceCookies.get(mService).get())); } unlinkToDeath(); } } private synchronized void resetProxyAndRequestList(int service) { /** * Reset services. If one of the AIDL service is reset, all the other AIDL services will be * reset as well. * @param service The service to reset. */ private synchronized void resetProxyAndRequestList(@HalService int service) { if (service == HAL_SERVICE_RADIO) { mRadioProxy = null; // Increment the cookie so that death notification can be ignored mServiceCookies.get(service).incrementAndGet(); } else { mServiceProxies.get(service).clear(); if (mFeatureFlags.combineRilDeathHandle()) { // Reset all aidl services. for (int i = MIN_SERVICE_IDX; i <= MAX_SERVICE_IDX; i++) { if (i == HAL_SERVICE_RADIO) continue; if (mServiceProxies.get(i) == null) { // This should only happen in tests riljLoge("Null service proxy for service " + serviceToString(i)); continue; } mServiceProxies.get(i).clear(); // Increment the cookie so that death notification can be ignored mServiceCookies.get(i).incrementAndGet(); } } else { mServiceProxies.get(service).clear(); // Increment the cookie so that death notification can be ignored mServiceCookies.get(service).incrementAndGet(); } } // TODO: If a service doesn't exist or is unimplemented, it shouldn't cause the radio to // become unavailable for all other services setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE, true /* forceNotifyRegistrants */); RILRequest.resetSerial(); Loading @@ -493,10 +542,23 @@ public class RIL extends BaseCommands implements CommandsInterface { if (service == HAL_SERVICE_RADIO) { getRadioProxy(); } else { if (mFeatureFlags.combineRilDeathHandle()) { // Reset all aidl services. for (int i = MIN_SERVICE_IDX; i <= MAX_SERVICE_IDX; i++) { if (i == HAL_SERVICE_RADIO) continue; if (mServiceProxies.get(i) == null) { // This should only happen in tests riljLoge("Null service proxy for service " + serviceToString(i)); continue; } getRadioServiceProxy(i); } } else { getRadioServiceProxy(service); } } } /** * Request to enable/disable the mock modem service. Loading @@ -512,10 +574,6 @@ public class RIL extends BaseCommands implements CommandsInterface { mMockModem = null; mMockModem = new MockModem(mContext, serviceName, mPhoneId); if (mMockModem == null) { riljLoge("MockModem create fail."); return false; } // Disable HIDL service if (mRadioProxy != null) { Loading Loading @@ -552,11 +610,17 @@ public class RIL extends BaseCommands implements CommandsInterface { if (serviceBound) { mIsRadioProxyInitialized = false; if (mFeatureFlags.combineRilDeathHandle()) { // Reset both hidl and aidl proxies. resetProxyAndRequestList(HAL_SERVICE_RADIO); resetProxyAndRequestList(HAL_SERVICE_DATA); } else { for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { resetProxyAndRequestList(service); } } } } if ((serviceName == null) || (!serviceBound)) { if (serviceBound) riljLog("Unbinding to MockModemService"); Loading @@ -581,9 +645,17 @@ public class RIL extends BaseCommands implements CommandsInterface { mHalVersion.put(service, RADIO_HAL_VERSION_UNSUPPORTED); } } if (!mFeatureFlags.combineRilDeathHandle()) { resetProxyAndRequestList(service); } } if (mFeatureFlags.combineRilDeathHandle()) { // Reset both hidl and aidl proxies. Must be after cleaning mocked halVersion, // otherwise an aidl service will be incorrectly considered as disabled. resetProxyAndRequestList(HAL_SERVICE_RADIO); resetProxyAndRequestList(HAL_SERVICE_DATA); } } } return serviceBound; Loading Loading @@ -990,6 +1062,22 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public synchronized void onSlotActiveStatusChange(boolean active) { mIsRadioProxyInitialized = false; if (mFeatureFlags.combineRilDeathHandle()) { if (active) { for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { // Try to connect to RIL services and set response functions. if (service == HAL_SERVICE_RADIO) { getRadioProxy(); } else { getRadioServiceProxy(service); } } } else { // Reset both hidl and aidl proxies resetProxyAndRequestList(HAL_SERVICE_RADIO); resetProxyAndRequestList(HAL_SERVICE_DATA); } } else { for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { if (active) { // Try to connect to RIL services and set response functions. Loading @@ -1003,23 +1091,21 @@ public class RIL extends BaseCommands implements CommandsInterface { } } } } //***** Constructors @UnsupportedAppUsage public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription) { this(context, allowedNetworkTypes, cdmaSubscription, null); } @UnsupportedAppUsage public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId) { this(context, allowedNetworkTypes, cdmaSubscription, instanceId, null); public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId, @NonNull FeatureFlags flags) { this(context, allowedNetworkTypes, cdmaSubscription, instanceId, null, flags); } @VisibleForTesting public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId, SparseArray<RadioServiceProxy> proxies) { SparseArray<RadioServiceProxy> proxies, @NonNull FeatureFlags flags) { super(context); mFeatureFlags = flags; if (RILJ_LOGD) { riljLog("RIL: init allowedNetworkTypes=" + allowedNetworkTypes + " cdmaSubscription=" + cdmaSubscription + ")"); Loading
src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java +5 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,11 @@ public class SatelliteSOSMessageRecommender extends Handler { return; } if (hasMessages(EVENT_EMERGENCY_CALL_STARTED)) { logd("onEmergencyCallStarted: Ignoring due to ongoing event:"); return; } /* * Right now, assume that the device is connected to satellite via carrier within hysteresis * time. However, this might not be correct when the monitoring timer expires. Thus, we Loading
src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +5 −0 Original line number Diff line number Diff line Loading @@ -4724,6 +4724,11 @@ public class SubscriptionManagerService extends ISub.Stub { "config_satellite_sim_spn_identifier", ""); } log("isSatelliteSpn: overlaySpn=" + overlaySpn + ", spn=" + spn); if (TextUtils.isEmpty(spn) || TextUtils.isEmpty(overlaySpn)) { return false; } return TextUtils.equals(spn, overlaySpn); } Loading