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

Commit e450a1fe authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Remove deadlock between Telecom and Telephony

Telecom was holding its lock when calling into
TelephonyManager, which would sometimes cause a deadlock.

Bug: 141455427
Test: manual
Change-Id: I8b89dfd89b79c6d34a21ef8d6f1a505efcdcdb18
parent b1b03d15
Loading
Loading
Loading
Loading
+79 −73
Original line number Diff line number Diff line
@@ -581,7 +581,6 @@ public class TelecomServiceImpl {
        public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) {
            try {
                Log.startSession("TSI.gVMN");
                synchronized (mLock) {
                if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
                    return null;
                }
@@ -594,16 +593,17 @@ public class TelecomServiceImpl {
                        return null;
                    }
                    int subId = mSubscriptionManagerAdapter.getDefaultVoiceSubId();
                    synchronized (mLock) {
                        if (accountHandle != null) {
                            subId = mPhoneAccountRegistrar
                                    .getSubscriptionIdForPhoneAccount(accountHandle);
                        }
                    }
                    return getTelephonyManager().getVoiceMailNumber(subId);
                } catch (Exception e) {
                    Log.e(this, e, "getSubscriptionIdForPhoneAccount");
                    throw e;
                }
                }
            } finally {
                Log.endSession();
            }
@@ -620,7 +620,6 @@ public class TelecomServiceImpl {
                    return null;
                }

                synchronized (mLock) {
                final UserHandle callingUserHandle = Binder.getCallingUserHandle();
                if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
                        callingUserHandle)) {
@@ -630,8 +629,11 @@ public class TelecomServiceImpl {

                long token = Binder.clearCallingIdentity();
                try {
                        int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
                    int subId;
                    synchronized (mLock) {
                        subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
                                accountHandle);
                    }
                    return getTelephonyManager().getLine1Number(subId);
                } catch (Exception e) {
                    Log.e(this, e, "getSubscriptionIdForPhoneAccount");
@@ -639,7 +641,6 @@ public class TelecomServiceImpl {
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                }
            } finally {
                Log.endSession();
            }
@@ -929,7 +930,6 @@ public class TelecomServiceImpl {
        public boolean handlePinMmi(String dialString, String callingPackage) {
            try {
                Log.startSession("TSI.hPM");
                synchronized (mLock) {
                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);

                // Switch identity so that TelephonyManager checks Telecom's permissions
@@ -943,7 +943,6 @@ public class TelecomServiceImpl {
                }

                return retval;
                }
            }finally {
                Log.endSession();
            }
@@ -957,29 +956,33 @@ public class TelecomServiceImpl {
                String dialString, String callingPackage) {
            try {
                Log.startSession("TSI.hPMFPA");
                synchronized (mLock) {
                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);

                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
                UserHandle callingUserHandle = Binder.getCallingUserHandle();
                synchronized (mLock) {
                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
                            callingUserHandle)) {
                        Log.d(this, "%s is not visible for the calling user [hMMI]", accountHandle);
                        Log.d(this, "%s is not visible for the calling user [hMMI]",
                                accountHandle);
                        return false;
                    }
                }

                // Switch identity so that TelephonyManager checks Telecom's permissions
                // instead.
                long token = Binder.clearCallingIdentity();
                boolean retval = false;
                int subId;
                try {
                        int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
                    synchronized (mLock) {
                        subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
                                accountHandle);
                    }
                    retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                return retval;
                }
            }finally {
                Log.endSession();
            }
@@ -993,14 +996,15 @@ public class TelecomServiceImpl {
                String callingPackage) {
            try {
                Log.startSession("TSI.aAUFPA");
                synchronized (mLock) {
                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
                synchronized (mLock) {
                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
                            Binder.getCallingUserHandle())) {
                        Log.d(this, "%s is not visible for the calling user [gA4PA]",
                                accountHandle);
                        return null;
                    }
                }
                // Switch identity so that TelephonyManager checks Telecom's permissions
                // instead.
                long token = Binder.clearCallingIdentity();
@@ -1014,7 +1018,6 @@ public class TelecomServiceImpl {
                }

                return Uri.parse(retval);
                }
            } finally {
                Log.endSession();
            }
@@ -1757,7 +1760,10 @@ public class TelecomServiceImpl {

    private boolean isPhoneAccountHandleVisibleToCallingUser(
            PhoneAccountHandle phoneAccountUserHandle, UserHandle callingUser) {
        return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser) != null;
        synchronized (mLock) {
            return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser)
                    != null;
        }
    }

    private boolean isCallerSystemApp() {