Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b036d299 authored by Ling Ma's avatar Ling Ma Committed by Android (Google) Code Review
Browse files

Merge "Combine handling AIDL binder death" into main

parents b40d2386 b78bb23b
Loading
Loading
Loading
Loading
+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"
+2 −2
Original line number Diff line number Diff line
@@ -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) {
@@ -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)) {
+124 −40
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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));
@@ -391,6 +408,7 @@ public class RIL extends BaseCommands implements CommandsInterface {
                            mIsRadioProxyInitialized = false;
                            resetProxyAndRequestList(aidlService);
                        }
                    }
                    break;
            }
        }
@@ -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;
@@ -467,24 +491,47 @@ 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;
        } 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();
@@ -493,10 +540,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.
@@ -512,10 +572,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) {
@@ -552,11 +608,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");
@@ -581,9 +643,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;
@@ -990,6 +1060,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.
@@ -1003,23 +1089,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 + ")");
+3 −1
Original line number Diff line number Diff line
@@ -330,7 +330,7 @@ public class RILTest extends TelephonyTest {
        proxies.put(HAL_SERVICE_MODEM, mRadioModemProxy);
        mRILInstance = new RIL(context,
                RadioAccessFamily.getRafFromNetworkType(RILConstants.PREFERRED_NETWORK_MODE),
                Phone.PREFERRED_CDMA_SUBSCRIPTION, 0, proxies);
                Phone.PREFERRED_CDMA_SUBSCRIPTION, 0, proxies, mFeatureFlags);
        mRILUnderTest = spy(mRILInstance);
        doReturn(mRadioProxy).when(mRILUnderTest).getRadioProxy();
        doReturn(mDataProxy).when(mRILUnderTest).getRadioServiceProxy(eq(RadioDataProxy.class));
@@ -354,6 +354,8 @@ public class RILTest extends TelephonyTest {
            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV14);
        } catch (Exception e) {
        }

        doReturn(true).when(mFeatureFlags).combineRilDeathHandle();
    }

    @After