1 /*
2  * Copyright (C) 2020 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.providers.contacts.util;
18 
19 import android.os.SystemClock;
20 import android.util.StatsEvent;
21 import android.util.StatsLog;
22 
23 public class LogUtils {
24     // Keep in sync with ContactsProviderStatus#ResultType in
25     // frameworks/proto_logging/stats/atoms.proto file.
26     public interface ResultType {
27         int SUCCESS = 1;
28         int FAIL = 2;
29         int ILLEGAL_ARGUMENT = 3;
30         int UNSUPPORTED_OPERATION = 4;
31     }
32 
33     // Keep in sync with ContactsProviderStatus#ApiType in
34     // frameworks/proto_logging/stats/atoms.proto file.
35     public interface ApiType {
36         int QUERY = 1;
37         int INSERT = 2;
38         int UPDATE = 3;
39         int DELETE = 4;
40         int CALL = 5;
41         int GAL_CALL = 6;
42     }
43 
44     // Keep in sync with ContactsProviderStatus#TaskType in
45     // frameworks/proto_logging/stats/atoms.proto file.
46     public interface TaskType {
47         int DANGLING_CONTACTS_CLEANUP_TASK = 1;
48     }
49 
50     // Keep in sync with ContactsProviderStatus#CallerType in
51     // frameworks/proto_logging/stats/atoms.proto file.
52     public interface CallerType {
53         int CALLER_IS_SYNC_ADAPTER = 1;
54         int CALLER_IS_NOT_SYNC_ADAPTER = 2;
55     }
56 
57     private static final int STATSD_LOG_ATOM_ID = 301;
58 
59     // The write methods must be called in the same order as the order of fields in the
60     // atom (frameworks/proto_logging/stats/atoms.proto) definition.
log(LogFields logFields)61     public static void log(LogFields logFields) {
62         StatsLog.write(StatsEvent.newBuilder()
63                 .setAtomId(STATSD_LOG_ATOM_ID)
64                 .writeInt(logFields.getApiType())
65                 .writeInt(logFields.getUriType())
66                 .writeInt(getCallerType(logFields.isCallerIsSyncAdapter()))
67                 .writeInt(getResultType(logFields.getException()))
68                 .writeInt(logFields.getResultCount())
69                 .writeLong(getLatencyMicros(logFields.getStartNanos()))
70                 .writeInt(logFields.getTaskType())
71                 .writeInt(0) // Not used yet.
72                 .writeInt(logFields.getUid())
73                 .usePooledBuffer()
74                 .build());
75     }
76 
getCallerType(boolean callerIsSyncAdapter)77     private static int getCallerType(boolean callerIsSyncAdapter) {
78         return callerIsSyncAdapter
79                 ? CallerType.CALLER_IS_SYNC_ADAPTER : CallerType.CALLER_IS_NOT_SYNC_ADAPTER;
80     }
81 
getResultType(Exception exception)82     private static int getResultType(Exception exception) {
83         if (exception == null) {
84             return ResultType.SUCCESS;
85         } else if (exception instanceof IllegalArgumentException) {
86             return ResultType.ILLEGAL_ARGUMENT;
87         } else if (exception instanceof UnsupportedOperationException) {
88             return ResultType.UNSUPPORTED_OPERATION;
89         } else {
90             return ResultType.FAIL;
91         }
92     }
93 
getLatencyMicros(long startNanos)94     private static long getLatencyMicros(long startNanos) {
95         return (SystemClock.elapsedRealtimeNanos() - startNanos) / 1000;
96     }
97 }
98