• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.server.telecom.metrics;
18 
19 import static com.android.server.telecom.TelecomStatsLog.TELECOM_API_STATS;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.app.StatsManager;
24 import android.content.Context;
25 import android.os.Looper;
26 import android.telecom.Log;
27 import android.util.StatsEvent;
28 
29 import androidx.annotation.VisibleForTesting;
30 
31 import com.android.server.telecom.TelecomStatsLog;
32 import com.android.server.telecom.nano.PulledAtomsClass;
33 
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.util.Arrays;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Objects;
41 
42 public class ApiStats extends TelecomPulledAtom {
43     public static final int API_UNSPECIFIC = TelecomStatsLog
44             .TELECOM_API_STATS__API_NAME__API_UNSPECIFIED;
45     public static final int API_ACCEPTHANDOVER = TelecomStatsLog
46             .TELECOM_API_STATS__API_NAME__API_ACCEPT_HANDOVER;
47     public static final int API_ACCEPTRINGINGCALL = TelecomStatsLog
48             .TELECOM_API_STATS__API_NAME__API_ACCEPT_RINGING_CALL;
49     public static final int API_ACCEPTRINGINGCALLWITHVIDEOSTATE = TelecomStatsLog
50             .TELECOM_API_STATS__API_NAME__API_ACCEPT_RINGING_CALL_WITH_VIDEO_STATE;
51     public static final int API_ADDCALL = TelecomStatsLog.TELECOM_API_STATS__API_NAME__API_ADD_CALL;
52     public static final int API_ADDNEWINCOMINGCALL = TelecomStatsLog
53             .TELECOM_API_STATS__API_NAME__API_ADD_NEW_INCOMING_CALL;
54     public static final int API_ADDNEWINCOMINGCONFERENCE = TelecomStatsLog
55             .TELECOM_API_STATS__API_NAME__API_ADD_NEW_INCOMING_CONFERENCE;
56     public static final int API_ADDNEWUNKNOWNCALL = TelecomStatsLog
57             .TELECOM_API_STATS__API_NAME__API_ADD_NEW_UNKNOWN_CALL;
58     public static final int API_CANCELMISSEDCALLSNOTIFICATION = TelecomStatsLog
59             .TELECOM_API_STATS__API_NAME__API_CANCEL_MISSED_CALLS_NOTIFICATION;
60     public static final int API_CLEARACCOUNTS = TelecomStatsLog
61             .TELECOM_API_STATS__API_NAME__API_CLEAR_ACCOUNTS;
62     public static final int API_CREATELAUNCHEMERGENCYDIALERINTENT = TelecomStatsLog
63             .TELECOM_API_STATS__API_NAME__API_CREATE_LAUNCH_EMERGENCY_DIALER_INTENT;
64     public static final int API_CREATEMANAGEBLOCKEDNUMBERSINTENT = TelecomStatsLog
65             .TELECOM_API_STATS__API_NAME__API_CREATE_MANAGE_BLOCKED_NUMBERS_INTENT;
66     public static final int API_DUMP = TelecomStatsLog.TELECOM_API_STATS__API_NAME__API_DUMP;
67     public static final int API_DUMPCALLANALYTICS = TelecomStatsLog
68             .TELECOM_API_STATS__API_NAME__API_DUMP_CALL_ANALYTICS;
69     public static final int API_ENABLEPHONEACCOUNT = TelecomStatsLog
70             .TELECOM_API_STATS__API_NAME__API_ENABLE_PHONE_ACCOUNT;
71     public static final int API_ENDCALL = TelecomStatsLog.TELECOM_API_STATS__API_NAME__API_END_CALL;
72     public static final int API_GETADNURIFORPHONEACCOUNT = TelecomStatsLog
73             .TELECOM_API_STATS__API_NAME__API_GET_ADN_URI_FOR_PHONE_ACCOUNT;
74     public static final int API_GETALLPHONEACCOUNTHANDLES = TelecomStatsLog
75             .TELECOM_API_STATS__API_NAME__API_GET_ALL_PHONE_ACCOUNT_HANDLES;
76     public static final int API_GETALLPHONEACCOUNTS = TelecomStatsLog
77             .TELECOM_API_STATS__API_NAME__API_GET_ALL_PHONE_ACCOUNTS;
78     public static final int API_GETALLPHONEACCOUNTSCOUNT = TelecomStatsLog
79             .TELECOM_API_STATS__API_NAME__API_GET_ALL_PHONE_ACCOUNTS_COUNT;
80     public static final int API_GETCALLCAPABLEPHONEACCOUNTS = TelecomStatsLog
81             .TELECOM_API_STATS__API_NAME__API_GET_CALL_CAPABLE_PHONE_ACCOUNTS;
82     public static final int API_GETCALLSTATE = TelecomStatsLog
83             .TELECOM_API_STATS__API_NAME__API_GET_CALL_STATE;
84     public static final int API_GETCALLSTATEUSINGPACKAGE = TelecomStatsLog
85             .TELECOM_API_STATS__API_NAME__API_GET_CALL_STATE_USING_PACKAGE;
86     public static final int API_GETCURRENTTTYMODE = TelecomStatsLog
87             .TELECOM_API_STATS__API_NAME__API_GET_CURRENT_TTY_MODE;
88     public static final int API_GETDEFAULTDIALERPACKAGE = TelecomStatsLog
89             .TELECOM_API_STATS__API_NAME__API_GET_DEFAULT_DIALER_PACKAGE;
90     public static final int API_GETDEFAULTDIALERPACKAGEFORUSER = TelecomStatsLog
91             .TELECOM_API_STATS__API_NAME__API_GET_DEFAULT_DIALER_PACKAGE_FOR_USER;
92     public static final int API_GETDEFAULTOUTGOINGPHONEACCOUNT = TelecomStatsLog
93             .TELECOM_API_STATS__API_NAME__API_GET_DEFAULT_OUTGOING_PHONE_ACCOUNT;
94     public static final int API_GETDEFAULTPHONEAPP = TelecomStatsLog
95             .TELECOM_API_STATS__API_NAME__API_GET_DEFAULT_PHONE_APP;
96     public static final int API_GETLINE1NUMBER = TelecomStatsLog
97             .TELECOM_API_STATS__API_NAME__API_GET_LINE1_NUMBER;
98     public static final int API_GETOWNSELFMANAGEDPHONEACCOUNTS = TelecomStatsLog
99             .TELECOM_API_STATS__API_NAME__API_GET_OWN_SELF_MANAGED_PHONE_ACCOUNTS;
100     public static final int API_GETPHONEACCOUNT = TelecomStatsLog
101             .TELECOM_API_STATS__API_NAME__API_GET_PHONE_ACCOUNT;
102     public static final int API_GETPHONEACCOUNTSFORPACKAGE = TelecomStatsLog
103             .TELECOM_API_STATS__API_NAME__API_GET_PHONE_ACCOUNTS_FOR_PACKAGE;
104     public static final int API_GETPHONEACCOUNTSSUPPORTINGSCHEME = TelecomStatsLog
105             .TELECOM_API_STATS__API_NAME__API_GET_PHONE_ACCOUNTS_SUPPORTING_SCHEME;
106     public static final int API_GETREGISTEREDPHONEACCOUNTS = TelecomStatsLog
107             .TELECOM_API_STATS__API_NAME__API_GET_REGISTERED_PHONE_ACCOUNTS;
108     public static final int API_GETSELFMANAGEDPHONEACCOUNTS = TelecomStatsLog
109             .TELECOM_API_STATS__API_NAME__API_GET_SELF_MANAGED_PHONE_ACCOUNTS;
110     public static final int API_GETSIMCALLMANAGER = TelecomStatsLog
111             .TELECOM_API_STATS__API_NAME__API_GET_SIM_CALL_MANAGER;
112     public static final int API_GETSIMCALLMANAGERFORUSER = TelecomStatsLog
113             .TELECOM_API_STATS__API_NAME__API_GET_SIM_CALL_MANAGER_FOR_USER;
114     public static final int API_GETSYSTEMDIALERPACKAGE = TelecomStatsLog
115             .TELECOM_API_STATS__API_NAME__API_GET_SYSTEM_DIALER_PACKAGE;
116     public static final int API_GETUSERSELECTEDOUTGOINGPHONEACCOUNT = TelecomStatsLog
117             .TELECOM_API_STATS__API_NAME__API_GET_USER_SELECTED_OUTGOING_PHONE_ACCOUNT;
118     public static final int API_GETVOICEMAILNUMBER = TelecomStatsLog
119             .TELECOM_API_STATS__API_NAME__API_GET_VOICE_MAIL_NUMBER;
120     public static final int API_HANDLEPINMMI = TelecomStatsLog
121             .TELECOM_API_STATS__API_NAME__API_HANDLE_PIN_MMI;
122     public static final int API_HANDLEPINMMIFORPHONEACCOUNT = TelecomStatsLog
123             .TELECOM_API_STATS__API_NAME__API_HANDLE_PIN_MMI_FOR_PHONE_ACCOUNT;
124     public static final int API_HASMANAGEONGOINGCALLSPERMISSION = TelecomStatsLog
125             .TELECOM_API_STATS__API_NAME__API_HAS_MANAGE_ONGOING_CALLS_PERMISSION;
126     public static final int API_ISINCALL = TelecomStatsLog
127             .TELECOM_API_STATS__API_NAME__API_IS_IN_CALL;
128     public static final int API_ISINCOMINGCALLPERMITTED = TelecomStatsLog
129             .TELECOM_API_STATS__API_NAME__API_IS_IN_EMERGENCY_CALL;
130     public static final int API_ISINEMERGENCYCALL = TelecomStatsLog
131             .TELECOM_API_STATS__API_NAME__API_IS_IN_MANAGED_CALL;
132     public static final int API_ISINMANAGEDCALL = TelecomStatsLog
133             .TELECOM_API_STATS__API_NAME__API_IS_IN_SELF_MANAGED_CALL;
134     public static final int API_ISINSELFMANAGEDCALL = TelecomStatsLog
135             .TELECOM_API_STATS__API_NAME__API_IS_INCOMING_CALL_PERMITTED;
136     public static final int API_ISOUTGOINGCALLPERMITTED = TelecomStatsLog
137             .TELECOM_API_STATS__API_NAME__API_IS_OUTGOING_CALL_PERMITTED;
138     public static final int API_ISRINGING = TelecomStatsLog
139             .TELECOM_API_STATS__API_NAME__API_IS_RINGING;
140     public static final int API_ISTTYSUPPORTED = TelecomStatsLog
141             .TELECOM_API_STATS__API_NAME__API_IS_TTY_SUPPORTED;
142     public static final int API_ISVOICEMAILNUMBER = TelecomStatsLog
143             .TELECOM_API_STATS__API_NAME__API_IS_VOICE_MAIL_NUMBER;
144     public static final int API_PLACECALL = TelecomStatsLog
145             .TELECOM_API_STATS__API_NAME__API_PLACE_CALL;
146     public static final int API_REGISTERPHONEACCOUNT = TelecomStatsLog
147             .TELECOM_API_STATS__API_NAME__API_REGISTER_PHONE_ACCOUNT;
148     public static final int API_SETDEFAULTDIALER = TelecomStatsLog
149             .TELECOM_API_STATS__API_NAME__API_SET_DEFAULT_DIALER;
150     public static final int API_SETUSERSELECTEDOUTGOINGPHONEACCOUNT = TelecomStatsLog
151             .TELECOM_API_STATS__API_NAME__API_SET_USER_SELECTED_OUTGOING_PHONE_ACCOUNT;
152     public static final int API_SHOWINCALLSCREEN = TelecomStatsLog
153             .TELECOM_API_STATS__API_NAME__API_SHOW_IN_CALL_SCREEN;
154     public static final int API_SILENCERINGER = TelecomStatsLog
155             .TELECOM_API_STATS__API_NAME__API_SILENCE_RINGER;
156     public static final int API_STARTCONFERENCE = TelecomStatsLog
157             .TELECOM_API_STATS__API_NAME__API_START_CONFERENCE;
158     public static final int API_UNREGISTERPHONEACCOUNT = TelecomStatsLog
159             .TELECOM_API_STATS__API_NAME__API_UNREGISTER_PHONE_ACCOUNT;
160     public static final int RESULT_UNKNOWN = TelecomStatsLog
161             .TELECOM_API_STATS__API_RESULT__RESULT_UNKNOWN;
162     public static final int RESULT_NORMAL = TelecomStatsLog
163             .TELECOM_API_STATS__API_RESULT__RESULT_SUCCESS;
164     public static final int RESULT_PERMISSION = TelecomStatsLog
165             .TELECOM_API_STATS__API_RESULT__RESULT_PERMISSION;
166     public static final int RESULT_EXCEPTION = TelecomStatsLog
167             .TELECOM_API_STATS__API_RESULT__RESULT_EXCEPTION;
168     private static final String TAG = ApiStats.class.getSimpleName();
169     private static final String FILE_NAME = "api_stats";
170     private Map<ApiEvent, Integer> mApiStatsMap;
171 
ApiStats(@onNull Context context, @NonNull Looper looper, boolean isTestMode)172     public ApiStats(@NonNull Context context, @NonNull Looper looper, boolean isTestMode) {
173         super(context, looper, isTestMode);
174     }
175 
176     @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
177     @Override
getTag()178     public int getTag() {
179         return TELECOM_API_STATS;
180     }
181 
182     @Override
getFileName()183     protected String getFileName() {
184         return FILE_NAME;
185     }
186 
187     @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
188     @Override
onPull(final List<StatsEvent> data)189     public synchronized int onPull(final List<StatsEvent> data) {
190         if (mPulledAtoms.telecomApiStats.length != 0) {
191             Arrays.stream(mPulledAtoms.telecomApiStats).forEach(v -> data.add(
192                     TelecomStatsLog.buildStatsEvent(getTag(),
193                             v.getApiName(), v.getUid(), v.getApiResult(), v.getCount())));
194             mApiStatsMap.clear();
195             onAggregate();
196             return StatsManager.PULL_SUCCESS;
197         } else {
198             return StatsManager.PULL_SKIP;
199         }
200     }
201 
202     @Override
onLoad()203     protected synchronized void onLoad() {
204         if (mPulledAtoms.telecomApiStats != null) {
205             mApiStatsMap = new HashMap<>();
206             for (PulledAtomsClass.TelecomApiStats v : mPulledAtoms.telecomApiStats) {
207                 mApiStatsMap.put(new ApiEvent(v.getApiName(), v.getUid(), v.getApiResult()),
208                         v.getCount());
209             }
210             mLastPulledTimestamps = mPulledAtoms.getTelecomApiStatsPullTimestampMillis();
211         }
212     }
213 
214     @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
215     @Override
onAggregate()216     public synchronized void onAggregate() {
217         Log.d(TAG, "onAggregate: %s", mApiStatsMap);
218         clearAtoms();
219         if (mApiStatsMap.isEmpty()) {
220             return;
221         }
222         mPulledAtoms.setTelecomApiStatsPullTimestampMillis(mLastPulledTimestamps);
223         mPulledAtoms.telecomApiStats =
224                 new PulledAtomsClass.TelecomApiStats[mApiStatsMap.size()];
225         int[] index = new int[1];
226         mApiStatsMap.forEach((k, v) -> {
227             mPulledAtoms.telecomApiStats[index[0]] = new PulledAtomsClass.TelecomApiStats();
228             mPulledAtoms.telecomApiStats[index[0]].setApiName(k.mId);
229             mPulledAtoms.telecomApiStats[index[0]].setUid(k.mCallerUid);
230             mPulledAtoms.telecomApiStats[index[0]].setApiResult(k.mResult);
231             mPulledAtoms.telecomApiStats[index[0]].setCount(v);
232             index[0]++;
233         });
234         save(DELAY_FOR_PERSISTENT_MILLIS);
235     }
236 
log(@onNull ApiEvent event)237     public void log(@NonNull ApiEvent event) {
238         post(() -> {
239             mApiStatsMap.put(event, mApiStatsMap.getOrDefault(event, 0) + 1);
240             onAggregate();
241         });
242     }
243 
244     @IntDef(prefix = "API", value = {
245             API_UNSPECIFIC,
246             API_ACCEPTHANDOVER,
247             API_ACCEPTRINGINGCALL,
248             API_ACCEPTRINGINGCALLWITHVIDEOSTATE,
249             API_ADDCALL,
250             API_ADDNEWINCOMINGCALL,
251             API_ADDNEWINCOMINGCONFERENCE,
252             API_ADDNEWUNKNOWNCALL,
253             API_CANCELMISSEDCALLSNOTIFICATION,
254             API_CLEARACCOUNTS,
255             API_CREATELAUNCHEMERGENCYDIALERINTENT,
256             API_CREATEMANAGEBLOCKEDNUMBERSINTENT,
257             API_DUMP,
258             API_DUMPCALLANALYTICS,
259             API_ENABLEPHONEACCOUNT,
260             API_ENDCALL,
261             API_GETADNURIFORPHONEACCOUNT,
262             API_GETALLPHONEACCOUNTHANDLES,
263             API_GETALLPHONEACCOUNTS,
264             API_GETALLPHONEACCOUNTSCOUNT,
265             API_GETCALLCAPABLEPHONEACCOUNTS,
266             API_GETCALLSTATE,
267             API_GETCALLSTATEUSINGPACKAGE,
268             API_GETCURRENTTTYMODE,
269             API_GETDEFAULTDIALERPACKAGE,
270             API_GETDEFAULTDIALERPACKAGEFORUSER,
271             API_GETDEFAULTOUTGOINGPHONEACCOUNT,
272             API_GETDEFAULTPHONEAPP,
273             API_GETLINE1NUMBER,
274             API_GETOWNSELFMANAGEDPHONEACCOUNTS,
275             API_GETPHONEACCOUNT,
276             API_GETPHONEACCOUNTSFORPACKAGE,
277             API_GETPHONEACCOUNTSSUPPORTINGSCHEME,
278             API_GETREGISTEREDPHONEACCOUNTS,
279             API_GETSELFMANAGEDPHONEACCOUNTS,
280             API_GETSIMCALLMANAGER,
281             API_GETSIMCALLMANAGERFORUSER,
282             API_GETSYSTEMDIALERPACKAGE,
283             API_GETUSERSELECTEDOUTGOINGPHONEACCOUNT,
284             API_GETVOICEMAILNUMBER,
285             API_HANDLEPINMMI,
286             API_HANDLEPINMMIFORPHONEACCOUNT,
287             API_HASMANAGEONGOINGCALLSPERMISSION,
288             API_ISINCALL,
289             API_ISINCOMINGCALLPERMITTED,
290             API_ISINEMERGENCYCALL,
291             API_ISINMANAGEDCALL,
292             API_ISINSELFMANAGEDCALL,
293             API_ISOUTGOINGCALLPERMITTED,
294             API_ISRINGING,
295             API_ISTTYSUPPORTED,
296             API_ISVOICEMAILNUMBER,
297             API_PLACECALL,
298             API_REGISTERPHONEACCOUNT,
299             API_SETDEFAULTDIALER,
300             API_SETUSERSELECTEDOUTGOINGPHONEACCOUNT,
301             API_SHOWINCALLSCREEN,
302             API_SILENCERINGER,
303             API_STARTCONFERENCE,
304             API_UNREGISTERPHONEACCOUNT,
305     })
306     @Retention(RetentionPolicy.SOURCE)
307     public @interface ApiId {
308     }
309 
310     @IntDef(prefix = "RESULT", value = {
311             RESULT_UNKNOWN,
312             RESULT_NORMAL,
313             RESULT_PERMISSION,
314             RESULT_EXCEPTION,
315     })
316     @Retention(RetentionPolicy.SOURCE)
317     public @interface ResultId {
318     }
319 
320     public static class ApiEvent {
321 
322         @ApiId
323         int mId;
324         int mCallerUid;
325         @ResultId
326         int mResult;
327 
ApiEvent(@piId int id, int callerUid, @ResultId int result)328         public ApiEvent(@ApiId int id, int callerUid, @ResultId int result) {
329             mId = id;
330             mCallerUid = callerUid;
331             mResult = result;
332         }
333 
setCallerUid(int uid)334         public void setCallerUid(int uid) {
335             this.mCallerUid = uid;
336         }
337 
setResult(@esultId int result)338         public void setResult(@ResultId int result) {
339             this.mResult = result;
340         }
341 
342         @Override
equals(Object other)343         public boolean equals(Object other) {
344             if (this == other) {
345                 return true;
346             }
347             if (!(other instanceof ApiEvent obj)) {
348                 return false;
349             }
350             return this.mId == obj.mId && this.mCallerUid == obj.mCallerUid
351                     && this.mResult == obj.mResult;
352         }
353 
354         @Override
hashCode()355         public int hashCode() {
356             return Objects.hash(mId, mCallerUid, mResult);
357         }
358 
359         @Override
toString()360         public String toString() {
361             return "[ApiEvent: mApiId=" + mId + ", mCallerUid=" + mCallerUid
362                     + ", mResult=" + mResult + "]";
363         }
364     }
365 }
366