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

Commit fc8df043 authored by Hyunho Shin's avatar Hyunho Shin Committed by Android (Google) Code Review
Browse files

Merge "Add a new api that does not send PUBLISH request with duplicated presence capabilities"

parents 0c31ace7 08151870
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.util.Log;

import com.android.ims.rcs.uce.util.FeatureTags;
import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.util.Arrays;
@@ -104,6 +105,11 @@ public class DeviceCapabilityInfo {
    private boolean mMobileData;
    private boolean mVtSetting;

    // The service description associated with the last publication update.
    private Set<ServiceDescription> mLastSuccessfulCapabilities = new ArraySet<>();
    // The service description to temporarily store the presence capability being sent.
    private Set<ServiceDescription> mPendingPublishCapabilities;

    public DeviceCapabilityInfo(int subId, String[] capToRegistrationMap) {
        mSubId = subId;
        mServiceCapRegTracker = PublishServiceDescTracker.fromCarrierConfig(capToRegistrationMap);
@@ -126,6 +132,8 @@ public class DeviceCapabilityInfo {
        mMmTelCapabilities = new MmTelCapabilities();
        mMmtelAssociatedUris = Collections.EMPTY_LIST;
        mRcsAssociatedUris = Collections.EMPTY_LIST;
        mLastSuccessfulCapabilities.clear();
        mPendingPublishCapabilities = null;
    }

    /**
@@ -173,6 +181,8 @@ public class DeviceCapabilityInfo {
        if (mMmtelRegistered) {
            mMmtelRegistered = false;
        }
        mLastSuccessfulCapabilities.clear();
        mPendingPublishCapabilities = null;
        mMmtelNetworkRegType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
    }

@@ -242,6 +252,8 @@ public class DeviceCapabilityInfo {
            changed = true;
        }
        mRcsNetworkRegType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
        mLastSuccessfulCapabilities.clear();
        mPendingPublishCapabilities = null;
        return changed;
    }

@@ -430,6 +442,52 @@ public class DeviceCapabilityInfo {
        return mPresenceCapable;
    }

    // Get the device's capabilities with the PRESENCE mechanism.
    public RcsContactUceCapability getChangedPresenceCapability(Context context) {
        if (context == null) {
            return null;
        }
        Set<ServiceDescription> capableFromReg =
                mServiceCapRegTracker.copyRegistrationCapabilities();
        if (isPresenceCapabilityChanged(capableFromReg)) {
            RcsContactUceCapability rcsContactUceCapability = getPresenceCapabilities(context);
            if (rcsContactUceCapability != null) {
                mPendingPublishCapabilities = mServiceCapRegTracker.copyRegistrationCapabilities();
            }
            return rcsContactUceCapability;
        }
        return null;
    }

    public void setPresencePublishResult(boolean isSuccess) {
        if (isSuccess) {
            mLastSuccessfulCapabilities = mPendingPublishCapabilities;
        }
        mPendingPublishCapabilities = null;
    }

    public void resetPresenceCapability() {
        mLastSuccessfulCapabilities.clear();
        mPendingPublishCapabilities = null;
    }

    @VisibleForTesting
    public void addLastSuccessfulServiceDescription(ServiceDescription capability) {
        mLastSuccessfulCapabilities.add(capability);
    }

    @VisibleForTesting
    public boolean isPresenceCapabilityChanged(Set<ServiceDescription> capableFromReg) {
        if (mLastSuccessfulCapabilities.isEmpty()) {
            return true;
        }

        if (capableFromReg.equals(mLastSuccessfulCapabilities)) {
            return false;
        }
        return true;
    }

    private boolean isVolteAvailable(int networkRegType, MmTelCapabilities capabilities) {
        return (networkRegType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                && capabilities.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+18 −3
Original line number Diff line number Diff line
@@ -112,6 +112,8 @@ public class PublishProcessor {
        logi("onRcsDisconnected");
        mRcsFeatureManager = null;
        mProcessorState.onRcsDisconnected();
        // reset the publish capabilities.
        mDeviceCapabilities.resetPresenceCapability();
    }

    /**
@@ -152,10 +154,15 @@ public class PublishProcessor {
        }

        // Get the latest device's capabilities.
        RcsContactUceCapability deviceCapability =
                mDeviceCapabilities.getDeviceCapabilities(CAPABILITY_MECHANISM_PRESENCE, mContext);
        RcsContactUceCapability deviceCapability;
        if (triggerType == PublishController.PUBLISH_TRIGGER_SERVICE) {
            deviceCapability = mDeviceCapabilities.getDeviceCapabilities(
                    CAPABILITY_MECHANISM_PRESENCE, mContext);
        } else {
            deviceCapability = mDeviceCapabilities.getChangedPresenceCapability(mContext);
        }
        if (deviceCapability == null) {
            logw("doPublishInternal: device capability is null");
            logi("doPublishInternal: device capability hasn't changed or is null");
            return false;
        }

@@ -349,6 +356,8 @@ public class PublishProcessor {
        // Increase the retry count
        mProcessorState.increaseRetryCount();

        // reset the last capabilities because of the request is failed
        mDeviceCapabilities.setPresencePublishResult(false);
        // Reset the pending flag because it is going to resend a request.
        clearPendingRequest();

@@ -373,10 +382,14 @@ public class PublishProcessor {
        Instant responseTime = response.getResponseTimestamp();

        // Record the time when the request is successful and reset the retry count.
        boolean publishSuccess = false;
        if (response.isRequestSuccess()) {
            mProcessorState.setLastPublishedTime(responseTime);
            mProcessorState.resetRetryCount();
            publishSuccess = true;
        }
        // set the last capabilities according to the result of request.
        mDeviceCapabilities.setPresencePublishResult(publishSuccess);

        // Update the publish state after the request has finished.
        int publishState = response.getPublishState();
@@ -492,6 +505,8 @@ public class PublishProcessor {
     */
    public void resetState() {
        mProcessorState.resetState();
        // reset the publish capabilities.
        mDeviceCapabilities.resetPresenceCapability();
    }

    /**
+128 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.presence.publish;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.telephony.ims.RcsContactPresenceTuple;
import android.util.ArraySet;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.ims.ImsTestBase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;

import java.util.Collections;
import java.util.Set;

@RunWith(AndroidJUnit4.class)
public class DeviceCapabilityInfoTest extends ImsTestBase {

    int mSubId = 1;
    @Mock PublishServiceDescTracker mPublishServiceDescTracker;

    @Before
    public void setUp() throws Exception {
        super.setUp();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    @SmallTest
    public void testGetPresenceCapabilityForSameDescription() throws Exception {
        DeviceCapabilityInfo deviceCapInfo = createDeviceCapabilityInfo();

        Set<ServiceDescription> mTestCapability = new ArraySet<>();
        mTestCapability.add(getChatDescription());
        mTestCapability.add(getMmtelDescription());
        mTestCapability.add(getUndefinedDescription());

        deviceCapInfo.addLastSuccessfulServiceDescription(getMmtelDescription());
        deviceCapInfo.addLastSuccessfulServiceDescription(getChatDescription());
        deviceCapInfo.addLastSuccessfulServiceDescription(getUndefinedDescription());
        assertFalse(deviceCapInfo.isPresenceCapabilityChanged(mTestCapability));
    }

    @Test
    @SmallTest
    public void testGetPresenceCapabilityForSameSizeOfDescription() throws Exception {
        DeviceCapabilityInfo deviceCapInfo = createDeviceCapabilityInfo();

        Set<ServiceDescription> mTestCapability = new ArraySet<>();
        mTestCapability.add(getChatDescription());
        mTestCapability.add(getMmtelDescription());
        mTestCapability.add(getUndefinedDescription());

        deviceCapInfo.addLastSuccessfulServiceDescription(getMmtelDescription());
        deviceCapInfo.addLastSuccessfulServiceDescription(getChatDescription());
        deviceCapInfo.addLastSuccessfulServiceDescription(getUndefined2Description());

        assertTrue(deviceCapInfo.isPresenceCapabilityChanged(mTestCapability));
    }
    private DeviceCapabilityInfo createDeviceCapabilityInfo() {
        DeviceCapabilityInfo deviceCapInfo = new DeviceCapabilityInfo(mSubId, null);
        return deviceCapInfo;
    }

    private ServiceDescription getChatDescription() {
        ServiceDescription SERVICE_DESCRIPTION_CHAT_SESSION =
                new ServiceDescription(
                        RcsContactPresenceTuple.SERVICE_ID_CHAT_V2,
                        "2.0" /*version*/,
                        null /*description*/
                );
        return SERVICE_DESCRIPTION_CHAT_SESSION;
    }

    private ServiceDescription getMmtelDescription() {
        ServiceDescription SERVICE_DESCRIPTION_MMTEL_VOICE = new ServiceDescription(
                RcsContactPresenceTuple.SERVICE_ID_MMTEL,
                "1.0" /*version*/,
                "Voice Service" /*description*/
        );
        return SERVICE_DESCRIPTION_MMTEL_VOICE;
    }

    private ServiceDescription getUndefinedDescription() {
        ServiceDescription SERVICE_DESCRIPTION_TEST = new ServiceDescription(
                "test",
                "1.0" /*version*/,
                "Test_Service" /*description*/
        );
        return SERVICE_DESCRIPTION_TEST;
    }

    private ServiceDescription getUndefined2Description() {
        ServiceDescription SERVICE_DESCRIPTION_TEST2 = new ServiceDescription(
                "test1",
                "1.0" /*version*/,
                "Test_Service" /*description*/
        );
        return SERVICE_DESCRIPTION_TEST2;
    }
}
+8 −1
Original line number Diff line number Diff line
@@ -66,8 +66,8 @@ public class PublishProcessorTest extends ImsTestBase {

        doReturn(true).when(mDeviceCapabilities).isImsRegistered();
        RcsContactUceCapability capability = getRcsContactUceCapability();
        doReturn(capability).when(mDeviceCapabilities).getChangedPresenceCapability(any());
        doReturn(capability).when(mDeviceCapabilities).getDeviceCapabilities(anyInt(), any());

        doReturn(mTaskId).when(mResponseCallback).getTaskId();
    }

