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

Commit ae3af1a3 authored by Hall Liu's avatar Hall Liu
Browse files

Add audio processing notification and testapp code

Implement the persistent notification during audio processing and add
code to the testapp to allow manual testing of the background call
screening functionality.

Bug: 140317205
Test: manual
Change-Id: I15cb7fc064bbcccc5c08b76a704244a502d13268
parent 8951278d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -48,6 +48,18 @@
         [CHAR LIMIT=18] -->
    <string name="notification_missedCall_message">Message</string>

    <!-- Title for the persistent notification presented when an app has requested that a call
         be put into the background so that the app can access the audio from the call
         [CHAR LIMIT=20] -->
    <string name="notification_audioProcessing_title">Background call</string>
    <!-- Body of the persistent notification presented when an app requests
         that a call be put into the background so that the app can access the audio from the call.
         [CHAR LIMIT=NONE] -->
    <string name="notification_audioProcessing_body">
        <xliff:g id="audio_processing_app_name">%s</xliff:g> has placed a call into the
        background. This app may be accessing and playing audio over the call.
    </string>

    <!-- Content description of the call muted notification icon for
         accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
    <string name="accessibility_call_muted">Call muted.</string>
@@ -276,6 +288,8 @@
    <string name="notification_channel_missed_call">Missed calls</string>
    <!-- Notification channel name for a channel containing call blocking notifications. -->
    <string name="notification_channel_call_blocking">Call Blocking</string>
    <!-- Notification channel name for a channel containing background call notifications. -->
    <string name="notification_channel_background_calls">Background calls</string>

    <!-- Alert dialog content used to inform the user that placing a new outgoing call will end the
         ongoing call in the app "other_app". -->
+14 −0
Original line number Diff line number Diff line
@@ -543,6 +543,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
     */
    private Call mHandoverSourceCall = null;

    /**
     * The user-visible app name of the app that requested for this call to be put into the
     * AUDIO_PROCESSING state. Used to display a notification to the user.
     */
    private CharSequence mAudioProcessingRequestingApp = null;

    /**
     * Indicates the current state of this call if it is in the process of a handover.
     */
