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

Commit cc2d187f authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Ensure Telecom catches UnsupportedOperationException from Telephony.

Telephony now enforces that various pkg mgr features are available and will
throw UnsupportedOperationExceptions if the features are not available.
Telecom needs to catch these and respond in a reasonable manner or the
system service will crash.

Fixes: 331853393
Test: Basis regression tests.
Test: Run existing unit tests.
Test: Add new unit tests for new code paths.
Change-Id: I37550b4d3c9ff8b7ec4f4e0ffc09c8450f616ccd
parent 104c22a1
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -720,6 +720,7 @@ public class Analytics {
    }

    private static int getCarrierId(Context context) {
        try {
            SubscriptionManager subscriptionManager =
                    context.getSystemService(SubscriptionManager.class).createForAllUserProfiles();
            List<SubscriptionInfo> subInfos = subscriptionManager.getActiveSubscriptionInfoList();
@@ -729,6 +730,9 @@ public class Analytics {
            return subInfos.stream()
                    .max(Comparator.comparing(Analytics::scoreSubscriptionInfo))
                    .map(SubscriptionInfo::getCarrierId).orElse(-1);
        } catch (UnsupportedOperationException ignored) {
            return -1;
        }
    }

    // Copied over from Telephony's server-side logic for consistency
+12 −2
Original line number Diff line number Diff line
@@ -1573,6 +1573,9 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
                    mIsEmergencyCall = mHandle != null &&
                            getTelephonyManager().isEmergencyNumber(
                                    mHandle.getSchemeSpecificPart());
                } catch (UnsupportedOperationException use) {
                    Log.i(this, "setHandle: no FEATURE_TELEPHONY; emergency state unknown.");
                    mIsEmergencyCall = false;
                } catch (IllegalStateException ise) {
                    Log.e(this, ise, "setHandle: can't determine if number is emergency");
                    mIsEmergencyCall = false;
@@ -1601,6 +1604,9 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
                    .anyMatch(eNumber ->
                            eNumber.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST) &&
                                    number.equals(eNumber.getNumber()));
        } catch (UnsupportedOperationException uoe) {
            // No Telephony feature, so unable to determine.
            return false;
        } catch (IllegalStateException ise) {
            return false;
        } catch (RuntimeException r) {
@@ -3740,10 +3746,14 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        }

        // Is there a valid SMS application on the phone?
        try {
            if (mContext.getSystemService(TelephonyManager.class)
                    .getAndUpdateDefaultRespondViaMessageApplication() == null) {
                return false;
            }
        } catch (UnsupportedOperationException uoe) {
            return false;
        }

        // TODO: with some carriers (in certain countries) you *can* actually
        // tell whether a given number is a mobile phone or not. So in that
