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

Commit 9539ab53 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Move outbound audiomanager calls to async task executor.

The setSpeakerphoneOn method calls out via 2-way binders to audiomanager
and status bar manager.  Refactoring that code so that it can happen
on an async task executor.

There was already a async executor in CallsManager (Added recently) so this
was refactored out to a common spot so it could be reused in both these
spots.

This prevents Telecom from potentially being blocked on outgoing calls
to the audio framework or the status bar manager.

Test: Run Telecom unit tests and verify pass.
Fixes: 268442423
Change-Id: I040da18528bd5c5a8fd738e65b2ba7c2c2503c05
parent 065ebfb9
Loading
Loading
Loading
Loading
+38 −24
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;

/**
 * This class describes the available routes of a call as a state machine.
@@ -81,14 +82,16 @@ public class CallAudioRouteStateMachine extends StateMachine {
                WiredHeadsetManager wiredHeadsetManager,
                StatusBarNotifier statusBarNotifier,
                CallAudioManager.AudioServiceFactory audioServiceFactory,
                int earpieceControl) {
                int earpieceControl,
                Executor asyncTaskExecutor) {
            return new CallAudioRouteStateMachine(context,
                    callsManager,
                    bluetoothManager,
                    wiredHeadsetManager,
                    statusBarNotifier,
                    audioServiceFactory,
                    earpieceControl);
                    earpieceControl,
                    asyncTaskExecutor);
        }
    }
    /** Values for CallAudioRouteStateMachine constructor's earPieceRouting arg. */
