Merge changes from topics "call-screening-refactor", "composer-call-screening" into sc-dev

* changes:
  Add APIs to support call composer filtering
  Refactor CallScreeningService's internal structure
This commit is contained in:
Hall Liu
2021-02-17 18:52:23 +00:00
committed by Android (Google) Code Review
9 changed files with 331 additions and 43 deletions

View File

@@ -39207,16 +39207,22 @@ package android.telecom {
} }
public static class CallScreeningService.CallResponse { public static class CallScreeningService.CallResponse {
method public int getCallComposerAttachmentsToShow();
method public boolean getDisallowCall(); method public boolean getDisallowCall();
method public boolean getRejectCall(); method public boolean getRejectCall();
method public boolean getSilenceCall(); method public boolean getSilenceCall();
method public boolean getSkipCallLog(); method public boolean getSkipCallLog();
method public boolean getSkipNotification(); method public boolean getSkipNotification();
field public static final int CALL_COMPOSER_ATTACHMENT_LOCATION = 2; // 0x2
field public static final int CALL_COMPOSER_ATTACHMENT_PICTURE = 1; // 0x1
field public static final int CALL_COMPOSER_ATTACHMENT_PRIORITY = 8; // 0x8
field public static final int CALL_COMPOSER_ATTACHMENT_SUBJECT = 4; // 0x4
} }
public static class CallScreeningService.CallResponse.Builder { public static class CallScreeningService.CallResponse.Builder {
ctor public CallScreeningService.CallResponse.Builder(); ctor public CallScreeningService.CallResponse.Builder();
method public android.telecom.CallScreeningService.CallResponse build(); method public android.telecom.CallScreeningService.CallResponse build();
method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setCallComposerAttachmentsToShow(int);
method public android.telecom.CallScreeningService.CallResponse.Builder setDisallowCall(boolean); method public android.telecom.CallScreeningService.CallResponse.Builder setDisallowCall(boolean);
method public android.telecom.CallScreeningService.CallResponse.Builder setRejectCall(boolean); method public android.telecom.CallScreeningService.CallResponse.Builder setRejectCall(boolean);
method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setSilenceCall(boolean); method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setSilenceCall(boolean);

View File

@@ -10769,7 +10769,7 @@ package android.telecom {
method @Nullable public android.telecom.PhoneAccountHandle getPhoneAccountHandle(); method @Nullable public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
method @Nullable public final String getTelecomCallId(); method @Nullable public final String getTelecomCallId();
method @Deprecated public void onAudioStateChanged(android.telecom.AudioState); method @Deprecated public void onAudioStateChanged(android.telecom.AudioState);
method @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public void onCallFilteringCompleted(boolean, boolean); method @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public void onCallFilteringCompleted(boolean, boolean, @Nullable android.telecom.CallScreeningService.CallResponse, boolean);
method public final void resetConnectionTime(); method public final void resetConnectionTime();
method public void setCallDirection(int); method public void setCallDirection(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public final void setConnectTimeMillis(@IntRange(from=0) long); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public final void setConnectTimeMillis(@IntRange(from=0) long);
@@ -10946,7 +10946,7 @@ package android.telecom {
} }
public final class RemoteConnection { public final class RemoteConnection {
method @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public void onCallFilteringCompleted(boolean, boolean); method @RequiresPermission(android.Manifest.permission.READ_CONTACTS) public void onCallFilteringCompleted(boolean, boolean, @Nullable android.telecom.CallScreeningService.CallResponse, boolean);
method @Deprecated public void setAudioState(android.telecom.AudioState); method @Deprecated public void setAudioState(android.telecom.AudioState);
} }

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2021 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 android.telecom;
/**
* {@hide}
*/
parcelable CallScreeningService.ParcelableCallResponse;

View File

@@ -17,6 +17,7 @@
package android.telecom; package android.telecom;
import android.Manifest; import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.RequiresPermission; import android.annotation.RequiresPermission;
import android.annotation.SdkConstant; import android.annotation.SdkConstant;
@@ -30,12 +31,18 @@ import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException; import android.os.RemoteException;
import com.android.internal.os.SomeArgs; import com.android.internal.os.SomeArgs;
import com.android.internal.telecom.ICallScreeningAdapter; import com.android.internal.telecom.ICallScreeningAdapter;
import com.android.internal.telecom.ICallScreeningService; import com.android.internal.telecom.ICallScreeningService;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/** /**
* This service can be implemented by the default dialer (see * This service can be implemented by the default dialer (see
* {@link TelecomManager#getDefaultDialerPackage()}) or a third party app to allow or disallow * {@link TelecomManager#getDefaultDialerPackage()}) or a third party app to allow or disallow
@@ -132,7 +139,10 @@ public abstract class CallScreeningService extends Service {
.createFromParcelableCall((ParcelableCall) args.arg2); .createFromParcelableCall((ParcelableCall) args.arg2);
onScreenCall(callDetails); onScreenCall(callDetails);
if (callDetails.getCallDirection() == Call.Details.DIRECTION_OUTGOING) { if (callDetails.getCallDirection() == Call.Details.DIRECTION_OUTGOING) {
mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId()); mCallScreeningAdapter.onScreeningResponse(
callDetails.getTelecomCallId(),
new ComponentName(getPackageName(), getClass().getName()),
null);
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(this, "Exception when screening call: " + e); Log.w(this, "Exception when screening call: " + e);
@@ -157,10 +167,11 @@ public abstract class CallScreeningService extends Service {
private ICallScreeningAdapter mCallScreeningAdapter; private ICallScreeningAdapter mCallScreeningAdapter;
/* /**
* Information about how to respond to an incoming call. * Parcelable version of {@link CallResponse} used to do IPC.
* @hide
*/ */
public static class CallResponse { public static class ParcelableCallResponse implements Parcelable {
private final boolean mShouldDisallowCall; private final boolean mShouldDisallowCall;
private final boolean mShouldRejectCall; private final boolean mShouldRejectCall;
private final boolean mShouldSilenceCall; private final boolean mShouldSilenceCall;
@@ -168,13 +179,168 @@ public abstract class CallScreeningService extends Service {
private final boolean mShouldSkipNotification; private final boolean mShouldSkipNotification;
private final boolean mShouldScreenCallViaAudioProcessing; private final boolean mShouldScreenCallViaAudioProcessing;
private final int mCallComposerAttachmentsToShow;
private ParcelableCallResponse(
boolean shouldDisallowCall,
boolean shouldRejectCall,
boolean shouldSilenceCall,
boolean shouldSkipCallLog,
boolean shouldSkipNotification,
boolean shouldScreenCallViaAudioProcessing,
int callComposerAttachmentsToShow) {
mShouldDisallowCall = shouldDisallowCall;
mShouldRejectCall = shouldRejectCall;
mShouldSilenceCall = shouldSilenceCall;
mShouldSkipCallLog = shouldSkipCallLog;
mShouldSkipNotification = shouldSkipNotification;
mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing;
mCallComposerAttachmentsToShow = callComposerAttachmentsToShow;
}
protected ParcelableCallResponse(Parcel in) {
mShouldDisallowCall = in.readBoolean();
mShouldRejectCall = in.readBoolean();
mShouldSilenceCall = in.readBoolean();
mShouldSkipCallLog = in.readBoolean();
mShouldSkipNotification = in.readBoolean();
mShouldScreenCallViaAudioProcessing = in.readBoolean();
mCallComposerAttachmentsToShow = in.readInt();
}
public CallResponse toCallResponse() {
return new CallResponse.Builder()
.setDisallowCall(mShouldDisallowCall)
.setRejectCall(mShouldRejectCall)
.setSilenceCall(mShouldSilenceCall)
.setSkipCallLog(mShouldSkipCallLog)
.setSkipNotification(mShouldSkipNotification)
.setShouldScreenCallViaAudioProcessing(mShouldScreenCallViaAudioProcessing)
.setCallComposerAttachmentsToShow(mCallComposerAttachmentsToShow)
.build();
}
public boolean shouldDisallowCall() {
return mShouldDisallowCall;
}
public boolean shouldRejectCall() {
return mShouldRejectCall;
}
public boolean shouldSilenceCall() {
return mShouldSilenceCall;
}
public boolean shouldSkipCallLog() {
return mShouldSkipCallLog;
}
public boolean shouldSkipNotification() {
return mShouldSkipNotification;
}
public boolean shouldScreenCallViaAudioProcessing() {
return mShouldScreenCallViaAudioProcessing;
}
public int getCallComposerAttachmentsToShow() {
return mCallComposerAttachmentsToShow;
}
public static final Creator<ParcelableCallResponse> CREATOR =
new Creator<ParcelableCallResponse>() {
@Override
public ParcelableCallResponse createFromParcel(Parcel in) {
return new ParcelableCallResponse(in);
}
@Override
public ParcelableCallResponse[] newArray(int size) {
return new ParcelableCallResponse[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeBoolean(mShouldDisallowCall);
dest.writeBoolean(mShouldRejectCall);
dest.writeBoolean(mShouldSilenceCall);
dest.writeBoolean(mShouldSkipCallLog);
dest.writeBoolean(mShouldSkipNotification);
dest.writeBoolean(mShouldScreenCallViaAudioProcessing);
dest.writeInt(mCallComposerAttachmentsToShow);
}
}
/**
* Information about how to respond to an incoming call. Call screening apps can construct an
* instance of this class using {@link CallResponse.Builder}.
*/
public static class CallResponse {
/**
* Bit flag indicating whether to show the picture attachment for call composer.
*
* Used with {@link Builder#setCallComposerAttachmentsToShow(int)}.
*/
public static final int CALL_COMPOSER_ATTACHMENT_PICTURE = 1;
/**
* Bit flag indicating whether to show the location attachment for call composer.
*
* Used with {@link Builder#setCallComposerAttachmentsToShow(int)}.
*/
public static final int CALL_COMPOSER_ATTACHMENT_LOCATION = 1 << 1;
/**
* Bit flag indicating whether to show the subject attachment for call composer.
*
* Used with {@link Builder#setCallComposerAttachmentsToShow(int)}.
*/
public static final int CALL_COMPOSER_ATTACHMENT_SUBJECT = 1 << 2;
/**
* Bit flag indicating whether to show the priority attachment for call composer.
*
* Used with {@link Builder#setCallComposerAttachmentsToShow(int)}.
*/
public static final int CALL_COMPOSER_ATTACHMENT_PRIORITY = 1 << 3;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "CALL_COMPOSER_ATTACHMENT_", flag = true,
value = {
CALL_COMPOSER_ATTACHMENT_PICTURE,
CALL_COMPOSER_ATTACHMENT_LOCATION,
CALL_COMPOSER_ATTACHMENT_SUBJECT,
CALL_COMPOSER_ATTACHMENT_PRIORITY
}
)
public @interface CallComposerAttachmentType {}
private static final int NUM_CALL_COMPOSER_ATTACHMENT_TYPES = 4;
private final boolean mShouldDisallowCall;
private final boolean mShouldRejectCall;
private final boolean mShouldSilenceCall;
private final boolean mShouldSkipCallLog;
private final boolean mShouldSkipNotification;
private final boolean mShouldScreenCallViaAudioProcessing;
private final int mCallComposerAttachmentsToShow;
private CallResponse( private CallResponse(
boolean shouldDisallowCall, boolean shouldDisallowCall,
boolean shouldRejectCall, boolean shouldRejectCall,
boolean shouldSilenceCall, boolean shouldSilenceCall,
boolean shouldSkipCallLog, boolean shouldSkipCallLog,
boolean shouldSkipNotification, boolean shouldSkipNotification,
boolean shouldScreenCallViaAudioProcessing) { boolean shouldScreenCallViaAudioProcessing,
int callComposerAttachmentsToShow) {
if (!shouldDisallowCall if (!shouldDisallowCall
&& (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) { && (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) {
throw new IllegalStateException("Invalid response state for allowed call."); throw new IllegalStateException("Invalid response state for allowed call.");
@@ -190,6 +356,7 @@ public abstract class CallScreeningService extends Service {
mShouldSkipNotification = shouldSkipNotification; mShouldSkipNotification = shouldSkipNotification;
mShouldSilenceCall = shouldSilenceCall; mShouldSilenceCall = shouldSilenceCall;
mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing; mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing;
mCallComposerAttachmentsToShow = callComposerAttachmentsToShow;
} }
/* /*
@@ -237,6 +404,49 @@ public abstract class CallScreeningService extends Service {
return mShouldScreenCallViaAudioProcessing; return mShouldScreenCallViaAudioProcessing;
} }
/**
* @return A bitmask of call composer attachments that should be shown to the user.
*/
public @CallComposerAttachmentType int getCallComposerAttachmentsToShow() {
return mCallComposerAttachmentsToShow;
}
/** @hide */
public ParcelableCallResponse toParcelable() {
return new ParcelableCallResponse(
mShouldDisallowCall,
mShouldRejectCall,
mShouldSilenceCall,
mShouldSkipCallLog,
mShouldSkipNotification,
mShouldScreenCallViaAudioProcessing,
mCallComposerAttachmentsToShow
);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CallResponse that = (CallResponse) o;
return mShouldDisallowCall == that.mShouldDisallowCall &&
mShouldRejectCall == that.mShouldRejectCall &&
mShouldSilenceCall == that.mShouldSilenceCall &&
mShouldSkipCallLog == that.mShouldSkipCallLog &&
mShouldSkipNotification == that.mShouldSkipNotification &&
mShouldScreenCallViaAudioProcessing
== that.mShouldScreenCallViaAudioProcessing &&
mCallComposerAttachmentsToShow == that.mCallComposerAttachmentsToShow;
}
@Override
public int hashCode() {
return Objects.hash(mShouldDisallowCall, mShouldRejectCall, mShouldSilenceCall,
mShouldSkipCallLog, mShouldSkipNotification,
mShouldScreenCallViaAudioProcessing,
mCallComposerAttachmentsToShow);
}
public static class Builder { public static class Builder {
private boolean mShouldDisallowCall; private boolean mShouldDisallowCall;
private boolean mShouldRejectCall; private boolean mShouldRejectCall;
@@ -244,6 +454,7 @@ public abstract class CallScreeningService extends Service {
private boolean mShouldSkipCallLog; private boolean mShouldSkipCallLog;
private boolean mShouldSkipNotification; private boolean mShouldSkipNotification;
private boolean mShouldScreenCallViaAudioProcessing; private boolean mShouldScreenCallViaAudioProcessing;
private int mCallComposerAttachmentsToShow = -1;
/** /**
* Sets whether the incoming call should be blocked. * Sets whether the incoming call should be blocked.
@@ -329,6 +540,38 @@ public abstract class CallScreeningService extends Service {
return this; return this;
} }
/**
* Sets the call composer attachments that should be shown to the user.
*
* Attachments that are not shown will not be passed to the in-call UI responsible for
* displaying the call to the user.
*
* If this method is not called on a {@link Builder}, all attachments will be shown,
* except pictures, which will only be shown to users if the call is from a contact.
*
* Setting attachments to show will have no effect if the call screening service does
* not belong to the same package as the system dialer (as returned by
* {@link TelecomManager#getSystemDialerPackage()}).
*
* @param callComposerAttachmentsToShow A bitmask of call composer attachments to show.
*/
public @NonNull Builder setCallComposerAttachmentsToShow(
@CallComposerAttachmentType int callComposerAttachmentsToShow) {
// If the argument is less than zero (meaning unset), no-op since the conversion
// to/from the parcelable version may call with that value.
if (callComposerAttachmentsToShow < 0) {
return this;
}
if ((callComposerAttachmentsToShow
& (1 << NUM_CALL_COMPOSER_ATTACHMENT_TYPES)) != 0) {
throw new IllegalArgumentException("Attachment types must match the ones"
+ " defined in CallResponse");
}
mCallComposerAttachmentsToShow = callComposerAttachmentsToShow;
return this;
}
public CallResponse build() { public CallResponse build() {
return new CallResponse( return new CallResponse(
mShouldDisallowCall, mShouldDisallowCall,
@@ -336,7 +579,8 @@ public abstract class CallScreeningService extends Service {
mShouldSilenceCall, mShouldSilenceCall,
mShouldSkipCallLog, mShouldSkipCallLog,
mShouldSkipNotification, mShouldSkipNotification,
mShouldScreenCallViaAudioProcessing); mShouldScreenCallViaAudioProcessing,
mCallComposerAttachmentsToShow);
} }
} }
} }
@@ -423,21 +667,12 @@ public abstract class CallScreeningService extends Service {
public final void respondToCall(@NonNull Call.Details callDetails, public final void respondToCall(@NonNull Call.Details callDetails,
@NonNull CallResponse response) { @NonNull CallResponse response) {
try { try {
if (response.getDisallowCall()) { mCallScreeningAdapter.onScreeningResponse(
mCallScreeningAdapter.disallowCall( callDetails.getTelecomCallId(),
callDetails.getTelecomCallId(), new ComponentName(getPackageName(), getClass().getName()),
response.getRejectCall(), response.toParcelable());
!response.getSkipCallLog(),
!response.getSkipNotification(),
new ComponentName(getPackageName(), getClass().getName()));
} else if (response.getSilenceCall()) {
mCallScreeningAdapter.silenceCall(callDetails.getTelecomCallId());
} else if (response.getShouldScreenCallViaAudioProcessing()) {
mCallScreeningAdapter.screenCallFurther(callDetails.getTelecomCallId());
} else {
mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId());
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(this, e, "Got remote exception when returning response");
} }
} }
} }

View File

@@ -3390,11 +3390,20 @@ public abstract class Connection extends Conferenceable {
* {@code true}, {@link #onDisconnect()} will be called soon after * {@code true}, {@link #onDisconnect()} will be called soon after
* this is called. * this is called.
* @param isInContacts Indicates whether the caller is in the user's contacts list. * @param isInContacts Indicates whether the caller is in the user's contacts list.
* @param callScreeningResponse The response that was returned from the
* {@link CallScreeningService} that handled this call. If no
* response was received from a call screening service,
* this will be {@code null}.
* @param isResponseFromSystemDialer Whether {@code callScreeningResponse} was sent from the
* system dialer. If {@code callScreeningResponse} is
* {@code null}, this will be {@code false}.
* @hide * @hide
*/ */
@SystemApi @SystemApi
@RequiresPermission(Manifest.permission.READ_CONTACTS) @RequiresPermission(Manifest.permission.READ_CONTACTS)
public void onCallFilteringCompleted(boolean isBlocked, boolean isInContacts) { } public void onCallFilteringCompleted(boolean isBlocked, boolean isInContacts,
@Nullable CallScreeningService.CallResponse callScreeningResponse,
boolean isResponseFromSystemDialer) { }
static String toLogSafePhoneNumber(String number) { static String toLogSafePhoneNumber(String number) {
// For unknown number, log empty string. // For unknown number, log empty string.

View File

@@ -759,6 +759,8 @@ public abstract class ConnectionService extends Service {
@Override @Override
public void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts, public void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts,
CallScreeningService.ParcelableCallResponse callScreeningResponse,
boolean isResponseFromSystemDialer,
Session.Info sessionInfo) { Session.Info sessionInfo) {
Log.startSession(sessionInfo, SESSION_CALL_FILTERING_COMPLETED); Log.startSession(sessionInfo, SESSION_CALL_FILTERING_COMPLETED);
try { try {
@@ -766,7 +768,9 @@ public abstract class ConnectionService extends Service {
args.arg1 = callId; args.arg1 = callId;
args.arg2 = isBlocked; args.arg2 = isBlocked;
args.arg3 = isInContacts; args.arg3 = isInContacts;
args.arg4 = Log.createSubsession(); args.arg4 = callScreeningResponse;
args.arg5 = isResponseFromSystemDialer;
args.arg6 = Log.createSubsession();
mHandler.obtainMessage(MSG_ON_CALL_FILTERING_COMPLETED, args).sendToTarget(); mHandler.obtainMessage(MSG_ON_CALL_FILTERING_COMPLETED, args).sendToTarget();
} finally { } finally {
Log.endSession(); Log.endSession();
@@ -1437,12 +1441,16 @@ public abstract class ConnectionService extends Service {
case MSG_ON_CALL_FILTERING_COMPLETED: { case MSG_ON_CALL_FILTERING_COMPLETED: {
SomeArgs args = (SomeArgs) msg.obj; SomeArgs args = (SomeArgs) msg.obj;
try { try {
Log.continueSession((Session) args.arg4, Log.continueSession((Session) args.arg6,
SESSION_HANDLER + SESSION_CALL_FILTERING_COMPLETED); SESSION_HANDLER + SESSION_CALL_FILTERING_COMPLETED);
String callId = (String) args.arg1; String callId = (String) args.arg1;
boolean isBlocked = (boolean) args.arg2; boolean isBlocked = (boolean) args.arg2;
boolean isInContacts = (boolean) args.arg3; boolean isInContacts = (boolean) args.arg3;
onCallFilteringCompleted(callId, isBlocked, isInContacts); CallScreeningService.ParcelableCallResponse callScreeningResponse =
(CallScreeningService.ParcelableCallResponse) args.arg4;
boolean isResponseFromSystemDialer = (boolean) args.arg5;
onCallFilteringCompleted(callId, isBlocked, isInContacts,
callScreeningResponse, isResponseFromSystemDialer);
} finally { } finally {
args.recycle(); args.recycle();
Log.endSession(); Log.endSession();
@@ -2458,11 +2466,16 @@ public abstract class ConnectionService extends Service {
} }
} }
private void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts) { private void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts,
Log.i(this, "onCallFilteringCompleted(%b, %b)", isBlocked, isInContacts); CallScreeningService.ParcelableCallResponse callScreeningResponse,
boolean isResponseFromSystemDialer) {
Log.i(this, "onCallFilteringCompleted(%s, %b, %b, %s, %b)", callId,
isBlocked, isInContacts, callScreeningResponse, isResponseFromSystemDialer);
Connection connection = findConnectionForAction(callId, "onCallFilteringCompleted"); Connection connection = findConnectionForAction(callId, "onCallFilteringCompleted");
if (connection != null) { if (connection != null) {
connection.onCallFilteringCompleted(isBlocked, isInContacts); connection.onCallFilteringCompleted(isBlocked, isInContacts,
callScreeningResponse == null ? null : callScreeningResponse.toCallResponse(),
isResponseFromSystemDialer);
} }
} }

View File

@@ -1204,15 +1204,25 @@ public final class RemoteConnection {
* the results of a contacts lookup for the remote party. * the results of a contacts lookup for the remote party.
* @param isBlocked Whether call filtering indicates that the call should be blocked * @param isBlocked Whether call filtering indicates that the call should be blocked
* @param isInContacts Whether the remote party is in the user's contacts * @param isInContacts Whether the remote party is in the user's contacts
* @param callScreeningResponse The response that was returned from the
* {@link CallScreeningService} that handled this call. If no
* response was received from a call screening service,
* this will be {@code null}.
* @param isResponseFromSystemDialer Whether {@code callScreeningResponse} was sent from the
* system dialer. If {@code callScreeningResponse} is
* {@code null}, this will be {@code false}.
* @hide * @hide
*/ */
@SystemApi @SystemApi
@RequiresPermission(Manifest.permission.READ_CONTACTS) @RequiresPermission(Manifest.permission.READ_CONTACTS)
public void onCallFilteringCompleted(boolean isBlocked, boolean isInContacts) { public void onCallFilteringCompleted(boolean isBlocked, boolean isInContacts,
@Nullable CallScreeningService.CallResponse callScreeningResponse,
boolean isResponseFromSystemDialer) {
Log.startSession("RC.oCFC", getActiveOwnerInfo()); Log.startSession("RC.oCFC", getActiveOwnerInfo());
try { try {
if (mConnected) { if (mConnected) {
mConnectionService.onCallFilteringCompleted(mConnectionId, isBlocked, isInContacts, mConnectionService.onCallFilteringCompleted(mConnectionId, isBlocked, isInContacts,
callScreeningResponse.toParcelable(), isResponseFromSystemDialer,
null /*Session.Info*/); null /*Session.Info*/);
} }
} catch (RemoteException ignored) { } catch (RemoteException ignored) {

View File

@@ -17,6 +17,7 @@
package com.android.internal.telecom; package com.android.internal.telecom;
import android.content.ComponentName; import android.content.ComponentName;
import android.telecom.CallScreeningService;
/** /**
* Internal remote callback interface for call screening services. * Internal remote callback interface for call screening services.
@@ -26,16 +27,6 @@ import android.content.ComponentName;
* {@hide} * {@hide}
*/ */
oneway interface ICallScreeningAdapter { oneway interface ICallScreeningAdapter {
void allowCall(String callId); void onScreeningResponse(String callId, in ComponentName componentName,
in CallScreeningService.ParcelableCallResponse response);
void silenceCall(String callId);
void screenCallFurther(String callId);
void disallowCall(
String callId,
boolean shouldReject,
boolean shouldAddToCallLog,
boolean shouldShowNotification,
in ComponentName componentName);
} }

View File

@@ -20,6 +20,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.telecom.CallAudioState; import android.telecom.CallAudioState;
import android.telecom.CallScreeningService;
import android.telecom.ConnectionRequest; import android.telecom.ConnectionRequest;
import android.telecom.Logging.Session; import android.telecom.Logging.Session;
import android.telecom.PhoneAccountHandle; import android.telecom.PhoneAccountHandle;
@@ -119,7 +120,8 @@ oneway interface IConnectionService {
void sendCallEvent(String callId, String event, in Bundle extras, in Session.Info sessionInfo); void sendCallEvent(String callId, String event, in Bundle extras, in Session.Info sessionInfo);
void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts, void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts,
in Session.Info sessionInfo); in CallScreeningService.ParcelableCallResponse callScreeningResponse,
boolean isResponseFromSystemDialer, in Session.Info sessionInfo);
void onExtrasChanged(String callId, in Bundle extras, in Session.Info sessionInfo); void onExtrasChanged(String callId, in Bundle extras, in Session.Info sessionInfo);