@@ -2041,6 +2047,14 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        Log.addEvent(this, LogUtils.Events.REQUEST_PICKUP_FOR_AUDIO_PROCESSING);
    }

    public void setAudioProcessingRequestingApp(CharSequence appName) {
        mAudioProcessingRequestingApp = appName;
    }

    public CharSequence getAudioProcessingRequestingApp() {
        return mAudioProcessingRequestingApp;
    }

    /**
     * Deflects the call if it is ringing.
     *
+19 −1
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.components.ErrorDialogActivity;
import com.android.server.telecom.settings.BlockedNumbersUtil;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity;
import com.android.server.telecom.ui.CallRedirectionTimeoutDialogActivity;
import com.android.server.telecom.ui.ConfirmCallDialogActivity;
@@ -440,6 +441,7 @@ public class CallsManager extends Call.ListenerBase
            EmergencyCallHelper emergencyCallHelper,
            InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
            ClockProxy clockProxy,
            AudioProcessingNotification audioProcessingNotification,
            BluetoothStateReceiver bluetoothStateReceiver,
            CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
            CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
@@ -532,6 +534,7 @@ public class CallsManager extends Call.ListenerBase
        mListeners.add(missedCallNotifier);
        mListeners.add(mHeadsetMediaButton);
        mListeners.add(mProximitySensorManager);
        mListeners.add(audioProcessingNotification);

        // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
        final UserManager userManager = UserManager.get(mContext);
@@ -692,6 +695,7 @@ public class CallsManager extends Call.ListenerBase
            } else if (result.shouldScreenViaAudio) {
                Log.i(this, "onCallFilteringCompleted: starting background audio processing");
                answerCallForAudioProcessing(incomingCall);
                incomingCall.setAudioProcessingRequestingApp(result.mCallScreeningAppName);
            } else {
                addCall(incomingCall);
            }
@@ -2028,7 +2032,7 @@ public class CallsManager extends Call.ListenerBase
     *
     * @param call The call to manipulate
     */
    public void enterBackgroundAudioProcessing(Call call) {
    public void enterBackgroundAudioProcessing(Call call, String requestingPackageName) {
        if (!mCalls.contains(call)) {
            Log.w(this, "Trying to exit audio processing on an untracked call");
            return;
@@ -2037,6 +2041,18 @@ public class CallsManager extends Call.ListenerBase
        Call activeCall = getActiveCall();
        if (activeCall != call) {
            Log.w(this, "Ignoring enter audio processing because there's already a call active");
            return;
        }

        CharSequence requestingAppName;

        PackageManager pm = mContext.getPackageManager();
        try {
            ApplicationInfo info = pm.getApplicationInfo( requestingPackageName, 0);
            requestingAppName = pm.getApplicationLabel(info);
        } catch (PackageManager.NameNotFoundException nnfe) {
            Log.w(this, "Could not determine package name.");
            requestingAppName = requestingPackageName;
        }

        // We only want this to work on active or ringing calls
@@ -2044,9 +2060,11 @@ public class CallsManager extends Call.ListenerBase
            // After the connection service sets up the call with the other end, it'll set the call
            // state to AUDIO_PROCESSING
            answerCallForAudioProcessing(call);
            call.setAudioProcessingRequestingApp(requestingAppName);
        } else if (call.getState() == CallState.ACTIVE) {
            setCallState(call, CallState.AUDIO_PROCESSING,
                    "audio processing set by dialer request");
            call.setAudioProcessingRequestingApp(requestingAppName);
        }
    }

+29 −30
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.server.telecom;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.telecom.Log;
import android.telecom.PhoneAccountHandle;

@@ -36,21 +35,21 @@ class InCallAdapter extends IInCallAdapter.Stub {
    private final CallsManager mCallsManager;
    private final CallIdMapper mCallIdMapper;
    private final TelecomSystem.SyncRoot mLock;
    private final String mOwnerComponentName;
    private final String mOwnerPackageName;

    /** Persists the specified parameters. */
    public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper,
            TelecomSystem.SyncRoot lock, String ownerComponentName) {
            TelecomSystem.SyncRoot lock, String ownerPackageName) {
        mCallsManager = callsManager;
        mCallIdMapper = callIdMapper;
        mLock = lock;
        mOwnerComponentName = ownerComponentName;
        mOwnerPackageName = ownerPackageName;
    }

    @Override
    public void answerCall(String callId, int videoState) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_ANSWER_CALL, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_ANSWER_CALL, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -73,7 +72,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void deflectCall(String callId, Uri address) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_DEFLECT_CALL, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_DEFLECT_CALL, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -96,7 +95,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_REJECT_CALL, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_REJECT_CALL, mOwnerPackageName);

            int callingUid = Binder.getCallingUid();
            long token = Binder.clearCallingIdentity();
