LogcatLog.java revision f5d90be206db98bbd5894afc8d757dd32360b2d9
1/* 2 * Copyright (C) 2016 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.wifi; 18 19import android.util.Log; 20 21import com.android.internal.annotations.Immutable; 22 23/** 24 * Provides a WifiLog implementation which uses logd as the 25 * logging backend. 26 * 27 * This class is trivially thread-safe, as instances are immutable. 28 * Note, however, that LogMessage instances are _not_ thread-safe. 29 */ 30// @ThreadSafe 31@Immutable 32class LogcatLog implements WifiLog { 33 private final String mTag; 34 35 LogcatLog(String tag) { 36 mTag = tag; 37 } 38 39 /* New-style methods */ 40 @Override 41 public LogMessage err(String format) { 42 return makeLogMessage(Log.ERROR, format); 43 } 44 45 @Override 46 public LogMessage warn(String format) { 47 return makeLogMessage(Log.WARN, format); 48 } 49 50 @Override 51 public LogMessage info(String format) { 52 return makeLogMessage(Log.INFO, format); 53 } 54 55 @Override 56 public LogMessage trace(String format) { 57 return makeLogMessage(Log.DEBUG, format); 58 } 59 60 @Override 61 public LogMessage dump(String format) { 62 return makeLogMessage(Log.VERBOSE, format); 63 } 64 65 @Override 66 public void eC(String msg) { 67 Log.e(mTag, msg); 68 } 69 70 @Override 71 public void wC(String msg) { 72 Log.w(mTag, msg); 73 } 74 75 @Override 76 public void iC(String msg) { 77 Log.i(mTag, msg); 78 } 79 80 @Override 81 public void tC(String msg) { 82 Log.d(mTag, msg); 83 } 84 85 /* Legacy methods */ 86 @Override 87 public void e(String msg) { 88 Log.e(mTag, msg); 89 } 90 91 @Override 92 public void w(String msg) { 93 Log.w(mTag, msg); 94 } 95 96 @Override 97 public void i(String msg) { 98 Log.i(mTag, msg); 99 } 100 101 @Override 102 public void d(String msg) { 103 Log.d(mTag, msg); 104 } 105 106 @Override 107 public void v(String msg) { 108 Log.v(mTag, msg); 109 } 110 111 /* Internal details */ 112 private static class RealLogMessage implements WifiLog.LogMessage { 113 private final int mLogLevel; 114 private final String mTag; 115 private final String mFormat; 116 private final StringBuilder mStringBuilder; 117 private int mNextFormatCharPos; 118 119 RealLogMessage(int logLevel, String tag, String format) { 120 mLogLevel = logLevel; 121 mTag = tag; 122 mFormat = format; 123 mStringBuilder = new StringBuilder(); 124 mNextFormatCharPos = 0; 125 } 126 127 @Override 128 public WifiLog.LogMessage r(String value) { 129 // Since the logcat back-end is just transitional, we don't attempt to tag sensitive 130 // information in it. 131 return c(value); 132 } 133 134 @Override 135 public WifiLog.LogMessage c(String value) { 136 copyUntilPlaceholder(); 137 if (mNextFormatCharPos < mFormat.length()) { 138 mStringBuilder.append(value); 139 ++mNextFormatCharPos; 140 } 141 return this; 142 } 143 144 @Override 145 public WifiLog.LogMessage c(long value) { 146 copyUntilPlaceholder(); 147 if (mNextFormatCharPos < mFormat.length()) { 148 mStringBuilder.append(value); 149 ++mNextFormatCharPos; 150 } 151 return this; 152 } 153 154 @Override 155 public WifiLog.LogMessage c(char value) { 156 copyUntilPlaceholder(); 157 if (mNextFormatCharPos < mFormat.length()) { 158 mStringBuilder.append(value); 159 ++mNextFormatCharPos; 160 } 161 return this; 162 } 163 164 @Override 165 public void flush() { 166 if (mNextFormatCharPos < mFormat.length()) { 167 mStringBuilder.append(mFormat, mNextFormatCharPos, mFormat.length()); 168 } 169 Log.println(mLogLevel, mTag, mStringBuilder.toString()); 170 } 171 172 /* Should generally not be used; implemented primarily to aid in testing. */ 173 public String toString() { 174 return mStringBuilder.toString(); 175 } 176 177 private void copyUntilPlaceholder() { 178 if (mNextFormatCharPos >= mFormat.length()) { 179 return; 180 } 181 182 int placeholderPos = mFormat.indexOf(WifiLog.PLACEHOLDER, mNextFormatCharPos); 183 if (placeholderPos == -1) { 184 placeholderPos = mFormat.length(); 185 } 186 187 mStringBuilder.append(mFormat, mNextFormatCharPos, placeholderPos); 188 mNextFormatCharPos = placeholderPos; 189 } 190 } 191 192 private LogMessage makeLogMessage(int logLevel, String format) { 193 // TODO(b/30737821): Consider adding an isLoggable() check. 194 return new RealLogMessage(logLevel, mTag, format); 195 } 196} 197