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

Commit 7d65ae81 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13256841 from b0df9087 to 25Q2-release

Change-Id: Ib13fb5529dc5b8eb0ac0fd35c546baac7c6e8408
parents 929b6e8e b0df9087
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -77,3 +77,11 @@ flag {
      purpose: PURPOSE_BUGFIX
    }
}

# OWNER=pmadapurmath TARGET=25Q4
flag {
  name: "call_sequencing_call_resume_failed"
  namespace: "telecom"
  description: "Connection event received when a call resume fails"
  bug: "390116261"
}
+25 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        default void onHoldToneRequested(Call call) {};
        default void onCallHoldFailed(Call call) {};
        default void onCallSwitchFailed(Call call) {};
        default void onCallResumeFailed(Call call) {};
        default void onConnectionEvent(Call call, String event, Bundle extras) {};
        default void onCallStreamingStateChanged(Call call, boolean isStreaming) {}
        default void onExternalCallChanged(Call call, boolean isExternalCall) {};
@@ -295,6 +296,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        @Override
        public void onCallSwitchFailed(Call call) {}
        @Override
        public void onCallResumeFailed(Call call) {}
        @Override
        public void onConnectionEvent(Call call, String event, Bundle extras) {}
        @Override
        public void onCallStreamingStateChanged(Call call, boolean isStreaming) {}
@@ -644,6 +647,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,

    private boolean mIsTransactionalCall = false;
    private CallingPackageIdentity mCallingPackageIdentity = new CallingPackageIdentity();
    private boolean mSkipAutoUnhold = false;

    /**
     * CallingPackageIdentity is responsible for storing properties about the calling package that
@@ -4544,6 +4548,10 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
            for (Listener l : mListeners) {
                l.onCallSwitchFailed(this);
            }
        } else if (Connection.EVENT_CALL_RESUME_FAILED.equals(event)) {
            for (Listener l : mListeners) {
                l.onCallResumeFailed(this);
            }
        } else if (Connection.EVENT_DEVICE_TO_DEVICE_MESSAGE.equals(event)
                && extras != null && extras.containsKey(
                Connection.EXTRA_DEVICE_TO_DEVICE_MESSAGE_TYPE)
@@ -5108,4 +5116,21 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
    public boolean hasVideoCall() {
        return mHasVideoCall;
    }

    /**
     * Used only for call sequencing for cases when we may end up auto-unholding the held call while
     * processing an outgoing (emergency) call. We want to refrain from unholding the held call so
     * that we don't end up with two active calls. Once the outgoing call is disconnected (either
     * from a successful disconnect by the user or a failed call), the auto-unhold logic will be
     * triggered again and successfully unhold the held call at that point. Note, that this only
     * applies to non-holdable phone accounts (i.e. Verizon). Refer to
     * {@link CallsManagerCallSequencingAdapter#maybeMoveHeldCallToForeground} for details.
     */
    public void setSkipAutoUnhold(boolean result) {
        mSkipAutoUnhold = result;
    }

    public boolean getSkipAutoUnhold() {
        return mSkipAutoUnhold;
    }
}
+5 −3
Original line number Diff line number Diff line
@@ -849,13 +849,15 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
    private void handleBtActiveDevicePresent(@AudioRoute.AudioRouteType int type,
            String deviceAddress) {
        AudioRoute bluetoothRoute = getBluetoothRoute(type, deviceAddress);
        if (bluetoothRoute != null) {
        boolean isBtDeviceCurrentActive = Objects.equals(bluetoothRoute,
                getArbitraryBluetoothDevice());
        if (bluetoothRoute != null && isBtDeviceCurrentActive) {
            Log.i(this, "request to route to bluetooth route: %s (active=%b)", bluetoothRoute,
                    mIsActive);
            routeTo(mIsActive, bluetoothRoute);
        } else {
            Log.i(this, "request to route to unavailable bluetooth route - type (%s), address (%s)",
                    type, deviceAddress);
            Log.i(this, "request to route to unavailable bluetooth route or the route isn't the "
                    + "currently active device - type (%s), address (%s)", type, deviceAddress);
        }
    }

+8 −0
Original line number Diff line number Diff line
@@ -1477,6 +1477,14 @@ public class CallsManager extends Call.ListenerBase
        markAllAnsweredCallAsRinging(call, "switch");
    }

    @Override
    public void onCallResumeFailed(Call call) {
        Call heldCall = getFirstCallWithState(call, true /* skipSelfManaged */, CallState.ON_HOLD);
        if (heldCall != null) {
            mCallSequencingAdapter.handleCallResumeFailed(call, heldCall);
        }
    }

    private void markAllAnsweredCallAsRinging(Call call, String actionName) {
        // Normally, we don't care whether a call hold or switch has failed.
        // However, if a call was held or switched in order to answer an incoming call, that
+44 −2
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PackageTagsList;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -1723,7 +1724,8 @@ public class InCallController extends CallsManagerListenerBase implements

                    try {
                        inCallService.updateCall(
                                sanitizeParcelableCallForService(info, parcelableCall));
                                copyIfLocal(sanitizeParcelableCallForService(info, parcelableCall),
                                        inCallService));
                    } catch (RemoteException ignored) {
                    }
                }
