Loading src/java/com/android/internal/telephony/CarrierResolver.java +42 −17 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.telephony; import static android.provider.Telephony.CarrierId; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ContentValues; import android.content.Context; import android.content.Intent; Loading Loading @@ -992,6 +993,44 @@ public class CarrierResolver extends Handler { // static helper function to get carrier id from mccmnc public static int getCarrierIdFromMccMnc(@NonNull Context context, String mccmnc) { try (Cursor cursor = getCursorForMccMnc(context, mccmnc)) { if (cursor == null || !cursor.moveToNext()) return TelephonyManager.UNKNOWN_CARRIER_ID; if (VDBG) { logd("[getCarrierIdFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } return cursor.getInt(cursor.getColumnIndex(CarrierId.CARRIER_ID)); } catch (Exception ex) { loge("[getCarrierIdFromMccMnc]- ex: " + ex); } return TelephonyManager.UNKNOWN_CARRIER_ID; } /** * Static helper function to get carrier name from mccmnc * @param context Context * @param mccmnc PLMN * @return Carrier name string given mccmnc/PLMN * * @hide */ @Nullable public static String getCarrierNameFromMccMnc(@NonNull Context context, String mccmnc) { try (Cursor cursor = getCursorForMccMnc(context, mccmnc)) { if (cursor == null || !cursor.moveToNext()) return null; if (VDBG) { logd("[getCarrierNameFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } return cursor.getString(cursor.getColumnIndex(CarrierId.CARRIER_NAME)); } catch (Exception ex) { loge("[getCarrierNameFromMccMnc]- ex: " + ex); } return null; } @Nullable private static Cursor getCursorForMccMnc(@NonNull Context context, String mccmnc) { try { Cursor cursor = context.getContentResolver().query( CarrierId.All.CONTENT_URI, Loading @@ -1007,25 +1046,11 @@ public class CarrierResolver extends Handler { + CarrierId.All.APN + " is NULL", /* selectionArgs */ new String[]{mccmnc}, null); try { if (cursor != null) { if (VDBG) { logd("[getCarrierIdFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } while (cursor.moveToNext()) { return cursor.getInt(cursor.getColumnIndex(CarrierId.CARRIER_ID)); } } } finally { if (cursor != null) { cursor.close(); } } return cursor; } catch (Exception ex) { loge("[getCarrierIdFromMccMnc]- ex: " + ex); loge("[getCursorForMccMnc]- ex: " + ex); return null; } return TelephonyManager.UNKNOWN_CARRIER_ID; } private static boolean equals(String a, String b, boolean ignoreCase) { Loading src/java/com/android/internal/telephony/MultiSimSettingController.java +16 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,22 @@ public class MultiSimSettingController extends Handler { return; } // b/153860050 Occasionally we receive carrier config change broadcast without subId // being specified in it. So here we do additional check to make sur we don't miss the // subId. if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { int[] subIds = mSubController.getSubId(phoneId); if (!ArrayUtils.isEmpty(subIds)) { CarrierConfigManager cm = (CarrierConfigManager) mContext.getSystemService( mContext.CARRIER_CONFIG_SERVICE); if (cm != null && cm.getConfigForSubId(subIds[0]) != null) { loge("onCarrierConfigChanged with invalid subId while subd " + subIds[0] + " is active and its config is loaded"); subId = subIds[0]; } } } mCarrierConfigLoadedSubIds[phoneId] = subId; reEvaluateAll(); } Loading src/java/com/android/internal/telephony/RIL.java +101 −25 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.internal.telephony.RILConstants.*; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.radio.V1_0.Carrier; Loading Loading @@ -132,6 +133,7 @@ import java.util.HashSet; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; Loading Loading @@ -266,6 +268,13 @@ public class RIL extends BaseCommands implements CommandsInterface { final RadioProxyDeathRecipient mRadioProxyDeathRecipient; final RilHandler mRilHandler; // Thread-safe HashMap to map from RIL_REQUEST_XXX constant to HalVersion. // This is for Radio HAL Fallback Compatibility feature. When a RIL request // is received, the HAL method from the mapping HalVersion here (if present), // instead of the latest HalVersion, will be invoked. private ConcurrentHashMap<Integer, HalVersion> mCompatOverrides = new ConcurrentHashMap<>(); //***** Events static final int EVENT_WAKE_LOCK_TIMEOUT = 2; static final int EVENT_ACK_WAKE_LOCK_TIMEOUT = 4; Loading Loading @@ -432,6 +441,25 @@ public class RIL extends BaseCommands implements CommandsInterface { getOemHookProxy(null); } /** Set a radio HAL fallback compatibility override. */ @VisibleForTesting public void setCompatVersion(int rilRequest, @NonNull HalVersion halVersion) { HalVersion oldVersion = getCompatVersion(rilRequest); // Do not allow to set same or greater verions if (oldVersion != null && halVersion.greaterOrEqual(oldVersion)) { riljLoge("setCompatVersion with equal or greater one, ignored, halVerion=" + halVersion + ", oldVerion=" + oldVersion); return; } mCompatOverrides.put(rilRequest, halVersion); } /** Get a radio HAL fallback compatibility override, or null if not exist. */ @VisibleForTesting public @Nullable HalVersion getCompatVersion(int rilRequest) { return mCompatOverrides.getOrDefault(rilRequest, null); } /** Returns a {@link IRadio} instance or null if the service is not available. */ @VisibleForTesting public synchronized IRadio getRadioProxy(Message result) { Loading Loading @@ -695,6 +723,13 @@ public class RIL extends BaseCommands implements CommandsInterface { return rr; } private RILRequest obtainRequest(int request, Message result, WorkSource workSource, Object... args) { RILRequest rr = RILRequest.obtain(request, result, workSource, args); addRequest(rr); return rr; } private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) { riljLoge(caller + ": " + e); resetProxyAndRequestList(); Loading Loading @@ -1458,7 +1493,13 @@ public class RIL extends BaseCommands implements CommandsInterface { if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_VOICE_REGISTRATION_STATE); if (RILJ_LOGD) { riljLog("getVoiceRegistrationState: overrideHalVersion=" + overrideHalVersion); } if ((overrideHalVersion == null || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { final android.hardware.radio.V1_5.IRadio radioProxy15 = (android.hardware.radio.V1_5.IRadio) radioProxy; try { Loading @@ -1485,8 +1526,13 @@ public class RIL extends BaseCommands implements CommandsInterface { if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_DATA_REGISTRATION_STATE); if (RILJ_LOGD) { riljLog("getDataRegistrationState: overrideHalVersion=" + overrideHalVersion); } if ((overrideHalVersion == null || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { final android.hardware.radio.V1_5.IRadio radioProxy15 = (android.hardware.radio.V1_5.IRadio) radioProxy; try { Loading Loading @@ -2443,11 +2489,25 @@ public class RIL extends BaseCommands implements CommandsInterface { return rasInHalFormat; } /** * Radio HAL fallback compatibility feature (b/151106728) assumes that the input parameter * networkScanRequest is immutable (read-only) here. Once the caller invokes the method, the * parameter networkScanRequest should not be modified. This helps us keep a consistent and * simple data model that avoid copying it in the scan result. */ @Override public void startNetworkScan(NetworkScanRequest nsr, Message result) { public void startNetworkScan(NetworkScanRequest networkScanRequest, Message result) { final NetworkScanRequest nsr = networkScanRequest; IRadio radioProxy = getRadioProxy(result); if (radioProxy != null) { if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_START_NETWORK_SCAN); if (RILJ_LOGD) { riljLog("startNetworkScan: overrideHalVersion=" + overrideHalVersion); } if ((overrideHalVersion == null || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { android.hardware.radio.V1_5.NetworkScanRequest request = new android.hardware.radio.V1_5.NetworkScanRequest(); request.type = nsr.getScanType(); Loading @@ -2469,7 +2529,7 @@ public class RIL extends BaseCommands implements CommandsInterface { request.mccMncs.addAll(nsr.getPlmns()); RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result, mRILDefaultWorkSource); mRILDefaultWorkSource, nsr); if (RILJ_LOGD) { riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); Loading Loading @@ -5514,6 +5574,28 @@ public class RIL extends BaseCommands implements CommandsInterface { } rr.onError(responseInfo.error, ret); } processResponseCleanUp(rr, responseInfo, ret); } /** * This is a helper function to be called at the end of all RadioResponse callbacks for * radio HAL fallback cases. It takes care of logging, decrementing wakelock if needed, and * releases the request from memory pool. Unlike processResponseDone, it will not send * error response to caller. * @param rr RILRequest for which response callback was called * @param responseInfo RadioResponseInfo received in the callback * @param ret object to be returned to request sender */ @VisibleForTesting public void processResponseFallback(RILRequest rr, RadioResponseInfo responseInfo, Object ret) { if (responseInfo.error == REQUEST_NOT_SUPPORTED && RILJ_LOGD) { riljLog(rr.serialString() + "< " + requestToString(rr.mRequest) + " request not supported, falling back"); } processResponseCleanUp(rr, responseInfo, ret); } private void processResponseCleanUp(RILRequest rr, RadioResponseInfo responseInfo, Object ret) { mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error, rr.mRequest, ret); if (rr != null) { Loading Loading @@ -6727,7 +6809,6 @@ public class RIL extends BaseCommands implements CommandsInterface { String[] pcscfs = null; List<LinkAddress> laList = new ArrayList<>(); int version; if (dcResult instanceof android.hardware.radio.V1_0.SetupDataCallResult) { final android.hardware.radio.V1_0.SetupDataCallResult result = Loading @@ -6750,9 +6831,12 @@ public class RIL extends BaseCommands implements CommandsInterface { if (!TextUtils.isEmpty(result.pcscf)) { pcscfs = result.pcscf.split("\\s+"); } mtu = result.mtu; mtuV4 = mtuV6 = 0; version = 0; mtu = mtuV4 = mtuV6 = result.mtu; if (addresses != null) { for (String address : addresses) { laList.add(createLinkAddressFromString(address)); } } } else if (dcResult instanceof android.hardware.radio.V1_4.SetupDataCallResult) { final android.hardware.radio.V1_4.SetupDataCallResult result = (android.hardware.radio.V1_4.SetupDataCallResult) dcResult; Loading @@ -6766,9 +6850,12 @@ public class RIL extends BaseCommands implements CommandsInterface { dnses = result.dnses.stream().toArray(String[]::new); gateways = result.gateways.stream().toArray(String[]::new); pcscfs = result.pcscf.stream().toArray(String[]::new); mtu = result.mtu; mtuV4 = mtuV6 = 0; version = 4; mtu = mtuV4 = mtuV6 = result.mtu; if (addresses != null) { for (String address : addresses) { laList.add(createLinkAddressFromString(address)); } } } else if (dcResult instanceof android.hardware.radio.V1_5.SetupDataCallResult) { final android.hardware.radio.V1_5.SetupDataCallResult result = (android.hardware.radio.V1_5.SetupDataCallResult) dcResult; Loading @@ -6785,24 +6872,14 @@ public class RIL extends BaseCommands implements CommandsInterface { dnses = result.dnses.stream().toArray(String[]::new); gateways = result.gateways.stream().toArray(String[]::new); pcscfs = result.pcscf.stream().toArray(String[]::new); mtu = 0; mtu = Math.max(result.mtuV4, result.mtuV6); mtuV4 = result.mtuV4; mtuV6 = result.mtuV6; version = 5; } else { Rlog.e(RILJ_LOG_TAG, "Unsupported SetupDataCallResult " + dcResult); return null; } if (version < 5) { // Process address if (addresses != null) { for (String address : addresses) { laList.add(createLinkAddressFromString(address)); } } } // Process dns List<InetAddress> dnsList = new ArrayList<>(); if (dnses != null) { Loading Loading @@ -6862,7 +6939,6 @@ public class RIL extends BaseCommands implements CommandsInterface { .setMtu(mtu) .setMtuV4(mtuV4) .setMtuV6(mtuV6) .setVersion(version) .build(); } Loading src/java/com/android/internal/telephony/RILRequest.java +22 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ public class RILRequest { String mClientId; // time in ms when RIL request was made long mStartTimeMs; /** Argument list for radio HAL fallback method call */ Object[] mArguments; public int getSerial() { return mSerial; Loading Loading @@ -133,6 +135,25 @@ public class RILRequest { return rr; } /** * Retrieves a new RILRequest instance from the pool and sets the clientId * * @param request RIL_REQUEST_* * @param result sent when operation completes * @param workSource WorkSource to track the client * @param args The list of parameters used to call the fallback HAL method * @return a RILRequest instance from the pool. */ // @VisibleForTesting public static RILRequest obtain(int request, Message result, WorkSource workSource, Object... args) { RILRequest rr = obtain(request, result, workSource); rr.mArguments = args; return rr; } /** * Generate a String client ID from the WorkSource. */ Loading Loading @@ -175,6 +196,7 @@ public class RILRequest { + serialString()); } } mArguments = null; } } } Loading src/java/com/android/internal/telephony/RadioResponse.java +71 −25 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.telephony.CarrierRestrictionRules; import android.telephony.CellInfo; import android.telephony.ModemActivityInfo; import android.telephony.NeighboringCellInfo; import android.telephony.NetworkScanRequest; import android.telephony.PhoneNumberUtils; import android.telephony.RadioAccessFamily; import android.telephony.SignalStrength; Loading Loading @@ -357,14 +358,27 @@ public class RadioResponse extends IRadioResponse.Stub { public void getVoiceRegistrationStateResponse_1_5(RadioResponseInfo responseInfo, android.hardware.radio.V1_5.RegStateResult voiceRegResponse) { RILRequest rr = mRil.processResponse(responseInfo); if (rr == null) { return; } if (rr != null) { if (responseInfo.error == RadioError.NONE) { if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED) { // Move the data needed for fallback call from rr which will be released soon final int request = rr.getRequest(); final Message result = rr.getResult(); mRil.mRilHandler.post(() -> { mRil.setCompatVersion(request, RIL.RADIO_HAL_VERSION_1_4); mRil.getVoiceRegistrationState(result); }); mRil.processResponseFallback(rr, responseInfo, voiceRegResponse); return; } else if (responseInfo.error == RadioError.NONE) { sendMessageResponse(rr.mResult, voiceRegResponse); } mRil.processResponseDone(rr, responseInfo, voiceRegResponse); } } /** * @param responseInfo Response info struct containing response type, serial no. and error Loading Loading @@ -425,14 +439,27 @@ public class RadioResponse extends IRadioResponse.Stub { public void getDataRegistrationStateResponse_1_5(RadioResponseInfo responseInfo, android.hardware.radio.V1_5.RegStateResult dataRegResponse) { RILRequest rr = mRil.processResponse(responseInfo); if (rr == null) { return; } if (rr != null) { if (responseInfo.error == RadioError.NONE) { if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED) { // Move the data needed for fallback call from rr which will be released soon final int request = rr.getRequest(); final Message result = rr.getResult(); mRil.mRilHandler.post(() -> { mRil.setCompatVersion(request, RIL.RADIO_HAL_VERSION_1_4); mRil.getDataRegistrationState(result); }); mRil.processResponseFallback(rr, responseInfo, dataRegResponse); return; } else if (responseInfo.error == RadioError.NONE) { sendMessageResponse(rr.mResult, dataRegResponse); } mRil.processResponseDone(rr, responseInfo, dataRegResponse); } } /** * @param responseInfo Response info struct containing response type, serial no. and error Loading Loading @@ -684,26 +711,26 @@ public class RadioResponse extends IRadioResponse.Stub { * @param responseInfo Response info struct containing response type, serial no. and error */ public void startNetworkScanResponse(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, null /*fallbackHalVersion*/); } /** * The same method as startNetworkScanResponse, except disallowing error codes * OPERATION_NOT_ALLOWED and REQUEST_NOT_SUPPORTED. * OPERATION_NOT_ALLOWED. * * @param responseInfo Response info struct containing response type, serial no. and error */ public void startNetworkScanResponse_1_4(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, null /*fallbackHalVersion*/); } /** * The same method as startNetworkScanResponse_1_5. * The same method as startNetworkScanResponse_1_4. * * @param responseInfo Response info struct containing response type, serial no. and error */ public void startNetworkScanResponse_1_5(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, RIL.RADIO_HAL_VERSION_1_4); } /** Loading @@ -711,7 +738,7 @@ public class RadioResponse extends IRadioResponse.Stub { * @param responseInfo Response info struct containing response type, serial no. and error */ public void stopNetworkScanResponse(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, null /*fallbackHalVersion*/); } /** Loading Loading @@ -2207,10 +2234,30 @@ public class RadioResponse extends IRadioResponse.Stub { } } private void responseScanStatus(RadioResponseInfo responseInfo) { private void responseScanStatus(RadioResponseInfo responseInfo, HalVersion fallbackHalVersion) { RILRequest rr = mRil.processResponse(responseInfo); if (rr == null) { return; } final boolean needFallback = responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED && fallbackHalVersion != null && rr.mArguments != null && rr.mArguments.length > 0 && rr.mArguments[0] instanceof NetworkScanRequest; if (needFallback) { // Move the data needed for fallback call from rr which will be released soon final int request = rr.getRequest(); final Message result = rr.getResult(); final NetworkScanRequest scanRequest = (NetworkScanRequest) rr.mArguments[0]; mRil.mRilHandler.post(() -> { mRil.setCompatVersion(request, RIL.RADIO_HAL_VERSION_1_4); mRil.startNetworkScan(scanRequest, result); }); mRil.processResponseFallback(rr, responseInfo, null); return; } if (rr != null) { NetworkScanResult nsr = null; if (responseInfo.error == RadioError.NONE) { nsr = new NetworkScanResult( Loading @@ -2219,7 +2266,6 @@ public class RadioResponse extends IRadioResponse.Stub { } mRil.processResponseDone(rr, responseInfo, nsr); } } private void responseDataCallList(RadioResponseInfo responseInfo, List<? extends Object> dataCallResultList) { Loading Loading
src/java/com/android/internal/telephony/CarrierResolver.java +42 −17 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.telephony; import static android.provider.Telephony.CarrierId; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ContentValues; import android.content.Context; import android.content.Intent; Loading Loading @@ -992,6 +993,44 @@ public class CarrierResolver extends Handler { // static helper function to get carrier id from mccmnc public static int getCarrierIdFromMccMnc(@NonNull Context context, String mccmnc) { try (Cursor cursor = getCursorForMccMnc(context, mccmnc)) { if (cursor == null || !cursor.moveToNext()) return TelephonyManager.UNKNOWN_CARRIER_ID; if (VDBG) { logd("[getCarrierIdFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } return cursor.getInt(cursor.getColumnIndex(CarrierId.CARRIER_ID)); } catch (Exception ex) { loge("[getCarrierIdFromMccMnc]- ex: " + ex); } return TelephonyManager.UNKNOWN_CARRIER_ID; } /** * Static helper function to get carrier name from mccmnc * @param context Context * @param mccmnc PLMN * @return Carrier name string given mccmnc/PLMN * * @hide */ @Nullable public static String getCarrierNameFromMccMnc(@NonNull Context context, String mccmnc) { try (Cursor cursor = getCursorForMccMnc(context, mccmnc)) { if (cursor == null || !cursor.moveToNext()) return null; if (VDBG) { logd("[getCarrierNameFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } return cursor.getString(cursor.getColumnIndex(CarrierId.CARRIER_NAME)); } catch (Exception ex) { loge("[getCarrierNameFromMccMnc]- ex: " + ex); } return null; } @Nullable private static Cursor getCursorForMccMnc(@NonNull Context context, String mccmnc) { try { Cursor cursor = context.getContentResolver().query( CarrierId.All.CONTENT_URI, Loading @@ -1007,25 +1046,11 @@ public class CarrierResolver extends Handler { + CarrierId.All.APN + " is NULL", /* selectionArgs */ new String[]{mccmnc}, null); try { if (cursor != null) { if (VDBG) { logd("[getCarrierIdFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } while (cursor.moveToNext()) { return cursor.getInt(cursor.getColumnIndex(CarrierId.CARRIER_ID)); } } } finally { if (cursor != null) { cursor.close(); } } return cursor; } catch (Exception ex) { loge("[getCarrierIdFromMccMnc]- ex: " + ex); loge("[getCursorForMccMnc]- ex: " + ex); return null; } return TelephonyManager.UNKNOWN_CARRIER_ID; } private static boolean equals(String a, String b, boolean ignoreCase) { Loading
src/java/com/android/internal/telephony/MultiSimSettingController.java +16 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,22 @@ public class MultiSimSettingController extends Handler { return; } // b/153860050 Occasionally we receive carrier config change broadcast without subId // being specified in it. So here we do additional check to make sur we don't miss the // subId. if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { int[] subIds = mSubController.getSubId(phoneId); if (!ArrayUtils.isEmpty(subIds)) { CarrierConfigManager cm = (CarrierConfigManager) mContext.getSystemService( mContext.CARRIER_CONFIG_SERVICE); if (cm != null && cm.getConfigForSubId(subIds[0]) != null) { loge("onCarrierConfigChanged with invalid subId while subd " + subIds[0] + " is active and its config is loaded"); subId = subIds[0]; } } } mCarrierConfigLoadedSubIds[phoneId] = subId; reEvaluateAll(); } Loading
src/java/com/android/internal/telephony/RIL.java +101 −25 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.internal.telephony.RILConstants.*; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.radio.V1_0.Carrier; Loading Loading @@ -132,6 +133,7 @@ import java.util.HashSet; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; Loading Loading @@ -266,6 +268,13 @@ public class RIL extends BaseCommands implements CommandsInterface { final RadioProxyDeathRecipient mRadioProxyDeathRecipient; final RilHandler mRilHandler; // Thread-safe HashMap to map from RIL_REQUEST_XXX constant to HalVersion. // This is for Radio HAL Fallback Compatibility feature. When a RIL request // is received, the HAL method from the mapping HalVersion here (if present), // instead of the latest HalVersion, will be invoked. private ConcurrentHashMap<Integer, HalVersion> mCompatOverrides = new ConcurrentHashMap<>(); //***** Events static final int EVENT_WAKE_LOCK_TIMEOUT = 2; static final int EVENT_ACK_WAKE_LOCK_TIMEOUT = 4; Loading Loading @@ -432,6 +441,25 @@ public class RIL extends BaseCommands implements CommandsInterface { getOemHookProxy(null); } /** Set a radio HAL fallback compatibility override. */ @VisibleForTesting public void setCompatVersion(int rilRequest, @NonNull HalVersion halVersion) { HalVersion oldVersion = getCompatVersion(rilRequest); // Do not allow to set same or greater verions if (oldVersion != null && halVersion.greaterOrEqual(oldVersion)) { riljLoge("setCompatVersion with equal or greater one, ignored, halVerion=" + halVersion + ", oldVerion=" + oldVersion); return; } mCompatOverrides.put(rilRequest, halVersion); } /** Get a radio HAL fallback compatibility override, or null if not exist. */ @VisibleForTesting public @Nullable HalVersion getCompatVersion(int rilRequest) { return mCompatOverrides.getOrDefault(rilRequest, null); } /** Returns a {@link IRadio} instance or null if the service is not available. */ @VisibleForTesting public synchronized IRadio getRadioProxy(Message result) { Loading Loading @@ -695,6 +723,13 @@ public class RIL extends BaseCommands implements CommandsInterface { return rr; } private RILRequest obtainRequest(int request, Message result, WorkSource workSource, Object... args) { RILRequest rr = RILRequest.obtain(request, result, workSource, args); addRequest(rr); return rr; } private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) { riljLoge(caller + ": " + e); resetProxyAndRequestList(); Loading Loading @@ -1458,7 +1493,13 @@ public class RIL extends BaseCommands implements CommandsInterface { if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_VOICE_REGISTRATION_STATE); if (RILJ_LOGD) { riljLog("getVoiceRegistrationState: overrideHalVersion=" + overrideHalVersion); } if ((overrideHalVersion == null || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { final android.hardware.radio.V1_5.IRadio radioProxy15 = (android.hardware.radio.V1_5.IRadio) radioProxy; try { Loading @@ -1485,8 +1526,13 @@ public class RIL extends BaseCommands implements CommandsInterface { if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_DATA_REGISTRATION_STATE); if (RILJ_LOGD) { riljLog("getDataRegistrationState: overrideHalVersion=" + overrideHalVersion); } if ((overrideHalVersion == null || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { final android.hardware.radio.V1_5.IRadio radioProxy15 = (android.hardware.radio.V1_5.IRadio) radioProxy; try { Loading Loading @@ -2443,11 +2489,25 @@ public class RIL extends BaseCommands implements CommandsInterface { return rasInHalFormat; } /** * Radio HAL fallback compatibility feature (b/151106728) assumes that the input parameter * networkScanRequest is immutable (read-only) here. Once the caller invokes the method, the * parameter networkScanRequest should not be modified. This helps us keep a consistent and * simple data model that avoid copying it in the scan result. */ @Override public void startNetworkScan(NetworkScanRequest nsr, Message result) { public void startNetworkScan(NetworkScanRequest networkScanRequest, Message result) { final NetworkScanRequest nsr = networkScanRequest; IRadio radioProxy = getRadioProxy(result); if (radioProxy != null) { if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_START_NETWORK_SCAN); if (RILJ_LOGD) { riljLog("startNetworkScan: overrideHalVersion=" + overrideHalVersion); } if ((overrideHalVersion == null || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) { android.hardware.radio.V1_5.NetworkScanRequest request = new android.hardware.radio.V1_5.NetworkScanRequest(); request.type = nsr.getScanType(); Loading @@ -2469,7 +2529,7 @@ public class RIL extends BaseCommands implements CommandsInterface { request.mccMncs.addAll(nsr.getPlmns()); RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result, mRILDefaultWorkSource); mRILDefaultWorkSource, nsr); if (RILJ_LOGD) { riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); Loading Loading @@ -5514,6 +5574,28 @@ public class RIL extends BaseCommands implements CommandsInterface { } rr.onError(responseInfo.error, ret); } processResponseCleanUp(rr, responseInfo, ret); } /** * This is a helper function to be called at the end of all RadioResponse callbacks for * radio HAL fallback cases. It takes care of logging, decrementing wakelock if needed, and * releases the request from memory pool. Unlike processResponseDone, it will not send * error response to caller. * @param rr RILRequest for which response callback was called * @param responseInfo RadioResponseInfo received in the callback * @param ret object to be returned to request sender */ @VisibleForTesting public void processResponseFallback(RILRequest rr, RadioResponseInfo responseInfo, Object ret) { if (responseInfo.error == REQUEST_NOT_SUPPORTED && RILJ_LOGD) { riljLog(rr.serialString() + "< " + requestToString(rr.mRequest) + " request not supported, falling back"); } processResponseCleanUp(rr, responseInfo, ret); } private void processResponseCleanUp(RILRequest rr, RadioResponseInfo responseInfo, Object ret) { mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error, rr.mRequest, ret); if (rr != null) { Loading Loading @@ -6727,7 +6809,6 @@ public class RIL extends BaseCommands implements CommandsInterface { String[] pcscfs = null; List<LinkAddress> laList = new ArrayList<>(); int version; if (dcResult instanceof android.hardware.radio.V1_0.SetupDataCallResult) { final android.hardware.radio.V1_0.SetupDataCallResult result = Loading @@ -6750,9 +6831,12 @@ public class RIL extends BaseCommands implements CommandsInterface { if (!TextUtils.isEmpty(result.pcscf)) { pcscfs = result.pcscf.split("\\s+"); } mtu = result.mtu; mtuV4 = mtuV6 = 0; version = 0; mtu = mtuV4 = mtuV6 = result.mtu; if (addresses != null) { for (String address : addresses) { laList.add(createLinkAddressFromString(address)); } } } else if (dcResult instanceof android.hardware.radio.V1_4.SetupDataCallResult) { final android.hardware.radio.V1_4.SetupDataCallResult result = (android.hardware.radio.V1_4.SetupDataCallResult) dcResult; Loading @@ -6766,9 +6850,12 @@ public class RIL extends BaseCommands implements CommandsInterface { dnses = result.dnses.stream().toArray(String[]::new); gateways = result.gateways.stream().toArray(String[]::new); pcscfs = result.pcscf.stream().toArray(String[]::new); mtu = result.mtu; mtuV4 = mtuV6 = 0; version = 4; mtu = mtuV4 = mtuV6 = result.mtu; if (addresses != null) { for (String address : addresses) { laList.add(createLinkAddressFromString(address)); } } } else if (dcResult instanceof android.hardware.radio.V1_5.SetupDataCallResult) { final android.hardware.radio.V1_5.SetupDataCallResult result = (android.hardware.radio.V1_5.SetupDataCallResult) dcResult; Loading @@ -6785,24 +6872,14 @@ public class RIL extends BaseCommands implements CommandsInterface { dnses = result.dnses.stream().toArray(String[]::new); gateways = result.gateways.stream().toArray(String[]::new); pcscfs = result.pcscf.stream().toArray(String[]::new); mtu = 0; mtu = Math.max(result.mtuV4, result.mtuV6); mtuV4 = result.mtuV4; mtuV6 = result.mtuV6; version = 5; } else { Rlog.e(RILJ_LOG_TAG, "Unsupported SetupDataCallResult " + dcResult); return null; } if (version < 5) { // Process address if (addresses != null) { for (String address : addresses) { laList.add(createLinkAddressFromString(address)); } } } // Process dns List<InetAddress> dnsList = new ArrayList<>(); if (dnses != null) { Loading Loading @@ -6862,7 +6939,6 @@ public class RIL extends BaseCommands implements CommandsInterface { .setMtu(mtu) .setMtuV4(mtuV4) .setMtuV6(mtuV6) .setVersion(version) .build(); } Loading
src/java/com/android/internal/telephony/RILRequest.java +22 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ public class RILRequest { String mClientId; // time in ms when RIL request was made long mStartTimeMs; /** Argument list for radio HAL fallback method call */ Object[] mArguments; public int getSerial() { return mSerial; Loading Loading @@ -133,6 +135,25 @@ public class RILRequest { return rr; } /** * Retrieves a new RILRequest instance from the pool and sets the clientId * * @param request RIL_REQUEST_* * @param result sent when operation completes * @param workSource WorkSource to track the client * @param args The list of parameters used to call the fallback HAL method * @return a RILRequest instance from the pool. */ // @VisibleForTesting public static RILRequest obtain(int request, Message result, WorkSource workSource, Object... args) { RILRequest rr = obtain(request, result, workSource); rr.mArguments = args; return rr; } /** * Generate a String client ID from the WorkSource. */ Loading Loading @@ -175,6 +196,7 @@ public class RILRequest { + serialString()); } } mArguments = null; } } } Loading
src/java/com/android/internal/telephony/RadioResponse.java +71 −25 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.telephony.CarrierRestrictionRules; import android.telephony.CellInfo; import android.telephony.ModemActivityInfo; import android.telephony.NeighboringCellInfo; import android.telephony.NetworkScanRequest; import android.telephony.PhoneNumberUtils; import android.telephony.RadioAccessFamily; import android.telephony.SignalStrength; Loading Loading @@ -357,14 +358,27 @@ public class RadioResponse extends IRadioResponse.Stub { public void getVoiceRegistrationStateResponse_1_5(RadioResponseInfo responseInfo, android.hardware.radio.V1_5.RegStateResult voiceRegResponse) { RILRequest rr = mRil.processResponse(responseInfo); if (rr == null) { return; } if (rr != null) { if (responseInfo.error == RadioError.NONE) { if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED) { // Move the data needed for fallback call from rr which will be released soon final int request = rr.getRequest(); final Message result = rr.getResult(); mRil.mRilHandler.post(() -> { mRil.setCompatVersion(request, RIL.RADIO_HAL_VERSION_1_4); mRil.getVoiceRegistrationState(result); }); mRil.processResponseFallback(rr, responseInfo, voiceRegResponse); return; } else if (responseInfo.error == RadioError.NONE) { sendMessageResponse(rr.mResult, voiceRegResponse); } mRil.processResponseDone(rr, responseInfo, voiceRegResponse); } } /** * @param responseInfo Response info struct containing response type, serial no. and error Loading Loading @@ -425,14 +439,27 @@ public class RadioResponse extends IRadioResponse.Stub { public void getDataRegistrationStateResponse_1_5(RadioResponseInfo responseInfo, android.hardware.radio.V1_5.RegStateResult dataRegResponse) { RILRequest rr = mRil.processResponse(responseInfo); if (rr == null) { return; } if (rr != null) { if (responseInfo.error == RadioError.NONE) { if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED) { // Move the data needed for fallback call from rr which will be released soon final int request = rr.getRequest(); final Message result = rr.getResult(); mRil.mRilHandler.post(() -> { mRil.setCompatVersion(request, RIL.RADIO_HAL_VERSION_1_4); mRil.getDataRegistrationState(result); }); mRil.processResponseFallback(rr, responseInfo, dataRegResponse); return; } else if (responseInfo.error == RadioError.NONE) { sendMessageResponse(rr.mResult, dataRegResponse); } mRil.processResponseDone(rr, responseInfo, dataRegResponse); } } /** * @param responseInfo Response info struct containing response type, serial no. and error Loading Loading @@ -684,26 +711,26 @@ public class RadioResponse extends IRadioResponse.Stub { * @param responseInfo Response info struct containing response type, serial no. and error */ public void startNetworkScanResponse(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, null /*fallbackHalVersion*/); } /** * The same method as startNetworkScanResponse, except disallowing error codes * OPERATION_NOT_ALLOWED and REQUEST_NOT_SUPPORTED. * OPERATION_NOT_ALLOWED. * * @param responseInfo Response info struct containing response type, serial no. and error */ public void startNetworkScanResponse_1_4(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, null /*fallbackHalVersion*/); } /** * The same method as startNetworkScanResponse_1_5. * The same method as startNetworkScanResponse_1_4. * * @param responseInfo Response info struct containing response type, serial no. and error */ public void startNetworkScanResponse_1_5(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, RIL.RADIO_HAL_VERSION_1_4); } /** Loading @@ -711,7 +738,7 @@ public class RadioResponse extends IRadioResponse.Stub { * @param responseInfo Response info struct containing response type, serial no. and error */ public void stopNetworkScanResponse(RadioResponseInfo responseInfo) { responseScanStatus(responseInfo); responseScanStatus(responseInfo, null /*fallbackHalVersion*/); } /** Loading Loading @@ -2207,10 +2234,30 @@ public class RadioResponse extends IRadioResponse.Stub { } } private void responseScanStatus(RadioResponseInfo responseInfo) { private void responseScanStatus(RadioResponseInfo responseInfo, HalVersion fallbackHalVersion) { RILRequest rr = mRil.processResponse(responseInfo); if (rr == null) { return; } final boolean needFallback = responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED && fallbackHalVersion != null && rr.mArguments != null && rr.mArguments.length > 0 && rr.mArguments[0] instanceof NetworkScanRequest; if (needFallback) { // Move the data needed for fallback call from rr which will be released soon final int request = rr.getRequest(); final Message result = rr.getResult(); final NetworkScanRequest scanRequest = (NetworkScanRequest) rr.mArguments[0]; mRil.mRilHandler.post(() -> { mRil.setCompatVersion(request, RIL.RADIO_HAL_VERSION_1_4); mRil.startNetworkScan(scanRequest, result); }); mRil.processResponseFallback(rr, responseInfo, null); return; } if (rr != null) { NetworkScanResult nsr = null; if (responseInfo.error == RadioError.NONE) { nsr = new NetworkScanResult( Loading @@ -2219,7 +2266,6 @@ public class RadioResponse extends IRadioResponse.Stub { } mRil.processResponseDone(rr, responseInfo, nsr); } } private void responseDataCallList(RadioResponseInfo responseInfo, List<? extends Object> dataCallResultList) { Loading