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

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

Prevent notification vibration when the user is on the earpiece.

am: eaaf074d

Change-Id: I5c2e60268ecdf717782fac271163207dc0c670ce
parents efe9907f eaaf074d
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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";
@@ -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();
@@ -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;
@@ -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;
@@ -1098,6 +1139,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
            WiredHeadsetManager wiredHeadsetManager,
            StatusBarNotifier statusBarNotifier,
            CallAudioManager.AudioServiceFactory audioServiceFactory,
            InterruptionFilterProxy interruptionFilterProxy,
            boolean doesDeviceSupportEarpieceRoute) {
        super(NAME);
        addState(mActiveEarpieceRoute);
@@ -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();

@@ -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);
+7 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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. */
@@ -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;
@@ -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,
@@ -249,6 +254,7 @@ public class CallsManager extends Call.ListenerBase
                wiredHeadsetManager,
                statusBarNotifier,
                audioServiceFactory,
                interruptionFilterProxy,
                CallAudioRouteStateMachine.doesDeviceSupportEarpieceRoute()
        );
        callAudioRouteStateMachine.initialize();
+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();
}
+4 −2
Original line number Diff line number Diff line
@@ -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();
@@ -199,7 +200,8 @@ public final class TelecomSystem {
                defaultDialerAdapter,
                timeoutsAdapter,
                asyncRingtonePlayer,
                phoneNumberUtilsAdapter);
                phoneNumberUtilsAdapter,
                interruptionFilterProxy);

        mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
        mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
+18 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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,
@@ -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