From 7aceeb96f65b52891b94c919d30509f209c2d0c1 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Mon, 5 Feb 2024 08:21:22 -0800 Subject: Add minimal_telephony_cdm_check flag Bug: 310710841 Test: build & boot aosp_cf_x86_phone-eng Change-Id: Ia507d2d35317929208c1becfd4c051e13a066656 --- flags/telephony.aconfig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/flags/telephony.aconfig b/flags/telephony.aconfig index d59b249e99..b6aa8b9f6a 100644 --- a/flags/telephony.aconfig +++ b/flags/telephony.aconfig @@ -26,4 +26,11 @@ flag { namespace: "telephony" description: "This flag prevents repeat invocation of call related APIs in RIL when the device is not voice capable" bug: "290833783" -} \ No newline at end of file +} + +flag { + name: "minimal_telephony_cdm_check" + namespace: "telephony" + description: "This flag disables Calling/Data/Messaging features if their respective feature is missing" + bug: "310710841" +} -- cgit v1.2.3 From d07a68b9674152fbc2240664af1df290836e689d Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 12 Dec 2023 15:12:02 -0800 Subject: Fix Telephony stack for Minimal Automotive Telephony Bug: 310710841 Test: atest DataNetworkControllerTest Test: atest DataSettingsManagerTest Test: atest EmergencyNumberTrackerTest Test: atest GsmSmsTest Test: atest MultiSimSettingControllerTest Test: atest PhoneInterfaceManagerTest Test: atest RingerTest Test: Confirmed network registration and receiving a call notification (without picking it up) on Raven Change-Id: I21811d4103a4be8dd81c4ca5ede0e0cf58ea3c60 --- .../internal/telephony/GsmCdmaCallTracker.java | 9 +- .../android/internal/telephony/GsmCdmaPhone.java | 68 +++++++++++---- .../telephony/MultiSimSettingController.java | 97 +++++++++++++++------- .../android/internal/telephony/PhoneFactory.java | 2 +- src/java/com/android/internal/telephony/RIL.java | 47 ++++++++++- .../RadioInterfaceCapabilityController.java | 12 ++- .../telephony/TelephonyComponentFactory.java | 16 ++-- .../internal/telephony/data/DataNetwork.java | 23 +++-- .../telephony/data/DataNetworkController.java | 33 +++++--- .../telephony/data/DataSettingsManager.java | 23 ++++- .../emergency/EmergencyNumberTracker.java | 18 +++- .../com/android/internal/telephony/GsmSmsTest.java | 26 ++++-- .../telephony/MultiSimSettingControllerTest.java | 2 +- .../android/internal/telephony/TelephonyTest.java | 10 ++- .../telephony/data/DataNetworkControllerTest.java | 5 +- .../telephony/data/DataSettingsManagerTest.java | 2 +- .../emergency/EmergencyNumberTrackerTest.java | 40 +++++---- 17 files changed, 314 insertions(+), 119 deletions(-) diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java index 5517bc6f4e..9113514c75 100644 --- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.os.AsyncResult; import android.os.Build; import android.os.Bundle; @@ -159,6 +160,12 @@ public class GsmCdmaCallTracker extends CallTracker { public GsmCdmaCallTracker(GsmCdmaPhone phone, FeatureFlags featureFlags) { super(featureFlags); + if (mFeatureFlags.minimalTelephonyCdmCheck() + && !phone.getContext().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING)) { + throw new UnsupportedOperationException("GsmCdmaCallTracker requires calling"); + } + this.mPhone = phone; mCi = phone.mCi; mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); @@ -1492,7 +1499,7 @@ public class GsmCdmaCallTracker extends CallTracker { switch (msg.what) { case EVENT_POLL_CALLS_RESULT: - Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); + if (DBG_POLL) Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); if (msg == mLastRelevantPoll) { if (DBG_POLL) log( diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java index aca759b703..e76a8b03d7 100644 --- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java +++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java @@ -42,6 +42,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.database.SQLException; import android.hardware.radio.modem.ImeiInfo; import android.net.Uri; @@ -370,9 +371,11 @@ public class GsmCdmaPhone extends Phone { SignalStrengthController.class.getName()).makeSignalStrengthController(this); mSST = mTelephonyComponentFactory.inject(ServiceStateTracker.class.getName()) .makeServiceStateTracker(this, this.mCi, featureFlags); - mEmergencyNumberTracker = mTelephonyComponentFactory - .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker( - this, this.mCi); + if (hasCalling()) { + mEmergencyNumberTracker = mTelephonyComponentFactory + .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker( + this, this.mCi, mFeatureFlags); + } mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName()) .makeDeviceStateMonitor(this, mFeatureFlags); @@ -412,9 +415,11 @@ public class GsmCdmaPhone extends Phone { mCallWaitingController = new CallWaitingController(this); - loadTtyMode(); + if (hasCalling()) { + loadTtyMode(); - CallManager.getInstance().registerPhone(this); + CallManager.getInstance().registerPhone(this); + } mSubscriptionsChangedListener = new SubscriptionManager.OnSubscriptionsChangedListener() { @@ -464,13 +469,21 @@ public class GsmCdmaPhone extends Phone { } }; + private boolean hasCalling() { + if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; + return mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING); + } + private void initOnce(CommandsInterface ci) { if (ci instanceof SimulatedRadioControl) { mSimulatedRadioControl = (SimulatedRadioControl) ci; } - mCT = mTelephonyComponentFactory.inject(GsmCdmaCallTracker.class.getName()) - .makeGsmCdmaCallTracker(this, mFeatureFlags); + if (hasCalling()) { + mCT = mTelephonyComponentFactory.inject(GsmCdmaCallTracker.class.getName()) + .makeGsmCdmaCallTracker(this, mFeatureFlags); + } mIccPhoneBookIntManager = mTelephonyComponentFactory .inject(IccPhoneBookInterfaceManager.class.getName()) .makeIccPhoneBookInterfaceManager(this); @@ -693,7 +706,7 @@ public class GsmCdmaPhone extends Phone { unregisterForIccRecordEvents(); registerForIccRecordEvents(); - mCT.updatePhoneType(); + if (mCT != null) mCT.updatePhoneType(); int radioState = mCi.getRadioState(); if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE) { @@ -753,6 +766,8 @@ public class GsmCdmaPhone extends Phone { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public PhoneConstants.State getState() { + if (!hasCalling()) return PhoneConstants.State.IDLE; + if (mImsPhone != null) { PhoneConstants.State imsState = mImsPhone.getState(); if (imsState != PhoneConstants.State.IDLE) { @@ -837,6 +852,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean isDataSuspended() { + if (mCT == null) return false; return mCT.mState != PhoneConstants.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed(); } @@ -884,7 +900,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean isInEmergencyCall() { - if (isPhoneTypeGsm()) { + if (!hasCalling() || isPhoneTypeGsm()) { return false; } else { return mCT.isInEmergencyCall(); @@ -893,7 +909,7 @@ public class GsmCdmaPhone extends Phone { @Override protected void setIsInEmergencyCall() { - if (!isPhoneTypeGsm()) { + if (!hasCalling() && !isPhoneTypeGsm()) { mCT.setIsInEmergencyCall(); } } @@ -985,6 +1001,7 @@ public class GsmCdmaPhone extends Phone { @Override public void acceptCall(int videoState) throws CallStateException { + if (!hasCalling()) throw new CallStateException(); Phone imsPhone = mImsPhone; if ( imsPhone != null && imsPhone.getRingingCall().isRinging() ) { imsPhone.acceptCall(videoState); @@ -995,6 +1012,7 @@ public class GsmCdmaPhone extends Phone { @Override public void rejectCall() throws CallStateException { + if (!hasCalling()) throw new CallStateException(); mCT.rejectCall(); } @@ -1025,6 +1043,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean canConference() { + if (!hasCalling()) return false; if (mImsPhone != null && mImsPhone.canConference()) { return true; } @@ -1075,12 +1094,13 @@ public class GsmCdmaPhone extends Phone { @Override public void clearDisconnected() { + if (!hasCalling()) return; mCT.clearDisconnected(); } @Override public boolean canTransfer() { - if (isPhoneTypeGsm()) { + if (hasCalling() && isPhoneTypeGsm()) { return mCT.canTransfer(); } else { loge("canTransfer: not possible in CDMA"); @@ -1090,7 +1110,7 @@ public class GsmCdmaPhone extends Phone { @Override public void explicitCallTransfer() { - if (isPhoneTypeGsm()) { + if (hasCalling() && isPhoneTypeGsm()) { mCT.explicitCallTransfer(); } else { loge("explicitCallTransfer: not possible in CDMA"); @@ -1104,11 +1124,13 @@ public class GsmCdmaPhone extends Phone { @Override public GsmCdmaCall getBackgroundCall() { + if (!hasCalling()) return null; return mCT.mBackgroundCall; } @Override public Call getRingingCall() { + if (!hasCalling()) return null; Phone imsPhone = mImsPhone; // It returns the ringing call of ImsPhone if the ringing call of GSMPhone isn't ringing. // In CallManager.registerPhone(), it always registers ringing call of ImsPhone, because @@ -1184,7 +1206,7 @@ public class GsmCdmaPhone extends Phone { private boolean handleCallDeflectionIncallSupplementaryService( String dialString) { - if (dialString.length() > 1) { + if (!hasCalling() || dialString.length() > 1) { return false; } @@ -1209,7 +1231,7 @@ public class GsmCdmaPhone extends Phone { private boolean handleCallWaitingIncallSupplementaryService(String dialString) { int len = dialString.length(); - if (len > 2) { + if (!hasCalling() || len > 2) { return false; } @@ -1429,6 +1451,9 @@ public class GsmCdmaPhone extends Phone { @Override public Connection dial(String dialString, @NonNull DialArgs dialArgs, Consumer chosenPhoneConsumer) throws CallStateException { + if (!hasCalling()) { + throw new CallStateException("Calling feature is not supported!"); + } if (!isPhoneTypeGsm() && dialArgs.uusInfo != null) { throw new CallStateException("Sending UUS information NOT supported in CDMA!"); } @@ -2148,7 +2173,9 @@ public class GsmCdmaPhone extends Phone { @Override public int getEmergencyNumberDbVersion() { - return getEmergencyNumberTracker().getEmergencyNumberDbVersion(); + EmergencyNumberTracker tracker = getEmergencyNumberTracker(); + if (tracker == null) return -1; + return tracker.getEmergencyNumberDbVersion(); } @Override @@ -3134,6 +3161,8 @@ public class GsmCdmaPhone extends Phone { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void syncClirSetting() { + if (!hasCalling()) return; + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); migrateClirSettingIfNeeded(sp); @@ -3339,8 +3368,10 @@ public class GsmCdmaPhone extends Phone { if (b != null) { updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged(b); updateCdmaRoamingSettingsAfterCarrierConfigChanged(b); - updateNrSettingsAfterCarrierConfigChanged(b); - updateVoNrSettings(b); + if (hasCalling()) { + updateNrSettingsAfterCarrierConfigChanged(b); + updateVoNrSettings(b); + } updateSsOverCdmaSupported(b); updateCarrierN1ModeSupported(b); } else { @@ -4912,6 +4943,7 @@ public class GsmCdmaPhone extends Phone { * Handler of RIL Voice Radio Technology changed event. */ private void onVoiceRegStateOrRatChanged(int vrs, int vrat) { + if (!hasCalling()) return; logd("onVoiceRegStateOrRatChanged"); mCT.dispatchCsCallRadioTech(getCsCallRadioTech(vrs, vrat)); } @@ -5113,6 +5145,8 @@ public class GsmCdmaPhone extends Phone { * Load the current TTY mode in GsmCdmaPhone based on Telecom and UI settings. */ private void loadTtyMode() { + if (!hasCalling()) return; + int ttyMode = TelecomManager.TTY_MODE_OFF; TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); if (telecomManager != null) { diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java index 8488ab0359..aaeba23622 100644 --- a/src/java/com/android/internal/telephony/MultiSimSettingController.java +++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java @@ -35,6 +35,7 @@ import android.annotation.NonNull; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.AsyncResult; import android.os.Handler; import android.os.Looper; @@ -52,6 +53,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback; +import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.util.ArrayUtils; @@ -122,6 +124,7 @@ public class MultiSimSettingController extends Handler { protected final Context mContext; private final SubscriptionManagerService mSubscriptionManagerService; + private final @NonNull FeatureFlags mFeatureFlags; // Keep a record of active primary (non-opportunistic) subscription list. @NonNull private List mPrimarySubList = new ArrayList<>(); @@ -201,10 +204,11 @@ public class MultiSimSettingController extends Handler { /** * Init instance of MultiSimSettingController. */ - public static MultiSimSettingController init(Context context) { + public static MultiSimSettingController init(Context context, + @NonNull FeatureFlags featureFlags) { synchronized (MultiSimSettingController.class) { if (sInstance == null) { - sInstance = new MultiSimSettingController(context); + sInstance = new MultiSimSettingController(context, featureFlags); } else { Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); } @@ -213,9 +217,10 @@ public class MultiSimSettingController extends Handler { } @VisibleForTesting - public MultiSimSettingController(Context context) { + public MultiSimSettingController(Context context, @NonNull FeatureFlags featureFlags) { mContext = context; mSubscriptionManagerService = SubscriptionManagerService.getInstance(); + mFeatureFlags = featureFlags; // Initialize mCarrierConfigLoadedSubIds and register to listen to carrier config change. TelephonyManager telephonyManager = ((TelephonyManager) mContext.getSystemService( @@ -239,6 +244,24 @@ public class MultiSimSettingController extends Handler { onCarrierConfigChanged(slotIndex, subId)); } + private boolean hasCalling() { + if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; + return mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING); + } + + private boolean hasData() { + if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; + return mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_DATA); + } + + private boolean hasMessaging() { + if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; + return mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_MESSAGING); + } + /** * Notify MOBILE_DATA of a subscription is changed. */ @@ -606,35 +629,43 @@ public class MultiSimSettingController extends Handler { || mActiveModemCount == 1)) { int subId = mPrimarySubList.get(0); if (DBG) log("updateDefaultValues: to only primary sub " + subId); - mSubscriptionManagerService.setDefaultDataSubId(subId); - mSubscriptionManagerService.setDefaultVoiceSubId(subId); - mSubscriptionManagerService.setDefaultSmsSubId(subId); + if (hasData()) mSubscriptionManagerService.setDefaultDataSubId(subId); + if (hasCalling()) mSubscriptionManagerService.setDefaultVoiceSubId(subId); + if (hasMessaging()) mSubscriptionManagerService.setDefaultSmsSubId(subId); sendDefaultSubConfirmedNotification(subId); return; } if (DBG) log("updateDefaultValues: records: " + mPrimarySubList); - boolean dataSelected, voiceSelected, smsSelected; + boolean dataSelected = false; + boolean voiceSelected = false; + boolean smsSelected = false; - // Update default data subscription. - if (DBG) log("updateDefaultValues: Update default data subscription"); - dataSelected = updateDefaultValue(mPrimarySubList, - mSubscriptionManagerService.getDefaultDataSubId(), - mSubscriptionManagerService::setDefaultDataSubId); + if (hasData()) { + // Update default data subscription. + if (DBG) log("updateDefaultValues: Update default data subscription"); + dataSelected = updateDefaultValue(mPrimarySubList, + mSubscriptionManagerService.getDefaultDataSubId(), + mSubscriptionManagerService::setDefaultDataSubId); + } - // Update default voice subscription. - if (DBG) log("updateDefaultValues: Update default voice subscription"); - voiceSelected = updateDefaultValue(mPrimarySubList, - mSubscriptionManagerService.getDefaultVoiceSubId(), - mSubscriptionManagerService::setDefaultVoiceSubId); + if (hasCalling()) { + // Update default voice subscription. + if (DBG) log("updateDefaultValues: Update default voice subscription"); + voiceSelected = updateDefaultValue(mPrimarySubList, + mSubscriptionManagerService.getDefaultVoiceSubId(), + mSubscriptionManagerService::setDefaultVoiceSubId); + } - // Update default sms subscription. - if (DBG) log("updateDefaultValues: Update default sms subscription"); - smsSelected = updateDefaultValue(mPrimarySubList, - mSubscriptionManagerService.getDefaultSmsSubId(), - mSubscriptionManagerService::setDefaultSmsSubId, - mIsAskEverytimeSupportedForSms); + if (hasMessaging()) { + // Update default sms subscription. + if (DBG) log("updateDefaultValues: Update default sms subscription"); + smsSelected = updateDefaultValue(mPrimarySubList, + mSubscriptionManagerService.getDefaultSmsSubId(), + mSubscriptionManagerService::setDefaultSmsSubId, + mIsAskEverytimeSupportedForSms); + } boolean autoFallbackEnabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_voice_data_sms_auto_fallback); @@ -1023,11 +1054,11 @@ public class MultiSimSettingController extends Handler { int autoDefaultSubId = primarySubList.get(0); - if ((primarySubList.size() == 1) && !smsSelected) { + if (hasMessaging() && (primarySubList.size() == 1) && !smsSelected) { mSubscriptionManagerService.setDefaultSmsSubId(autoDefaultSubId); } - if ((primarySubList.size() == 1) && !voiceSelected) { + if (hasCalling() && (primarySubList.size() == 1) && !voiceSelected) { mSubscriptionManagerService.setDefaultVoiceSubId(autoDefaultSubId); } @@ -1036,13 +1067,15 @@ public class MultiSimSettingController extends Handler { log("User pref subId = " + userPrefDataSubId + " current dds " + defaultDataSubId + " next active subId " + autoDefaultSubId); - // If earlier user selected DDS is now available, set that as DDS subId. - if (primarySubList.contains(userPrefDataSubId) - && SubscriptionManager.isValidSubscriptionId(userPrefDataSubId) - && (defaultDataSubId != userPrefDataSubId)) { - mSubscriptionManagerService.setDefaultDataSubId(userPrefDataSubId); - } else if (!dataSelected) { - mSubscriptionManagerService.setDefaultDataSubId(autoDefaultSubId); + if (hasData()) { + // If earlier user selected DDS is now available, set that as DDS subId. + if (primarySubList.contains(userPrefDataSubId) + && SubscriptionManager.isValidSubscriptionId(userPrefDataSubId) + && (defaultDataSubId != userPrefDataSubId)) { + mSubscriptionManagerService.setDefaultDataSubId(userPrefDataSubId); + } else if (!dataSelected) { + mSubscriptionManagerService.setDefaultDataSubId(autoDefaultSubId); + } } if (DBG) { diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java index b1ff5002e2..e4d6fc951d 100644 --- a/src/java/com/android/internal/telephony/PhoneFactory.java +++ b/src/java/com/android/internal/telephony/PhoneFactory.java @@ -211,7 +211,7 @@ public class PhoneFactory { Looper.myLooper(), featureFlags); TelephonyComponentFactory.getInstance().inject(MultiSimSettingController.class. - getName()).initMultiSimSettingController(context); + getName()).initMultiSimSettingController(context, featureFlags); if (context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_EUICC)) { diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java index 5177adb3b9..8b3be1ea84 100644 --- a/src/java/com/android/internal/telephony/RIL.java +++ b/src/java/com/android/internal/telephony/RIL.java @@ -31,6 +31,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.content.pm.PackageManager; import android.hardware.radio.V1_0.IRadio; import android.hardware.radio.V1_0.RadioError; import android.hardware.radio.V1_0.RadioIndicationType; @@ -271,6 +272,13 @@ public class RIL extends BaseCommands implements CommandsInterface { static final String[] HIDL_SERVICE_NAME = {"slot1", "slot2", "slot3"}; + private static final Map FEATURES_TO_SERVICES = Map.ofEntries( + Map.entry(PackageManager.FEATURE_TELEPHONY_CALLING, HAL_SERVICE_VOICE), + Map.entry(PackageManager.FEATURE_TELEPHONY_DATA, HAL_SERVICE_DATA), + Map.entry(PackageManager.FEATURE_TELEPHONY_MESSAGING, HAL_SERVICE_MESSAGING), + Map.entry(PackageManager.FEATURE_TELEPHONY_IMS, HAL_SERVICE_IMS) + ); + public static List getTelephonyRILTimingHistograms() { List list; synchronized (sRilTimeHistograms) { @@ -621,6 +629,7 @@ public class RIL extends BaseCommands implements CommandsInterface { if (mDisabledRadioServices.get(HAL_SERVICE_RADIO).contains(mPhoneId)) { riljLoge("getRadioProxy: mRadioProxy for " + HIDL_SERVICE_NAME[mPhoneId] + " is disabled"); + return null; } else { try { mRadioProxy = android.hardware.radio.V1_6.IRadio.getService( @@ -662,6 +671,7 @@ public class RIL extends BaseCommands implements CommandsInterface { mDisabledRadioServices.get(HAL_SERVICE_RADIO).add(mPhoneId); riljLoge("getRadioProxy: set mRadioProxy for " + HIDL_SERVICE_NAME[mPhoneId] + " as disabled"); + return null; } } } catch (RemoteException e) { @@ -718,6 +728,9 @@ public class RIL extends BaseCommands implements CommandsInterface { public synchronized RadioServiceProxy getRadioServiceProxy(int service) { if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return mServiceProxies.get(service); if ((service >= HAL_SERVICE_IMS) && !isRadioServiceSupported(service)) { + riljLogw("getRadioServiceProxy: " + serviceToString(service) + " for " + + HIDL_SERVICE_NAME[mPhoneId] + " is not supported\n" + + android.util.Log.getStackTraceString(new RuntimeException())); return mServiceProxies.get(service); } if (!mIsCellularSupported) { @@ -733,7 +746,9 @@ public class RIL extends BaseCommands implements CommandsInterface { try { if (mMockModem == null && mDisabledRadioServices.get(service).contains(mPhoneId)) { riljLoge("getRadioServiceProxy: " + serviceToString(service) + " for " - + HIDL_SERVICE_NAME[mPhoneId] + " is disabled"); + + HIDL_SERVICE_NAME[mPhoneId] + " is disabled\n" + + android.util.Log.getStackTraceString(new RuntimeException())); + return null; } else { IBinder binder; switch (service) { @@ -944,7 +959,8 @@ public class RIL extends BaseCommands implements CommandsInterface { mDisabledRadioServices.get(service).add(mPhoneId); mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN); riljLoge("getRadioServiceProxy: set " + serviceToString(service) + " for " - + HIDL_SERVICE_NAME[mPhoneId] + " as disabled"); + + HIDL_SERVICE_NAME[mPhoneId] + " as disabled\n" + + android.util.Log.getStackTraceString(new RuntimeException())); } } } catch (RemoteException e) { @@ -1094,9 +1110,16 @@ public class RIL extends BaseCommands implements CommandsInterface { tdc.registerRIL(this); } + validateFeatureFlags(); + // Set radio callback; needed to set RadioIndication callback (should be done after // wakelock stuff is initialized above as callbacks are received on separate binder threads) for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) { + if (!isRadioServiceSupported(service)) { + riljLog("Not initializing " + serviceToString(service) + " (not supported)"); + continue; + } + if (service == HAL_SERVICE_RADIO) { getRadioProxy(); } else { @@ -1161,6 +1184,26 @@ public class RIL extends BaseCommands implements CommandsInterface { return false; } + private void validateFeatureFlags() { + PackageManager pm = mContext.getPackageManager(); + for (var entry : FEATURES_TO_SERVICES.entrySet()) { + String feature = entry.getKey(); + int service = entry.getValue(); + + boolean hasFeature = pm.hasSystemFeature(feature); + boolean hasService = isRadioServiceSupported(service); + + if (hasFeature && !hasService) { + riljLoge("Feature " + feature + " is declared, but service " + + serviceToString(service) + " is missing"); + } + if (!hasFeature && hasService) { + riljLoge("Service " + serviceToString(service) + " is available, but feature " + + feature + " is not declared"); + } + } + } + private boolean isRadioBugDetectionEnabled() { return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ENABLE_RADIO_BUG_DETECTION, 1) != 0; diff --git a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java index bab4d12185..4d9196e469 100644 --- a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java +++ b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java @@ -86,6 +86,13 @@ public class RadioInterfaceCapabilityController extends Handler { register(); } + private void requestCapabilities() { + if (mRadioInterfaceCapabilities != null) return; + + mRadioConfig.getHalDeviceCapabilities(obtainMessage( + EVENT_GET_HAL_DEVICE_CAPABILITIES_DONE)); + } + /** * Gets the radio interface capabilities for the device */ @@ -95,8 +102,7 @@ public class RadioInterfaceCapabilityController extends Handler { // Only incur cost of synchronization block if mRadioInterfaceCapabilities isn't null synchronized (mLockRadioInterfaceCapabilities) { if (mRadioInterfaceCapabilities == null) { - mRadioConfig.getHalDeviceCapabilities( - obtainMessage(EVENT_GET_HAL_DEVICE_CAPABILITIES_DONE)); + requestCapabilities(); try { if (Looper.myLooper() != getLooper()) { mLockRadioInterfaceCapabilities.wait(2000); @@ -158,7 +164,7 @@ public class RadioInterfaceCapabilityController extends Handler { switch (msg.what) { case Phone.EVENT_RADIO_AVAILABLE: case Phone.EVENT_RADIO_ON: - getCapabilities(); + requestCapabilities(); break; case EVENT_GET_HAL_DEVICE_CAPABILITIES_DONE: setupCapabilities((AsyncResult) msg.obj); diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java index f5aa0746c5..ba63c1299d 100644 --- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java +++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java @@ -305,8 +305,9 @@ public class TelephonyComponentFactory { /** * Create a new EmergencyNumberTracker. */ - public EmergencyNumberTracker makeEmergencyNumberTracker(Phone phone, CommandsInterface ci) { - return new EmergencyNumberTracker(phone, ci); + public EmergencyNumberTracker makeEmergencyNumberTracker(Phone phone, CommandsInterface ci, + @NonNull FeatureFlags featureFlags) { + return new EmergencyNumberTracker(phone, ci, featureFlags); } private static final boolean USE_NEW_NITZ_STATE_MACHINE = true; @@ -507,8 +508,9 @@ public class TelephonyComponentFactory { * @param c The context. * @return The multi sim settings controller instance. */ - public MultiSimSettingController initMultiSimSettingController(Context c) { - return MultiSimSettingController.init(c); + public MultiSimSettingController initMultiSimSettingController(Context c, + @NonNull FeatureFlags featureFlags) { + return MultiSimSettingController.init(c, featureFlags); } /** @@ -571,9 +573,11 @@ public class TelephonyComponentFactory { * @return The data settings manager instance. */ public @NonNull DataSettingsManager makeDataSettingsManager(@NonNull Phone phone, - @NonNull DataNetworkController dataNetworkController, @NonNull Looper looper, + @NonNull DataNetworkController dataNetworkController, + @NonNull FeatureFlags featureFlags, @NonNull Looper looper, @NonNull DataSettingsManager.DataSettingsManagerCallback callback) { - return new DataSettingsManager(phone, dataNetworkController, looper, callback); + return new DataSettingsManager(phone, dataNetworkController, featureFlags, looper, + callback); } /** Create CellularNetworkSecuritySafetySource. */ diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java index b99065b142..fde73726db 100644 --- a/src/java/com/android/internal/telephony/data/DataNetwork.java +++ b/src/java/com/android/internal/telephony/data/DataNetwork.java @@ -1171,12 +1171,14 @@ public class DataNetwork extends StateMachine { mPhone.getServiceStateTracker().registerForCssIndicatorChanged( getHandler(), EVENT_CSS_INDICATOR_CHANGED, null); - mPhone.getCallTracker().registerForVoiceCallStarted( - getHandler(), EVENT_VOICE_CALL_STARTED, null); - mPhone.getCallTracker().registerForVoiceCallEnded( - getHandler(), EVENT_VOICE_CALL_ENDED, null); + if (mPhone.getCallTracker() != null) { + mPhone.getCallTracker().registerForVoiceCallStarted( + getHandler(), EVENT_VOICE_CALL_STARTED, null); + mPhone.getCallTracker().registerForVoiceCallEnded( + getHandler(), EVENT_VOICE_CALL_ENDED, null); + } // Check null for devices not supporting FEATURE_TELEPHONY_IMS. - if (mPhone.getImsPhone() != null) { + if (mPhone.getImsPhone() != null && mPhone.getImsPhone().getCallTracker() != null) { mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted( getHandler(), EVENT_VOICE_CALL_STARTED, null); mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( @@ -1214,12 +1216,14 @@ public class DataNetwork extends StateMachine { } // Check null for devices not supporting FEATURE_TELEPHONY_IMS. - if (mPhone.getImsPhone() != null) { + if (mPhone.getImsPhone() != null && mPhone.getImsPhone().getCallTracker() != null) { mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallStarted(getHandler()); mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallEnded(getHandler()); } - mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler()); - mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler()); + if (mPhone.getCallTracker() != null) { + mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler()); + mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler()); + } mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler()); TelephonyManager tm = mPhone.getContext().getSystemService(TelephonyManager.class); @@ -2498,7 +2502,8 @@ public class DataNetwork extends StateMachine { newSuspendedState = true; // Check voice/data concurrency. } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed() - && mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { + && mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN + && mPhone.getCallTracker() != null) { newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; } diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java index 62449f5234..9ee291e805 100644 --- a/src/java/com/android/internal/telephony/data/DataNetworkController.java +++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java @@ -26,6 +26,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; @@ -425,6 +426,12 @@ public class DataNetworkController extends Handler { } }; + private boolean hasCalling() { + if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; + return mPhone.getContext().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING); + } + /** * The sorted network request list by priority. The highest priority network request stays at * the head of the list. The highest priority is 100, the lowest is 0. @@ -853,7 +860,7 @@ public class DataNetworkController extends Handler { mDataSettingsManager = TelephonyComponentFactory.getInstance().inject( DataSettingsManager.class.getName()) - .makeDataSettingsManager(mPhone, this, looper, + .makeDataSettingsManager(mPhone, this, mFeatureFlags, looper, new DataSettingsManagerCallback(this::post) { @Override public void onDataEnabledChanged(boolean enabled, @@ -1034,16 +1041,18 @@ public class DataNetworkController extends Handler { } }, this::post); - // Register for call ended event for voice/data concurrent not supported case. It is - // intended to only listen for events from the same phone as most of the telephony modules - // are designed as per-SIM basis. For DSDS call ended on non-DDS sub, the frameworks relies - // on service state on DDS sub change from out-of-service to in-service to trigger data - // retry. - mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_VOICE_CALL_ENDED, null); - // Check null for devices not supporting FEATURE_TELEPHONY_IMS. - if (mPhone.getImsPhone() != null) { - mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( - this, EVENT_VOICE_CALL_ENDED, null); + if (hasCalling()) { + // Register for call ended event for voice/data concurrent not supported case. It is + // intended to only listen for events from the same phone as most of the telephony + // modules are designed as per-SIM basis. For DSDS call ended on non-DDS sub, the + // frameworks relies on service state on DDS sub change from out-of-service to + // in-service to trigger data retry. + mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_VOICE_CALL_ENDED, null); + // Check null for devices not supporting FEATURE_TELEPHONY_IMS. + if (mPhone.getImsPhone() != null) { + mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( + this, EVENT_VOICE_CALL_ENDED, null); + } } mPhone.mCi.registerForSlicingConfigChanged(this, EVENT_SLICE_CONFIG_CHANGED, null); mPhone.mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null); @@ -1558,7 +1567,7 @@ public class DataNetworkController extends Handler { } // Check CS call state and see if concurrent voice/data is allowed. - if (mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE + if (hasCalling() && mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { evaluation.addDataDisallowedReason( DataDisallowedReason.CONCURRENT_VOICE_DATA_NOT_ALLOWED); diff --git a/src/java/com/android/internal/telephony/data/DataSettingsManager.java b/src/java/com/android/internal/telephony/data/DataSettingsManager.java index e54f6d382e..51e5b7d8f1 100644 --- a/src/java/com/android/internal/telephony/data/DataSettingsManager.java +++ b/src/java/com/android/internal/telephony/data/DataSettingsManager.java @@ -20,6 +20,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.content.ContentResolver; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -47,6 +48,7 @@ import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.SettingsObserver; import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback; +import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.metrics.DeviceTelephonyPropertiesStats; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; @@ -57,6 +59,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.stream.Collectors; @@ -88,6 +91,7 @@ public class DataSettingsManager extends Handler { private static final int EVENT_INITIALIZE = 11; private final Phone mPhone; + private final @NonNull FeatureFlags mFeatureFlags; private final ContentResolver mResolver; private final SettingsObserver mSettingsObserver; private final String mLogTag; @@ -178,10 +182,12 @@ public class DataSettingsManager extends Handler { * @param callback Data settings manager callback. */ public DataSettingsManager(@NonNull Phone phone, - @NonNull DataNetworkController dataNetworkController, @NonNull Looper looper, + @NonNull DataNetworkController dataNetworkController, + @NonNull FeatureFlags featureFlags, @NonNull Looper looper, @NonNull DataSettingsManagerCallback callback) { super(looper); mPhone = phone; + mFeatureFlags = Objects.requireNonNull(featureFlags); mLogTag = "DSMGR-" + mPhone.getPhoneId(); log("DataSettingsManager created."); mSubId = mPhone.getSubId(); @@ -264,6 +270,12 @@ public class DataSettingsManager extends Handler { } } + private boolean hasCalling() { + if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; + return mPhone.getContext().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING); + } + /** * Called when needed to register for all events that data network controller is interested. */ @@ -281,9 +293,12 @@ public class DataSettingsManager extends Handler { mSettingsObserver.observe( Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED), EVENT_PROVISIONING_DATA_ENABLED_CHANGED); - mPhone.getCallTracker().registerForVoiceCallStarted(this, EVENT_CALL_STATE_CHANGED, null); - mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_CALL_STATE_CHANGED, null); - if (mPhone.getImsPhone() != null) { + if (hasCalling()) { + mPhone.getCallTracker().registerForVoiceCallStarted(this, EVENT_CALL_STATE_CHANGED, + null); + mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_CALL_STATE_CHANGED, null); + } + if (hasCalling() && mPhone.getImsPhone() != null) { mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted( this, EVENT_CALL_STATE_CHANGED, null); mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded( diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java index e2418c5acd..02dd613b88 100644 --- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java +++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java @@ -16,10 +16,12 @@ package com.android.internal.telephony.emergency; +import android.annotation.NonNull; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.os.AsyncResult; import android.os.Environment; @@ -48,6 +50,7 @@ import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.ServiceStateTracker; +import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.metrics.EmergencyNumberStats; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nano.PersistAtomsProto; @@ -102,6 +105,7 @@ public class EmergencyNumberTracker extends Handler { private final CommandsInterface mCi; private final Phone mPhone; + private final @NonNull FeatureFlags mFeatureFlags; private int mPhoneId; private String mCountryIso; private String mLastKnownEmergencyCountryIso = ""; @@ -173,10 +177,20 @@ public class EmergencyNumberTracker extends Handler { } }; - public EmergencyNumberTracker(Phone phone, CommandsInterface ci) { + public EmergencyNumberTracker(Phone phone, CommandsInterface ci, + @NonNull FeatureFlags featureFlags) { + Context ctx = phone.getContext(); + mPhone = phone; mCi = ci; - mResources = mPhone.getContext().getResources(); + mFeatureFlags = featureFlags; + mResources = ctx.getResources(); + + if (mFeatureFlags.minimalTelephonyCdmCheck() + && !ctx.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING)) { + throw new UnsupportedOperationException("EmergencyNumberTracker requires calling"); + } if (mPhone != null) { mPhoneId = phone.getPhoneId(); diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java index 776715c9a1..41fd45aab7 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java @@ -16,10 +16,12 @@ package com.android.internal.telephony; +import android.content.pm.PackageManager; import android.telephony.TelephonyManager; import android.test.AndroidTestCase; import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.telephony.gsm.SmsMessage; import com.android.internal.util.HexDump; @@ -28,6 +30,12 @@ import java.util.ArrayList; public class GsmSmsTest extends AndroidTestCase { + private boolean hasMessaging() { + final PackageManager pm = InstrumentationRegistry.getInstrumentation().getContext() + .getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING); + } + @SmallTest public void testAddressing() throws Exception { String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E"; @@ -258,8 +266,8 @@ public class GsmSmsTest extends AndroidTestCase { @SmallTest public void testFragmentText() throws Exception { - boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == - TelephonyManager.PHONE_TYPE_GSM); + boolean isGsmPhoneWithMessaging = (TelephonyManager.getDefault().getPhoneType() + == TelephonyManager.PHONE_TYPE_GSM) && hasMessaging(); // Valid 160 character 7-bit text. String text = "123456789012345678901234567890123456789012345678901234567890" + @@ -271,7 +279,7 @@ public class GsmSmsTest extends AndroidTestCase { assertEquals(1, ted.codeUnitSize); assertEquals(0, ted.languageTable); assertEquals(0, ted.languageShiftTable); - if (isGsmPhone) { + if (isGsmPhoneWithMessaging) { ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); assertEquals(1, fragments.size()); } @@ -286,7 +294,7 @@ public class GsmSmsTest extends AndroidTestCase { assertEquals(1, ted.codeUnitSize); assertEquals(0, ted.languageTable); assertEquals(0, ted.languageShiftTable); - if (isGsmPhone) { + if (isGsmPhoneWithMessaging) { ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); assertEquals(2, fragments.size()); assertEquals(text, fragments.get(0) + fragments.get(1)); @@ -297,8 +305,8 @@ public class GsmSmsTest extends AndroidTestCase { @SmallTest public void testFragmentTurkishText() throws Exception { - boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == - TelephonyManager.PHONE_TYPE_GSM); + boolean isGsmPhoneWithMessaging = (TelephonyManager.getDefault().getPhoneType() + == TelephonyManager.PHONE_TYPE_GSM) && hasMessaging(); int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables(); int[] turkishTable = { 1 }; @@ -313,7 +321,7 @@ public class GsmSmsTest extends AndroidTestCase { assertEquals(1, ted.codeUnitSize); assertEquals(0, ted.languageTable); assertEquals(1, ted.languageShiftTable); - if (isGsmPhone) { + if (isGsmPhoneWithMessaging) { ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); assertEquals(1, fragments.size()); assertEquals(text, fragments.get(0)); @@ -329,7 +337,7 @@ public class GsmSmsTest extends AndroidTestCase { assertEquals(1, ted.codeUnitSize); assertEquals(0, ted.languageTable); assertEquals(1, ted.languageShiftTable); - if (isGsmPhone) { + if (isGsmPhoneWithMessaging) { ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); assertEquals(2, fragments.size()); assertEquals(text, fragments.get(0) + fragments.get(1)); @@ -347,7 +355,7 @@ public class GsmSmsTest extends AndroidTestCase { assertEquals(1, ted.codeUnitSize); assertEquals(0, ted.languageTable); assertEquals(1, ted.languageShiftTable); - if (isGsmPhone) { + if (isGsmPhoneWithMessaging) { ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); assertEquals(3, fragments.size()); assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2)); diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java index 4c68e2640b..a7e9604c23 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java @@ -255,7 +255,7 @@ public class MultiSimSettingControllerTest extends TelephonyTest { // Capture listener to emulate the carrier config change notification used later ArgumentCaptor listenerArgumentCaptor = ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class); - mMultiSimSettingControllerUT = new MultiSimSettingController(mContext); + mMultiSimSettingControllerUT = new MultiSimSettingController(mContext, mFeatureFlags); processAllMessages(); verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(), listenerArgumentCaptor.capture()); diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java index a6e06e385b..50e6eedef5 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java @@ -577,6 +577,8 @@ public abstract class TelephonyTest { mDomainSelectionResolver = Mockito.mock(DomainSelectionResolver.class); mNullCipherNotifier = Mockito.mock(NullCipherNotifier.class); + doReturn(true).when(mFeatureFlags).minimalTelephonyCdmCheck(); + TelephonyManager.disableServiceHandleCaching(); PropertyInvalidatedCache.disableForTestMode(); // For testing do not allow Log.WTF as it can cause test process to crash @@ -640,7 +642,7 @@ public abstract class TelephonyTest { nullable(CommandsInterface.class), nullable(FeatureFlags.class)); doReturn(mEmergencyNumberTracker).when(mTelephonyComponentFactory) .makeEmergencyNumberTracker(nullable(Phone.class), - nullable(CommandsInterface.class)); + nullable(CommandsInterface.class), any(FeatureFlags.class)); doReturn(getTestEmergencyNumber()).when(mEmergencyNumberTracker) .getEmergencyNumber(any()); doReturn(mUiccProfile).when(mTelephonyComponentFactory) @@ -821,6 +823,12 @@ public abstract class TelephonyTest { doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt()); doReturn(true).when(mTelephonyManager).isDataCapable(); + mContextFixture.addSystemFeature(PackageManager.FEATURE_TELECOM); + mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING); + mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_DATA); + mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_EUICC); + mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING); + doReturn(TelephonyManager.PHONE_TYPE_GSM).when(mTelephonyManager).getPhoneType(); doReturn(mServiceState).when(mSST).getServiceState(); doReturn(mServiceStateStats).when(mSST).getServiceStateStats(); diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java index a4598d3fab..a4ba1772a3 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java @@ -865,7 +865,7 @@ public class DataNetworkControllerTest extends TelephonyTest { mMockSubInfo = Mockito.mock(SubscriptionInfo.class); mFeatureFlags = Mockito.mock(FeatureFlags.class); when(mTelephonyComponentFactory.makeDataSettingsManager(any(Phone.class), - any(DataNetworkController.class), any(Looper.class), + any(DataNetworkController.class), any(FeatureFlags.class), any(Looper.class), any(DataSettingsManager.DataSettingsManagerCallback.class))).thenCallRealMethod(); doReturn(mMockedImsMmTelManager).when(mMockedImsManager).getImsMmTelManager(anyInt()); doReturn(mMockedImsRcsManager).when(mMockedImsManager).getImsRcsManager(anyInt()); @@ -1850,7 +1850,8 @@ public class DataNetworkControllerTest extends TelephonyTest { boolean isDataEnabled = mDataNetworkControllerUT.getDataSettingsManager().isDataEnabled(); doReturn(mDataNetworkControllerUT.getDataSettingsManager()) .when(mPhone).getDataSettingsManager(); - MultiSimSettingController controller = Mockito.spy(new MultiSimSettingController(mContext)); + MultiSimSettingController controller = Mockito.spy(new MultiSimSettingController(mContext, + mFeatureFlags)); doReturn(true).when(controller).isCarrierConfigLoadedForAllSub(); replaceInstance(MultiSimSettingController.class, "sInstance", null, controller); diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java index fc1bf0da85..3f18a3a94b 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java @@ -77,7 +77,7 @@ public class DataSettingsManagerTest extends TelephonyTest { .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt()); mDataSettingsManagerUT = new DataSettingsManager(mPhone, mDataNetworkController, - Looper.myLooper(), mMockedDataSettingsManagerCallback); + mFeatureFlags, Looper.myLooper(), mMockedDataSettingsManagerCallback); logd("DataSettingsManagerTest -Setup!"); } diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java index c47eb3beae..10dbfea768 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java @@ -51,7 +51,6 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; -import com.android.internal.telephony.ServiceStateTracker; import com.android.internal.telephony.TelephonyTest; import com.google.i18n.phonenumbers.ShortNumberInfo; @@ -61,6 +60,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import java.io.BufferedInputStream; @@ -139,7 +139,7 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { mShortNumberInfo = mock(ShortNumberInfo.class); mCarrierConfigManagerMock = mock(CarrierConfigManager.class); - mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()); + mContext = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); mMockContext = mock(Context.class); mResources = mock(Resources.class); @@ -151,9 +151,14 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { doReturn(1).when(mPhone2).getPhoneId(); doReturn(SUB_ID_PHONE_2).when(mPhone2).getSubId(); + doReturn(mPackageManager).when(mContext).getPackageManager(); + doReturn(mPackageManager).when(mMockContext).getPackageManager(); + initializeEmergencyNumberListTestSamples(); - mEmergencyNumberTrackerMock = new EmergencyNumberTracker(mPhone, mSimulatedCommands); - mEmergencyNumberTrackerMock2 = new EmergencyNumberTracker(mPhone2, mSimulatedCommands); + mEmergencyNumberTrackerMock = new EmergencyNumberTracker(mPhone, mSimulatedCommands, + mFeatureFlags); + mEmergencyNumberTrackerMock2 = new EmergencyNumberTracker(mPhone2, mSimulatedCommands, + mFeatureFlags); doReturn(mEmergencyNumberTrackerMock2).when(mPhone2).getEmergencyNumberTracker(); mEmergencyNumberTrackerMock.DBG = true; @@ -171,10 +176,13 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { public void tearDown() throws Exception { // Set back to single sim mode setSinglePhone(); - Path target = Paths.get(mLocalDownloadDirectory.getPath(), EMERGENCY_NUMBER_DB_OTA_FILE); - Files.deleteIfExists(target); - mLocalDownloadDirectory.delete(); - mLocalDownloadDirectory = null; + if (mLocalDownloadDirectory != null) { + Path target = Paths.get(mLocalDownloadDirectory.getPath(), + EMERGENCY_NUMBER_DB_OTA_FILE); + Files.deleteIfExists(target); + mLocalDownloadDirectory.delete(); + mLocalDownloadDirectory = null; + } mEmergencyNumberTrackerMock = null; mEmergencyNumberTrackerMock2 = null; mEmergencyNumberListTestSample.clear(); @@ -361,12 +369,12 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { @Test public void testRegistrationForCountryChangeIntent() throws Exception { EmergencyNumberTracker localEmergencyNumberTracker; - Context spyContext = spy(mContext); - doReturn(spyContext).when(mPhone).getContext(); + Mockito.clearInvocations(mContext); ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(IntentFilter.class); - localEmergencyNumberTracker = new EmergencyNumberTracker(mPhone, mSimulatedCommands); - verify(spyContext, times(1)).registerReceiver(any(), intentCaptor.capture()); + localEmergencyNumberTracker = new EmergencyNumberTracker(mPhone, mSimulatedCommands, + mFeatureFlags); + verify(mContext, times(1)).registerReceiver(any(), intentCaptor.capture()); IntentFilter ifilter = intentCaptor.getValue(); assertTrue(ifilter.hasAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)); } @@ -543,7 +551,7 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { com.android.internal.R.bool.ignore_emergency_number_routing_from_db); EmergencyNumberTracker emergencyNumberTrackerMock = new EmergencyNumberTracker( - mPhone, mSimulatedCommands); + mPhone, mSimulatedCommands, mFeatureFlags); emergencyNumberTrackerMock.sendMessage( emergencyNumberTrackerMock.obtainMessage( 1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */, @@ -616,7 +624,7 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { com.android.internal.R.bool.ignore_emergency_number_routing_from_db); EmergencyNumberTracker emergencyNumberTrackerMock = new EmergencyNumberTracker( - mPhone, mSimulatedCommands); + mPhone, mSimulatedCommands, mFeatureFlags); emergencyNumberTrackerMock.sendMessage( emergencyNumberTrackerMock.obtainMessage( 1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */, @@ -720,7 +728,7 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { com.android.internal.R.bool.ignore_emergency_number_routing_from_db); EmergencyNumberTracker emergencyNumberTrackerMock = new EmergencyNumberTracker( - mPhone, mSimulatedCommands); + mPhone, mSimulatedCommands, mFeatureFlags); emergencyNumberTrackerMock.sendMessage( emergencyNumberTrackerMock.obtainMessage( 1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */, @@ -843,7 +851,7 @@ public class EmergencyNumberTrackerTest extends TelephonyTest { ArgumentCaptor listenerArgumentCaptor = ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class); EmergencyNumberTracker localEmergencyNumberTracker = - new EmergencyNumberTracker(mPhone, mSimulatedCommands); + new EmergencyNumberTracker(mPhone, mSimulatedCommands, mFeatureFlags); verify(mCarrierConfigManagerMock) .registerCarrierConfigChangeListener(any(), listenerArgumentCaptor.capture()); CarrierConfigManager.CarrierConfigChangeListener carrierConfigChangeListener = -- cgit v1.2.3