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

Commit 9cc2f6d8 authored by Pranav Madapurmath's avatar Pranav Madapurmath Committed by Android (Google) Code Review
Browse files

Merge "Support notion of ECBM for work profiles." into udc-dev

parents 70411eee 93383385
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -414,6 +414,16 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,

    private boolean mIsEmergencyCall;

    /**
     * Flag indicating if ECBM is active for the target phone account. This only applies to MT calls
     * in the scenario of work profiles (when the profile is paused and the user has only registered
     * a work sim). Normally, MT calls made to the work sim should be rejected when the work apps
     * are paused. However, when the admin makes a MO ecall, ECBM should be enabled for that sim to
     * allow non-emergency MT calls. MO calls don't apply because the phone account would be
     * rejected from selection if the owner is not placing the call.
     */
    private boolean mIsInECBM;

    // The Call is considered an emergency call for testing, but will not actually connect to
    // emergency services.
    private boolean mIsTestEmergencyCall;
@@ -1591,6 +1601,21 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        return mIsTestEmergencyCall;
    }

    /**
     * @return {@code true} if the target phone account is in ECBM.
     */
    public boolean isInECBM() {
        return mIsInECBM;
    }

    /**
     * Set if the target phone account is in ECBM.
     * @param isInEcbm {@code true} if target phone account is in ECBM, {@code false} otherwise.
     */
    public void setIsInECBM(boolean isInECBM) {
        mIsInECBM = isInECBM;
    }

    /**
     * @return {@code true} if the network has identified this call as an emergency call.
     */
