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

Commit a7a44d91 authored by Tyler Gunn's avatar Tyler Gunn Committed by android-build-merger
Browse files

Handover API cleanup.

am: 7c031f22

Change-Id: Ice65485609cbfd35f7ab1f12fe21f7efe1440fb0
parents 012c9271 7c031f22
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        void onHandoverRequested(Call call, PhoneAccountHandle handoverTo, int videoState,
                                 Bundle extras, boolean isLegacy);
        void onHandoverFailed(Call call, int error);
        void onHandoverComplete(Call call);
    }

    public abstract static class ListenerBase implements Listener {
@@ -214,6 +215,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
                                        Bundle extras, boolean isLegacy) {}
        @Override
        public void onHandoverFailed(Call call, int error) {}
        @Override
        public void onHandoverComplete(Call call) {}
    }

    private final CallerInfoLookupHelper.OnQueryCompleteListener mCallerInfoQueryListener =
@@ -2778,7 +2781,26 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        }
    }

    /**
     * Notifies interested parties that the handover has completed.
     * Notifies:
     * 1. {@link InCallController} which communicates this to the
     * {@link android.telecom.InCallService} via {@link Listener#onHandoverComplete()}.
     * 2. {@link ConnectionServiceWrapper} which informs the {@link android.telecom.Connection} of
     * the successful handover.
     */
    public void onHandoverComplete() {
        Log.i(this, "onHandoverComplete; callId=%s", getId());
        if (mConnectionService != null) {
            mConnectionService.handoverComplete(this);
        }
        for (Listener l : mListeners) {
            l.onHandoverComplete(this);
        }
    }

    public void onHandoverFailed(int handoverError) {
        Log.i(this, "onHandoverFailed; callId=%s, handoverError=%d", getId(), handoverError);
        for (Listener l : mListeners) {
            l.onHandoverFailed(this, handoverError);
        }
+30 −10
Original line number Diff line number Diff line
@@ -2415,8 +2415,11 @@ public class CallsManager extends Call.ListenerBase
        // completed; this allows the InCallService to be notified that a handover it
        // initiated completed.
        call.onConnectionEvent(Connection.EVENT_HANDOVER_COMPLETE, null);
        call.onHandoverComplete();

        // Inform the "to" ConnectionService that handover to it has completed.
        handoverTo.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_COMPLETE, null);
        handoverTo.onHandoverComplete();
        answerCall(handoverTo, handoverTo.getVideoState());
        call.markFinishedHandoverStateAndCleanup(HandoverState.HANDOVER_COMPLETE);

@@ -3227,8 +3230,12 @@ public class CallsManager extends Call.ListenerBase
    }

    private void setIntentExtrasAndStartTime(Call call, Bundle extras) {
        if (extras != null) {
            // Create our own instance to modify (since extras may be Bundle.EMPTY)
            extras = new Bundle(extras);
        } else {
            extras = new Bundle();
        }

        // Specifies the time telecom began routing the call. This is used by the dialer for
        // analytics.
@@ -3272,7 +3279,6 @@ public class CallsManager extends Call.ListenerBase
        service.handoverFailed(call, reason);
        call.setDisconnectCause(new DisconnectCause(DisconnectCause.CANCELED));
        call.disconnect();

    }

    /**
@@ -3338,7 +3344,7 @@ public class CallsManager extends Call.ListenerBase
     * @param handoverFromCall The {@link Call} to be handed over.
     * @param handoverToHandle The {@link PhoneAccountHandle} to hand over the call to.
     * @param videoState The desired video state of {@link Call} after handover.
     * @param initiatingExtras Extras associated with the handover, to be passed to the handover
     * @param extras Extras associated with the handover, to be passed to the handover
     *               {@link android.telecom.ConnectionService}.
     */
    private void requestHandover(Call handoverFromCall, PhoneAccountHandle handoverToHandle,
@@ -3384,8 +3390,6 @@ public class CallsManager extends Call.ListenerBase
        }
        call.setInitiatingUser(getCurrentUserHandle());



        // Ensure we don't try to place an outgoing call with video if video is not
        // supported.
        if (VideoProfile.isVideo(videoState) && account != null &&
@@ -3409,6 +3413,14 @@ public class CallsManager extends Call.ListenerBase
        call.setState(
                CallState.CONNECTING,
                handoverToHandle == null ? "no-handle" : handoverToHandle.toString());

        // Mark as handover so that the ConnectionService knows this is a handover request.
        if (extras == null) {
            extras = new Bundle();
        }
        extras.putBoolean(TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, true);
        extras.putParcelable(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT,
                handoverFromCall.getTargetPhoneAccount());
        setIntentExtrasAndStartTime(call, extras);

        // Add call to call tracker
@@ -3619,6 +3631,14 @@ public class CallsManager extends Call.ListenerBase
            call.setStartWithSpeakerphoneOn(true);
        }

        Bundle extras = call.getIntentExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        extras.putBoolean(TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, true);
        extras.putParcelable(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT,
                fromCall.getTargetPhoneAccount());

        call.startCreateConnection(mPhoneAccountRegistrar);
    }