@@ -2854,7 +2856,8 @@ public class InCallController extends CallsManagerListenerBase implements
            ParcelableCall parcelableCall, ComponentName componentName) {
        try {
            inCallService.updateCall(
                    sanitizeParcelableCallForService(info, parcelableCall));
                    copyIfLocal(sanitizeParcelableCallForService(info, parcelableCall),
                            inCallService));
        } catch (RemoteException exception) {
            Log.w(this, "Call status update did not send to: "
                    + componentName + " successfully with error " + exception);
@@ -3435,4 +3438,43 @@ public class InCallController extends CallsManagerListenerBase implements
        }
        return false;
    }

    /**
     * Given a {@link ParcelableCall} and a {@link IInCallService}, determines if the ICS binder is
     * local or remote.  If the binder is remote, we just return the parcelable call instance
     * already constructed.
     * If the binder if local, as will be the case for
     * {@code EnhancedConfirmationCallTrackerService} (or any other ICS in the system server, the
     * underlying Binder implementation is NOT going to parcel and unparcel the
     * {@link ParcelableCall} instance automatically.  This means that the parcelable call instance
     * is passed by reference and that the ICS in the system server could potentially try to access
     * internals in the {@link ParcelableCall} in an unsafe manner.  As a workaround, we will
     * manually parcel and unparcel the {@link ParcelableCall} instance so that they get a fresh
     * copy that they can use safely.
     *
     * @param parcelableCall The ParcelableCall instance we want to maybe copy.
     * @param remote the binder the call is going out over.
     * @return either the original {@link ParcelableCall} or a deep copy of it if the destination
     * binder is local.
     */
    private ParcelableCall copyIfLocal(ParcelableCall parcelableCall, IInCallService remote) {
        // We care more about parceling than local (though they should be the same); so, use
        // queryLocalInterface since that's what Binder uses to decide if it needs to parcel.
        if (remote.asBinder().queryLocalInterface(IInCallService.Stub.DESCRIPTOR) == null) {
            // No local interface, so binder itself will parcel and thus we don't need to.
            return parcelableCall;
        }
        // Binder won't be parceling; however, the remotes assume they have their own native
        // objects (and don't know if caller is local or not), so we need to make a COPY here so
        // that the remote can clean it up without clearing the original transaction.
        // Since there's no direct `copy` for Transaction, we have to parcel/unparcel instead.
        final Parcel p = Parcel.obtain();
        try {
            parcelableCall.writeToParcel(p, 0);
            p.setDataPosition(0);
            return ParcelableCall.CREATOR.createFromParcel(p);
        } finally {
            p.recycle();
        }
    }
}
Loading