@@ -1682,6 +1707,11 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
    public void setTargetPhoneAccount(PhoneAccountHandle accountHandle) {
        if (!Objects.equals(mTargetPhoneAccountHandle, accountHandle)) {
            mTargetPhoneAccountHandle = accountHandle;
            // Update the last MO emergency call in the helper, if applicable.
            if (isEmergencyCall() && !isIncoming()) {
                mCallsManager.getEmergencyCallHelper().setLastOutgoingEmergencyCallPAH(
                        accountHandle);
            }
            for (Listener l : mListeners) {
                l.onTargetPhoneAccountChanged(this);
            }
+19 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.provider.CallLog.Calls.SHORT_RING_THRESHOLD;
import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
import static android.provider.CallLog.Calls.USER_MISSED_CALL_SCREENING_SERVICE_SILENCED;
import static android.provider.CallLog.Calls.USER_MISSED_NEVER_RANG;
import static android.provider.CallLog.Calls.USER_MISSED_NOT_RUNNING;
import static android.provider.CallLog.Calls.USER_MISSED_NO_ANSWER;
import static android.provider.CallLog.Calls.USER_MISSED_SHORT_RING;
import static android.telecom.TelecomManager.ACTION_POST_CALL;
@@ -446,6 +447,7 @@ public class CallsManager extends Call.ListenerBase
    private final CallStreamingController mCallStreamingController;
    private final BlockedNumbersAdapter mBlockedNumbersAdapter;
    private final TransactionManager mTransactionManager;
    private final UserManager mUserManager;

    private final ConnectionServiceFocusManager.CallsManagerRequester mRequester =
            new ConnectionServiceFocusManager.CallsManagerRequester() {
@@ -685,6 +687,7 @@ public class CallsManager extends Call.ListenerBase

        mCallAnomalyWatchdog = callAnomalyWatchdog;
        mAsyncTaskExecutor = asyncTaskExecutor;
        mUserManager = mContext.getSystemService(UserManager.class);
    }

    public void setIncomingCallNotifier(IncomingCallNotifier incomingCallNotifier) {
@@ -1534,7 +1537,22 @@ public class CallsManager extends Call.ListenerBase

        CallFailureCause startFailCause =
                checkIncomingCallPermitted(call, call.getTargetPhoneAccount());
        if (!isHandoverAllowed ||
        // Check if the target phone account is possibly in ECBM.
        call.setIsInECBM(getEmergencyCallHelper()
                .isLastOutgoingEmergencyCallPAH(call.getTargetPhoneAccount()));
        if (mUserManager.isQuietModeEnabled(call.getUserHandleFromTargetPhoneAccount())
                && !call.isEmergencyCall() && !call.isInECBM()) {
            Log.d(TAG, "Rejecting non-emergency call because the owner %s is not running.",
                    phoneAccountHandle.getUserHandle());
            call.setMissedReason(USER_MISSED_NOT_RUNNING);
            call.setStartFailCause(CallFailureCause.INVALID_USE);
            if (isConference) {
                notifyCreateConferenceFailed(phoneAccountHandle, call);
            } else {
                notifyCreateConnectionFailed(phoneAccountHandle, call);
            }
        }
        else if (!isHandoverAllowed ||
                (call.isSelfManaged() && !startFailCause.isSuccess())) {
            if (isConference) {
                notifyCreateConferenceFailed(phoneAccountHandle, call);
+33 −6
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.telecom.Log;
import android.telecom.PhoneAccountHandle;

import com.android.internal.annotations.VisibleForTesting;

/**
@@ -34,6 +36,7 @@ public class EmergencyCallHelper {
    private final DefaultDialerCache mDefaultDialerCache;
    private final Timeouts.Adapter mTimeoutsAdapter;
    private UserHandle mLocationPermissionGrantedToUser;
    private PhoneAccountHandle mLastOutgoingEmergencyCallPAH;

    //stores the original state of permissions that dialer had
    private boolean mHadFineLocation = false;
@@ -46,6 +49,7 @@ public class EmergencyCallHelper {
    private boolean mBackgroundLocationGranted = false;

    private long mLastEmergencyCallTimestampMillis;
    private long mLastOutgoingEmergencyCallTimestampMillis;

    @VisibleForTesting
    public EmergencyCallHelper(
@@ -63,7 +67,7 @@ public class EmergencyCallHelper {
            grantLocationPermission(userHandle);
        }
        if (call != null && call.isEmergencyCall()) {
            recordEmergencyCallTime();
            recordEmergencyCall(call);
        }
    }

@@ -78,15 +82,37 @@ public class EmergencyCallHelper {
        return mLastEmergencyCallTimestampMillis;
    }

    private void recordEmergencyCallTime() {
        mLastEmergencyCallTimestampMillis = System.currentTimeMillis();
    void setLastOutgoingEmergencyCallPAH(PhoneAccountHandle accountHandle) {
        mLastOutgoingEmergencyCallPAH = accountHandle;
    }

    public boolean isLastOutgoingEmergencyCallPAH(PhoneAccountHandle currentCallHandle) {
        boolean ecbmActive = mLastOutgoingEmergencyCallPAH != null
                && isInEmergencyCallbackWindow(mLastOutgoingEmergencyCallTimestampMillis)
                && currentCallHandle != null
                && currentCallHandle.equals(mLastOutgoingEmergencyCallPAH);
        if (ecbmActive) {
            Log.i(this, "ECBM is enabled for %s. The last recorded call timestamp was at %s",
                    currentCallHandle, mLastOutgoingEmergencyCallTimestampMillis);
        }

        return ecbmActive;
    }

    private boolean isInEmergencyCallbackWindow() {
        return System.currentTimeMillis() - getLastEmergencyCallTimeMillis()
    boolean isInEmergencyCallbackWindow(long lastEmergencyCallTimestampMillis) {
        return System.currentTimeMillis() - lastEmergencyCallTimestampMillis
                < mTimeoutsAdapter.getEmergencyCallbackWindowMillis(mContext.getContentResolver());
    }

    private void recordEmergencyCall(Call call) {
        mLastEmergencyCallTimestampMillis = System.currentTimeMillis();
        if (!call.isIncoming()) {
            // ECBM is applicable to MO emergency calls
            mLastOutgoingEmergencyCallTimestampMillis = mLastEmergencyCallTimestampMillis;
            mLastOutgoingEmergencyCallPAH = call.getTargetPhoneAccount();
        }
    }

    private boolean shouldGrantTemporaryLocationPermission(Call call) {
        if (!mContext.getResources().getBoolean(R.bool.grant_location_permission_enabled)) {
            Log.i(this, "ShouldGrantTemporaryLocationPermission, disabled by config");
@@ -96,7 +122,8 @@ public class EmergencyCallHelper {
            Log.i(this, "ShouldGrantTemporaryLocationPermission, no call");
            return false;
        }
        if (!call.isEmergencyCall() && !isInEmergencyCallbackWindow()) {
        if (!call.isEmergencyCall() && !isInEmergencyCallbackWindow(
                getLastEmergencyCallTimeMillis())) {
            Log.i(this, "ShouldGrantTemporaryLocationPermission, not emergency");
            return false;
        }
+6 −2
Original line number Diff line number Diff line
@@ -338,7 +338,10 @@ public class InCallController extends CallsManagerListenerBase implements
            UserHandle userToBind = getUserFromCall(call);
            boolean isManagedProfile = UserUtil.isManagedProfile(mContext, userToBind);
            // Note that UserHandle.CURRENT fails to capture the work profile, so we need to handle
            // it separately to ensure that the ICS is bound to the appropriate user.
            // it separately to ensure that the ICS is bound to the appropriate user. If ECBM is
            // active, we know that a work sim was previously used to place a MO emergency call. We
            // need to ensure that we bind to the CURRENT_USER in this case, as the work user would
            // not be running (handled in getUserFromCall).
            userToBind = isManagedProfile ? userToBind : UserHandle.CURRENT;
            if (!mContext.bindServiceAsUser(intent, mServiceConnection,
                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
@@ -2601,7 +2604,8 @@ public class InCallController extends CallsManagerListenerBase implements
            UserManager userManager = mContext.getSystemService(UserManager.class);
            // Emergency call should never be blocked, so if the user associated with call is in
            // quite mode, use the primary user for the emergency call.
            if (call.isEmergencyCall() && userManager.isQuietModeEnabled(userFromCall)) {
            if ((call.isEmergencyCall() || call.isInECBM())
                    && userManager.isQuietModeEnabled(userFromCall)) {
                return mCallsManager.getCurrentUserHandle();
            }
            return userFromCall;
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.BlockedNumberContract;
import android.telecom.Call;
import android.telecom.CallAudioState;
Loading