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

Commit 7601e75e authored by Shuo Qian's avatar Shuo Qian Committed by android-build-merger
Browse files

Merge "User Interaction for Call Redirection service in Telecom"

am: 7a5f11b8

Change-Id: Ib3572e03ae6324a3da134e02c949bcaae0b2cafb
parents d9ac861a 7a5f11b8
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -235,6 +235,8 @@
                <action android:name="com.android.server.telecom.ACTION_REJECT_FROM_NOTIFICATION" />
                <action android:name="com.android.server.telecom.PROCEED_WITH_CALL" />
                <action android:name="com.android.server.telecom.CANCEL_CALL" />
                <action android:name="com.android.server.telecom.PROCEED_WITH_REDIRECTED_CALL" />
                <action android:name="com.android.server.telecom.CANCEL_REDIRECTED_CALL" />
            </intent-filter>
        </receiver>

@@ -285,6 +287,22 @@
                android:process=":ui">
        </activity>

        <activity android:name=".ui.CallRedirectionConfirmDialogActivity"
                  android:configChanges="orientation|screenSize|keyboardHidden"
                  android:excludeFromRecents="true"
                  android:launchMode="singleInstance"
                  android:theme="@style/Theme.Telecomm.Transparent"
                  android:process=":ui">
        </activity>

        <activity android:name=".ui.CallRedirectionTimeoutDialogActivity"
                  android:configChanges="orientation|screenSize|keyboardHidden"
                  android:excludeFromRecents="true"
                  android:launchMode="singleInstance"
                  android:theme="@style/Theme.Telecomm.Transparent"
                  android:process=":ui">
        </activity>

        <activity android:name=".components.ChangeDefaultDialerDialog"
                  android:label="@string/change_default_dialer_dialog_title"
                  android:excludeFromRecents="true"
+6 −0
Original line number Diff line number Diff line
@@ -281,6 +281,12 @@
         ongoing call in the app "other_app". -->
    <string name="alert_outgoing_call">Placing this call will end your <xliff:g id="other_app">%1$s</xliff:g> call.</string>

    <!-- Alert dialog content used to ask the user to confirm if they want to place a new outgoing call redirected by the app "other_app". -->
    <string name="alert_redirect_outgoing_call">Allow <xliff:g id="other_app">%1$s</xliff:g> to place call using a different number or account.</string>

    <!-- Alert dialog content used to tell the user the call is canceled because no response from the call redirection app "other_app". -->
    <string name="alert_redirect_outgoing_call_timeout">Call can\'t be placed by <xliff:g id="other_app">%1$s</xliff:g>. Try using a different call redirecting app or contacting the developer for help.</string>

    <!-- The name of a feature available under the Call settings. -->
    <string name="phone_settings_call_blocking_txt">Call Blocking</string>
    <!-- Call type to be blocked. See the explanatory text "phone_settings_number_not_in_contact_summary_txt". -->
+89 −4
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Pair;
import android.widget.Toast;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.AsyncEmergencyContactNotifier;
@@ -81,8 +82,11 @@ import com.android.server.telecom.callfiltering.CallFilteringResult;
import com.android.server.telecom.callfiltering.CallScreeningServiceController;
import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter;
import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.components.ErrorDialogActivity;
import com.android.server.telecom.settings.BlockedNumbersUtil;
import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity;
import com.android.server.telecom.ui.CallRedirectionTimeoutDialogActivity;
import com.android.server.telecom.ui.ConfirmCallDialogActivity;
import com.android.server.telecom.ui.IncomingCallNotifier;