@@ -97,6 +97,7 @@ public class PublishProcessorTest extends ImsTestBase {

        publishProcessor.doPublish(PublishController.PUBLISH_TRIGGER_RETRY);

        verify(mDeviceCapabilities).getChangedPresenceCapability(any());
        verify(mProcessorState, never()).resetRetryCount();
    }

@@ -155,6 +156,7 @@ public class PublishProcessorTest extends ImsTestBase {

        publishProcessor.onCommandError(mResponseCallback);

        verify(mDeviceCapabilities).setPresencePublishResult(false);
        verify(mProcessorState).increaseRetryCount();
        verify(mPublishCtrlCallback).requestPublishFromInternal(
                eq(PublishController.PUBLISH_TRIGGER_RETRY));
@@ -172,10 +174,12 @@ public class PublishProcessorTest extends ImsTestBase {
        doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
        doReturn(mTaskId).when(mResponseCallback).getTaskId();
        doReturn(false).when(mResponseCallback).needRetry();
        doReturn(true).when(mResponseCallback).isRequestSuccess();
        PublishProcessor publishProcessor = getPublishProcessor();

        publishProcessor.onCommandError(mResponseCallback);

        verify(mDeviceCapabilities).setPresencePublishResult(true);
        verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any());
        verify(mResponseCallback).onDestroy();
        verify(mProcessorState).setPublishingFlag(false);
@@ -193,6 +197,7 @@ public class PublishProcessorTest extends ImsTestBase {

        publishProcessor.onNetworkResponse(mResponseCallback);

        verify(mDeviceCapabilities).setPresencePublishResult(false);
        verify(mProcessorState).increaseRetryCount();
        verify(mPublishCtrlCallback).requestPublishFromInternal(
                eq(PublishController.PUBLISH_TRIGGER_RETRY));
@@ -214,6 +219,7 @@ public class PublishProcessorTest extends ImsTestBase {

        publishProcessor.onNetworkResponse(mResponseCallback);

        verify(mDeviceCapabilities).setPresencePublishResult(true);
        verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any());
        verify(mResponseCallback).onDestroy();
        verify(mProcessorState).setPublishingFlag(false);
@@ -248,6 +254,7 @@ public class PublishProcessorTest extends ImsTestBase {

        publishProcessor.publishUpdated(mResponseCallback);

        verify(mDeviceCapabilities).setPresencePublishResult(true);
        verify(mProcessorState).setLastPublishedTime(any());
        verify(mProcessorState).resetRetryCount();
        verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any());