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

Commit 0012abc0 authored by Amit Mahajan's avatar Amit Mahajan
Browse files

Exception and death notification handling for IRadio.

Test: Basic telephony sanity
Bug: 32020264
Change-Id: Id0ea4ca839cf67d3810bdec91814199005e03794
parent 21c9e33b
Loading
Loading
Loading
Loading
+96 −70
Original line number Diff line number Diff line
@@ -43,11 +43,13 @@ import android.os.AsyncResult;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HwBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.WorkSource;
@@ -56,13 +58,11 @@ import android.telephony.CellInfo;
import android.telephony.ClientRequestStats;
import android.telephony.ModemActivityInfo;
import android.telephony.NeighboringCellInfo;
import android.telephony.PcoData;
import android.telephony.PhoneNumberUtils;
import android.telephony.RadioAccessFamily;
import android.telephony.Rlog;
import android.telephony.SignalStrength;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
@@ -70,14 +70,12 @@ import android.text.TextUtils;
import android.util.SparseArray;
import android.view.Display;

import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaInformationRecords;
import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
import com.android.internal.telephony.dataconnection.DataCallResponse;
import com.android.internal.telephony.dataconnection.DataProfile;
import com.android.internal.telephony.dataconnection.DcFailCause;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SsData;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
@@ -97,6 +95,7 @@ import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import static com.android.internal.telephony.RILConstants.*;

@@ -352,6 +351,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
    static final int EVENT_SEND_ACK             = 3;
    static final int EVENT_ACK_WAKE_LOCK_TIMEOUT    = 4;
    static final int EVENT_BLOCKING_RESPONSE_TIMEOUT = 5;
    static final int EVENT_RADIO_PROXY_DEAD     = 6;

    //***** Constants

@@ -366,6 +366,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
    static final String[] SOCKET_NAME_RIL = {"rild", "rild2", "rild3"};

    static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000;
    static final int IRADIO_GET_SERVICE_DELAY_MILLIS = 3 * 1000;

    // The number of the required config values for broadcast SMS stored in the C struct
    // RIL_CDMA_BroadcastServiceInfo
