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

Commit 303c5dc0 authored by James Lin's avatar James Lin Committed by Gerrit Code Review
Browse files

Merge "[RCS] Create AIDL layer for RcsUceAdapter, create RCS UCE controller...

Merge "[RCS] Create AIDL layer for RcsUceAdapter, create RCS UCE controller implementation in Telephony."
parents 8eacf37e 2bc9cd4c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsManager;
import android.telephony.ims.RcsMessageManager;
import android.util.ArrayMap;
import android.util.Log;
@@ -630,6 +631,14 @@ final class SystemServiceRegistry {
                    }
                });

        registerService(Context.TELEPHONY_IMS_SERVICE, ImsManager.class,
                new CachedServiceFetcher<ImsManager>() {
                    @Override
                    public ImsManager createService(ContextImpl ctx) {
                        return new ImsManager(ctx.getOuterContext());
                    }
                });

        registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
                new CachedServiceFetcher<CarrierConfigManager>() {
            @Override
+7 −0
Original line number Diff line number Diff line
@@ -4724,6 +4724,13 @@ public abstract class Context {
     */
    public static final String APP_BINDING_SERVICE = "app_binding";

    /**
     * Use with {@link #getSystemService(String)} to retrieve an
     * {@link android.telephony.ims.ImsManager}.
     * @hide
     */
    public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";

    /**
     * Use with {@link #getSystemService(String)} to retrieve an
     * {@link android.telephony.ims.RcsMessageManager}.
+66 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.telephony.ims;

import android.annotation.SystemService;
import android.content.Context;
import android.telephony.SubscriptionManager;

/**
 * Provides access to information about Telephony IMS services on the device.
 *
 * @hide
 */
@SystemService(Context.TELEPHONY_IMS_SERVICE)
public class ImsManager {

    private Context mContext;

    public ImsManager(Context context) {
        mContext = context;
    }

    /**
     * Create an instance of ImsRcsManager for the subscription id specified.
     *
     * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
     * @throws IllegalArgumentException if the subscription is invalid.
     * @return a ImsRcsManager instance with the specific subscription ID.
     */
    public ImsRcsManager getImsRcsManager(int subscriptionId) {
        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
            throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
        }

        return new ImsRcsManager(mContext, subscriptionId);
    }

    /**
     * Create an instance of ImsMmTelManager for the subscription id specified.
     *
     * @param subscriptionId The ID of the subscription that this ImsMmTelManager will use.
     * @throws IllegalArgumentException if the subscription is invalid.
     * @return a ImsMmTelManager instance with the specific subscription ID.
     */
    public ImsMmTelManager getImsMmTelManager(int subscriptionId) {
        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
            throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
        }

        return new ImsMmTelManager(subscriptionId);
    }
}
+93 −35
Original line number Diff line number Diff line
@@ -22,11 +22,15 @@ import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
import android.util.Log;

import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -35,10 +39,11 @@ import java.util.function.Consumer;
 * Manager for interfacing with the framework RCS services, including the User Capability Exchange
 * (UCE) service, as well as managing user settings.
 *
 * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager.
 * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
 * @hide
 */
public class ImsRcsManager implements RegistrationManager {
    private static final String TAG = "ImsRcsManager";

    /**
     * Receives RCS availability status updates from the ImsService.
@@ -112,30 +117,23 @@ public class ImsRcsManager implements RegistrationManager {
    private final int mSubId;
    private final Context mContext;


    /**
     * Create an instance of ImsRcsManager for the subscription id specified.
     *
     * @param context The context to create this ImsRcsManager instance within.
     * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
     * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
     * @throws IllegalArgumentException if the subscription is invalid.
     * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this class.
     * @hide
     */
    public static ImsRcsManager createForSubscriptionId(Context context, int subscriptionId) {
        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
            throw new IllegalArgumentException("Invalid subscription ID");
        }

        return new ImsRcsManager(context, subscriptionId);
    public ImsRcsManager(Context context, int subId) {
        mSubId = subId;
        mContext = context;
    }

