Loading src/java/com/android/internal/telephony/metrics/RcsStats.java +148 −31 Original line number Diff line number Diff line Loading @@ -305,16 +305,9 @@ public class RcsStats { private static final int SUBSCRIBE_SUCCESS = 1; private static final int SUBSCRIBE_NOTIFY = 2; private enum QosEstablishStatus {none, establishing, established}; private final List<ImsDedicatedBearerListenerEvent> mImsDedicatedBearerListenerEvent = new ArrayList<>(); private final Map<ImsDedicatedBearerListenerEvent, QosEstablishStatus> mQosEstablishedStatusMap = new HashMap<>(); @VisibleForTesting protected final Map<Integer, ImsDedicatedBearerListenerEvent> mDedicatedBearerListenerEventMap = new HashMap<>(); protected final Map<Integer, ImsDedicatedBearerListenerEvent> mDedicatedBearerListenerEventMap = new HashMap<>(); @VisibleForTesting protected final List<RcsAcsProvisioningStats> mRcsAcsProvisioningStatsList = new ArrayList<RcsAcsProvisioningStats>(); Loading @@ -327,7 +320,8 @@ public class RcsStats { new ArrayList<>(); // Maps service id -> ImsRegistrationServiceDescStats. private final List<ImsRegistrationServiceDescStats> mImsRegistrationServiceDescStatsList = @VisibleForTesting protected final List<ImsRegistrationServiceDescStats> mImsRegistrationServiceDescStatsList = new ArrayList<>(); private List<LastSipDelegateStat> mLastSipDelegateStatList = new ArrayList<>(); Loading Loading @@ -739,8 +733,12 @@ public class RcsStats { private synchronized void addSipMessageStat( @NonNull int subId, @NonNull String sipMessageMethod, int sipMessageResponse, int sipMessageDirection, int messageError) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } SipMessageResponse proto = new SipMessageResponse(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.sipMessageMethod = convertMessageTypeToValue(sipMessageMethod); proto.sipMessageResponse = sipMessageResponse; Loading @@ -767,8 +765,12 @@ public class RcsStats { private synchronized void addSipTransportSessionStat( @NonNull int subId, @NonNull String sessionMethod, int sipMessageDirection, int sipResponse, boolean isEndedGracefully) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } SipTransportSession proto = new SipTransportSession(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.sessionMethod = convertMessageTypeToValue(sessionMethod); proto.sipMessageDirection = sipMessageDirection; Loading Loading @@ -809,6 +811,12 @@ public class RcsStats { public void onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList, int registrationTech) { synchronized (mImsRegistrationFeatureTagStatsList) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { flushImsRegistrationFeatureTagStatsInvalid(); return; } // update cached atom if exists onStoreCompleteImsRegistrationFeatureTagStats(subId); Loading @@ -819,7 +827,7 @@ public class RcsStats { for (String featureTag : featureTagList) { ImsRegistrationFeatureTagStats proto = new ImsRegistrationFeatureTagStats(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.featureTagName = convertTagNameToValue(featureTag); proto.registrationTech = registrationTech; Loading Loading @@ -865,8 +873,14 @@ public class RcsStats { /** Create a new atom when RCS client stat changed. */ public synchronized void onRcsClientProvisioningStats(int subId, int event) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } RcsClientProvisioningStats proto = new RcsClientProvisioningStats(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.event = event; proto.count = 1; Loading @@ -878,12 +892,18 @@ public class RcsStats { boolean enableSingleRegistration) { synchronized (mRcsAcsProvisioningStatsList) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { flushRcsAcsProvisioningStatsInvalid(); return; } // update cached atom if exists onStoreCompleteRcsAcsProvisioningStats(subId); // create new stats to cache RcsAcsProvisioningStats newStats = new RcsAcsProvisioningStats(); newStats.carrierId = getCarrierId(subId); newStats.carrierId = carrierId; newStats.slotId = getSlotId(subId); newStats.responseCode = responseCode; newStats.responseType = responseType; Loading Loading @@ -1054,16 +1074,20 @@ public class RcsStats { public synchronized void onImsDedicatedBearerListenerAdded(@NonNull final int listenerId, @NonNull final int slotId, @NonNull final int ratAtEnd, @NonNull final int qci) { int subId = getSubId(slotId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { int carrierId = getCarrierId(subId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || !isValidCarrierId(carrierId)) { return; } if (mDedicatedBearerListenerEventMap.containsKey(listenerId)) { return; } ImsDedicatedBearerListenerEvent preProto = new ImsDedicatedBearerListenerEvent(); preProto.carrierId = getCarrierId(subId); preProto.slotId = getSlotId(subId); preProto.carrierId = carrierId; preProto.slotId = slotId; preProto.ratAtEnd = ratAtEnd; preProto.qci = qci; preProto.dedicatedBearerEstablished = false; Loading @@ -1078,7 +1102,10 @@ public class RcsStats { final int slotId, final int rat, final int qci, @NonNull final boolean dedicatedBearerEstablished) { int subId = getSubId(slotId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { int carrierId = getCarrierId(subId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || !isValidCarrierId(carrierId)) { return; } Loading @@ -1093,8 +1120,8 @@ public class RcsStats { mDedicatedBearerListenerEventMap.replace(listenerId, preProto); } else { ImsDedicatedBearerListenerEvent preProto = new ImsDedicatedBearerListenerEvent(); preProto.carrierId = getCarrierId(subId); preProto.slotId = getSlotId(subId); preProto.carrierId = carrierId; preProto.slotId = slotId; preProto.ratAtEnd = rat; preProto.qci = qci; preProto.dedicatedBearerEstablished = dedicatedBearerEstablished; Loading Loading @@ -1146,6 +1173,11 @@ public class RcsStats { public void onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList, List<String> serviceIdVersionList, int registrationTech) { synchronized (mImsRegistrationServiceDescStatsList) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { handleImsRegistrationServiceDescStats(); return; } // update cached atom if exists onStoreCompleteImsRegistrationServiceDescStats(subId); Loading @@ -1153,15 +1185,14 @@ public class RcsStats { Rlog.d(TAG, "serviceIds is null or empty"); return; } int carrierid = getCarrierId(subId); int slotid = getSlotId(subId); int index = 0; for (String serviceId : serviceIdList) { ImsRegistrationServiceDescStats mImsRegistrationServiceDescStats = new ImsRegistrationServiceDescStats(); mImsRegistrationServiceDescStats.carrierId = carrierid; mImsRegistrationServiceDescStats.slotId = slotid; mImsRegistrationServiceDescStats.carrierId = carrierId; mImsRegistrationServiceDescStats.slotId = getSlotId(subId); mImsRegistrationServiceDescStats.serviceIdName = convertServiceIdToValue(serviceId); mImsRegistrationServiceDescStats.serviceIdVersion = Float.parseFloat(serviceIdVersionList.get(index++)); Loading Loading @@ -1192,7 +1223,12 @@ public class RcsStats { int commandCode, int networkResponse) { UceEventStats proto = new UceEventStats(); proto.carrierId = getCarrierId(subId); int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { handleImsRegistrationServiceDescStats(); return; } proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.type = type; proto.successful = successful; Loading Loading @@ -1221,7 +1257,13 @@ public class RcsStats { boolean contentBodyReceived, boolean rcsCaps, boolean mmtelCaps, boolean noCaps) { PresenceNotifyEvent proto = new PresenceNotifyEvent(); proto.carrierId = getCarrierId(subId); int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { handleImsRegistrationServiceDescStats(); return; } proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.reason = convertPresenceNotifyReason(reason); proto.contentBodyReceived = contentBodyReceived; Loading Loading @@ -1252,8 +1294,13 @@ public class RcsStats { /** Create a new atom when GBA Success Event changed. */ public synchronized void onGbaSuccessEvent(int subId) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } GbaEvent proto = new GbaEvent(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.successful = true; proto.failedReason = -1; Loading @@ -1263,8 +1310,13 @@ public class RcsStats { /** Create a new atom when GBA Failure Event changed. */ public synchronized void onGbaFailureEvent(int subId, int reason) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } GbaEvent proto = new GbaEvent(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.successful = false; proto.failedReason = reason; Loading Loading @@ -1363,6 +1415,26 @@ public class RcsStats { } } private void handleImsRegistrationServiceDescStats() { synchronized (mImsRegistrationServiceDescStatsList) { List<ImsRegistrationServiceDescStats> deleteList = new ArrayList<>(); for (ImsRegistrationServiceDescStats proto : mImsRegistrationServiceDescStatsList) { int subId = getSubId(proto.slotId); int newCarrierId = getCarrierId(subId); if (proto.carrierId != newCarrierId) { deleteList.add(proto); if (proto.publishedMillis != 0) { proto.publishedMillis = getWallTimeMillis() - proto.publishedMillis; mAtomsStorage.addImsRegistrationServiceDescStats(proto); } } } for (ImsRegistrationServiceDescStats stats : deleteList) { mImsRegistrationServiceDescStatsList.remove(stats); } } } private RcsAcsProvisioningStats getRcsAcsProvisioningStats(int subId) { int carrierId = getCarrierId(subId); int slotId = getSlotId(subId); Loading @@ -1378,6 +1450,51 @@ public class RcsStats { return null; } private void flushRcsAcsProvisioningStatsInvalid() { List<RcsAcsProvisioningStats> inValidList = new ArrayList<RcsAcsProvisioningStats>(); int subId; int newCarrierId; for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) { subId = getSubId(stats.slotId); newCarrierId = getCarrierId(subId); if (stats.carrierId != newCarrierId) { inValidList.add(stats); } } for (RcsAcsProvisioningStats inValid : inValidList) { inValid.stateTimerMillis = getWallTimeMillis() - inValid.stateTimerMillis; mAtomsStorage.addRcsAcsProvisioningStats(inValid); mRcsAcsProvisioningStatsList.remove(inValid); } inValidList.clear(); } private void flushImsRegistrationFeatureTagStatsInvalid() { List<ImsRegistrationFeatureTagStats> inValidList = new ArrayList<ImsRegistrationFeatureTagStats>(); int subId; int newCarrierId; for (ImsRegistrationFeatureTagStats stats : mImsRegistrationFeatureTagStatsList) { subId = getSubId(stats.slotId); newCarrierId = getCarrierId(subId); if (stats.carrierId != newCarrierId) { inValidList.add(stats); } } for (ImsRegistrationFeatureTagStats inValid : inValidList) { inValid.registeredMillis = getWallTimeMillis() - inValid.registeredMillis; mAtomsStorage.addImsRegistrationFeatureTagStats(inValid); mImsRegistrationFeatureTagStatsList.remove(inValid); } inValidList.clear(); } private LastSipDelegateStat getLastSipDelegateStat(int subId, Set<String> supportedTags) { LastSipDelegateStat stat = null; for (LastSipDelegateStat lastStat : mLastSipDelegateStatList) { Loading Loading @@ -1419,8 +1536,8 @@ public class RcsStats { } return sipTransportFeatureTags; } private boolean isValidCarrierId(int carrierId) { @VisibleForTesting protected boolean isValidCarrierId(int carrierId) { return carrierId > TelephonyManager.UNKNOWN_CARRIER_ID; } Loading tests/telephonytests/src/com/android/internal/telephony/metrics/RcsStatsTest.java +154 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package com.android.internal.telephony.metrics; import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading Loading @@ -64,6 +67,7 @@ public class RcsStatsTest extends TelephonyTest { private static final long START_TIME_MILLIS = 2000L; private static final int SLOT_ID = 0; private static final int SLOT2_ID = 1; private static final int INVALID_SLOT_ID = -1; private static final int CARRIER_ID = 100; private static final int CARRIER2_ID = 200; private static final int INVALID_CARRIER_ID = -1; Loading Loading @@ -92,6 +96,7 @@ public class RcsStatsTest extends TelephonyTest { private class TestableRcsStats extends RcsStats { private long mTimeMillis = START_TIME_MILLIS; private boolean mEnabledInvalidSubId = false; TestableRcsStats() { super(); Loading @@ -99,21 +104,38 @@ public class RcsStatsTest extends TelephonyTest { @Override protected int getSlotId(int subId) { if (mEnabledInvalidSubId) { return INVALID_SLOT_ID; } if (subId == mSubId) { return SLOT_ID; } else if (subId == mSubId2) { return SLOT2_ID; } return SLOT2_ID; } @Override protected int getCarrierId(int subId) { if (subId == INVALID_SUB_ID) { if (mEnabledInvalidSubId) { return INVALID_CARRIER_ID; } else if (subId == mSubId) { } if (subId == mSubId) { return CARRIER_ID; } else { } else if (subId == mSubId2) { return CARRIER2_ID; } return INVALID_CARRIER_ID; } @Override protected boolean isValidCarrierId(int carrierId) { if (carrierId == INVALID_CARRIER_ID) { return false; } return true; } @Override Loading @@ -131,12 +153,21 @@ public class RcsStatsTest extends TelephonyTest { @Override protected int getSubId(int slotId) { if (mEnabledInvalidSubId) { return INVALID_SUB_ID; } if (slotId == SLOT_ID) { return mSubId; } } else if (slotId == SLOT2_ID) { return mSubId2; } return INVALID_SUB_ID; } public void setEnableInvalidSubId() { mEnabledInvalidSubId = true; } private void setTimeMillis(long timeMillis) { mTimeMillis = timeMillis; } Loading @@ -150,6 +181,10 @@ public class RcsStatsTest extends TelephonyTest { return mRcsAcsProvisioningStatsList.size(); } public int getImsRegistrationServiceDescCachedSize() { return mImsRegistrationServiceDescStatsList.size(); } public long getRcsAcsProvisioningCachedTime(int carreirId, int slotId) { for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) { if (stats.carrierId == carreirId && stats.slotId == slotId) { Loading Loading @@ -285,6 +320,50 @@ public class RcsStatsTest extends TelephonyTest { assertEquals(responseType[0], stats.responseType); assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); assertEquals(timeGap, stats.stateTimerMillis); // the last atoms will be cached assertEquals(1, mRcsStats.getRcsAcsProvisioningCachedSize()); verifyNoMoreInteractions(mPersistAtomsStorage); } @Test @SmallTest public void onRcsAcsProvisioningStats_withAtomsInvalidSubId() throws Exception { boolean isSingleRegistrationEnabled = true; int[] responseCode = {200, 401}; int[] responseType = { TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML, TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR}; int[] slotIds = {SLOT_ID, SLOT_ID}; int[] carrierIds = {CARRIER_ID, CARRIER_ID}; // this will be cached mRcsStats.onRcsAcsProvisioningStats( mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled); long timeGap = 6000L; mRcsStats.incTimeMillis(timeGap); // slotId and carrierId are invalid based on subId mRcsStats.setEnableInvalidSubId(); // this will not be cached, previous will be stored mRcsStats.onRcsAcsProvisioningStats( mSubId, responseCode[1], responseType[1], isSingleRegistrationEnabled); ArgumentCaptor<RcsAcsProvisioningStats> captor = ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture()); RcsAcsProvisioningStats stats = captor.getValue(); assertEquals(carrierIds[0], stats.carrierId); assertEquals(slotIds[0], stats.slotId); assertEquals(responseCode[0], stats.responseCode); assertEquals(responseType[0], stats.responseType); assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); assertEquals(timeGap, stats.stateTimerMillis); // the last atoms will not be cached assertEquals(0, mRcsStats.getRcsAcsProvisioningCachedSize()); verifyNoMoreInteractions(mPersistAtomsStorage); } Loading Loading @@ -1027,6 +1106,76 @@ public class RcsStatsTest extends TelephonyTest { verifyNoMoreInteractions(mPersistAtomsStorage); } @Test @SmallTest public void onImsRegistrationServiceDescStats_withAtomsInvalidSubId() throws Exception { int registrationTech = 0; //ImsRegistrationImplBase.REGISTRATION_TECH_LTE ArrayList<String> serviceIdList = new ArrayList<>(); serviceIdList.add("org.openmobilealliance:File-Transfer-HTTP"); serviceIdList.add("org.openmobilealliance:IM-session"); serviceIdList.add("Unknown1"); ArrayList<String> serviceIdVersionList = new ArrayList<>(); serviceIdVersionList.add("1.0"); serviceIdVersionList.add("1.0"); serviceIdVersionList.add("3.0"); mRcsStats.onImsRegistrationServiceDescStats(mSubId, serviceIdList, serviceIdVersionList, registrationTech); // getWallTimeMillis /* * UCE_EVENT__TYPE__PUBLISH = 0; * UCE_EVENT__TYPE__SUBSCRIBE = 1; * UCE_EVENT__TYPE__INCOMING_OPTION = 2; * UCE_EVENT__TYPE__OUTGOING_OPTION = 3; */ int type = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH; boolean successful = true; /* * UCE_EVENT__COMMAND_CODE__SERVICE_UNKNOWN = 0; * UCE_EVENT__COMMAND_CODE__GENERIC_FAILURE = 1; * UCE_EVENT__COMMAND_CODE__INVALID_PARAM = 2; * UCE_EVENT__COMMAND_CODE__FETCH_ERROR = 3; * UCE_EVENT__COMMAND_CODE__REQUEST_TIMEOUT = 4; * UCE_EVENT__COMMAND_CODE__INSUFFICIENT_MEMORY = 5; * UCE_EVENT__COMMAND_CODE__LOST_NETWORK_CONNECTION = 6; * UCE_EVENT__COMMAND_CODE__NOT_SUPPORTED = 7; * UCE_EVENT__COMMAND_CODE__NOT_FOUND = 8; * UCE_EVENT__COMMAND_CODE__SERVICE_UNAVAILABLE = 9; * UCE_EVENT__COMMAND_CODE__NO_CHANGE = 10; */ int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__SERVICE_UNAVAILABLE; int networkResponse = 200; mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); // slotId and carrierId are invalid based on subId mRcsStats.setEnableInvalidSubId(); long timeGap = 6000L; mRcsStats.incTimeMillis(timeGap); mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); ArgumentCaptor<ImsRegistrationServiceDescStats> captor = ArgumentCaptor.forClass(ImsRegistrationServiceDescStats.class); verify(mPersistAtomsStorage, times(3)) .addImsRegistrationServiceDescStats(captor.capture()); List<ImsRegistrationServiceDescStats> captorValues = captor.getAllValues(); assertEquals(captorValues.size(), serviceIdList.size()); for (int index = 0; index < captorValues.size(); index++) { ImsRegistrationServiceDescStats stats = captorValues.get(index); assertEquals(CARRIER_ID, stats.carrierId); assertEquals(SLOT_ID, stats.slotId); int serviceId = mRcsStats.convertServiceIdToValue(serviceIdList.get(index)); assertEquals(serviceId, stats.serviceIdName); float serviceVersionFloat = Float.parseFloat(serviceIdVersionList.get(index)); assertEquals(serviceVersionFloat, stats.serviceIdVersion, 0.1f); assertEquals(registrationTech, stats.registrationTech); assertEquals(timeGap, stats.publishedMillis); } assertEquals(0, mRcsStats.getImsRegistrationServiceDescCachedSize()); } @Test @SmallTest public void onUceEventStats_withAtoms() throws Exception { Loading Loading
src/java/com/android/internal/telephony/metrics/RcsStats.java +148 −31 Original line number Diff line number Diff line Loading @@ -305,16 +305,9 @@ public class RcsStats { private static final int SUBSCRIBE_SUCCESS = 1; private static final int SUBSCRIBE_NOTIFY = 2; private enum QosEstablishStatus {none, establishing, established}; private final List<ImsDedicatedBearerListenerEvent> mImsDedicatedBearerListenerEvent = new ArrayList<>(); private final Map<ImsDedicatedBearerListenerEvent, QosEstablishStatus> mQosEstablishedStatusMap = new HashMap<>(); @VisibleForTesting protected final Map<Integer, ImsDedicatedBearerListenerEvent> mDedicatedBearerListenerEventMap = new HashMap<>(); protected final Map<Integer, ImsDedicatedBearerListenerEvent> mDedicatedBearerListenerEventMap = new HashMap<>(); @VisibleForTesting protected final List<RcsAcsProvisioningStats> mRcsAcsProvisioningStatsList = new ArrayList<RcsAcsProvisioningStats>(); Loading @@ -327,7 +320,8 @@ public class RcsStats { new ArrayList<>(); // Maps service id -> ImsRegistrationServiceDescStats. private final List<ImsRegistrationServiceDescStats> mImsRegistrationServiceDescStatsList = @VisibleForTesting protected final List<ImsRegistrationServiceDescStats> mImsRegistrationServiceDescStatsList = new ArrayList<>(); private List<LastSipDelegateStat> mLastSipDelegateStatList = new ArrayList<>(); Loading Loading @@ -739,8 +733,12 @@ public class RcsStats { private synchronized void addSipMessageStat( @NonNull int subId, @NonNull String sipMessageMethod, int sipMessageResponse, int sipMessageDirection, int messageError) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } SipMessageResponse proto = new SipMessageResponse(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.sipMessageMethod = convertMessageTypeToValue(sipMessageMethod); proto.sipMessageResponse = sipMessageResponse; Loading @@ -767,8 +765,12 @@ public class RcsStats { private synchronized void addSipTransportSessionStat( @NonNull int subId, @NonNull String sessionMethod, int sipMessageDirection, int sipResponse, boolean isEndedGracefully) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } SipTransportSession proto = new SipTransportSession(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.sessionMethod = convertMessageTypeToValue(sessionMethod); proto.sipMessageDirection = sipMessageDirection; Loading Loading @@ -809,6 +811,12 @@ public class RcsStats { public void onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList, int registrationTech) { synchronized (mImsRegistrationFeatureTagStatsList) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { flushImsRegistrationFeatureTagStatsInvalid(); return; } // update cached atom if exists onStoreCompleteImsRegistrationFeatureTagStats(subId); Loading @@ -819,7 +827,7 @@ public class RcsStats { for (String featureTag : featureTagList) { ImsRegistrationFeatureTagStats proto = new ImsRegistrationFeatureTagStats(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.featureTagName = convertTagNameToValue(featureTag); proto.registrationTech = registrationTech; Loading Loading @@ -865,8 +873,14 @@ public class RcsStats { /** Create a new atom when RCS client stat changed. */ public synchronized void onRcsClientProvisioningStats(int subId, int event) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } RcsClientProvisioningStats proto = new RcsClientProvisioningStats(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.event = event; proto.count = 1; Loading @@ -878,12 +892,18 @@ public class RcsStats { boolean enableSingleRegistration) { synchronized (mRcsAcsProvisioningStatsList) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { flushRcsAcsProvisioningStatsInvalid(); return; } // update cached atom if exists onStoreCompleteRcsAcsProvisioningStats(subId); // create new stats to cache RcsAcsProvisioningStats newStats = new RcsAcsProvisioningStats(); newStats.carrierId = getCarrierId(subId); newStats.carrierId = carrierId; newStats.slotId = getSlotId(subId); newStats.responseCode = responseCode; newStats.responseType = responseType; Loading Loading @@ -1054,16 +1074,20 @@ public class RcsStats { public synchronized void onImsDedicatedBearerListenerAdded(@NonNull final int listenerId, @NonNull final int slotId, @NonNull final int ratAtEnd, @NonNull final int qci) { int subId = getSubId(slotId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { int carrierId = getCarrierId(subId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || !isValidCarrierId(carrierId)) { return; } if (mDedicatedBearerListenerEventMap.containsKey(listenerId)) { return; } ImsDedicatedBearerListenerEvent preProto = new ImsDedicatedBearerListenerEvent(); preProto.carrierId = getCarrierId(subId); preProto.slotId = getSlotId(subId); preProto.carrierId = carrierId; preProto.slotId = slotId; preProto.ratAtEnd = ratAtEnd; preProto.qci = qci; preProto.dedicatedBearerEstablished = false; Loading @@ -1078,7 +1102,10 @@ public class RcsStats { final int slotId, final int rat, final int qci, @NonNull final boolean dedicatedBearerEstablished) { int subId = getSubId(slotId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { int carrierId = getCarrierId(subId); if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || !isValidCarrierId(carrierId)) { return; } Loading @@ -1093,8 +1120,8 @@ public class RcsStats { mDedicatedBearerListenerEventMap.replace(listenerId, preProto); } else { ImsDedicatedBearerListenerEvent preProto = new ImsDedicatedBearerListenerEvent(); preProto.carrierId = getCarrierId(subId); preProto.slotId = getSlotId(subId); preProto.carrierId = carrierId; preProto.slotId = slotId; preProto.ratAtEnd = rat; preProto.qci = qci; preProto.dedicatedBearerEstablished = dedicatedBearerEstablished; Loading Loading @@ -1146,6 +1173,11 @@ public class RcsStats { public void onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList, List<String> serviceIdVersionList, int registrationTech) { synchronized (mImsRegistrationServiceDescStatsList) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { handleImsRegistrationServiceDescStats(); return; } // update cached atom if exists onStoreCompleteImsRegistrationServiceDescStats(subId); Loading @@ -1153,15 +1185,14 @@ public class RcsStats { Rlog.d(TAG, "serviceIds is null or empty"); return; } int carrierid = getCarrierId(subId); int slotid = getSlotId(subId); int index = 0; for (String serviceId : serviceIdList) { ImsRegistrationServiceDescStats mImsRegistrationServiceDescStats = new ImsRegistrationServiceDescStats(); mImsRegistrationServiceDescStats.carrierId = carrierid; mImsRegistrationServiceDescStats.slotId = slotid; mImsRegistrationServiceDescStats.carrierId = carrierId; mImsRegistrationServiceDescStats.slotId = getSlotId(subId); mImsRegistrationServiceDescStats.serviceIdName = convertServiceIdToValue(serviceId); mImsRegistrationServiceDescStats.serviceIdVersion = Float.parseFloat(serviceIdVersionList.get(index++)); Loading Loading @@ -1192,7 +1223,12 @@ public class RcsStats { int commandCode, int networkResponse) { UceEventStats proto = new UceEventStats(); proto.carrierId = getCarrierId(subId); int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { handleImsRegistrationServiceDescStats(); return; } proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.type = type; proto.successful = successful; Loading Loading @@ -1221,7 +1257,13 @@ public class RcsStats { boolean contentBodyReceived, boolean rcsCaps, boolean mmtelCaps, boolean noCaps) { PresenceNotifyEvent proto = new PresenceNotifyEvent(); proto.carrierId = getCarrierId(subId); int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { handleImsRegistrationServiceDescStats(); return; } proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.reason = convertPresenceNotifyReason(reason); proto.contentBodyReceived = contentBodyReceived; Loading Loading @@ -1252,8 +1294,13 @@ public class RcsStats { /** Create a new atom when GBA Success Event changed. */ public synchronized void onGbaSuccessEvent(int subId) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } GbaEvent proto = new GbaEvent(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.successful = true; proto.failedReason = -1; Loading @@ -1263,8 +1310,13 @@ public class RcsStats { /** Create a new atom when GBA Failure Event changed. */ public synchronized void onGbaFailureEvent(int subId, int reason) { int carrierId = getCarrierId(subId); if (!isValidCarrierId(carrierId)) { return; } GbaEvent proto = new GbaEvent(); proto.carrierId = getCarrierId(subId); proto.carrierId = carrierId; proto.slotId = getSlotId(subId); proto.successful = false; proto.failedReason = reason; Loading Loading @@ -1363,6 +1415,26 @@ public class RcsStats { } } private void handleImsRegistrationServiceDescStats() { synchronized (mImsRegistrationServiceDescStatsList) { List<ImsRegistrationServiceDescStats> deleteList = new ArrayList<>(); for (ImsRegistrationServiceDescStats proto : mImsRegistrationServiceDescStatsList) { int subId = getSubId(proto.slotId); int newCarrierId = getCarrierId(subId); if (proto.carrierId != newCarrierId) { deleteList.add(proto); if (proto.publishedMillis != 0) { proto.publishedMillis = getWallTimeMillis() - proto.publishedMillis; mAtomsStorage.addImsRegistrationServiceDescStats(proto); } } } for (ImsRegistrationServiceDescStats stats : deleteList) { mImsRegistrationServiceDescStatsList.remove(stats); } } } private RcsAcsProvisioningStats getRcsAcsProvisioningStats(int subId) { int carrierId = getCarrierId(subId); int slotId = getSlotId(subId); Loading @@ -1378,6 +1450,51 @@ public class RcsStats { return null; } private void flushRcsAcsProvisioningStatsInvalid() { List<RcsAcsProvisioningStats> inValidList = new ArrayList<RcsAcsProvisioningStats>(); int subId; int newCarrierId; for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) { subId = getSubId(stats.slotId); newCarrierId = getCarrierId(subId); if (stats.carrierId != newCarrierId) { inValidList.add(stats); } } for (RcsAcsProvisioningStats inValid : inValidList) { inValid.stateTimerMillis = getWallTimeMillis() - inValid.stateTimerMillis; mAtomsStorage.addRcsAcsProvisioningStats(inValid); mRcsAcsProvisioningStatsList.remove(inValid); } inValidList.clear(); } private void flushImsRegistrationFeatureTagStatsInvalid() { List<ImsRegistrationFeatureTagStats> inValidList = new ArrayList<ImsRegistrationFeatureTagStats>(); int subId; int newCarrierId; for (ImsRegistrationFeatureTagStats stats : mImsRegistrationFeatureTagStatsList) { subId = getSubId(stats.slotId); newCarrierId = getCarrierId(subId); if (stats.carrierId != newCarrierId) { inValidList.add(stats); } } for (ImsRegistrationFeatureTagStats inValid : inValidList) { inValid.registeredMillis = getWallTimeMillis() - inValid.registeredMillis; mAtomsStorage.addImsRegistrationFeatureTagStats(inValid); mImsRegistrationFeatureTagStatsList.remove(inValid); } inValidList.clear(); } private LastSipDelegateStat getLastSipDelegateStat(int subId, Set<String> supportedTags) { LastSipDelegateStat stat = null; for (LastSipDelegateStat lastStat : mLastSipDelegateStatList) { Loading Loading @@ -1419,8 +1536,8 @@ public class RcsStats { } return sipTransportFeatureTags; } private boolean isValidCarrierId(int carrierId) { @VisibleForTesting protected boolean isValidCarrierId(int carrierId) { return carrierId > TelephonyManager.UNKNOWN_CARRIER_ID; } Loading
tests/telephonytests/src/com/android/internal/telephony/metrics/RcsStatsTest.java +154 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package com.android.internal.telephony.metrics; import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading Loading @@ -64,6 +67,7 @@ public class RcsStatsTest extends TelephonyTest { private static final long START_TIME_MILLIS = 2000L; private static final int SLOT_ID = 0; private static final int SLOT2_ID = 1; private static final int INVALID_SLOT_ID = -1; private static final int CARRIER_ID = 100; private static final int CARRIER2_ID = 200; private static final int INVALID_CARRIER_ID = -1; Loading Loading @@ -92,6 +96,7 @@ public class RcsStatsTest extends TelephonyTest { private class TestableRcsStats extends RcsStats { private long mTimeMillis = START_TIME_MILLIS; private boolean mEnabledInvalidSubId = false; TestableRcsStats() { super(); Loading @@ -99,21 +104,38 @@ public class RcsStatsTest extends TelephonyTest { @Override protected int getSlotId(int subId) { if (mEnabledInvalidSubId) { return INVALID_SLOT_ID; } if (subId == mSubId) { return SLOT_ID; } else if (subId == mSubId2) { return SLOT2_ID; } return SLOT2_ID; } @Override protected int getCarrierId(int subId) { if (subId == INVALID_SUB_ID) { if (mEnabledInvalidSubId) { return INVALID_CARRIER_ID; } else if (subId == mSubId) { } if (subId == mSubId) { return CARRIER_ID; } else { } else if (subId == mSubId2) { return CARRIER2_ID; } return INVALID_CARRIER_ID; } @Override protected boolean isValidCarrierId(int carrierId) { if (carrierId == INVALID_CARRIER_ID) { return false; } return true; } @Override Loading @@ -131,12 +153,21 @@ public class RcsStatsTest extends TelephonyTest { @Override protected int getSubId(int slotId) { if (mEnabledInvalidSubId) { return INVALID_SUB_ID; } if (slotId == SLOT_ID) { return mSubId; } } else if (slotId == SLOT2_ID) { return mSubId2; } return INVALID_SUB_ID; } public void setEnableInvalidSubId() { mEnabledInvalidSubId = true; } private void setTimeMillis(long timeMillis) { mTimeMillis = timeMillis; } Loading @@ -150,6 +181,10 @@ public class RcsStatsTest extends TelephonyTest { return mRcsAcsProvisioningStatsList.size(); } public int getImsRegistrationServiceDescCachedSize() { return mImsRegistrationServiceDescStatsList.size(); } public long getRcsAcsProvisioningCachedTime(int carreirId, int slotId) { for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) { if (stats.carrierId == carreirId && stats.slotId == slotId) { Loading Loading @@ -285,6 +320,50 @@ public class RcsStatsTest extends TelephonyTest { assertEquals(responseType[0], stats.responseType); assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); assertEquals(timeGap, stats.stateTimerMillis); // the last atoms will be cached assertEquals(1, mRcsStats.getRcsAcsProvisioningCachedSize()); verifyNoMoreInteractions(mPersistAtomsStorage); } @Test @SmallTest public void onRcsAcsProvisioningStats_withAtomsInvalidSubId() throws Exception { boolean isSingleRegistrationEnabled = true; int[] responseCode = {200, 401}; int[] responseType = { TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML, TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR}; int[] slotIds = {SLOT_ID, SLOT_ID}; int[] carrierIds = {CARRIER_ID, CARRIER_ID}; // this will be cached mRcsStats.onRcsAcsProvisioningStats( mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled); long timeGap = 6000L; mRcsStats.incTimeMillis(timeGap); // slotId and carrierId are invalid based on subId mRcsStats.setEnableInvalidSubId(); // this will not be cached, previous will be stored mRcsStats.onRcsAcsProvisioningStats( mSubId, responseCode[1], responseType[1], isSingleRegistrationEnabled); ArgumentCaptor<RcsAcsProvisioningStats> captor = ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture()); RcsAcsProvisioningStats stats = captor.getValue(); assertEquals(carrierIds[0], stats.carrierId); assertEquals(slotIds[0], stats.slotId); assertEquals(responseCode[0], stats.responseCode); assertEquals(responseType[0], stats.responseType); assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); assertEquals(timeGap, stats.stateTimerMillis); // the last atoms will not be cached assertEquals(0, mRcsStats.getRcsAcsProvisioningCachedSize()); verifyNoMoreInteractions(mPersistAtomsStorage); } Loading Loading @@ -1027,6 +1106,76 @@ public class RcsStatsTest extends TelephonyTest { verifyNoMoreInteractions(mPersistAtomsStorage); } @Test @SmallTest public void onImsRegistrationServiceDescStats_withAtomsInvalidSubId() throws Exception { int registrationTech = 0; //ImsRegistrationImplBase.REGISTRATION_TECH_LTE ArrayList<String> serviceIdList = new ArrayList<>(); serviceIdList.add("org.openmobilealliance:File-Transfer-HTTP"); serviceIdList.add("org.openmobilealliance:IM-session"); serviceIdList.add("Unknown1"); ArrayList<String> serviceIdVersionList = new ArrayList<>(); serviceIdVersionList.add("1.0"); serviceIdVersionList.add("1.0"); serviceIdVersionList.add("3.0"); mRcsStats.onImsRegistrationServiceDescStats(mSubId, serviceIdList, serviceIdVersionList, registrationTech); // getWallTimeMillis /* * UCE_EVENT__TYPE__PUBLISH = 0; * UCE_EVENT__TYPE__SUBSCRIBE = 1; * UCE_EVENT__TYPE__INCOMING_OPTION = 2; * UCE_EVENT__TYPE__OUTGOING_OPTION = 3; */ int type = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH; boolean successful = true; /* * UCE_EVENT__COMMAND_CODE__SERVICE_UNKNOWN = 0; * UCE_EVENT__COMMAND_CODE__GENERIC_FAILURE = 1; * UCE_EVENT__COMMAND_CODE__INVALID_PARAM = 2; * UCE_EVENT__COMMAND_CODE__FETCH_ERROR = 3; * UCE_EVENT__COMMAND_CODE__REQUEST_TIMEOUT = 4; * UCE_EVENT__COMMAND_CODE__INSUFFICIENT_MEMORY = 5; * UCE_EVENT__COMMAND_CODE__LOST_NETWORK_CONNECTION = 6; * UCE_EVENT__COMMAND_CODE__NOT_SUPPORTED = 7; * UCE_EVENT__COMMAND_CODE__NOT_FOUND = 8; * UCE_EVENT__COMMAND_CODE__SERVICE_UNAVAILABLE = 9; * UCE_EVENT__COMMAND_CODE__NO_CHANGE = 10; */ int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__SERVICE_UNAVAILABLE; int networkResponse = 200; mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); // slotId and carrierId are invalid based on subId mRcsStats.setEnableInvalidSubId(); long timeGap = 6000L; mRcsStats.incTimeMillis(timeGap); mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); ArgumentCaptor<ImsRegistrationServiceDescStats> captor = ArgumentCaptor.forClass(ImsRegistrationServiceDescStats.class); verify(mPersistAtomsStorage, times(3)) .addImsRegistrationServiceDescStats(captor.capture()); List<ImsRegistrationServiceDescStats> captorValues = captor.getAllValues(); assertEquals(captorValues.size(), serviceIdList.size()); for (int index = 0; index < captorValues.size(); index++) { ImsRegistrationServiceDescStats stats = captorValues.get(index); assertEquals(CARRIER_ID, stats.carrierId); assertEquals(SLOT_ID, stats.slotId); int serviceId = mRcsStats.convertServiceIdToValue(serviceIdList.get(index)); assertEquals(serviceId, stats.serviceIdName); float serviceVersionFloat = Float.parseFloat(serviceIdVersionList.get(index)); assertEquals(serviceVersionFloat, stats.serviceIdVersion, 0.1f); assertEquals(registrationTech, stats.registrationTech); assertEquals(timeGap, stats.publishedMillis); } assertEquals(0, mRcsStats.getImsRegistrationServiceDescCachedSize()); } @Test @SmallTest public void onUceEventStats_withAtoms() throws Exception { Loading