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

Commit cbaa692c authored by James Lin's avatar James Lin Committed by Automerger Merge Worker
Browse files

Merge "[RCS UCE] Create the controller implmentation classes for the...

Merge "[RCS UCE] Create the controller implmentation classes for the UceController initalization" am: bb80becb am: 23517ceb am: 4e6eafcf am: 7bf45f7a

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/net/ims/+/1486799

Change-Id: I47870b33637c0759fbc48b8946213dda41acdc01
parents deab6b63 7bf45f7a
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -21,19 +21,19 @@ import android.content.Context;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsRcsFeature;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IPublishResponseCallback;
import android.telephony.ims.aidl.IRcsFeatureListener;
import android.telephony.ims.aidl.ISipTransport;
import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;

import com.android.ims.rcs.uce.RcsCapabilityExchangeImplAdapter.PublishResponseCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.telephony.Rlog;

@@ -225,9 +225,20 @@ public class RcsFeatureConnection extends FeatureConnection {
        }
    }

    public void requestPublication(String pidfXml, PublishResponseCallback responseCallback)
    public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener)
            throws RemoteException{
        // TODO: add the new API: requestPublication
        synchronized (mLock) {
            checkServiceIsReady();
            getServiceInterface(mBinder).setCapabilityExchangeEventListener(listener);
        }
    }

    public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback)
            throws RemoteException {
        synchronized (mLock) {
            checkServiceIsReady();
            getServiceInterface(mBinder).publishCapabilities(pidfXml, responseCallback);
        }
    }

    public void requestCapabilities(List<Uri> uris, int taskId) throws RemoteException {
+8 −2
Original line number Diff line number Diff line
@@ -30,10 +30,12 @@ import android.telephony.ims.ImsException;
import android.telephony.ims.ImsService;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.aidl.IImsRcsFeature;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IPublishResponseCallback;
import android.telephony.ims.aidl.IRcsFeatureListener;
import android.telephony.ims.aidl.ISipTransport;
import android.telephony.ims.feature.CapabilityChangeRequest;
@@ -47,7 +49,6 @@ import android.telephony.ims.stub.RcsSipOptionsImplBase;
import android.util.Log;

import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.ims.rcs.uce.RcsCapabilityExchangeImplAdapter.PublishResponseCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.ITelephony;
import com.android.telephony.Rlog;
@@ -450,7 +451,12 @@ public class RcsFeatureManager implements FeatureUpdates {
        mRcsFeatureConnection.requestPublication(capabilities, taskId);
    }

    public void requestPublication(String pidfXml, PublishResponseCallback responseCallback)
    public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener)
            throws RemoteException {
        mRcsFeatureConnection.setCapabilityExchangeEventListener(listener);
    }

    public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback)
            throws RemoteException {
        mRcsFeatureConnection.requestPublication(pidfXml, responseCallback);
    }
+0 −118
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 com.android.ims.rcs.uce;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.Uri;
import android.telephony.ims.ImsException;

import java.util.List;

/**
 * The adapter class of RcsCapabilityExchangeImplBase
 */
public class RcsCapabilityExchangeImplAdapter {

    /**  Service is unknown. */
    public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0;
    /** The command failed with an unknown error. */
    public static final int COMMAND_CODE_GENERIC_FAILURE = 1;
    /**  Invalid parameter(s). */
    public static final int COMMAND_CODE_INVALID_PARAM = 2;
    /**  Fetch error. */
    public static final int COMMAND_CODE_FETCH_ERROR = 3;
    /**  Request timed out. */
    public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4;
    /**  Failure due to insufficient memory available. */
    public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5;
    /**  Network connection is lost. */
    public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6;
    /**  Requested feature/resource is not supported. */
    public static final int COMMAND_CODE_NOT_SUPPORTED = 7;
    /**  Contact or resource is not found. */
    public static final int COMMAND_CODE_NOT_FOUND = 8;
    /**  Service is not available. */
    public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9;
    /** Command resulted in no change in state, ignoring. */
    public static final int COMMAND_CODE_NO_CHANGE = 10;

    /**
     * The adapter class of the interface PublishResponseCallback
     */
    public interface PublishResponseCallback {
        /**
         * Notify the framework that the command associated with this callback has failed.
         */
        void onCommandError(int code) throws ImsException;

        /**
         * Provide the framework with a subsequent network response update to
         * {@link #publishCapabilities(RcsContactUceCapability, int)}.
         */
        void onNetworkResponse(int code, @NonNull String reason) throws ImsException;
    }

