blob: c7add75d346be3ea3967a011e214a061b420ec62 [file] [log] [blame]
Jungshik Jangdbe6b452014-08-22 13:49:55 +09001/*
2 * Copyright (C) 2014 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
17package com.android.server.hdmi;
18
Jungshik Jang339227d2014-08-25 15:37:20 +090019import android.annotation.Nullable;
Jungshik Jangdbe6b452014-08-22 13:49:55 +090020import android.os.SystemClock;
21import android.util.Pair;
22import android.util.Slog;
23
24import java.util.HashMap;
25
26/**
27 * A logger that prevents spammy log. For the same log message, it logs once every 20seconds.
28 * This class is not thread-safe.
29 */
30final class HdmiLogger {
31 // Logging duration for same error message.
32 private static final long ERROR_LOG_DURATTION_MILLIS = 20 * 1000; // 20s
33
Yuncheol Heo192ba202014-09-02 14:59:15 +090034 private static final boolean DEBUG = false;
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090035
Jungshik Jangdbe6b452014-08-22 13:49:55 +090036 // Key (String): log message.
37 // Value (Pair(Long, Integer)): a pair of last log time millis and the number of logMessage.
38 // Cache for warning.
39 private final HashMap<String, Pair<Long, Integer>> mWarningTimingCache = new HashMap<>();
40 // Cache for error.
41 private final HashMap<String, Pair<Long, Integer>> mErrorTimingCache = new HashMap<>();
Jungshik Jangdbe6b452014-08-22 13:49:55 +090042 private final String mTag;
43
44 HdmiLogger(String tag) {
Jungshik Janga7221ce2014-08-28 16:35:30 +090045 mTag = "HDMI:" + tag;
Jungshik Jangdbe6b452014-08-22 13:49:55 +090046 }
47
48 void warning(String logMessage) {
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090049 String log = updateLog(mWarningTimingCache, logMessage);
50 if (!log.isEmpty()) {
51 Slog.w(mTag, log);
Jungshik Jangdbe6b452014-08-22 13:49:55 +090052 }
53 }
54
55 void error(String logMessage) {
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090056 String log = updateLog(mErrorTimingCache, logMessage);
57 if (!log.isEmpty()) {
58 Slog.e(mTag, log);
Jungshik Jangdbe6b452014-08-22 13:49:55 +090059 }
60 }
61
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090062 void debug(String logMessage) {
63 if (!DEBUG) {
64 return;
65 }
66 Slog.d(mTag, logMessage);
Jungshik Jangdbe6b452014-08-22 13:49:55 +090067 }
68
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090069 private static String updateLog(HashMap<String, Pair<Long, Integer>> cache, String logMessage) {
70 long curTime = SystemClock.uptimeMillis();
71 Pair<Long, Integer> timing = cache.get(logMessage);
72 if (shouldLogNow(timing, curTime)) {
73 String log = buildMessage(logMessage, timing);
74 cache.put(logMessage, new Pair<>(curTime, 1));
75 return log;
76 } else {
77 increaseLogCount(cache, logMessage);
78 }
79 return "";
80 }
81
82 private static String buildMessage(String message, @Nullable Pair<Long, Integer> timing) {
83 return new StringBuilder()
84 .append("[").append(timing == null ? 1 : timing.second).append("]:")
85 .append(message).toString();
86 }
87
88 private static void increaseLogCount(HashMap<String, Pair<Long, Integer>> cache,
89 String message) {
Jungshik Jangdbe6b452014-08-22 13:49:55 +090090 Pair<Long, Integer> timing = cache.get(message);
91 if (timing != null) {
92 cache.put(message, new Pair<>(timing.first, timing.second + 1));
93 }
94 }
95
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090096 private static boolean shouldLogNow(@Nullable Pair<Long, Integer> timing, long curTime) {
Jungshik Jangdbe6b452014-08-22 13:49:55 +090097 return timing == null || curTime - timing.first > ERROR_LOG_DURATTION_MILLIS;
98 }
99}