1 /*
2  * Copyright (C) 2012 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.util;
18 
19 import android.util.IndentingPrintWriter;
20 import android.util.Slog;
21 import android.util.proto.ProtoOutputStream;
22 
23 import java.util.ArrayList;
24 
25 /**
26  * Helper class for logging serious issues, which also keeps a small
27  * snapshot of the logged events that can be printed later, such as part
28  * of a system service's dumpsys output.
29  * @hide
30  */
31 // Exported to Mainline modules; cannot use annotations
32 // @android.ravenwood.annotation.RavenwoodKeepWholeClass
33 public class LocalLog {
34     private final String mTag;
35     private final int mMaxLines = 20;
36     private final ArrayList<String> mLines = new ArrayList<String>(mMaxLines);
37 
LocalLog(String tag)38     public LocalLog(String tag) {
39         mTag = tag;
40     }
41 
w(String msg)42     public void w(String msg) {
43         synchronized (mLines) {
44             Slog.w(mTag, msg);
45             if (mLines.size() >= mMaxLines) {
46                 mLines.remove(0);
47             }
48             mLines.add(msg);
49         }
50     }
51 
dump(IndentingPrintWriter pw, String header)52     public boolean dump(IndentingPrintWriter pw, String header) {
53         synchronized (mLines) {
54             if (mLines.size() <= 0) {
55                 return false;
56             }
57             if (header != null) {
58                 pw.println(header);
59                 pw.increaseIndent();
60             }
61             for (int i=0; i<mLines.size(); i++) {
62                 pw.println(mLines.get(i));
63             }
64             if (header != null) {
65                 pw.decreaseIndent();
66             }
67             return true;
68         }
69     }
70 
dumpDebug(ProtoOutputStream proto, long fieldId)71     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
72         final long token = proto.start(fieldId);
73 
74         synchronized (mLines) {
75             for (int i = 0; i < mLines.size(); ++i) {
76                 proto.write(LocalLogProto.LINES, mLines.get(i));
77             }
78         }
79 
80         proto.end(token);
81     }
82 }
83