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

Commit e02cc84c authored by Thomas Stuart's avatar Thomas Stuart
Browse files

telecom-bluetooth DND bug

Bugs came in about Do Not Disturb being on but still
interrupting users of incoming calls.  Turns out, this was a
result of BluetoothInCallService putting the headset into ring
mode before Telecom informed the InCallService to not ring.

Fix is to add a new EXTRA called EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB.
The extra is intended for InCallServices that may interrupt the user of
an incoming call.

Note that is currently in the process of updating there min sdk version
so they can fetch this new extra.

Bug:   208652088

Test:  manual + 5 unit tests:
         2 DndCallFilter tests,
         2 RingerTests,
         1 CallTests

Change-Id: I873823def01b14872d5a2cfea1a917f81eabdff2
parent 896da1b6
Loading
Loading
Loading
Loading
+105 −99
Original line number Diff line number Diff line
@@ -99,7 +99,9 @@ public class Analytics {
            entry(LogUtils.Events.BLOCK_CHECK_INITIATED, AnalyticsEvent.BLOCK_CHECK_INITIATED),
            entry(LogUtils.Events.FILTERING_INITIATED, AnalyticsEvent.FILTERING_INITIATED),
            entry(LogUtils.Events.FILTERING_COMPLETED, AnalyticsEvent.FILTERING_COMPLETED),
                entry(LogUtils.Events.FILTERING_TIMED_OUT, AnalyticsEvent.FILTERING_TIMED_OUT));
            entry(LogUtils.Events.FILTERING_TIMED_OUT, AnalyticsEvent.FILTERING_TIMED_OUT),
            entry(LogUtils.Events.DND_PRE_CHECK_INITIATED, AnalyticsEvent.DND_CHECK_INITIATED),
            entry(LogUtils.Events.DND_PRE_CHECK_COMPLETED, AnalyticsEvent.DND_CHECK_COMPLETED));

    public static final Map<String, Integer> sLogSessionToSessionId = Map.ofEntries(
            entry(LogUtils.Sessions.ICA_ANSWER_CALL, SessionTiming.ICA_ANSWER_CALL),
@@ -149,9 +151,12 @@ public class Analytics {
                    ParcelableCallAnalytics.EventTiming.FILTERING_TIMED_OUT_TIMING),
            entry(LogUtils.Events.Timings.START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING,
                    ParcelableCallAnalytics.EventTiming.
                                START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING));
                            START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING),
            entry(LogUtils.Events.Timings.DND_PRE_CHECK_COMPLETED_TIMING,
                    ParcelableCallAnalytics.EventTiming.DND_PRE_CALL_PRE_CHECK_TIMING));

    public static final Map<Integer, String> sSessionIdToLogSession = new HashMap<>();

    static {
        for (Map.Entry<String, Integer> e : sLogSessionToSessionId.entrySet()) {
            sSessionIdToLogSession.put(e.getValue(), e.getKey());
@@ -575,6 +580,7 @@ public class Analytics {
            }
        }
    }

    public static final String TAG = "TelecomAnalytics";

    // Constants for call direction
+21 −0
Original line number Diff line number Diff line
@@ -1279,6 +1279,27 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        return mSilentRingingRequested;
    }

    public void setCallIsSuppressedByDoNotDisturb(boolean isCallSuppressed) {
        Bundle bundle = new Bundle();
        bundle.putBoolean(android.telecom.Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB,
                isCallSuppressed);
        putExtras(SOURCE_CONNECTION_SERVICE, bundle);
    }

    public boolean isCallSuppressedByDoNotDisturb() {
        if (getExtras() == null) {
            return false;
        }
        return getExtras().getBoolean(android.telecom.Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB);
    }

    public boolean wasDndCheckComputedForCall() {
        if (getExtras() == null) {
            return false;
        }
        return getExtras().containsKey(android.telecom.Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB);
    }

    @VisibleForTesting
    public boolean isConference() {
        return mIsConference;
+6 −2
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -113,6 +114,7 @@ import com.android.server.telecom.callfiltering.CallFilteringResult;
import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
import com.android.server.telecom.callfiltering.DirectToVoicemailFilter;
import com.android.server.telecom.callfiltering.DndCallFilter;
import com.android.server.telecom.callfiltering.IncomingCallFilterGraph;
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.components.ErrorDialogActivity;
@@ -532,7 +534,6 @@ public class CallsManager extends Call.ListenerBase
                        bluetoothManager,
                        wiredHeadsetManager,
                        mDockManager);

        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        InCallTonePlayer.MediaPlayerFactory mediaPlayerFactory =
                (resourceId, attributes) ->
