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.internal.protolog;
18 
19 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.CACHE_UPDATER;
20 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LEGACY_OUTPUT_FILE_PATH;
21 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LEGACY_VIEWER_CONFIG_PATH;
22 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LOG_GROUPS;
23 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.VIEWER_CONFIG_PATH;
24 
25 import android.annotation.Nullable;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.internal.protolog.common.IProtoLog;
29 import com.android.internal.protolog.common.IProtoLogGroup;
30 import com.android.internal.protolog.common.LogLevel;
31 import com.android.internal.protolog.common.ProtoLogToolInjected;
32 
33 import java.util.TreeMap;
34 
35 /**
36  * A service for the ProtoLog logging system.
37  */
38 public class ProtoLogImpl {
39     private static IProtoLog sServiceInstance = null;
40 
41     @ProtoLogToolInjected(VIEWER_CONFIG_PATH)
42     private static String sViewerConfigPath;
43 
44     @ProtoLogToolInjected(LEGACY_VIEWER_CONFIG_PATH)
45     private static String sLegacyViewerConfigPath;
46 
47     @ProtoLogToolInjected(LEGACY_OUTPUT_FILE_PATH)
48     private static String sLegacyOutputFilePath;
49 
50     @ProtoLogToolInjected(LOG_GROUPS)
51     private static TreeMap<String, IProtoLogGroup> sLogGroups;
52 
53     @ProtoLogToolInjected(CACHE_UPDATER)
54     private static Runnable sCacheUpdater;
55 
56     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
d(IProtoLogGroup group, long messageHash, int paramsMask, @Nullable String messageString, Object... args)57     public static void d(IProtoLogGroup group, long messageHash, int paramsMask,
58             @Nullable String messageString,
59             Object... args) {
60         getSingleInstance()
61                 .log(LogLevel.DEBUG, group, messageHash, paramsMask, messageString, args);
62     }
63 
64     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
v(IProtoLogGroup group, long messageHash, int paramsMask, @Nullable String messageString, Object... args)65     public static void v(IProtoLogGroup group, long messageHash, int paramsMask,
66             @Nullable String messageString,
67             Object... args) {
68         getSingleInstance().log(LogLevel.VERBOSE, group, messageHash, paramsMask, messageString,
69                 args);
70     }
71 
72     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
i(IProtoLogGroup group, long messageHash, int paramsMask, @Nullable String messageString, Object... args)73     public static void i(IProtoLogGroup group, long messageHash, int paramsMask,
74             @Nullable String messageString,
75             Object... args) {
76         getSingleInstance().log(LogLevel.INFO, group, messageHash, paramsMask, messageString, args);
77     }
78 
79     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
w(IProtoLogGroup group, long messageHash, int paramsMask, @Nullable String messageString, Object... args)80     public static void w(IProtoLogGroup group, long messageHash, int paramsMask,
81             @Nullable String messageString,
82             Object... args) {
83         getSingleInstance().log(LogLevel.WARN, group, messageHash, paramsMask, messageString, args);
84     }
85 
86     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
e(IProtoLogGroup group, long messageHash, int paramsMask, @Nullable String messageString, Object... args)87     public static void e(IProtoLogGroup group, long messageHash, int paramsMask,
88             @Nullable String messageString,
89             Object... args) {
90         getSingleInstance()
91                 .log(LogLevel.ERROR, group, messageHash, paramsMask, messageString, args);
92     }
93 
94     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
wtf(IProtoLogGroup group, long messageHash, int paramsMask, @Nullable String messageString, Object... args)95     public static void wtf(IProtoLogGroup group, long messageHash, int paramsMask,
96             @Nullable String messageString,
97             Object... args) {
98         getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, messageString, args);
99     }
100 
101     /**
102      * Should return true iff we should be logging to either protolog or logcat for this group
103      * and log level.
104      */
isEnabled(IProtoLogGroup group, LogLevel level)105     public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
106         return getSingleInstance().isEnabled(group, level);
107     }
108 
109     /**
110      * Returns the single instance of the ProtoLogImpl singleton class.
111      */
getSingleInstance()112     public static synchronized IProtoLog getSingleInstance() {
113         if (sServiceInstance == null) {
114             if (android.tracing.Flags.perfettoProtologTracing()) {
115                 sServiceInstance = new PerfettoProtoLogImpl(
116                         sViewerConfigPath, sLogGroups, sCacheUpdater);
117             } else {
118                 sServiceInstance = new LegacyProtoLogImpl(
119                         sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups, sCacheUpdater);
120             }
121 
122             sCacheUpdater.run();
123         }
124         return sServiceInstance;
125     }
126 
127     @VisibleForTesting
setSingleInstance(@ullable IProtoLog instance)128     public static synchronized void setSingleInstance(@Nullable IProtoLog instance) {
129         sServiceInstance = instance;
130     }
131 }
132 
133