blob: ffe89505ead68d777a4dbed4855e7512e7a02f03 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import android.util.Log;
import com.android.internal.annotations.Immutable;
import javax.annotation.concurrent.ThreadSafe;
/**
* Provides a WifiLog implementation which uses logd as the
* logging backend.
*
* This class is trivially thread-safe, as instances are immutable.
* Note, however, that LogMessage instances are _not_ thread-safe.
*/
@ThreadSafe
@Immutable
class LogcatLog implements WifiLog {
private final String mTag;
private static volatile boolean sVerboseLogging = false;
LogcatLog(String tag) {
mTag = tag;
}
public static void enableVerboseLogging(int verboseMode) {
if (verboseMode > 0) {
sVerboseLogging = true;
} else {
sVerboseLogging = false;
}
}
/* New-style methods */
@Override
public LogMessage err(String format) {
return makeLogMessage(Log.ERROR, format);
}
@Override
public LogMessage warn(String format) {
return makeLogMessage(Log.WARN, format);
}
@Override
public LogMessage info(String format) {
return makeLogMessage(Log.INFO, format);
}
@Override
public LogMessage trace(String format) {
return makeLogMessage(Log.DEBUG, format);
}
@Override
public LogMessage dump(String format) {
return makeLogMessage(Log.VERBOSE, format);
}
@Override
public void eC(String msg) {
Log.e(mTag, msg);
}
@Override
public void wC(String msg) {
Log.w(mTag, msg);
}
@Override
public void iC(String msg) {
Log.i(mTag, msg);
}
@Override
public void tC(String msg) {
Log.d(mTag, msg);
}
/* Legacy methods */
@Override
public void e(String msg) {
Log.e(mTag, msg);
}
@Override
public void w(String msg) {
Log.w(mTag, msg);
}
@Override
public void i(String msg) {
Log.i(mTag, msg);
}
@Override
public void d(String msg) {
Log.d(mTag, msg);
}
@Override
public void v(String msg) {
Log.v(mTag, msg);
}
/* Internal details */
private static class RealLogMessage implements WifiLog.LogMessage {
private final int mLogLevel;
private final String mTag;
private final String mFormat;
private final StringBuilder mStringBuilder;
private int mNextFormatCharPos;
RealLogMessage(int logLevel, String tag, String format) {
mLogLevel = logLevel;
mTag = tag;
mFormat = format;
mStringBuilder = new StringBuilder();
mNextFormatCharPos = 0;
}
@Override
public WifiLog.LogMessage r(String value) {
// Since the logcat back-end is just transitional, we don't attempt to tag sensitive
// information in it.
return c(value);
}
@Override
public WifiLog.LogMessage c(String value) {
copyUntilPlaceholder();
if (mNextFormatCharPos < mFormat.length()) {
mStringBuilder.append(value);
++mNextFormatCharPos;
}
return this;
}
@Override
public WifiLog.LogMessage c(long value) {
copyUntilPlaceholder();
if (mNextFormatCharPos < mFormat.length()) {
mStringBuilder.append(value);
++mNextFormatCharPos;
}
return this;
}
@Override
public WifiLog.LogMessage c(char value) {
copyUntilPlaceholder();
if (mNextFormatCharPos < mFormat.length()) {
mStringBuilder.append(value);
++mNextFormatCharPos;
}
return this;
}
@Override
public WifiLog.LogMessage c(boolean value) {
copyUntilPlaceholder();
if (mNextFormatCharPos < mFormat.length()) {
mStringBuilder.append(value);
++mNextFormatCharPos;
}
return this;
}
@Override
public void flush() {
if (mNextFormatCharPos < mFormat.length()) {
mStringBuilder.append(mFormat, mNextFormatCharPos, mFormat.length());
}
if (sVerboseLogging || mLogLevel > Log.DEBUG) {
Log.println(mLogLevel, mTag, mStringBuilder.toString());
}
}
/* Should generally not be used; implemented primarily to aid in testing. */
public String toString() {
return mStringBuilder.toString();
}
private void copyUntilPlaceholder() {
if (mNextFormatCharPos >= mFormat.length()) {
return;
}
int placeholderPos = mFormat.indexOf(WifiLog.PLACEHOLDER, mNextFormatCharPos);
if (placeholderPos == -1) {
placeholderPos = mFormat.length();
}
mStringBuilder.append(mFormat, mNextFormatCharPos, placeholderPos);
mNextFormatCharPos = placeholderPos;
}
}
private LogMessage makeLogMessage(int logLevel, String format) {
// TODO(b/30737821): Consider adding an isLoggable() check.
return new RealLogMessage(logLevel, mTag, format);
}
}