1470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt/*
2470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * Copyright (C) 2006 The Android Open Source Project
3470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt *
4470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License");
5470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * you may not use this file except in compliance with the License.
6470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * You may obtain a copy of the License at
7470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt *
8470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt *      http://www.apache.org/licenses/LICENSE-2.0
9470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt *
10470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * Unless required by applicable law or agreed to in writing, software
11470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS,
12470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * See the License for the specific language governing permissions and
14470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * limitations under the License.
15470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt */
16470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
17470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwaltpackage android.util;
18470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
19470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwaltimport java.io.FileDescriptor;
20470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwaltimport java.io.PrintWriter;
21c520aa89a33ddb7c065ef06bcd2d2dbf96e1f989vandwalleimport java.util.Calendar;
22470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwaltimport java.util.Iterator;
23de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichiimport java.util.Deque;
24de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichiimport java.util.ArrayDeque;
25470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
26470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt/**
27470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt * @hide
28470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt */
29470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwaltpublic final class LocalLog {
30470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
31de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi    private final Deque<String> mLog;
32de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi    private final int mMaxLines;
33470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
34470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt    public LocalLog(int maxLines) {
35de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        mMaxLines = Math.max(0, maxLines);
36de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        mLog = new ArrayDeque<>(mMaxLines);
37470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt    }
38470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
39de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi    public void log(String msg) {
40de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        if (mMaxLines <= 0) {
41de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi            return;
42470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt        }
43de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        Calendar c = Calendar.getInstance();
44de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        c.setTimeInMillis(System.currentTimeMillis());
45de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        append(String.format("%tm-%td %tH:%tM:%tS.%tL - %s", c, c, c, c, c, c, msg));
46de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi    }
47de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi
48de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi    private synchronized void append(String logLine) {
49de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        while (mLog.size() >= mMaxLines) {
50de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi            mLog.remove();
51de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        }
52de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        mLog.add(logLine);
53470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt    }
54470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
55470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
56de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        Iterator<String> itr = mLog.iterator();
57470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt        while (itr.hasNext()) {
58470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt            pw.println(itr.next());
59470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt        }
60470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt    }
6122b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt
627523eb349e7ecb1fdfd8e8a9371306ab28c046ecErik Kline    public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
63de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        Iterator<String> itr = mLog.descendingIterator();
64de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        while (itr.hasNext()) {
65de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi            pw.println(itr.next());
667523eb349e7ecb1fdfd8e8a9371306ab28c046ecErik Kline        }
677523eb349e7ecb1fdfd8e8a9371306ab28c046ecErik Kline    }
687523eb349e7ecb1fdfd8e8a9371306ab28c046ecErik Kline
6922b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt    public static class ReadOnlyLocalLog {
7022b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt        private final LocalLog mLog;
7122b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt        ReadOnlyLocalLog(LocalLog log) {
7222b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt            mLog = log;
7322b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt        }
7422b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7522b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt            mLog.dump(fd, pw, args);
7622b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt        }
77de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        public void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
78de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi            mLog.reverseDump(fd, pw, args);
79de310dba78fa7cd60ad01cefa7fadb6d48fffcaaHugo Benichi        }
8022b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt    }
8122b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt
8222b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt    public ReadOnlyLocalLog readOnlyLocalLog() {
8322b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt        return new ReadOnlyLocalLog(this);
8422b4c6a027d72ec90dc91d150bee007cb8167eedRobert Greenwalt    }
85470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt}
86