    /**
     * The adapter class of the interface OptionsResponseCallback
     */
    public interface OptionsResponseCallback {
        /**
         * Notify the framework that the command associated with this callback has
         * failed.
         */
        void onCommandError(int code) throws ImsException;

        /**
         * Send the response of a SIP OPTIONS capability exchange to the framework.
         */
        void onNetworkResponse(int code, @NonNull String reason,
                @Nullable List<String> theirCaps) throws ImsException;
    }

    /**
     * The adapter class of the interface SubscribeResponseCallback
     */
    public interface SubscribeResponseCallback {
        /**
         * Notify the framework that the command associated with this callback has failed.
         */
        void onCommandError(int code) throws ImsException;

        /**
         * Notify the framework  of the response to the SUBSCRIBE request from
         * {@link #subscribeForCapabilities(RcsContactUceCapability, int)}.
         */
        void onNetworkResponse(int code, @NonNull String reason) throws ImsException;

        /**
         * Provides the framework with latest XML PIDF documents included in the
         * network response for the requested  contacts' capabilities requested by the
         * Framework  using {@link #requestCapabilities(List, int)}. This should be
         * called every time a new NOTIFY event is received with new capability
         * information.
         */
        void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException;

        /**
         * The subscription associated with a previous #requestCapabilities operation
         * has been terminated. This will mostly be due to the subscription expiring,
         * but may also happen due to an error.
         */
        void onTerminated(String reason, String retryAfter) throws ImsException;
    }
}
+126 −26
Original line number Diff line number Diff line
@@ -21,25 +21,32 @@ import android.content.Context;
import android.net.Uri;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.RemoteException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.RcsUceAdapter.CapabilitiesCallback;
import android.telephony.ims.RcsUceAdapter.PublishState;
import android.telephony.ims.RcsUceAdapter.StackPublishTriggerType;
import android.telephony.ims.RcsUceAdapter.PublishStateCallback;
import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
import android.telephony.ims.aidl.IOptionsRequestCallback;
import android.telephony.ims.aidl.IOptionsResponseCallback;
import android.telephony.ims.aidl.IRcsUceControllerCallback;
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
import android.util.Log;

import com.android.ims.RcsFeatureManager;
import com.android.ims.rcs.uce.eab.EabCapabilityResult;
import com.android.ims.rcs.uce.eab.EabController;
import com.android.ims.rcs.uce.eab.EabControllerImpl;
import com.android.ims.rcs.uce.options.OptionsController;
import com.android.ims.rcs.uce.options.OptionsControllerImpl;
import com.android.ims.rcs.uce.presence.publish.PublishController;
import com.android.ims.rcs.uce.presence.publish.PublishControllerImpl;
import com.android.ims.rcs.uce.presence.subscribe.SubscribeController;
import com.android.ims.rcs.uce.presence.subscribe.SubscribeControllerImpl;
import com.android.internal.annotations.VisibleForTesting;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * The UceController will manage the RCS UCE requests on a per subscription basis. When it receives
@@ -80,14 +87,14 @@ public class UceController {
         */
        void requestCapabilitiesByOptions(@NonNull Uri contactUri,
                @NonNull RcsContactUceCapability ownCapabilities,
                @NonNull RcsCapabilityExchangeImplAdapter.OptionsResponseCallback callback);
                @NonNull IOptionsResponseCallback callback);

        /**
         * The method is called when the given contacts' capabilities are expired and need to be
         * refreshed.
         */
        void refreshCapabilities(@NonNull List<Uri> contactNumbers,
                @NonNull CapabilitiesCallback callback);
                @NonNull IRcsUceControllerCallback callback) throws RemoteException;

        /**
         * The method is called when the EabController and the PublishController want to receive
@@ -109,6 +116,9 @@ public class UceController {
        UceRequestTaskManager createTaskManager(Context context, int subId, Looper looper);
    }

    private RequestTaskManagerFactory mTaskManagerFactory = (context, subId, looper) ->
            new UceRequestTaskManager(context, subId, looper);

    /**
     * Used to inject Controller instances for testing.
     */