@@ -1478,6 +1481,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
    private final QuiescentSpeakerRoute mQuiescentSpeakerRoute = new QuiescentSpeakerRoute();
    private final StreamingState mStreamingState = new StreamingState();

    private final Executor mAsyncTaskExecutor;

    /**
     * A few pieces of hidden state. Used to avoid exponential explosion of number of explicit
     * states
@@ -1516,7 +1521,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
            WiredHeadsetManager wiredHeadsetManager,
            StatusBarNotifier statusBarNotifier,
            CallAudioManager.AudioServiceFactory audioServiceFactory,
            int earpieceControl) {
            int earpieceControl,
            Executor asyncTaskExecutor) {
        super(NAME);
        mContext = context;
        mCallsManager = callsManager;
@@ -1526,7 +1532,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        mStatusBarNotifier = statusBarNotifier;
        mAudioServiceFactory = audioServiceFactory;
        mLock = callsManager.getLock();

        mAsyncTaskExecutor = asyncTaskExecutor;
        createStates(earpieceControl);
    }

@@ -1538,7 +1544,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
            WiredHeadsetManager wiredHeadsetManager,
            StatusBarNotifier statusBarNotifier,
            CallAudioManager.AudioServiceFactory audioServiceFactory,
            int earpieceControl, Looper looper) {
            int earpieceControl, Looper looper, Executor asyncTaskExecutor) {
        super(NAME, looper);
        mContext = context;
        mCallsManager = callsManager;
@@ -1548,6 +1554,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        mStatusBarNotifier = statusBarNotifier;
        mAudioServiceFactory = audioServiceFactory;
        mLock = callsManager.getLock();
        mAsyncTaskExecutor = asyncTaskExecutor;

        createStates(earpieceControl);
    }
@@ -1629,7 +1636,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                new IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED));

        mStatusBarNotifier.notifyMute(initState.isMuted());
        mStatusBarNotifier.notifySpeakerphone(initState.getRoute() == CallAudioState.ROUTE_SPEAKER);
        // We used to call mStatusBarNotifier.notifySpeakerphone, but that makes no sense as there
        // is never a call at this boot (init) time.
        setInitialState(mRouteCodeToQuiescentState.get(initState.getRoute()));
        start();
    }
@@ -1722,6 +1730,10 @@ public class CallAudioRouteStateMachine extends StateMachine {

    private void setSpeakerphoneOn(boolean on) {
        Log.i(this, "turning speaker phone %s", on);
        final boolean hasAnyCalls = mCallsManager.hasAnyCalls();
        // These APIs are all via two-way binder calls so can potentially block Telecom.  Since none
        // of this has to happen in the Telecom lock we'll offload it to the async executor.
        mAsyncTaskExecutor.execute(() -> {
            AudioDeviceInfo speakerDevice = null;
            for (AudioDeviceInfo info : mAudioManager.getAvailableCommunicationDevices()) {
                if (info.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
@@ -1737,11 +1749,13 @@ public class CallAudioRouteStateMachine extends StateMachine {
                }
            } else {
                AudioDeviceInfo curDevice = mAudioManager.getCommunicationDevice();
            if (curDevice != null && curDevice.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
                if (curDevice != null
                        && curDevice.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
                    mAudioManager.clearCommunicationDevice();
                }
            }
        mStatusBarNotifier.notifySpeakerphone(speakerOn);
            mStatusBarNotifier.notifySpeakerphone(hasAnyCalls && speakerOn);
        });
    }

    private void setBluetoothOn(String address) {
+4 −3
Original line number Diff line number Diff line
@@ -558,8 +558,8 @@ public class CallsManager extends Call.ListenerBase
            ToastFactory toastFactory,
            CallEndpointControllerFactory callEndpointControllerFactory,
            CallAnomalyWatchdog callAnomalyWatchdog,
            Executor asyncTaskExecutor,
            Ringer.AccessibilityManagerAdapter accessibilityManagerAdapter) {
            Ringer.AccessibilityManagerAdapter accessibilityManagerAdapter,
            Executor asyncTaskExecutor) {
        mContext = context;
        mLock = lock;
        mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter;
@@ -587,7 +587,8 @@ public class CallsManager extends Call.ListenerBase
                        wiredHeadsetManager,
                        statusBarNotifier,
                        audioServiceFactory,
                        CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT
                        CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT,
                        asyncTaskExecutor
                );
        callAudioRouteStateMachine.initialize();

+7 −5
Original line number Diff line number Diff line
@@ -79,13 +79,15 @@ public class StatusBarNotifier extends CallsManagerListenerBase {
        mIsShowingMute = isMuted;
    }

    /**
     * Update the status bar manager with the new speakerphone state.
     *
     * IMPORTANT: DO NOT call into any Telecom code here; this is usually scheduled on an async
     * executor to save Telecom from blocking on outgoing binder calls.
     * @param isSpeakerphone
     */
    @VisibleForTesting
    public void notifySpeakerphone(boolean isSpeakerphone) {
        // Never display anything if there are no calls.
        if (!mCallsManager.hasAnyCalls()) {
            isSpeakerphone = false;
        }

        if (mIsShowingSpeakerphone == isSpeakerphone) {
            return;
        }
+5 −3
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import com.android.server.telecom.ui.ToastFactory;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
@@ -210,7 +211,8 @@ public class TelecomSystem {
            RoleManagerAdapter roleManagerAdapter,
            ContactsAsyncHelper.Factory contactsAsyncHelperFactory,
            DeviceIdleControllerAdapter deviceIdleControllerAdapter,
            Ringer.AccessibilityManagerAdapter accessibilityManagerAdapter) {
            Ringer.AccessibilityManagerAdapter accessibilityManagerAdapter,
            Executor asyncTaskExecutor) {
        mContext = context.getApplicationContext();
        LogUtils.initLogging(mContext);
        AnomalyReporter.initialize(mContext);
@@ -367,8 +369,8 @@ public class TelecomSystem {
                    toastFactory,
                    callEndpointControllerFactory,
                    callAnomalyWatchdog,
                    Executors.newSingleThreadExecutor(),
                    accessibilityManagerAdapter);
                    accessibilityManagerAdapter,
                    asyncTaskExecutor);

            mIncomingCallNotifier = incomingCallNotifier;
            incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
+4 −1
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl;
import com.android.server.telecom.ui.NotificationChannelManager;

import java.util.concurrent.Executors;

/**
 * Implementation of the ITelecom interface.
 */
@@ -208,7 +210,8 @@ public class TelecomService extends Service implements TelecomSystem.Component {
                                    return context.getSystemService(AccessibilityManager.class)
                                            .stopFlashNotificationSequence(context);
                                }
                            }));
                            },
                            Executors.newSingleThreadExecutor()));
        }
    }

Loading