@@ -242,6 +246,18 @@ public class CallsManager extends Call.ListenerBase
     * Used by {@link #startCallConfirmation}.
     */
    private Call mPendingCall;
    /**
     * Cached latest pending redirected call which requires user-intervention in order to be placed.
     * Used by {@link #onCallRedirectionComplete}.
     */
    private Call mPendingRedirectedOutgoingCall;
    /**
     * Cached latest pending redirected call information which require user-intervention in order
     * to be placed. Used by {@link #onCallRedirectionComplete}.
     */
    private final Map<String, Runnable> mPendingRedirectionOutgoingCallInfo =
            new ConcurrentHashMap<>();

    private CompletableFuture<Call> mPendingCallConfirm;
    private CompletableFuture<Pair<Call, PhoneAccountHandle>> mPendingAccountSelection;

@@ -1698,11 +1714,24 @@ public class CallsManager extends Call.ListenerBase
        boolean endEarly = false;
        String disconnectReason = "";

        String callRedirectionApp = mRoleManagerAdapter.getDefaultCallRedirectionApp();

        if (shouldCancelCall) {
            Log.w(this, "onCallRedirectionComplete: call is canceled");
            endEarly = true;
            disconnectReason = "Canceled from Call Redirection Service";
            // TODO show UI uiAction is CallRedirectionProcessor#UI_TYPE_USER_DEFINED_TIMEOUT
            // Show UX when user-defined call redirection service does not response; the UX
            // is not needed to show if the call is disconnected (e.g. by the user)
            if (uiAction.equals(CallRedirectionProcessor.UI_TYPE_USER_DEFINED_TIMEOUT)
                    && !call.isDisconnected()) {
                Intent timeoutIntent = new Intent(mContext,
                        CallRedirectionTimeoutDialogActivity.class);
                timeoutIntent.putExtra(
                        CallRedirectionTimeoutDialogActivity.EXTRA_REDIRECTION_APP_NAME,
                        mRoleManagerAdapter.getApplicationLabelForPackageName(callRedirectionApp));
                timeoutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mContext.startActivityAsUser(timeoutIntent, UserHandle.CURRENT);
            }
        } else if (handle == null) {
            Log.w(this, "onCallRedirectionComplete: handle is null");
            endEarly = true;
@@ -1732,11 +1761,67 @@ public class CallsManager extends Call.ListenerBase
            return;
        }

        // TODO show UI uiAction is CallRedirectionProcessor#UI_TYPE_USER_DEFINED_ASK_FOR_CONFIRM
        if (uiAction.equals(CallRedirectionProcessor.UI_TYPE_USER_DEFINED_ASK_FOR_CONFIRM)) {
            Log.addEvent(call, LogUtils.Events.REDIRECTION_USER_CONFIRMATION);
            mPendingRedirectedOutgoingCall = call;

            mPendingRedirectionOutgoingCallInfo.put(call.getId(),
                    new Runnable("CM.oCRC", mLock) {
                        @Override
                        public void loggedRun() {
                            Log.addEvent(call, LogUtils.Events.REDIRECTION_USER_CONFIRMED);
                            call.setTargetPhoneAccount(phoneAccountHandle);
                            placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn,
                                    videoState);
                        }
                    });

            Log.i(this, "onCallRedirectionComplete: UI_TYPE_USER_DEFINED_ASK_FOR_CONFIRM "
                    + "callId=%s, callRedirectionAppName=%s",
                    call.getId(), callRedirectionApp);

            Intent confirmIntent = new Intent(mContext,
                    CallRedirectionConfirmDialogActivity.class);
            confirmIntent.putExtra(
                    CallRedirectionConfirmDialogActivity.EXTRA_REDIRECTION_OUTGOING_CALL_ID,
                    call.getId());
            confirmIntent.putExtra(CallRedirectionConfirmDialogActivity.EXTRA_REDIRECTION_APP_NAME,
                    mRoleManagerAdapter.getApplicationLabelForPackageName(callRedirectionApp));
            confirmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivityAsUser(confirmIntent, UserHandle.CURRENT);
        } else {
            call.setTargetPhoneAccount(phoneAccountHandle);
            placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn, videoState);
        }
    }

    public void placeRedirectedOutgoingCallAfterUserInteraction(String callId) {
        Log.i(this, "placeRedirectedOutgoingCallAfterUserInteraction for Call ID %s", callId);
        if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId()
                .equals(callId)) {
            mHandler.post(mPendingRedirectionOutgoingCallInfo.get(callId).prepare());
            mPendingRedirectedOutgoingCall = null;
            mPendingRedirectionOutgoingCallInfo.remove(callId);
        } else {
            Log.w(this, "placeRedirectedOutgoingCallAfterUserInteraction for non-matched Call ID "
                    + " %s with handle %s and phoneAccountHandle %s", callId);
        }
    }

    public void cancelRedirectedOutgoingCallAfterUserInteraction(String callId) {
        Log.i(this, "cancelRedirectedOutgoingCallAfterUserInteraction for Call ID %s", callId);
        if (mPendingRedirectedOutgoingCall != null && mPendingRedirectedOutgoingCall.getId()
                .equals(callId)) {
            Log.addEvent(mPendingRedirectedOutgoingCall,
                    LogUtils.Events.REDIRECTION_USER_CANCELLED);
            mPendingRedirectedOutgoingCall.disconnect("User canceled the redirected call.");
            mPendingRedirectedOutgoingCall = null;
            mPendingRedirectionOutgoingCallInfo.remove(callId);
        } else {
            Log.w(this, "cancelRedirectedOutgoingCallAfterUserInteraction for non-matched Call"
                    + " ID ", callId);
        }
    }

    /**
     * Attempts to issue/connect the specified call.
+3 −0
Original line number Diff line number Diff line
@@ -149,6 +149,9 @@ public class LogUtils {
        public static final String REDIRECTION_COMPLETED_CARRIER = "REDIRECTION_COMPLETED_CARRIER";
        public static final String REDIRECTION_TIMED_OUT_USER = "REDIRECTION_TIMED_OUT_USER";
        public static final String REDIRECTION_TIMED_OUT_CARRIER = "REDIRECTION_TIMED_OUT_CARRIER";
        public static final String REDIRECTION_USER_CONFIRMATION = "REDIRECTION_USER_CONFIRMATION";
        public static final String REDIRECTION_USER_CONFIRMED = "REDIRECTION_USER_CONFIRMED";
        public static final String REDIRECTION_USER_CANCELLED = "REDIRECTION_USER_CANCELLED";

        public static class Timings {
            public static final String ACCEPT_TIMING = "accept";
+7 −0
Original line number Diff line number Diff line
@@ -87,4 +87,11 @@ public interface RoleManagerAdapter {
     * @param currentUserHandle The new user handle.
     */
    void setCurrentUserHandle(UserHandle currentUserHandle);

    /**
     * Returns the application label that corresponds to the given package name.
     * @param packageName A valid package name.
     * @return Application label for the given package name, or null if not found.
     */
    String getApplicationLabelForPackageName(String packageName);
}
Loading