Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +86 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,11 @@ package com.android.server.telecom; import android.app.ActivityManagerNative; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; import android.media.AudioManager; import android.media.IAudioService; Loading Loading @@ -147,6 +151,34 @@ public class CallAudioRouteStateMachine extends StateMachine { put(RUN_RUNNABLE, "RUN_RUNNABLE"); }}; /** * BroadcastReceiver used to track changes in the notification interruption filter. This * ensures changes to the notification interruption filter made by the user during a call are * respected when restoring the notification interruption filter state. */ private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.startSession("CARSM.oR"); try { String action = intent.getAction(); if (action.equals(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)) { if (mAreNotificationSuppressed) { // If we've already set the interruption filter, and the user changes it to // something other than INTERRUPTION_FILTER_ALARMS, assume we will no longer // try to change it back if the audio route changes. mAreNotificationSuppressed = mInterruptionFilterProxy.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_ALARMS; } } } finally { Log.endSession(); } } }; private static final String ACTIVE_EARPIECE_ROUTE_NAME = "ActiveEarpieceRoute"; private static final String ACTIVE_BLUETOOTH_ROUTE_NAME = "ActiveBluetoothRoute"; private static final String ACTIVE_SPEAKER_ROUTE_NAME = "ActiveSpeakerRoute"; Loading Loading @@ -250,12 +282,19 @@ public class CallAudioRouteStateMachine extends StateMachine { super.enter(); setSpeakerphoneOn(false); setBluetoothOn(false); setNotificationsSuppressed(true); CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE, mAvailableRoutes); setSystemAudioState(newState); updateInternalCallAudioState(); } @Override public void exit() { super.exit(); setNotificationsSuppressed(false); } @Override public void updateSystemAudioState() { updateInternalCallAudioState(); Loading Loading @@ -1071,6 +1110,7 @@ public class CallAudioRouteStateMachine extends StateMachine { private int mAudioFocusType; private boolean mWasOnSpeaker; private boolean mIsMuted; private boolean mAreNotificationSuppressed = false; private final Context mContext; private final CallsManager mCallsManager; Loading @@ -1079,6 +1119,7 @@ public class CallAudioRouteStateMachine extends StateMachine { private final WiredHeadsetManager mWiredHeadsetManager; private final StatusBarNotifier mStatusBarNotifier; private final CallAudioManager.AudioServiceFactory mAudioServiceFactory; private final InterruptionFilterProxy mInterruptionFilterProxy; private final boolean mDoesDeviceSupportEarpieceRoute; private final TelecomSystem.SyncRoot mLock; private boolean mHasUserExplicitlyLeftBluetooth = false; Loading @@ -1098,6 +1139,7 @@ public class CallAudioRouteStateMachine extends StateMachine { WiredHeadsetManager wiredHeadsetManager, StatusBarNotifier statusBarNotifier, CallAudioManager.AudioServiceFactory audioServiceFactory, InterruptionFilterProxy interruptionFilterProxy, boolean doesDeviceSupportEarpieceRoute) { super(NAME); addState(mActiveEarpieceRoute); Loading @@ -1117,6 +1159,11 @@ public class CallAudioRouteStateMachine extends StateMachine { mWiredHeadsetManager = wiredHeadsetManager; mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mInterruptionFilterProxy = interruptionFilterProxy; // Register for misc other intent broadcasts. IntentFilter intentFilter = new IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED); context.registerReceiver(mReceiver, intentFilter); mDoesDeviceSupportEarpieceRoute = doesDeviceSupportEarpieceRoute; mLock = callsManager.getLock(); Loading Loading @@ -1224,6 +1271,45 @@ public class CallAudioRouteStateMachine extends StateMachine { quitNow(); } /** * Sets whether notifications should be suppressed or not. Used when in a call to ensure the * device will not vibrate due to notifications. * Alarm-only filtering is activated when * * @param on {@code true} when notification suppression should be activated, {@code false} when * it should be deactivated. */ private void setNotificationsSuppressed(boolean on) { if (mInterruptionFilterProxy == null) { return; } if (on) { // Enabling suppression of notifications. int interruptionFilter = mInterruptionFilterProxy.getCurrentInterruptionFilter(); if (interruptionFilter == NotificationManager.INTERRUPTION_FILTER_ALL) { // No interruption filter is specified, so suppress notifications by setting the // current filter to alarms-only. mAreNotificationSuppressed = true; mInterruptionFilterProxy.setInterruptionFilter( NotificationManager.INTERRUPTION_FILTER_ALARMS); } else { // Interruption filter is already chosen by the user, so do not attempt to change // it. mAreNotificationSuppressed = false; } } else { // Disabling suppression of notifications. if (mAreNotificationSuppressed) { // We have implemented the alarms-only policy and the user has not changed it since // we originally set it, so reset the notification filter. mInterruptionFilterProxy.setInterruptionFilter( NotificationManager.INTERRUPTION_FILTER_ALL); } mAreNotificationSuppressed = false; } } private void setSpeakerphoneOn(boolean on) { if (mAudioManager.isSpeakerphoneOn() != on) { Log.i(this, "turning speaker phone %s", on); Loading src/com/android/server/telecom/CallsManager.java +7 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.telecom; import android.app.ActivityManager; import android.app.NotificationManager; import android.content.Context; import android.content.pm.UserInfo; import android.content.Intent; Loading Loading @@ -193,6 +194,7 @@ public class CallsManager extends Call.ListenerBase private final DefaultDialerManagerAdapter mDefaultDialerManagerAdapter; private final Timeouts.Adapter mTimeoutsAdapter; private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter; private final NotificationManager mNotificationManager; private final Set<Call> mLocallyDisconnectingCalls = new HashSet<>(); private final Set<Call> mPendingCallsToDisconnect = new HashSet<>(); /* Handler tied to thread in which CallManager was initialized. */ Loading Loading @@ -224,7 +226,8 @@ public class CallsManager extends Call.ListenerBase DefaultDialerManagerAdapter defaultDialerAdapter, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter) { PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, InterruptionFilterProxy interruptionFilterProxy) { mContext = context; mLock = lock; mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter; Loading @@ -242,6 +245,8 @@ public class CallsManager extends Call.ListenerBase mContactsAsyncHelper, mLock); mDtmfLocalTonePlayer = new DtmfLocalTonePlayer(); mNotificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); CallAudioRouteStateMachine callAudioRouteStateMachine = new CallAudioRouteStateMachine( context, this, Loading @@ -249,6 +254,7 @@ public class CallsManager extends Call.ListenerBase wiredHeadsetManager, statusBarNotifier, audioServiceFactory, interruptionFilterProxy, CallAudioRouteStateMachine.doesDeviceSupportEarpieceRoute() ); callAudioRouteStateMachine.initialize(); Loading src/com/android/server/telecom/InterruptionFilterProxy.java 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.telecom; /** * Defines common functionality used by {@link CallAudioRouteStateMachine} to control the current * interruption filter for notifications while in a call. Used to ensure that this functionality * can be mocked out in unit tests. */ public interface InterruptionFilterProxy { void setInterruptionFilter(int interruptionFilter); int getCurrentInterruptionFilter(); } src/com/android/server/telecom/TelecomSystem.java +4 −2 Original line number Diff line number Diff line Loading @@ -155,7 +155,8 @@ public final class TelecomSystem { bluetoothPhoneServiceImplFactory, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter) { PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, InterruptionFilterProxy interruptionFilterProxy) { mContext = context.getApplicationContext(); Log.setContext(mContext); Log.initMd5Sum(); Loading Loading @@ -199,7 +200,8 @@ public final class TelecomSystem { defaultDialerAdapter, timeoutsAdapter, asyncRingtonePlayer, phoneNumberUtilsAdapter); phoneNumberUtilsAdapter, interruptionFilterProxy); mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); Loading src/com/android/server/telecom/components/TelecomService.java +18 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.telecom.components; import android.app.Notification; import android.app.NotificationManager; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.content.Context; Loading @@ -35,6 +37,7 @@ import com.android.server.telecom.HeadsetMediaButton; import com.android.server.telecom.HeadsetMediaButtonFactory; import com.android.server.telecom.InCallWakeLockControllerFactory; import com.android.server.telecom.CallAudioManager; import com.android.server.telecom.InterruptionFilterProxy; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.PhoneNumberUtilsAdapter; import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; Loading Loading @@ -73,6 +76,9 @@ public class TelecomService extends Service implements TelecomSystem.Component { */ static void initializeTelecomSystem(Context context) { if (TelecomSystem.getInstance() == null) { final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); TelecomSystem.setInstance( new TelecomSystem( context, Loading Loading @@ -152,7 +158,18 @@ public class TelecomService extends Service implements TelecomSystem.Component { }, new Timeouts.Adapter(), new AsyncRingtonePlayer(), new PhoneNumberUtilsAdapterImpl() new PhoneNumberUtilsAdapterImpl(), new InterruptionFilterProxy() { @Override public void setInterruptionFilter(int interruptionFilter) { notificationManager.setInterruptionFilter(interruptionFilter); } @Override public int getCurrentInterruptionFilter() { return notificationManager.getCurrentInterruptionFilter(); } } )); } if (BluetoothAdapter.getDefaultAdapter() != null) { Loading Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +86 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,11 @@ package com.android.server.telecom; import android.app.ActivityManagerNative; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; import android.media.AudioManager; import android.media.IAudioService; Loading Loading @@ -147,6 +151,34 @@ public class CallAudioRouteStateMachine extends StateMachine { put(RUN_RUNNABLE, "RUN_RUNNABLE"); }}; /** * BroadcastReceiver used to track changes in the notification interruption filter. This * ensures changes to the notification interruption filter made by the user during a call are * respected when restoring the notification interruption filter state. */ private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.startSession("CARSM.oR"); try { String action = intent.getAction(); if (action.equals(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)) { if (mAreNotificationSuppressed) { // If we've already set the interruption filter, and the user changes it to // something other than INTERRUPTION_FILTER_ALARMS, assume we will no longer // try to change it back if the audio route changes. mAreNotificationSuppressed = mInterruptionFilterProxy.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_ALARMS; } } } finally { Log.endSession(); } } }; private static final String ACTIVE_EARPIECE_ROUTE_NAME = "ActiveEarpieceRoute"; private static final String ACTIVE_BLUETOOTH_ROUTE_NAME = "ActiveBluetoothRoute"; private static final String ACTIVE_SPEAKER_ROUTE_NAME = "ActiveSpeakerRoute"; Loading Loading @@ -250,12 +282,19 @@ public class CallAudioRouteStateMachine extends StateMachine { super.enter(); setSpeakerphoneOn(false); setBluetoothOn(false); setNotificationsSuppressed(true); CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE, mAvailableRoutes); setSystemAudioState(newState); updateInternalCallAudioState(); } @Override public void exit() { super.exit(); setNotificationsSuppressed(false); } @Override public void updateSystemAudioState() { updateInternalCallAudioState(); Loading Loading @@ -1071,6 +1110,7 @@ public class CallAudioRouteStateMachine extends StateMachine { private int mAudioFocusType; private boolean mWasOnSpeaker; private boolean mIsMuted; private boolean mAreNotificationSuppressed = false; private final Context mContext; private final CallsManager mCallsManager; Loading @@ -1079,6 +1119,7 @@ public class CallAudioRouteStateMachine extends StateMachine { private final WiredHeadsetManager mWiredHeadsetManager; private final StatusBarNotifier mStatusBarNotifier; private final CallAudioManager.AudioServiceFactory mAudioServiceFactory; private final InterruptionFilterProxy mInterruptionFilterProxy; private final boolean mDoesDeviceSupportEarpieceRoute; private final TelecomSystem.SyncRoot mLock; private boolean mHasUserExplicitlyLeftBluetooth = false; Loading @@ -1098,6 +1139,7 @@ public class CallAudioRouteStateMachine extends StateMachine { WiredHeadsetManager wiredHeadsetManager, StatusBarNotifier statusBarNotifier, CallAudioManager.AudioServiceFactory audioServiceFactory, InterruptionFilterProxy interruptionFilterProxy, boolean doesDeviceSupportEarpieceRoute) { super(NAME); addState(mActiveEarpieceRoute); Loading @@ -1117,6 +1159,11 @@ public class CallAudioRouteStateMachine extends StateMachine { mWiredHeadsetManager = wiredHeadsetManager; mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mInterruptionFilterProxy = interruptionFilterProxy; // Register for misc other intent broadcasts. IntentFilter intentFilter = new IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED); context.registerReceiver(mReceiver, intentFilter); mDoesDeviceSupportEarpieceRoute = doesDeviceSupportEarpieceRoute; mLock = callsManager.getLock(); Loading Loading @@ -1224,6 +1271,45 @@ public class CallAudioRouteStateMachine extends StateMachine { quitNow(); } /** * Sets whether notifications should be suppressed or not. Used when in a call to ensure the * device will not vibrate due to notifications. * Alarm-only filtering is activated when * * @param on {@code true} when notification suppression should be activated, {@code false} when * it should be deactivated. */ private void setNotificationsSuppressed(boolean on) { if (mInterruptionFilterProxy == null) { return; } if (on) { // Enabling suppression of notifications. int interruptionFilter = mInterruptionFilterProxy.getCurrentInterruptionFilter(); if (interruptionFilter == NotificationManager.INTERRUPTION_FILTER_ALL) { // No interruption filter is specified, so suppress notifications by setting the // current filter to alarms-only. mAreNotificationSuppressed = true; mInterruptionFilterProxy.setInterruptionFilter( NotificationManager.INTERRUPTION_FILTER_ALARMS); } else { // Interruption filter is already chosen by the user, so do not attempt to change // it. mAreNotificationSuppressed = false; } } else { // Disabling suppression of notifications. if (mAreNotificationSuppressed) { // We have implemented the alarms-only policy and the user has not changed it since // we originally set it, so reset the notification filter. mInterruptionFilterProxy.setInterruptionFilter( NotificationManager.INTERRUPTION_FILTER_ALL); } mAreNotificationSuppressed = false; } } private void setSpeakerphoneOn(boolean on) { if (mAudioManager.isSpeakerphoneOn() != on) { Log.i(this, "turning speaker phone %s", on); Loading
src/com/android/server/telecom/CallsManager.java +7 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.telecom; import android.app.ActivityManager; import android.app.NotificationManager; import android.content.Context; import android.content.pm.UserInfo; import android.content.Intent; Loading Loading @@ -193,6 +194,7 @@ public class CallsManager extends Call.ListenerBase private final DefaultDialerManagerAdapter mDefaultDialerManagerAdapter; private final Timeouts.Adapter mTimeoutsAdapter; private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter; private final NotificationManager mNotificationManager; private final Set<Call> mLocallyDisconnectingCalls = new HashSet<>(); private final Set<Call> mPendingCallsToDisconnect = new HashSet<>(); /* Handler tied to thread in which CallManager was initialized. */ Loading Loading @@ -224,7 +226,8 @@ public class CallsManager extends Call.ListenerBase DefaultDialerManagerAdapter defaultDialerAdapter, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter) { PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, InterruptionFilterProxy interruptionFilterProxy) { mContext = context; mLock = lock; mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter; Loading @@ -242,6 +245,8 @@ public class CallsManager extends Call.ListenerBase mContactsAsyncHelper, mLock); mDtmfLocalTonePlayer = new DtmfLocalTonePlayer(); mNotificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); CallAudioRouteStateMachine callAudioRouteStateMachine = new CallAudioRouteStateMachine( context, this, Loading @@ -249,6 +254,7 @@ public class CallsManager extends Call.ListenerBase wiredHeadsetManager, statusBarNotifier, audioServiceFactory, interruptionFilterProxy, CallAudioRouteStateMachine.doesDeviceSupportEarpieceRoute() ); callAudioRouteStateMachine.initialize(); Loading
src/com/android/server/telecom/InterruptionFilterProxy.java 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.telecom; /** * Defines common functionality used by {@link CallAudioRouteStateMachine} to control the current * interruption filter for notifications while in a call. Used to ensure that this functionality * can be mocked out in unit tests. */ public interface InterruptionFilterProxy { void setInterruptionFilter(int interruptionFilter); int getCurrentInterruptionFilter(); }
src/com/android/server/telecom/TelecomSystem.java +4 −2 Original line number Diff line number Diff line Loading @@ -155,7 +155,8 @@ public final class TelecomSystem { bluetoothPhoneServiceImplFactory, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter) { PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, InterruptionFilterProxy interruptionFilterProxy) { mContext = context.getApplicationContext(); Log.setContext(mContext); Log.initMd5Sum(); Loading Loading @@ -199,7 +200,8 @@ public final class TelecomSystem { defaultDialerAdapter, timeoutsAdapter, asyncRingtonePlayer, phoneNumberUtilsAdapter); phoneNumberUtilsAdapter, interruptionFilterProxy); mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); Loading
src/com/android/server/telecom/components/TelecomService.java +18 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.telecom.components; import android.app.Notification; import android.app.NotificationManager; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.content.Context; Loading @@ -35,6 +37,7 @@ import com.android.server.telecom.HeadsetMediaButton; import com.android.server.telecom.HeadsetMediaButtonFactory; import com.android.server.telecom.InCallWakeLockControllerFactory; import com.android.server.telecom.CallAudioManager; import com.android.server.telecom.InterruptionFilterProxy; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.PhoneNumberUtilsAdapter; import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; Loading Loading @@ -73,6 +76,9 @@ public class TelecomService extends Service implements TelecomSystem.Component { */ static void initializeTelecomSystem(Context context) { if (TelecomSystem.getInstance() == null) { final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); TelecomSystem.setInstance( new TelecomSystem( context, Loading Loading @@ -152,7 +158,18 @@ public class TelecomService extends Service implements TelecomSystem.Component { }, new Timeouts.Adapter(), new AsyncRingtonePlayer(), new PhoneNumberUtilsAdapterImpl() new PhoneNumberUtilsAdapterImpl(), new InterruptionFilterProxy() { @Override public void setInterruptionFilter(int interruptionFilter) { notificationManager.setInterruptionFilter(interruptionFilter); } @Override public int getCurrentInterruptionFilter() { return notificationManager.getCurrentInterruptionFilter(); } } )); } if (BluetoothAdapter.getDefaultAdapter() != null) { Loading