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

Commit 8b194fe9 authored by Tyler Gunn's avatar Tyler Gunn Committed by Gerrit Code Review
Browse files

Merge "Call Screening / Caller ID API Changes"

parents 62a9b66a 94f8f113
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -41157,6 +41157,7 @@ package android.telecom {
    method public static String capabilitiesToString(int);
    method public android.telecom.PhoneAccountHandle getAccountHandle();
    method public int getCallCapabilities();
    method public int getCallDirection();
    method @Nullable public android.telecom.CallIdentification getCallIdentification();
    method public int getCallProperties();
    method public String getCallerDisplayName();
@@ -41193,6 +41194,9 @@ package android.telecom {
    field public static final int CAPABILITY_SUPPORT_DEFLECT = 16777216; // 0x1000000
    field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
    field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
    field public static final int DIRECTION_INCOMING = 0; // 0x0
    field public static final int DIRECTION_OUTGOING = 1; // 0x1
    field public static final int DIRECTION_UNKNOWN = -1; // 0xffffffff
    field public static final int PROPERTY_CONFERENCE = 1; // 0x1
    field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 4; // 0x4
    field public static final int PROPERTY_ENTERPRISE_CALL = 32; // 0x20
+42 −4
Original line number Diff line number Diff line
@@ -239,6 +239,30 @@ public final class Call {
            "android.telecom.event.HANDOVER_FAILED";

    public static class Details {
        /** @hide */
        @Retention(RetentionPolicy.SOURCE)
        @IntDef(
                prefix = { "DIRECTION_" },
                value = {DIRECTION_UNKNOWN, DIRECTION_INCOMING, DIRECTION_OUTGOING})
        public @interface CallDirection {}

        /**
         * Indicates that the call is neither and incoming nor an outgoing call.  This can be the
         * case for calls reported directly by a {@link ConnectionService} in special cases such as
         * call handovers.
         */
        public static final int DIRECTION_UNKNOWN = -1;

        /**
         * Indicates that the call is an incoming call.
         */
        public static final int DIRECTION_INCOMING = 0;

        /**
         * Indicates that the call is an outgoing call.
         */
        public static final int DIRECTION_OUTGOING = 1;


        /** Call can currently be put on hold or unheld. */
        public static final int CAPABILITY_HOLD = 0x00000001;
@@ -519,6 +543,7 @@ public final class Call {
        private final Bundle mIntentExtras;
        private final long mCreationTimeMillis;
        private final CallIdentification mCallIdentification;
        private final @CallDirection int mCallDirection;

        /**
         * Whether the supplied capabilities  supports the specified capability.
@@ -838,6 +863,14 @@ public final class Call {
            return mCallIdentification;
        }

        /**
         * Indicates whether the call is an incoming or outgoing call.
         * @return The call's direction.
         */
        public @CallDirection int getCallDirection() {
            return mCallDirection;
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof Details) {
@@ -859,7 +892,8 @@ public final class Call {
                        areBundlesEqual(mExtras, d.mExtras) &&
                        areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
                        Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
                        Objects.equals(mCallIdentification, d.mCallIdentification);
                        Objects.equals(mCallIdentification, d.mCallIdentification) &&
                        Objects.equals(mCallDirection, d.mCallDirection);
            }
            return false;
        }
@@ -881,7 +915,8 @@ public final class Call {
                            mExtras,
                            mIntentExtras,
                            mCreationTimeMillis,
                            mCallIdentification);
                            mCallIdentification,
                            mCallDirection);
        }

        /** {@hide} */
@@ -902,7 +937,8 @@ public final class Call {
                Bundle extras,
                Bundle intentExtras,
                long creationTimeMillis,
                CallIdentification callIdentification) {
                CallIdentification callIdentification,
                int callDirection) {
            mTelecomCallId = telecomCallId;
            mHandle = handle;
            mHandlePresentation = handlePresentation;
@@ -920,6 +956,7 @@ public final class Call {
            mIntentExtras = intentExtras;
            mCreationTimeMillis = creationTimeMillis;
            mCallIdentification = callIdentification;
            mCallDirection = callDirection;
        }

        /** {@hide} */
@@ -941,7 +978,8 @@ public final class Call {
                    parcelableCall.getExtras(),
                    parcelableCall.getIntentExtras(),
                    parcelableCall.getCreationTimeMillis(),
                    parcelableCall.getCallIdentification());
                    parcelableCall.getCallIdentification(),
                    parcelableCall.getCallDirection());
        }

        @Override
+20 −2
Original line number Diff line number Diff line
@@ -250,8 +250,8 @@ public final class CallIdentification implements Parcelable {
        mDetails = details;
        mPhoto = photo;
        mNuisanceConfidence = nuisanceConfidence;
        mCallScreeningAppName = callScreeningPackageName;
        mCallScreeningPackageName = callScreeningAppName;
        mCallScreeningAppName = callScreeningAppName;
        mCallScreeningPackageName = callScreeningPackageName;
    }

    private String mName;
@@ -430,4 +430,22 @@ public final class CallIdentification implements Parcelable {
        return Objects.hash(mName, mDescription, mDetails, mPhoto, mNuisanceConfidence,
                mCallScreeningAppName, mCallScreeningPackageName);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[CallId mName=");
        sb.append(Log.pii(mName));
        sb.append(", mDesc=");
        sb.append(mDescription);
        sb.append(", mDet=");
        sb.append(mDetails);
        sb.append(", conf=");
        sb.append(mNuisanceConfidence);
        sb.append(", appName=");
        sb.append(mCallScreeningAppName);
        sb.append(", pkgName=");
        sb.append(mCallScreeningPackageName);
        return sb.toString();
    }
}
+54 −8
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.SdkConstant;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -33,8 +34,9 @@ import com.android.internal.telecom.ICallScreeningService;

/**
 * This service can be implemented by the default dialer (see
 * {@link TelecomManager#getDefaultDialerPackage()}) to allow or disallow incoming calls before
 * they are shown to a user.
 * {@link TelecomManager#getDefaultDialerPackage()}) or a third party app to allow or disallow
 * incoming calls before they are shown to a user.  This service can also provide
 * {@link CallIdentification} information for calls.
 * <p>
 * Below is an example manifest registration for a {@code CallScreeningService}.
 * <pre>
@@ -56,6 +58,34 @@ import com.android.internal.telecom.ICallScreeningService;
 *     information about a {@link Call.Details call} which will be shown to the user in the
 *     Dialer app.</li>
 * </ol>
 * <p>
 * <h2>Becoming the {@link CallScreeningService}</h2>
 * Telecom will bind to a single app chosen by the user which implements the
 * {@link CallScreeningService} API when there are new incoming and outgoing calls.
 * <p>
 * The code snippet below illustrates how your app can request that it fills the call screening
 * role.
 * <pre>
 * {@code
 * private static final int REQUEST_ID = 1;
 *
 * public void requestRole() {
 *     RoleManager roleManager = (RoleManager) getSystemService(ROLE_SERVICE);
 *     Intent intent = roleManager.createRequestRoleIntent("android.app.role.CALL_SCREENING_APP");
 *     startActivityForResult(intent, REQUEST_ID);
 * }
 *
 * &#64;Override
 * public void onActivityResult(int requestCode, int resultCode, Intent data) {
 *     if (requestCode == REQUEST_ID) {
 *         if (resultCode == android.app.Activity.RESULT_OK) {
 *             // Your app is now the call screening app
 *         } else {
 *             // Your app is not the call screening app
 *         }
 *     }
 * }
 * </pre>
 */
public abstract class CallScreeningService extends Service {
    /**
@@ -222,30 +252,46 @@ public abstract class CallScreeningService extends Service {
    }

    /**
     * Called when a new incoming call is added.
     * {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
     * should be called to allow or disallow the call.
     * Called when a new incoming or outgoing call is added which is not in the user's contact list.
     * <p>
     * A {@link CallScreeningService} must indicate whether an incoming call is allowed or not by
     * calling
     * {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}.
     * Your app can tell if a call is an incoming call by checking to see if
     * {@link Call.Details#getCallDirection()} is {@link Call.Details#DIRECTION_INCOMING}.
     * <p>
     * For incoming or outgoing calls, the {@link CallScreeningService} can call
     * {@link #provideCallIdentification(Call.Details, CallIdentification)} in order to provide
     * {@link CallIdentification} for the call.
     * <p>
     * Note: The {@link Call.Details} instance provided to a call screening service will only have
     * the following properties set.  The rest of the {@link Call.Details} properties will be set to
     * their default value or {@code null}.
     * <ul>
     *     <li>{@link Call.Details#getState()}</li>
     *     <li>{@link Call.Details#getCallDirection()}</li>
     *     <li>{@link Call.Details#getConnectTimeMillis()}</li>
     *     <li>{@link Call.Details#getCreationTimeMillis()}</li>
     *     <li>{@link Call.Details#getHandle()}</li>
     *     <li>{@link Call.Details#getHandlePresentation()}</li>
     * </ul>
     * <p>
     * Only calls where the {@link Call.Details#getHandle() handle} {@link Uri#getScheme() scheme}
     * is {@link PhoneAccount#SCHEME_TEL} are passed for call
     * screening.  Further, only calls which are not in the user's contacts are passed for
     * screening.  For outgoing calls, no post-dial digits are passed.
     *
     * @param callDetails Information about a new incoming call, see {@link Call.Details}.
     * @param callDetails Information about a new call, see {@link Call.Details}.
     */
    public abstract void onScreenCall(@NonNull Call.Details callDetails);

    /**
     * Responds to the given call, either allowing it or disallowing it.
     * Responds to the given incoming call, either allowing it or disallowing it.
     * <p>
     * The {@link CallScreeningService} calls this method to inform the system whether the call
     * should be silently blocked or not.
     * <p>
     * Calls to this method are ignored unless the {@link Call.Details#getCallDirection()} is
     * {@link Call.Details#DIRECTION_INCOMING}.
     *
     * @param callDetails The call to allow.
     *                    <p>
+95 −12
Original line number Diff line number Diff line
@@ -40,11 +40,30 @@ import java.util.Collections;
import java.util.List;

/**
 * This service is implemented by any app that wishes to provide the user-interface for managing
 * phone calls. Telecom binds to this service while there exists a live (active or incoming) call,
 * and uses it to notify the in-call app of any live and recently disconnected calls. An app must
 * first be set as the default phone app (See {@link TelecomManager#getDefaultDialerPackage()})
 * before the telecom service will bind to its {@code InCallService} implementation.
 * This service is implemented by an app that wishes to provide functionality for managing
 * phone calls.
 * <p>
 * There are three types of apps which Telecom can bind to when there exists a live (active or
 * incoming) call:
 * <ol>
 *     <li>Default Dialer/Phone app - the default dialer/phone app is one which provides the
 *     in-call user interface while the device is in a call.  A device is bundled with a system
 *     provided default dialer/phone app.  The user may choose a single app to take over this role
 *     from the system app.</li>
 *     <li>Default Car-mode Dialer/Phone app - the default car-mode dialer/phone app is one which
 *     provides the in-call user interface while the device is in a call and the device is in car
 *     mode.  The user may choose a single app to fill this role.</li>
 *     <li>Call Companion app - a call companion app is one which provides no user interface itself,
 *     but exposes call information to another display surface, such as a wearable device.  The
 *     user may choose multiple apps to fill this role.</li>
 * </ol>
 * <p>
 * Apps which wish to fulfill one of the above roles use the {@code android.app.role.RoleManager}
 * to request that they fill the desired role.
 *
 * <h2>Becoming the Default Phone App</h2>
 * An app filling the role of the default phone app provides a user interface while the device is in
 * a call, and the device is not in car mode.
 * <p>
 * Below is an example manifest registration for an {@code InCallService}. The meta-data
 * {@link TelecomManager#METADATA_IN_CALL_SERVICE_UI} indicates that this particular
@@ -82,12 +101,34 @@ import java.util.List;
 * }
 * </pre>
 * <p>
 * When a user installs your application and runs it for the first time, you should prompt the user
 * to see if they would like your application to be the new default phone app.  See the
 * {@link TelecomManager#ACTION_CHANGE_DEFAULT_DIALER} intent documentation for more information on
 * how to do this.
 * When a user installs your application and runs it for the first time, you should use the
 * {@code android.app.role.RoleManager} to prompt the user to see if they would like your app to
 * be the new default phone app.
 * <p id="requestRole">
 * The code below shows how your app can request to become the default phone/dialer app:
 * <pre>
 * {@code
 * private static final int REQUEST_ID = 1;
 *
 * public void requestRole() {
 *     RoleManager roleManager = (RoleManager) getSystemService(ROLE_SERVICE);
 *     Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER);
 *     startActivityForResult(intent, REQUEST_ID);
 * }
 *
 * &#64;Override
 * public void onActivityResult(int requestCode, int resultCode, Intent data) {
 *     if (requestCode == REQUEST_ID) {
 *         if (resultCode == android.app.Activity.RESULT_OK) {
 *             // Your app is now the default dialer app
 *         } else {
 *             // Your app is not the default dialer app
 *         }
 *     }
 * }
 * </pre>
 * <p id="incomingCallNotification">
 * <h2>Showing the Incoming Call Notification</h2>
 * <h3>Showing the Incoming Call Notification</h3>
 * When your app receives a new incoming call via {@link InCallService#onCallAdded(Call)}, it is
 * responsible for displaying an incoming call UI for the incoming call.  It should do this using
 * {@link android.app.NotificationManager} APIs to post a new incoming call notification.
@@ -121,7 +162,7 @@ import java.util.List;
 * heads-up notification if the user is actively using the phone.  When the user is not using the
 * phone, your full-screen incoming call UI is used instead.
 * For example:
 * <pre><code>
 * <pre><code>{@code
 * // Create an intent which triggers your fullscreen incoming call user interface.
 * Intent intent = new Intent(Intent.ACTION_MAIN, null);
 * intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -151,7 +192,49 @@ import java.util.List;
 * NotificationManager notificationManager = mContext.getSystemService(
 *     NotificationManager.class);
 * notificationManager.notify(YOUR_CHANNEL_ID, YOUR_TAG, YOUR_ID, builder.build());
 * </code></pre>
 * }</pre>
 * <p>
 * <h2>Becoming the Default Car-mode Phone App</h2>
 * An app filling the role of the default car-mode dialer/phone app provides a user interface while
 * the device is in a call, and in car mode.  See
 * {@link android.app.UiModeManager#ACTION_ENTER_CAR_MODE} for more information about car mode.
 * When the device is in car mode, Telecom binds to the default car-mode dialer/phone app instead
 * of the usual dialer/phone app.
 * <p>
 * Similar to the requirements for becoming the default dialer/phone app, your app must declare a
 * manifest entry for its {@link InCallService} implementation.  Your manifest entry should ensure
 * the following conditions are met:
 * <ul>
 *     <li>Do NOT declare the {@link TelecomManager#METADATA_IN_CALL_SERVICE_UI} metadata.</li>
 *     <li>Set the {@link TelecomManager#METADATA_IN_CALL_SERVICE_CAR_MODE_UI} metadata to
 *     {@code true}<li>
 *     <li>Your app must request the permission
 *     {@link android.Manifest.permission.CALL_COMPANION_APP}.</li>
 * </ul>
 * <p>
 * Your app should request to fill the role {@code android.app.role.CAR_MODE_DIALER_APP} in order to
 * become the default (see <a href="#requestRole">above</a> for how to request your app fills this
 * role).
 *
 * <h2>Becoming a Call Companion App</h2>
 * An app which fills the companion app role does not directly provide a user interface while the
 * device is in a call.  Instead, it is typically used to relay information about calls to another
 * display surface, such as a wearable device.
 * <p>
 * Similar to the requirements for becoming the default dialer/phone app, your app must declare a
 * manifest entry for its {@link InCallService} implementation.  Your manifest entry should
 * ensure the following conditions are met:
 * <ul>
 *     <li>Do NOT declare the {@link TelecomManager#METADATA_IN_CALL_SERVICE_UI} metadata.</li>
 *     <li>Do NOT declare the {@link TelecomManager#METADATA_IN_CALL_SERVICE_CAR_MODE_UI}
 *     metadata.</li>
 *     <li>Your app must request the permission
 *     {@link android.Manifest.permission.CALL_COMPANION_APP}.</li>
 * </ul>
 * <p>
 * Your app should request to fill the role {@code android.app.role.CALL_COMPANION_APP} in order to
 * become a call companion app (see <a href="#requestRole">above</a> for how to request your app
 * fills this role).
 */
public abstract class InCallService extends Service {

Loading