1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ims.rcs.uce;
18 
19 import android.annotation.IntDef;
20 import android.telephony.ims.stub.ImsRegistrationImplBase;
21 import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
22 import android.telephony.ims.RcsContactPresenceTuple;
23 import android.telephony.ims.RcsContactUceCapability;
24 import com.android.internal.annotations.VisibleForTesting;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Map;
33 
34 /**
35  * The UceStatsWriter should be a singleton class for storing atoms in RcsStats.
36  * ims-common provides an interface for setting atoms to telephony-common.
37  **/
38 public class UceStatsWriter {
39     private static UceStatsWriter sInstance = null;
40     private UceStatsCallback mCallBack;
41 
42     /**
43      * @hide
44      */
45     // Defines which UCE event occurred.
46     @IntDef(value = {
47         PUBLISH_EVENT,
48         SUBSCRIBE_EVENT,
49         INCOMING_OPTION_EVENT,
50         OUTGOING_OPTION_EVENT
51     })
52     @Retention(RetentionPolicy.SOURCE)
53     public @interface UceEventType {}
54     /**
55      * UCE events related to Publish Method.
56      */
57     public static final int PUBLISH_EVENT = 0;
58     /**
59      * UCE events related to Subscribe Method.
60      */
61     public static final int SUBSCRIBE_EVENT = 1;
62     /**
63      * UCE events related to incoming Options Method.
64      */
65     public static final int INCOMING_OPTION_EVENT = 2;
66     /**
67      * UCE events related to outgoing Options Method.
68      */
69     public static final int OUTGOING_OPTION_EVENT = 3;
70 
71     /**
72      * The callback interface is called by the Metrics data creator to receive information from
73      * others controllers.
74      */
75     public interface UceStatsCallback {
76         /**
77          * Notify the callback listener that the feature tag associated with
78          * IMS registration of this device have changed.
79          */
onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList, int registrationTech)80         public void onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList,
81             int registrationTech);
82 
83         /**
84          * Notify that the active IMS registration to the carrier network has been terminated.
85          */
onStoreCompleteImsRegistrationFeatureTagStats(int subId)86         public void onStoreCompleteImsRegistrationFeatureTagStats(int subId);
87 
88         /**
89          * Notify the callback listener that the PIDF ServiceDescriptions associated with
90          * the UCE presence of this device have changed.
91          */
onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList, List<String> serviceIdVersionList, int registrationTech)92         void onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList,
93             List<String> serviceIdVersionList, int registrationTech);
94 
95         /**
96          * Notify the callback listener that a subscribe response received.
97          */
onSubscribeResponse(int subId, long taskId, int networkResponse)98         void onSubscribeResponse(int subId, long taskId, int networkResponse);
99 
100         /**
101          * Notify the callback listener that a UCE Network Event has occurred.
102          */
onUceEvent(int subId, int type, boolean successful, int commandCode, int networkResponse)103         void onUceEvent(int subId, int type, boolean successful, int commandCode,
104             int networkResponse);
105 
106         /**
107          * Notify the callback listener that a subscribe has ended.
108          */
onSubscribeTerminated(int subId, long taskId, String reason)109         void onSubscribeTerminated(int subId, long taskId, String reason);
110 
111         /**
112          * Notify that the Presence Notify Event has changed.
113          */
onPresenceNotifyEvent(int subId, long taskId, List<RcsContactUceCapability> updatedCapList)114         void onPresenceNotifyEvent(int subId, long taskId,
115             List<RcsContactUceCapability> updatedCapList);
116 
117         /**
118          * Notify that the active UCE PUBLISH to the carrier network has been terminated.
119          */
onStoreCompleteImsRegistrationServiceDescStats(int subId)120         void onStoreCompleteImsRegistrationServiceDescStats(int subId);
121     }
122 
123     /**
124      * create an instance of UceStatsWriter
125      */
init(UceStatsCallback callback)126     public static UceStatsWriter init(UceStatsCallback callback) {
127         synchronized (UceStatsWriter.class) {
128             if (sInstance == null) {
129                 sInstance = new UceStatsWriter(callback);
130             }
131             return sInstance;
132         }
133     }
134 
135     /**
136      * get the current instance of UceStatsWriter
137      */
getInstance()138     public static UceStatsWriter getInstance() {
139         synchronized (UceStatsWriter.class) {
140             return sInstance;
141         }
142     }
143 
144     /**
145      * Stats about each Feature tag that was included in IMS registration received from
146      * the network during register.
147      * @param subId The subId associated with the event.
148      * @param featureTagList Ims Feature tag list.
149      * @param registrationTech The registration tech associated with the feature tag.
150      */
setImsRegistrationFeatureTagStats(int subId, List<String> featureTagList, @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech)151     public void setImsRegistrationFeatureTagStats(int subId, List<String> featureTagList,
152         @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) {
153         if (mCallBack == null) {
154             return;
155         }
156         mCallBack.onImsRegistrationFeatureTagStats(subId, featureTagList, registrationTech);
157     }
158 
159     /**
160      * Update time of stats for each stored feature tag.
161      * @param subId The subId associated with the event.
162      */
setStoreCompleteImsRegistrationFeatureTagStats(int subId)163     public void setStoreCompleteImsRegistrationFeatureTagStats(int subId) {
164         if (mCallBack == null) {
165             return;
166         }
167         mCallBack.onStoreCompleteImsRegistrationFeatureTagStats(subId);
168     }
169 
170     /**
171      * Stats about each ServiceDescription that was included in the PIDF XML sent to
172      * the network during publish
173      * @param subId The subId associated with the event.
174      * @param tupleList Tuple information set in PIDF.
175      * @param registrationTech The registration tech associated with the feature tag.
176      */
setImsRegistrationServiceDescStats(int subId, List<RcsContactPresenceTuple> tupleList, @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech)177     public void setImsRegistrationServiceDescStats(int subId,
178         List<RcsContactPresenceTuple> tupleList,
179         @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) {
180         if (mCallBack == null) {
181             return;
182         }
183         ArrayList<String> svcId = new ArrayList<>();
184         ArrayList<String> svcVersion = new ArrayList<>();
185 
186         for (RcsContactPresenceTuple tuple : tupleList) {
187             svcId.add(tuple.getServiceId());
188             svcVersion.add(tuple.getServiceVersion());
189         }
190         mCallBack.onImsRegistrationServiceDescStats(subId, svcId, svcVersion, registrationTech);
191     }
192 
193     /**
194      * Stats related to UCE queries to the network
195      * @param subId The subId associated with the event.
196      * @param taskId The taskId associate with the event.
197      * @param networkResponse The network response code for the Uce event
198      */
setSubscribeResponse(int subId, long taskId, int networkResponse)199     public void setSubscribeResponse(int subId, long taskId, int networkResponse) {
200         if (mCallBack != null) {
201             mCallBack.onSubscribeResponse(subId, taskId, networkResponse);
202         }
203     }
204 
205     /**
206      * Stats related to UCE queries to the network
207      * @param subId The subId associated with the event.
208      * @param type Used to identify the message type.
209      * @param successful Whether the UCE event is successfully finished.
210      * @param commandCode The command error code for the Uce event
211      * @param networkResponse The network response code for the Uce event
212      */
setUceEvent(int subId, @UceEventType int type, boolean successful, @RcsCapabilityExchangeImplBase.CommandCode int commandCode, int networkResponse)213     public void setUceEvent(int subId, @UceEventType int type, boolean successful,
214         @RcsCapabilityExchangeImplBase.CommandCode int commandCode, int networkResponse) {
215         if (mCallBack != null) {
216             mCallBack.onUceEvent(subId, type, successful, commandCode, networkResponse);
217         }
218     }
219 
220     /**
221      * The result of processing received notify messages.
222      * @param subId The subId associated with the event.
223      * @param taskId The taskId associate with the event.
224      * @param updatedCapList Capability information of the user contained in Presence Notify.
225      */
setPresenceNotifyEvent(int subId, long taskId, List<RcsContactUceCapability> updatedCapList)226     public void setPresenceNotifyEvent(int subId, long taskId,
227         List<RcsContactUceCapability> updatedCapList) {
228         if (mCallBack == null || updatedCapList == null || updatedCapList.isEmpty()) {
229             return;
230         }
231         mCallBack.onPresenceNotifyEvent(subId, taskId, updatedCapList);
232     }
233 
234     /**
235      * Indicates that the subscription request has become a terminated state.
236      * @param subId The subId associated with the event.
237      * @param taskId The taskId associate with the event.
238      * @param reason The terminated reason associated with the subscription state.
239      */
setSubscribeTerminated(int subId, long taskId, String reason)240     public void setSubscribeTerminated(int subId, long taskId, String reason) {
241         if (mCallBack != null) {
242             mCallBack.onSubscribeTerminated(subId, taskId, reason);
243         }
244     }
245 
246     /**
247      * indicates that the device has removed an existing PUBLISH from the carrier's network
248      * containing the device's RCS capabilities state.
249      * The registered time of publication must be set in ImsRegistrationServiceDescStats,
250      * which is the life time of publication, so it can be set only when publication is over.
251      * @param subId The subId associated with the event.
252      */
setUnPublish(int subId)253     public void setUnPublish(int subId) {
254         if (mCallBack != null) {
255             mCallBack.onStoreCompleteImsRegistrationServiceDescStats(subId);
256         }
257     }
258 
259     @VisibleForTesting
UceStatsWriter(UceStatsCallback callback)260     protected UceStatsWriter(UceStatsCallback callback) {
261         mCallBack = callback;
262     }
263 }
264