@@ -129,7 +128,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void playDtmfTone(String callId, char digit) {
        try {
            Log.startSession("ICA.pDT", mOwnerComponentName);
            Log.startSession("ICA.pDT", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -152,7 +151,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void stopDtmfTone(String callId) {
        try {
            Log.startSession("ICA.sDT", mOwnerComponentName);
            Log.startSession("ICA.sDT", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -175,7 +174,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void postDialContinue(String callId, boolean proceed) {
        try {
            Log.startSession("ICA.pDC", mOwnerComponentName);
            Log.startSession("ICA.pDC", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -198,7 +197,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void disconnectCall(String callId) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_DISCONNECT_CALL, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_DISCONNECT_CALL, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -221,7 +220,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void holdCall(String callId) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_HOLD_CALL, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_HOLD_CALL, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -243,7 +242,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void unholdCall(String callId) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_UNHOLD_CALL, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_UNHOLD_CALL, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -266,7 +265,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle,
            boolean setDefault) {
        try {
            Log.startSession("ICA.pAS", mOwnerComponentName);
            Log.startSession("ICA.pAS", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -288,7 +287,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void mute(boolean shouldMute) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_MUTE, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_MUTE, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -305,7 +304,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void setAudioRoute(int route, String bluetoothAddress) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_SET_AUDIO_ROUTE, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_SET_AUDIO_ROUTE, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -322,13 +321,13 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void enterBackgroundAudioProcessing(String callId) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_ENTER_AUDIO_PROCESSING, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_ENTER_AUDIO_PROCESSING, mOwnerPackageName);
            // TODO: enforce the extra permission.
            Binder.withCleanCallingIdentity(() -> {
                synchronized (mLock) {
                    Call call = mCallIdMapper.getCall(callId);
                    if (call != null) {
                        mCallsManager.enterBackgroundAudioProcessing(call);
                        mCallsManager.enterBackgroundAudioProcessing(call, mOwnerPackageName);
                    } else {
                        Log.w(this, "enterBackgroundAudioProcessing, unknown call id: %s", callId);
                    }
@@ -342,7 +341,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_EXIT_AUDIO_PROCESSING, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_EXIT_AUDIO_PROCESSING, mOwnerPackageName);
            Binder.withCleanCallingIdentity(() -> {
                synchronized (mLock) {
                    Call call = mCallIdMapper.getCall(callId);
@@ -362,7 +361,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void conference(String callId, String otherCallId) {
        try {
            Log.startSession(LogUtils.Sessions.ICA_CONFERENCE, mOwnerComponentName);
            Log.startSession(LogUtils.Sessions.ICA_CONFERENCE, mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -385,7 +384,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void splitFromConference(String callId) {
        try {
            Log.startSession("ICA.sFC", mOwnerComponentName);
            Log.startSession("ICA.sFC", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -407,7 +406,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void mergeConference(String callId) {
        try {
            Log.startSession("ICA.mC", mOwnerComponentName);
            Log.startSession("ICA.mC", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -429,7 +428,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void swapConference(String callId) {
        try {
            Log.startSession("ICA.sC", mOwnerComponentName);
            Log.startSession("ICA.sC", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -451,7 +450,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void pullExternalCall(String callId) {
        try {
            Log.startSession("ICA.pEC", mOwnerComponentName);
            Log.startSession("ICA.pEC", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -473,7 +472,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras) {
        try {
            Log.startSession("ICA.sCE", mOwnerComponentName);
            Log.startSession("ICA.sCE", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -495,7 +494,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void putExtras(String callId, Bundle extras) {
        try {
            Log.startSession("ICA.pE", mOwnerComponentName);
            Log.startSession("ICA.pE", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -517,7 +516,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void removeExtras(String callId, List<String> keys) {
        try {
            Log.startSession("ICA.rE", mOwnerComponentName);
            Log.startSession("ICA.rE", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -539,7 +538,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void turnOnProximitySensor() {
        try {
            Log.startSession("ICA.tOnPS", mOwnerComponentName);
            Log.startSession("ICA.tOnPS", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -556,7 +555,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    @Override
    public void turnOffProximitySensor(boolean screenOnImmediately) {
        try {
            Log.startSession("ICA.tOffPS", mOwnerComponentName);
            Log.startSession("ICA.tOffPS", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
@@ -657,7 +656,7 @@ class InCallAdapter extends IInCallAdapter.Stub {
    public void handoverTo(String callId, PhoneAccountHandle destAcct, int videoState,
                           Bundle extras) {
        try {
            Log.startSession("ICA.hT", mOwnerComponentName);
            Log.startSession("ICA.hT", mOwnerPackageName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
@@ -267,6 +268,9 @@ public class TelecomSystem {
            }
        };

        AudioProcessingNotification audioProcessingNotification =
                new AudioProcessingNotification(mContext);

        mCallsManager = new CallsManager(
                mContext,
                mLock,
@@ -288,6 +292,7 @@ public class TelecomSystem {
                emergencyCallHelper,
                toneGeneratorFactory,
                clockProxy,
                audioProcessingNotification,
                bluetoothStateReceiver,
                callAudioRouteStateMachineFactory,
                callAudioModeStateMachineFactory,
Loading