+34 −15
Original line number Diff line number Diff line
@@ -856,10 +856,16 @@ public class CallsManager extends Call.ListenerBase
                ? new Bundle()
                : phoneAccount.getExtras();
        TelephonyManager telephonyManager = getTelephonyManager();
        boolean isInEmergencySmsMode;
        try {
            isInEmergencySmsMode = telephonyManager.isInEmergencySmsMode();
        } catch (UnsupportedOperationException uoe) {
            isInEmergencySmsMode = false;
        }
        boolean performDndFilter = mFeatureFlags.skipFilterPhoneAccountPerformDndFilter();
        if (incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE) ||
                incomingCall.hasProperty(Connection.PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL) ||
                telephonyManager.isInEmergencySmsMode() ||
                isInEmergencySmsMode ||
                incomingCall.isSelfManaged() ||
                (!performDndFilter && extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING))) {
            Log.i(this, "Skipping call filtering for %s (ecm=%b, "
@@ -868,7 +874,7 @@ public class CallsManager extends Call.ListenerBase
                    incomingCall.getId(),
                    incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE),
                    incomingCall.hasProperty(Connection.PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL),
                    telephonyManager.isInEmergencySmsMode(),
                    isInEmergencySmsMode,
                    incomingCall.isSelfManaged(),
                    extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING));
            onCallFilteringComplete(incomingCall, new Builder()
@@ -1406,7 +1412,7 @@ public class CallsManager extends Call.ListenerBase
        return mCallEndpointController;
    }

    EmergencyCallHelper getEmergencyCallHelper() {
    public EmergencyCallHelper getEmergencyCallHelper() {
        return mEmergencyCallHelper;
    }

@@ -1914,6 +1920,7 @@ public class CallsManager extends Call.ListenerBase

            // Log info for emergency call
            if (call.isEmergencyCall()) {
                try {
                    String simNumeric = "";
                    String networkNumeric = "";
                    int defaultVoiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
@@ -1927,6 +1934,11 @@ public class CallsManager extends Call.ListenerBase
                    TelecomStatsLog.write(TelecomStatsLog.EMERGENCY_NUMBER_DIALED,
                            handle.getSchemeSpecificPart(),
                            callingPackage, simNumeric, networkNumeric);
                } catch (UnsupportedOperationException uoe) {
                    // Ignore; likely we should not be able to get here since emergency calls
                    // require Telephony at the current time, however that could change in the
                    // future, so we best be safe.
                }
            }

            // Ensure new calls related to self-managed calls/connections are set as such.  This
@@ -2681,6 +2693,9 @@ public class CallsManager extends Call.ListenerBase
            isEmergencyNumber =
                    handle != null && getTelephonyManager().isEmergencyNumber(
                            handle.getSchemeSpecificPart());
        } catch (UnsupportedOperationException uoe) {
            // If device has no telephony, we can't check if it is an emergency call.
            isEmergencyNumber = false;
        } catch (IllegalStateException ise) {
            isEmergencyNumber = false;
        } catch (RuntimeException r) {
@@ -3481,11 +3496,15 @@ public class CallsManager extends Call.ListenerBase
    }

    // Returns whether the device is capable of 2 simultaneous active voice calls on different subs.
    private boolean isDsdaCallingPossible() {
    @VisibleForTesting
    public boolean isDsdaCallingPossible() {
        try {
            return getTelephonyManager().getMaxNumberOfSimultaneouslyActiveSims() > 1
                    || getTelephonyManager().getPhoneCapability()
                           .getMaxActiveVoiceSubscriptions() > 1;
        } catch(UnsupportedOperationException uoe) {
            Log.w(this, "Telephony not supported");
            return false;
        } catch (Exception e) {
            Log.w(this, "exception in isDsdaCallingPossible(): ", e);
            return false;
+6 −3
Original line number Diff line number Diff line
@@ -1407,20 +1407,23 @@ public class ConnectionServiceWrapper extends ServiceBinder implements
        }
    }

    private CellIdentity getLastKnownCellIdentity() {
    @VisibleForTesting
    public CellIdentity getLastKnownCellIdentity() {
        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
        if (telephonyManager != null) {
            CellIdentity lastKnownCellIdentity = telephonyManager.getLastKnownCellIdentity();
            try {
                CellIdentity lastKnownCellIdentity = telephonyManager.getLastKnownCellIdentity();
                mAppOpsManager.noteOp(AppOpsManager.OP_FINE_LOCATION,
                        mContext.getPackageManager().getPackageUid(
                                getComponentName().getPackageName(), 0),
                        getComponentName().getPackageName());
                return lastKnownCellIdentity;
            } catch (UnsupportedOperationException ignored) {
                Log.w(this, "getLastKnownCellIdentity - no telephony on this device");
            } catch (PackageManager.NameNotFoundException nameNotFoundException) {
                Log.e(this, nameNotFoundException, "could not find the package -- %s",
                        getComponentName().getPackageName());
            }
            return lastKnownCellIdentity;
        }
        return null;
    }
+13 −3
Original line number Diff line number Diff line
@@ -103,22 +103,32 @@ public class CreateConnectionProcessor implements CreateConnectionResponse {
        int getSlotIndex(int subId);
    }

    private ITelephonyManagerAdapter mTelephonyAdapter = new ITelephonyManagerAdapter() {
    public static class ITelephonyManagerAdapterImpl implements ITelephonyManagerAdapter {
        @Override
        public int getSubIdForPhoneAccount(Context context, PhoneAccount account) {
            TelephonyManager manager = context.getSystemService(TelephonyManager.class);
            if (manager == null) {
                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
            }
            try {
                return manager.getSubscriptionId(account.getAccountHandle());
            } catch (UnsupportedOperationException uoe) {
                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
            }
        }

        @Override
        public int getSlotIndex(int subId) {
            try {
                return SubscriptionManager.getSlotIndex(subId);
            } catch (UnsupportedOperationException uoe) {
                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
            }
        }
    };

    private ITelephonyManagerAdapter mTelephonyAdapter = new ITelephonyManagerAdapterImpl();

    private final Call mCall;
    private final ConnectionServiceRepository mRepository;
    private List<CallAttemptRecord> mAttemptRecords;
Loading