+28 −0
Original line number Diff line number Diff line
@@ -1106,6 +1106,34 @@ public class ConnectionServiceWrapper extends ServiceBinder implements
        mBinder.bind(callback, call);
    }

    void handoverComplete(final Call call) {
        Log.d(this, "handoverComplete(%s) via %s.", call, getComponentName());
        BindCallback callback = new BindCallback() {
            @Override
            public void onSuccess() {
                final String callId = mCallIdMapper.getCallId(call);
                // If still bound, tell the connection service create connection has failed.
                if (callId != null && isServiceValid("handoverComplete")) {
                    try {
                        mServiceInterface.handoverComplete(
                                callId,
                                Log.getExternalSession());
                    } catch (RemoteException e) {
                    }
                }
            }

            @Override
            public void onFailure() {
                // Binding failed.
                Log.w(this, "onFailure - could not bind to CS for call %s",
                        call.getId());
            }
        };

        mBinder.bind(callback, call);
    }

    /** @see IConnectionService#abort(String, Session.Info)  */
    void abort(Call call) {
        // Clear out any pending outgoing call data
+16 −0
Original line number Diff line number Diff line
@@ -681,6 +681,11 @@ public class InCallController extends CallsManagerListenerBase {
            notifyHandoverFailed(call, error);
        }

        @Override
        public void onHandoverComplete(Call call) {
            notifyHandoverComplete(call);
        }

        @Override
        public void onRttInitiationFailure(Call call, int reason) {
            notifyRttInitiationFailure(call, reason);
@@ -1037,6 +1042,17 @@ public class InCallController extends CallsManagerListenerBase {
        }
    }

    private void notifyHandoverComplete(Call call) {
        if (!mInCallServices.isEmpty()) {
            for (IInCallService inCallService : mInCallServices.values()) {
                try {
                    inCallService.onHandoverComplete(mCallIdMapper.getCallId(call));
                } catch (RemoteException ignored) {
                }
            }
        }
    }

    /**
     * Unbinds an existing bound connection to the in-call app.
     */
+33 −2
Original line number Diff line number Diff line
@@ -1089,8 +1089,10 @@ public class TelecomServiceImpl {
            try {
                Log.startSession("TSI.aHO");
                synchronized (mLock) {
                    Log.i(this, "Handover call to phoneAccountHandle %s",
                    Log.i(this, "acceptHandover; srcAddr=%s, videoState=%s, dest=%s",
                            Log.pii(srcAddr), VideoProfile.videoStateToString(videoState),
                            destAcct);

                    if (destAcct != null && destAcct.getComponentName() != null) {
                        mAppOpsManager.checkPackage(
                                Binder.getCallingUid(),
@@ -1105,8 +1107,19 @@ public class TelecomServiceImpl {
                                    "Self-managed phone accounts must have MANAGE_OWN_CALLS " +
                                            "permission.");
                        }
                        if (!enforceAcceptHandoverPermission(
                                destAcct.getComponentName().getPackageName(),
                                Binder.getCallingUid())) {
                            throw new SecurityException("App must be granted runtime "
                                    + "ACCEPT_HANDOVER permission.");
                        }

                        long token = Binder.clearCallingIdentity();
                        try {
                            mCallsManager.acceptHandover(srcAddr, videoState, destAcct);
                        } finally {
                            Binder.restoreCallingIdentity(token);
                        }
                    } else {
                        Log.w(this, "Null phoneAccountHandle. Ignoring request " +
                                "to handover the call");
@@ -1449,6 +1462,24 @@ public class TelecomServiceImpl {
        return true;
    }

    /**
     * @return {@code true} if the app has the handover permission and has received runtime
     * permission to perform that operation, {@code false}.
     * @throws SecurityException same as {@link Context#enforceCallingOrSelfPermission}
     */
    private boolean enforceAcceptHandoverPermission(String packageName, int uid) {
        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCEPT_HANDOVER,
                "App requires ACCEPT_HANDOVER permission to accept handovers.");

        final int opCode = AppOpsManager.permissionToOpCode(Manifest.permission.ACCEPT_HANDOVER);
        if (opCode != AppOpsManager.OP_ACCEPT_HANDOVER || (
                mAppOpsManager.checkOp(opCode, uid, packageName)
                        != AppOpsManager.MODE_ALLOWED)) {
            return false;
        }
        return true;
    }

    private Context mContext;
    private AppOpsManager mAppOpsManager;
    private PackageManager mPackageManager;
Loading