Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +38 −24 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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. */ Loading Loading @@ -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 Loading Loading @@ -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; Loading @@ -1526,7 +1532,7 @@ public class CallAudioRouteStateMachine extends StateMachine { mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mLock = callsManager.getLock(); mAsyncTaskExecutor = asyncTaskExecutor; createStates(earpieceControl); } Loading @@ -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; Loading @@ -1548,6 +1554,7 @@ public class CallAudioRouteStateMachine extends StateMachine { mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mLock = callsManager.getLock(); mAsyncTaskExecutor = asyncTaskExecutor; createStates(earpieceControl); } Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading @@ -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) { Loading src/com/android/server/telecom/CallsManager.java +4 −3 Original line number Diff line number Diff line Loading @@ -556,8 +556,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; Loading Loading @@ -585,7 +585,8 @@ public class CallsManager extends Call.ListenerBase wiredHeadsetManager, statusBarNotifier, audioServiceFactory, CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT, asyncTaskExecutor ); callAudioRouteStateMachine.initialize(); Loading src/com/android/server/telecom/StatusBarNotifier.java +7 −5 Original line number Diff line number Diff line Loading @@ -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; } Loading src/com/android/server/telecom/TelecomSystem.java +5 −3 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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); Loading Loading @@ -367,8 +369,8 @@ public class TelecomSystem { toastFactory, callEndpointControllerFactory, callAnomalyWatchdog, Executors.newSingleThreadExecutor(), accessibilityManagerAdapter); accessibilityManagerAdapter, asyncTaskExecutor); mIncomingCallNotifier = incomingCallNotifier; incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() { Loading src/com/android/server/telecom/components/TelecomService.java +4 −1 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -208,7 +210,8 @@ public class TelecomService extends Service implements TelecomSystem.Component { return context.getSystemService(AccessibilityManager.class) .stopFlashNotificationSequence(context); } })); }, Executors.newSingleThreadExecutor())); } } Loading Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +38 −24 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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. */ Loading Loading @@ -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 Loading Loading @@ -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; Loading @@ -1526,7 +1532,7 @@ public class CallAudioRouteStateMachine extends StateMachine { mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mLock = callsManager.getLock(); mAsyncTaskExecutor = asyncTaskExecutor; createStates(earpieceControl); } Loading @@ -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; Loading @@ -1548,6 +1554,7 @@ public class CallAudioRouteStateMachine extends StateMachine { mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mLock = callsManager.getLock(); mAsyncTaskExecutor = asyncTaskExecutor; createStates(earpieceControl); } Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading @@ -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) { Loading
src/com/android/server/telecom/CallsManager.java +4 −3 Original line number Diff line number Diff line Loading @@ -556,8 +556,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; Loading Loading @@ -585,7 +585,8 @@ public class CallsManager extends Call.ListenerBase wiredHeadsetManager, statusBarNotifier, audioServiceFactory, CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT, asyncTaskExecutor ); callAudioRouteStateMachine.initialize(); Loading
src/com/android/server/telecom/StatusBarNotifier.java +7 −5 Original line number Diff line number Diff line Loading @@ -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; } Loading
src/com/android/server/telecom/TelecomSystem.java +5 −3 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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); Loading Loading @@ -367,8 +369,8 @@ public class TelecomSystem { toastFactory, callEndpointControllerFactory, callAnomalyWatchdog, Executors.newSingleThreadExecutor(), accessibilityManagerAdapter); accessibilityManagerAdapter, asyncTaskExecutor); mIncomingCallNotifier = incomingCallNotifier; incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() { Loading
src/com/android/server/telecom/components/TelecomService.java +4 −1 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -208,7 +210,8 @@ public class TelecomService extends Service implements TelecomSystem.Component { return context.getSystemService(AccessibilityManager.class) .stopFlashNotificationSequence(context); } })); }, Executors.newSingleThreadExecutor())); } } Loading