    /**
     * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this class.
     * @return A {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
     * this subscription.
     * @hide
     */
    private ImsRcsManager(Context context, int subId) {
        mContext = context;
        mSubId = subId;
    @NonNull
    public RcsUceAdapter getUceAdapter() {
        return new RcsUceAdapter(mSubId);
    }

    /**{@inheritDoc}*/
@@ -225,9 +223,22 @@ public class ImsRcsManager implements RegistrationManager {
        if (executor == null) {
            throw new IllegalArgumentException("Must include a non-null Executor.");
        }

        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "Register availability callback: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        c.setExecutor(executor);
        throw new UnsupportedOperationException("registerRcsAvailabilityCallback is not"
                + "supported.");
        try {
            imsRcsController.registerRcsAvailabilityCallback(c.getBinder());
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#registerRcsAvailabilityCallback", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
@@ -238,14 +249,31 @@ public class ImsRcsManager implements RegistrationManager {
     * inactive subscription, it will result in a no-op.
     * @param c The RCS {@link AvailabilityCallback} to be removed.
     * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
     * @throws ImsException if the IMS service is not available when calling this method
     * {@link ImsRcsController#unregisterRcsAvailabilityCallback()}.
     * See {@link ImsException#getCode()} for more information on the error codes.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c) {
    public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c)
            throws ImsException {
        if (c == null) {
            throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
        }
        throw new UnsupportedOperationException("unregisterRcsAvailabilityCallback is not"
                + "supported.");

        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "Unregister availability callback: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        try {
            imsRcsController.unregisterRcsAvailabilityCallback(c.getBinder());
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#unregisterRcsAvailabilityCallback", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
@@ -260,10 +288,27 @@ public class ImsRcsManager implements RegistrationManager {
     * rather the subscription is capable of this service over IMS.
     * @see #isAvailable(int)
     * @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL
     * @throws ImsException if the IMS service is not available when calling this method
     * {@link ImsRcsController#isCapable(int, int)}.
     * See {@link ImsException#getCode()} for more information on the error codes.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
        throw new UnsupportedOperationException("isCapable is not supported.");
    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
            throws ImsException {
        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "isCapable: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        try {
            return imsRcsController.isCapable(mSubId, capability);
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#isCapable", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
@@ -277,18 +322,31 @@ public class ImsRcsManager implements RegistrationManager {
     * false otherwise. If the capability is available, IMS is registered and the service is
     * currently available over IMS.
     * @see #isCapable(int)
     * @throws ImsException if the IMS service is not available when calling this method
     * {@link ImsRcsController#isAvailable(int, int)}.
     * See {@link ImsException#getCode()} for more information on the error codes.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
        throw new UnsupportedOperationException("isAvailable is not supported.");
    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
            throws ImsException {
        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "isAvailable: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

    /**
     * @return A new {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
     * this subscription.
     */
    @NonNull
    public RcsUceAdapter getUceAdapter() {
        return new RcsUceAdapter(mSubId);
        try {
            return imsRcsController.isAvailable(mSubId, capability);
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#isAvailable", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    private IImsRcsController getIImsRcsController() {
        IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
        return IImsRcsController.Stub.asInterface(binder);
    }
}
+95 −7
Original line number Diff line number Diff line
@@ -23,6 +23,13 @@ import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.content.Context;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.aidl.IRcsUceControllerCallback;
import android.util.Log;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,6 +43,7 @@ import java.util.concurrent.Executor;
 * @hide
 */
public class RcsUceAdapter {
    private static final String TAG = "RcsUceAdapter";

    /**
     * An unknown error has caused the request to fail.
@@ -188,7 +196,6 @@ public class RcsUceAdapter {

    /**
     * Not to be instantiated directly, use
     * {@link ImsRcsManager#createForSubscriptionId(Context, int)} and
     * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
     */
    RcsUceAdapter(int subId) {
@@ -218,7 +225,45 @@ public class RcsUceAdapter {
    public void requestCapabilities(@CallbackExecutor Executor executor,
            @NonNull List<Uri> contactNumbers,
            @NonNull CapabilitiesCallback c) throws ImsException {
        throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
        if (c == null) {
            throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
        }
        if (executor == null) {
            throw new IllegalArgumentException("Must include a non-null Executor.");
        }
        if (contactNumbers == null) {
            throw new IllegalArgumentException("Must include non-null contact number list.");
        }

        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "requestCapabilities: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
            @Override
            public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
                Binder.withCleanCallingIdentity(() ->
                        executor.execute(() ->
                                c.onCapabilitiesReceived(contactCapabilities)));
            }
            @Override
            public void onError(int errorCode) {
                Binder.withCleanCallingIdentity(() ->
                        executor.execute(() ->
                                c.onError(errorCode)));
            }
        };

        try {
            imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback);
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
@@ -233,7 +278,20 @@ public class RcsUceAdapter {
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public @PublishState int getUcePublishState() throws ImsException {
        throw new UnsupportedOperationException("getPublishState is not supported.");
        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "getUcePublishState: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        try {
            return imsRcsController.getUcePublishState(mSubId);
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#getUcePublishState", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
@@ -252,9 +310,22 @@ public class RcsUceAdapter {
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public boolean isUceSettingEnabled() throws ImsException {
        // TODO: add SubscriptionController column for this property.
        throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "isUceSettingEnabled: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        try {
            return imsRcsController.isUceSettingEnabled(mSubId);
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
     * Change the user’s setting for whether or not UCE is enabled for the associated subscription.
     * @param isEnabled the user's setting for whether or not they wish for Presence and User
@@ -270,7 +341,24 @@ public class RcsUceAdapter {
     */
    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
    public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
        // TODO: add SubscriptionController column for this property.
        throw new UnsupportedOperationException("setUceSettingEnabled is not supported.");
        IImsRcsController imsRcsController = getIImsRcsController();
        if (imsRcsController == null) {
            Log.e(TAG, "setUceSettingEnabled: IImsRcsController is null");
            throw new ImsException("Can not find remote IMS service",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }

        try {
            imsRcsController.setUceSettingEnabled(mSubId, isEnabled);
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling IImsRcsController#setUceSettingEnabled", e);
            throw new ImsException("Remote IMS Service is not available",
                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    private IImsRcsController getIImsRcsController() {
        IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
        return IImsRcsController.Stub.asInterface(binder);
    }
}
Loading