@@ -553,7 +554,8 @@ public class CallsManager extends Call.ListenerBase
        mCallDiagnosticServiceController.setInCallTonePlayerFactory(playerFactory);
        mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer,
                ringtoneFactory, systemVibrator,
                new Ringer.VibrationEffectProxy(), mInCallController);
                new Ringer.VibrationEffectProxy(), mInCallController,
                mContext.getSystemService(NotificationManager.class));
        mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager,
                mTimeoutsAdapter, mLock);
        mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine,
@@ -717,6 +719,7 @@ public class CallsManager extends Call.ListenerBase
                mCallerInfoLookupHelper);
        BlockCheckerFilter blockCheckerFilter = new BlockCheckerFilter(mContext, incomingCall,
                mCallerInfoLookupHelper, new BlockCheckerAdapter());
        DndCallFilter dndCallFilter = new DndCallFilter(incomingCall, getRinger());
        CallScreeningServiceFilter carrierCallScreeningServiceFilter =
                new CallScreeningServiceFilter(incomingCall, carrierPackageName,
                        CallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, this,
@@ -734,6 +737,7 @@ public class CallsManager extends Call.ListenerBase
                    mContext, this, appLabelProxy, converter);
        }
        graph.addFilter(voicemailFilter);
        graph.addFilter(dndCallFilter);
        graph.addFilter(blockCheckerFilter);
        graph.addFilter(carrierCallScreeningServiceFilter);
        graph.addFilter(callScreeningServiceFilter);
+14 −1
Original line number Diff line number Diff line
@@ -2155,11 +2155,24 @@ public class InCallController extends CallsManagerListenerBase implements
            InCallServiceInfo info, ParcelableCall parcelableCall) {
        ParcelableCall.ParcelableCallBuilder builder =
                ParcelableCall.ParcelableCallBuilder.fromParcelableCall(parcelableCall);
        // Check for contacts permission. If it's not there, remove the contactsDisplayName.
        PackageManager pm = mContext.getPackageManager();

        // Check for contacts permission.
        if (pm.checkPermission(Manifest.permission.READ_CONTACTS,
                info.getComponentName().getPackageName()) != PackageManager.PERMISSION_GRANTED) {
            // contacts permission is not present...

            // removing the contactsDisplayName
            builder.setContactDisplayName(null);

            // removing the Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB extra
            Bundle callBundle = parcelableCall.getExtras();
            if (callBundle.containsKey(
                    android.telecom.Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB)) {
                Bundle newBundle = callBundle.deepCopy();
                newBundle.remove(android.telecom.Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB);
                builder.setExtras(newBundle);
            }
        }

        // TODO: move all the other service-specific sanitizations in here
+5 −0
Original line number Diff line number Diff line
@@ -168,6 +168,8 @@ public class LogUtils {
        public static final String DIRECT_TO_VM_INITIATED = "DIRECT_TO_VM_INITIATED";
        public static final String DIRECT_TO_VM_FINISHED = "DIRECT_TO_VM_FINISHED";
        public static final String FILTERING_INITIATED = "FILTERING_INITIATED";
        public static final String DND_PRE_CHECK_INITIATED = "DND_PRE_CHECK_INITIATED";
        public static final String DND_PRE_CHECK_COMPLETED = "DND_PRE_CHECK_COMPLETED";
        public static final String FILTERING_COMPLETED = "FILTERING_COMPLETED";
        public static final String FILTERING_TIMED_OUT = "FILTERING_TIMED_OUT";
        public static final String REMOTELY_HELD = "REMOTELY_HELD";
@@ -222,6 +224,7 @@ public class LogUtils {
            public static final String DIRECT_TO_VM_FINISHED_TIMING = "direct_to_vm_finished";
            public static final String BLOCK_CHECK_FINISHED_TIMING = "block_check_finished";
            public static final String FILTERING_COMPLETED_TIMING = "filtering_completed";
            public static final String DND_PRE_CHECK_COMPLETED_TIMING = "dnd_pre_check_completed";
            public static final String FILTERING_TIMED_OUT_TIMING = "filtering_timed_out";
            public static final String START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING =
                    "start_connection_to_request_disconnect";
@@ -243,6 +246,8 @@ public class LogUtils {
                            BLOCK_CHECK_FINISHED_TIMING),
                    new TimedEventPair(FILTERING_INITIATED, FILTERING_COMPLETED,
                            FILTERING_COMPLETED_TIMING),
                    new TimedEventPair(DND_PRE_CHECK_INITIATED, DND_PRE_CHECK_COMPLETED,
                            DND_PRE_CHECK_COMPLETED_TIMING),
                    new TimedEventPair(FILTERING_INITIATED, FILTERING_TIMED_OUT,
                            FILTERING_TIMED_OUT_TIMING, 6000L),
                    new TimedEventPair(START_CONNECTION, REQUEST_DISCONNECT,
Loading