• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.providers.contacts.flags.Flags.logCallMethod;
20 import static com.android.providers.contacts.flags.Flags.logContactSaveInvalidAccountError;
21 
22 import android.os.SystemClock;
23 import android.util.StatsEvent;
24 import android.util.StatsLog;
25 
26 import com.android.providers.contacts.AccountResolver;
27 
28 public class LogUtils {
29     // Keep in sync with ContactsProviderStatus#ResultType in
30     // frameworks/proto_logging/stats/atoms.proto file.
31     public interface ResultType {
32         int SUCCESS = 1;
33         int FAIL = 2;
34         int ILLEGAL_ARGUMENT = 3;
35         int UNSUPPORTED_OPERATION = 4;
36         int INVALID_ACCOUNT = 5;
37     }
38 
39     // Keep in sync with ContactsProviderStatus#ApiType in
40     // frameworks/proto_logging/stats/atoms.proto file.
41     public interface ApiType {
42         int QUERY = 1;
43         int INSERT = 2;
44         int UPDATE = 3;
45         int DELETE = 4;
46         int CALL = 5;
47         int GAL_CALL = 6;
48     }
49 
50     // Keep in sync with ContactsProviderStatus#TaskType in
51     // frameworks/proto_logging/stats/atoms.proto file.
52     public interface TaskType {
53         int DANGLING_CONTACTS_CLEANUP_TASK = 1;
54     }
55 
56     // Keep in sync with ContactsProviderStatus#MethodCall in
57     // frameworks/proto_logging/stats/atoms.proto file.
58     public interface MethodCall {
59         int UNKNOWN_METHOD = 0;
60         int ADD_SIM_ACCOUNTS = 1;
61         int REMOVE_SIM_ACCOUNTS = 2;
62         int GET_SIM_ACCOUNTS = 3;
63         int SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS = 4;
64         int GET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS = 5;
65         int MOVE_LOCAL_CONTACTS_TO_DEFAULT_ACCOUNT = 6;
66         int MOVE_SIM_CONTACTS_TO_DEFAULT_ACCOUNT = 7;
67         int GET_ELIGIBLE_CLOUD_ACCOUNTS = 8;
68     }
69 
70     // Keep in sync with ContactsProviderStatus#CallerType in
71     // frameworks/proto_logging/stats/atoms.proto file.
72     public interface CallerType {
73         int CALLER_IS_SYNC_ADAPTER = 1;
74         int CALLER_IS_NOT_SYNC_ADAPTER = 2;
75     }
76 
77     private static final int STATSD_LOG_ATOM_ID = 301;
78 
79     // The write methods must be called in the same order as the order of fields in the
80     // atom (frameworks/proto_logging/stats/atoms.proto) definition.
log(LogFields logFields)81     public static void log(LogFields logFields) {
82         StatsLog.write(StatsEvent.newBuilder()
83                 .setAtomId(STATSD_LOG_ATOM_ID)
84                 .writeInt(logFields.getApiType())
85                 .writeInt(logFields.getUriType())
86                 .writeInt(getCallerType(logFields.isCallerIsSyncAdapter()))
87                 .writeInt(getResultType(logFields.getException()))
88                 .writeInt(logFields.getResultCount())
89                 .writeLong(getLatencyMicros(logFields.getStartNanos()))
90                 .writeInt(logFields.getTaskType())
91                 .writeInt(logCallMethod() ? logFields.getMethodCalled() : 0)
92                 .writeInt(logFields.getUid())
93                 .usePooledBuffer()
94                 .build());
95     }
96 
getCallerType(boolean callerIsSyncAdapter)97     private static int getCallerType(boolean callerIsSyncAdapter) {
98         return callerIsSyncAdapter
99                 ? CallerType.CALLER_IS_SYNC_ADAPTER : CallerType.CALLER_IS_NOT_SYNC_ADAPTER;
100     }
101 
102 
getResultType(Exception exception)103     private static int getResultType(Exception exception) {
104         if (exception == null) {
105             return ResultType.SUCCESS;
106         } else if (exception instanceof IllegalArgumentException) {
107             if (logContactSaveInvalidAccountError()
108                     && AccountResolver.UNABLE_TO_WRITE_TO_LOCAL_OR_SIM_EXCEPTION_MESSAGE.equals(
109                     exception.getMessage())) {
110                 return ResultType.INVALID_ACCOUNT;
111             }
112             return ResultType.ILLEGAL_ARGUMENT;
113         } else if (exception instanceof UnsupportedOperationException) {
114             return ResultType.UNSUPPORTED_OPERATION;
115         } else {
116             return ResultType.FAIL;
117         }
118     }
119 
getLatencyMicros(long startNanos)120     private static long getLatencyMicros(long startNanos) {
121         return (SystemClock.elapsedRealtimeNanos() - startNanos) / 1000;
122     }
123 }
124