@@ -138,31 +148,61 @@ public class UceController {
                UceControllerCallback c, Looper looper);
    }

    private ControllerFactory mControllerFactory = new ControllerFactory() {
        @Override
        public EabController createEabController(Context context, int subId,
                UceControllerCallback c, Looper looper) {
            return new EabControllerImpl(context, subId, c, looper);
        }

        @Override
        public PublishController createPublishController(Context context, int subId,
                Looper looper) {
            return new PublishControllerImpl(context, subId, looper);
        }

        @Override
        public SubscribeController createSubscribeController(Context context, int subId,
                UceControllerCallback c, Looper looper) {
            return new SubscribeControllerImpl(context, subId, c, looper);
        }

        @Override
        public OptionsController createOptionsController(Context context, int subId,
                UceControllerCallback c, Looper looper) {
            return new OptionsControllerImpl(context, subId, c, looper);
        }
    };

    private final int mSubId;
    private final Context mContext;
    private volatile boolean mIsRcsConnected;
    private volatile boolean mIsDestroyedFlag;

    private Looper mLooper;

    private UceRequestTaskManager mTaskManager;
    private final RequestTaskManagerFactory mTaskManagerFactory;

    private EabController mEabController;
    private PublishController mPublishController;
    private SubscribeController mSubscribeController;
    private OptionsController mOptionsController;
    private final ControllerFactory mControllerFactory;
    private UceRequestTaskManager mTaskManager;

    public UceController(Context context, int subId, ControllerFactory controllerFactory,
            RequestTaskManagerFactory taskManagerFactory) {
    public UceController(Context context, int subId) {
        mSubId = subId;
        mContext = context;
        logi("create");

        initLooper();
        initRequestTaskManager();
        initControllers();
    }

    @VisibleForTesting
    public UceController(Context context, int subId, ControllerFactory controllerFactory,
            RequestTaskManagerFactory taskManagerFactory) {
        mSubId = subId;
        mContext = context;
        mControllerFactory = controllerFactory;
        mTaskManagerFactory = taskManagerFactory;

        initLooper();
        initRequestTaskManager();
        initControllers();
@@ -200,6 +240,12 @@ public class UceController {
        mPublishController.onRcsConnected(manager);
        mSubscribeController.onRcsConnected(manager);
        mOptionsController.onRcsConnected(manager);

        try {
            manager.setCapabilityExchangeEventListener(mCapabilityEventListener);
        } catch (RemoteException e) {
            logw("Set capability event listener error: " + e.getMessage());
        }
    }

    /**
@@ -230,7 +276,10 @@ public class UceController {
        mLooper.quit();
    }

    // The implementation of the interface UceControllerCallback.
    /*
     * The implementation of the interface UceControllerCallback. These methods are called by other
     * controllers.
     */
    private UceControllerCallback mCtrlCallback = new UceControllerCallback() {
        @Override
        public EabCapabilityResult getCapabilitiesFromCache(List<Uri> uris) {
@@ -253,14 +302,15 @@ public class UceController {
        }

        @Override
        public void requestCapabilitiesByOptions(Uri uri, RcsContactUceCapability ownCapabilities,
                RcsCapabilityExchangeImplAdapter.OptionsResponseCallback callback) {
        public void requestCapabilitiesByOptions(@NonNull Uri uri,
                @NonNull RcsContactUceCapability ownCapabilities,
                @NonNull IOptionsResponseCallback callback) {
            mOptionsController.sendCapabilitiesRequest(uri, ownCapabilities, callback);
        }

        @Override
        public void refreshCapabilities(@NonNull List<Uri> contactNumbers,
                @NonNull CapabilitiesCallback callback) {
                @NonNull IRcsUceControllerCallback callback) throws RemoteException{
            logd("refreshCapabilities: " + contactNumbers.size());
            UceController.this.requestCapabilities(contactNumbers, callback);
        }
@@ -283,12 +333,44 @@ public class UceController {
        mCtrlCallback = callback;
    }

    /*
     * Setup the listener to listen to the requests and updates from ImsService.
     */
    private ICapabilityExchangeEventListener mCapabilityEventListener =
            new ICapabilityExchangeEventListener.Stub() {
                @Override
                public void onRequestPublishCapabilities(
                        @StackPublishTriggerType int publishTriggerType) {
                    onRequestPublishCapabilitiesFromService(publishTriggerType);
                }

                @Override
                public void onUnpublish() {
                    UceController.this.onUnpublish();
                }

                @Override
                public void onRemoteCapabilityRequest(Uri contactUri,
                        List<String> remoteCapabilities, IOptionsRequestCallback cb) {
                    retrieveOptionsCapabilitiesForRemote(contactUri, remoteCapabilities, cb);
                }
            };

    /**
     * Request to get the contacts' capabilities. This method will retrieve the capabilities from
     * the cache If the capabilities are out of date, it will trigger another request to get the
     * latest contact's capabilities from the carrier network.
     */
    public void requestCapabilities(@NonNull List<Uri> uriList, @NonNull CapabilitiesCallback c) {
    public void requestCapabilities(@NonNull List<Uri> uriList,
            @NonNull IRcsUceControllerCallback c) throws RemoteException {
        if (uriList == null || c == null) {
            logw("requestCapabilities: parameter is empty");
            if (c != null) {
                c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE);
            }
            return;
        }

        if (isUnavailable()) {
            logw("requestCapabilities: controller is unavailable");
            c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE);
@@ -296,7 +378,7 @@ public class UceController {
        }

        // Trigger the capabilities request task
        logd("requestCapabilities");
        logd("requestCapabilities: " + uriList.size());
        mTaskManager.triggerCapabilityRequestTask(mCtrlCallback, uriList, c);
    }

@@ -305,7 +387,16 @@ public class UceController {
     * the capability in the availability cache is expired then it will retrieve the capability
     * from the carrier network.
     */
    public void requestAvailability(@NonNull Uri uri, @NonNull CapabilitiesCallback c) {
    public void requestAvailability(@NonNull Uri uri, @NonNull IRcsUceControllerCallback c)
            throws RemoteException{
        if (uri == null || c == null) {
            logw("requestCapabilities: parameter is empty");
            if (c != null) {
                c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE);
            }
            return;
        }

        if (isUnavailable()) {
            logw("requestAvailability: controller is unavailable");
            c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE);
@@ -320,9 +411,9 @@ public class UceController {
    /**
     * Publish the device's capabilities. This request is triggered from the ImsService.
     */
    public void onRequestPublishCapabilitiesFromService() {
        logd("onRequestPublishCapabilitiesFromService");
        mPublishController.requestPublishCapabilitiesFromService();
    public void onRequestPublishCapabilitiesFromService(@StackPublishTriggerType int triggerType) {
        logd("onRequestPublishCapabilitiesFromService: " + triggerType);
        mPublishController.requestPublishCapabilitiesFromService(triggerType);
    }

    /**
@@ -339,8 +430,7 @@ public class UceController {
     * capabilities to the remote side.
     */
    public void retrieveOptionsCapabilitiesForRemote(@NonNull Uri contactUri,
            @NonNull List<String> remoteCapabilities,
            @NonNull CapabilityExchangeListenerAdapter.OptionsRequestCallback c) {
            @NonNull List<String> remoteCapabilities, @NonNull IOptionsRequestCallback c) {
        logd("retrieveOptionsCapabilitiesForRemote");
        mOptionsController.retrieveCapabilitiesForRemote(contactUri, remoteCapabilities, c);
    }
@@ -366,11 +456,21 @@ public class UceController {
        return mPublishController.getUcePublishState();
    }

    @VisibleForTesting
    public void setRequestTaskManagerFactory(RequestTaskManagerFactory factory) {
        mTaskManagerFactory = factory;
    }

    @VisibleForTesting
    public void setControllerFactory(ControllerFactory factory) {
        mControllerFactory = factory;
    }

    public int getSubId() {
        return mSubId;
    }

    private boolean isUnavailable() {
    public boolean isUnavailable() {
        if (!mIsRcsConnected || mIsDestroyedFlag) {
            return true;
        }
+26 −7
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.ims.rcs.uce;

import android.content.Context;
import android.net.Uri;
import android.telephony.ims.RcsUceAdapter;
import android.os.Looper;
import android.telephony.ims.aidl.IRcsUceControllerCallback;

import com.android.ims.rcs.uce.UceController.UceControllerCallback;

@@ -26,20 +28,37 @@ import java.util.List;
/**
 * The interface of managing the capability request and the availability request.
 */
public interface UceRequestTaskManager {
public class UceRequestTaskManager {

    private final Context mContext;
    private final int mSubId;
    private final Looper mLooper;

    public UceRequestTaskManager(Context context, int subId, Looper looper) {
        mContext = context;
        mSubId = subId;
        mLooper = looper;
    }

    /**
     * Trigger the capability request task.
     */
    void triggerCapabilityRequestTask(UceControllerCallback controller, List<Uri> uriList,
            RcsUceAdapter.CapabilitiesCallback callback);
    public void triggerCapabilityRequestTask(UceControllerCallback controller, List<Uri> uriList,
            IRcsUceControllerCallback callback) {
        // TODO: Implement this method
    }
    /**
     * Trigger the availability request task.
     */
    void triggerAvailabilityRequestTask(UceControllerCallback controller, Uri uri,
            RcsUceAdapter.CapabilitiesCallback callback);
    public void triggerAvailabilityRequestTask(UceControllerCallback controller, Uri uri,
            IRcsUceControllerCallback callback) {
        // TODO: Implement this method
    }

    /**
     * Notify the task manager to destroy.
     */
    void onDestroy();
    public void onDestroy() {
        // TODO: Implement this method
    }
}
Loading