@@ -772,33 +773,85 @@ public final class RIL extends BaseCommands implements CommandsInterface {
        }
    }

    RadioResponse mRadioResponse;
    RadioIndication mRadioIndication;
    volatile IRadio mRadioProxy = null;
    final AtomicLong mRadioProxyCookie = new AtomicLong(0);
    final RadioProxyDeathRecipient mRadioProxyDeathRecipient;
    final RilHandler mRilHandler;

    class RilHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            riljLog("handleMessage: msg.what = " + msg.what + " cookie = " + msg.obj +
                    " mRadioProxyCookie = " + mRadioProxyCookie.get());
            if (msg.what == EVENT_RADIO_PROXY_DEAD && (long) msg.obj == mRadioProxyCookie.get()) {
                resetProxyAndRequestList();

    //***** Constructors
                // todo: rild should be back up since message was sent with a delay. this is a hack.
                getRadioProxy();
            }
        }
    }

    public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
        this(context, preferredNetworkType, cdmaSubscription, null);
    final class RadioProxyDeathRecipient implements HwBinder.DeathRecipient {
        @Override
        public void serviceDied(long cookie) {
            // Deal with service going away
            riljLog("serviceDied");
            // todo: temp hack to send delayed message so that rild is back up by then
            //mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
            mRilHandler.sendMessageDelayed(
                    mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie),
                    IRADIO_GET_SERVICE_DELAY_MILLIS);
        }
    }

    private void resetProxyAndRequestList() {
        mRadioProxy = null;
        RILRequest.resetSerial();
        // Clear request list on close
        clearRequestList(RADIO_NOT_AVAILABLE, false);

        // todo: need to get service right away so setResponseFunctions() can be called for
        // unsolicited indications. getService() is not a blocking call, so it doesn't help to call
        // it here. Current hack is to call getService() on death notification after a delay.
    }

    RadioResponse mRadioResponse;
    RadioIndication mRadioIndication;
    private void handleRadioProxyExceptionForRR(String caller, Exception e, RILRequest rr) {
        riljLoge(caller, e);
        rr.onError(RADIO_NOT_AVAILABLE, null);
        decrementWakeLock(rr);
        rr.release();

        resetProxyAndRequestList();
    }

    private IRadio getRadioProxy() {
        IRadio radioProxy = null;
        if (mRadioProxy != null) {
            return mRadioProxy;
        }
        try {
            radioProxy = IRadio.getService(SOCKET_NAME_RIL[mInstanceId == null ? 0 : mInstanceId]);
            if (radioProxy != null) {
                // todo(b/31632518): should not need to be called every time
                radioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
            mRadioProxy = IRadio.getService(
                    SOCKET_NAME_RIL[mInstanceId == null ? 0 : mInstanceId]);
            if (mRadioProxy != null) {
                mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
                        mRadioProxyCookie.incrementAndGet());
                mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
            } else {
                riljLoge("getRadioProxy: radioProxy == null");
            }
        } catch (Exception e) {
            riljLoge("getRadioProxy: exception", e);
        } catch (RemoteException | RuntimeException e) {
            mRadioProxy = null;
            riljLoge("setResponseFunctions", e);
        }
        return mRadioProxy;
    }
        return radioProxy;

    //***** Constructors

    public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
        this(context, preferredNetworkType, cdmaSubscription, null);
    }

    public RIL(Context context, int preferredNetworkType,
@@ -817,6 +870,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {

        mRadioResponse = new RadioResponse(this);
        mRadioIndication = new RadioIndication(this);
        mRilHandler = new RilHandler();
        mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();
        // set radio callback; needed to set RadioIndication callback
        getRadioProxy();

@@ -922,11 +977,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
            addRequest(rr);
            try {
                radioProxy.getIccCardStatus(rr.mSerial);
            } catch (Exception e) {
                riljLoge("getIccCardStatus", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("getIccCardStatus", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -952,11 +1004,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                radioProxy.supplyIccPinForApp(rr.mSerial,
                        pin != null ? pin : "",
                        aid != null ? aid : "");
            } catch (Exception e) {
                riljLoge("supplyIccPinForApp", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("supplyIccPinForApp", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -983,11 +1032,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                        puk != null ? puk : "",
                        newPin != null ? newPin : "",
                        aid != null ? aid : "");
            } catch (Exception e) {
                riljLoge("supplyIccPukForApp", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("supplyIccPukForApp", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1014,11 +1060,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                radioProxy.supplyIccPin2ForApp(rr.mSerial,
                        pin != null ? pin : "",
                        aid != null ? aid : "");
            } catch (Exception e) {
                riljLoge("supplyIccPin2ForApp", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("supplyIccPin2ForApp", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1046,11 +1089,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                        puk != null ? puk : "",
                        newPin2 != null ? newPin2 : "",
                        aid != null ? aid : "");
            } catch (Exception e) {
                riljLoge("supplyIccPuk2ForApp", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("supplyIccPuk2ForApp", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1078,11 +1118,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                        oldPin != null ? oldPin : "",
                        newPin != null ? newPin : "",
                        aid != null ? aid : "");
            } catch (Exception e) {
                riljLoge("changeIccPinForApp", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("changeIccPinForApp", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1110,11 +1147,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                        oldPin2 != null ? oldPin2 : "",
                        newPin2 != null ? newPin2 : "",
                        aid != null ? aid : "");
            } catch (Exception e) {
                riljLoge("changeIccPin2ForApp", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("changeIccPin2ForApp", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1135,11 +1169,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
            try {
                radioProxy.supplyNetworkDepersonalization(rr.mSerial,
                        netpin != null ? netpin : "");
            } catch (Exception e) {
                riljLoge("supplyNetworkDepersonalization", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("supplyNetworkDepersonalization", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1159,11 +1190,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
            addRequest(rr);
            try {
                radioProxy.getCurrentCalls(rr.mSerial);
            } catch (Exception e) {
                riljLoge("getCurrentCalls", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("getCurrentCalls", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -1198,11 +1226,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
            addRequest(rr);
            try {
                radioProxy.dial(rr.mSerial, dialInfo);
            } catch (Exception e) {
                riljLoge("dial", e);
                rr.onError(RADIO_NOT_AVAILABLE, null);
                decrementWakeLock(rr);
                rr.release();
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR("dial", e, rr);
            }
        } else {
            rr.onError(RADIO_NOT_AVAILABLE, null);
@@ -2803,8 +2828,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
        if (radioProxy != null) {
            try {
                radioProxy.responseAcknowledgement();
            } catch (Exception e) {
                riljLoge("sendAck: exception : " + e);
            } catch (RemoteException | RuntimeException e) {
                resetProxyAndRequestList();
                riljLoge("sendAck", e);
            }
        } else {
            Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, radioProxy = null");