| /* |
| * 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.annotation.NonNull; |
| |
| import com.google.errorprone.annotations.CompileTimeConstant; |
| |
| import javax.annotation.CheckReturnValue; |
| |
| /** |
| * Provides an abstraction of logging back-ends. |
| * |
| * The abstraction is designed to |
| * a) minimize the cost of disabled log messages, |
| * b) allow callers to tag message parameters as containing sensitive |
| * information, |
| * c) avoid the use of format codes, and |
| * d) easily support additional data types. |
| * |
| * Implementations of WifiLog may or may not be thread-safe. |
| * Implementations of LogMessage are expected _not_ to be thread-safe, |
| * as LogMessage instances are not expected to be shared between threads. |
| */ |
| @SuppressWarnings("NonFinalCompileTimeConstant") // See below. |
| public interface WifiLog { |
| // Explanation of SuppressWarnings above: |
| // |
| // We use @CompileTimeConstant to verify that our callers do not stringify |
| // arguments into the |format| parameter. And, by default, error-prone |
| // requires that CompileTimeConstant parameters are declared final. |
| // |
| // However, declaring an interface parameter as final has no effect, since |
| // classes implementing the interface are free to declare their parameters |
| // as non-final. Moreover, to avoid such confusing situations (interface says |
| // final, implementation does not), checkstyle rejects |final| qualification |
| // of method parameters in interface methods. |
| // |
| // To avoid making empty promises. we override error-prone's default behavior, |
| // and allow the CompileTimeConstant parameters to be non-final. |
| |
| char PLACEHOLDER = '%'; |
| |
| // New-style API. |
| /** |
| * Allocate an error-level log message, which the caller will fill with |
| * additional parameters according to |format|. After filling the message |
| * with parameters, the caller must call flush(), to actually log the message. |
| * |
| * Error-level messages should be used when a malfunction has occurred, |
| * and the malfunction is likely to cause an externally visible problem. |
| * For example: we failed to initialize the Wifi interface. |
| * |
| * Typical usage is as follows: |
| * WifiDevice() { |
| * mLog = new LogcatLog("ModuleName"); |
| * } |
| * |
| * void start() { |
| * // ... |
| * mLog.err("error % while starting interface %").c(errNum).c(ifaceName).flush(); |
| * } |
| * |
| * void stop() { |
| * // ... |
| * mLog.err("error % while stopping interface %").c(errNum).c(ifaceName).flush(); |
| * } |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage err(@CompileTimeConstant @NonNull String format); |
| |
| /** |
| * Like {@link #err(String) err()}, except that a warning-level message is |
| * allocated. |
| * |
| * Warning-level messages should be used when a malfunction has occurred, |
| * but the malfunction is _unlikely_ to cause an externally visible problem |
| * on its own. For example: if we fail to start the debugging subsystem. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage warn(@CompileTimeConstant @NonNull String format); |
| |
| /** |
| * Like {@link #err(String) err()}, except that a info-level message is |
| * allocated. |
| * |
| * Info-level messages should be used to report progress or status messages |
| * that help understand the program's external behavior. For example: we |
| * might log an info message before initiating a Wifi association. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage info(@CompileTimeConstant @NonNull String format); |
| |
| /** |
| * Like {@link #err(String) err()}, except: |
| * - a trace-level message is allocated |
| * - the log message is prefixed with the caller's name |
| * |
| * Trace-level messages should be used to report progress or status messages |
| * that help understand the program's internal behavior. For example: |
| * "invoked with verbose=%". |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage trace(@CompileTimeConstant @NonNull String format); |
| |
| /** |
| * Like {@link #trace(String) trace(String)}, except that, rather than logging |
| * the immediate caller, the |numFramesToIgnore + 1|-th caller will be logged. |
| * |
| * E.g. if numFramesToIgnore == 1, then the caller's caller will be logged. |
| * |
| * Trace-level messages should be used to report progress or status messages |
| * that help understand the program's internal behavior. For example: |
| * "invoked with verbose=%". |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage trace(@NonNull String format, int numFramesToIgnore); |
| |
| /** |
| * Like {@link #err(String) err()}, except that a dump-level message is |
| * allocated. |
| * |
| * Dump-level messages should be used to report detailed internal state. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage dump(@CompileTimeConstant @NonNull String format); |
| |
| /** |
| * Log a warning using the default tag for this WifiLog instance. Mark |
| * the message as 'clean' (i.e. _not_ containing any sensitive data). |
| * |
| * NOTE: this method should only be used for literal strings. For messages with |
| * parameters, use err(). |
| * |
| * @param msg the message to be logged |
| */ |
| void eC(@CompileTimeConstant String msg); |
| |
| /** |
| * Like {@link #eC(String)} eC()}, except that a warning-level message |
| * is logged. |
| */ |
| void wC(@CompileTimeConstant String msg); |
| |
| /** |
| * Like {@link #eC(String)} eC()}, except that an info-level message |
| * is logged. |
| */ |
| void iC(@CompileTimeConstant String msg); |
| |
| /** |
| * Like {@link #eC(String)} eC()}, except that a trace-level message |
| * is logged. |
| */ |
| void tC(@CompileTimeConstant String msg); |
| |
| /** |
| * Note: dC() is deliberately omitted, as "dumping" is inherently at |
| * odds with the intention that the caller pass in a literal string. |
| */ |
| |
| /** |
| * Represents a single log message. |
| * |
| * Implementations are expected _not_ to be thread-safe. |
| */ |
| interface LogMessage { |
| /** |
| * Replace the first available placeholder in this LogMessage's format |
| * with the specified value. Mark the value as 'raw', to inform the |
| * logging daemon that the value may contain sensitive data. |
| * |
| * @return |this|, to allow chaining of calls |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage r(String value); |
| |
| /** |
| * Like {@link #r(String) r()}, except that the value is marked |
| * as 'clean', to inform the logging daemon that the value does _not_ |
| * contain sensitive data. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage c(String value); |
| |
| /** |
| * Like {@link #c(String) c(String)}, except that the value is a long. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage c(long value); |
| |
| /** |
| * Like {@link #c(String) c(String)}, except that the value is a char. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage c(char value); |
| |
| /** |
| * Like {@link #c(String) c(String)}, except that the value is a boolean. |
| */ |
| @CheckReturnValue |
| @NonNull |
| LogMessage c(boolean value); |
| |
| /** |
| * Write this LogMessage to the logging daemon. Writing the |
| * message is best effort. More specifically: |
| * 1) The operation is non-blocking. If we’re unable to write |
| * the log message to the IPC channel, the message is |
| * dropped silently. |
| * 2) If the number of |value|s provided exceeds the number of |
| * placeholders in the |format|, then extraneous |value|s |
| * are silently dropped. |
| * 3) If the number of placeholders in the |format| exceeds |
| * the number of |value|s provided, the message is sent to |
| * the logging daemon without generating an Exception. |
| * 4) If the total message length exceeds the logging |
| * protocol’s maximum message length, the message is |
| * silently truncated. |
| */ |
| void flush(); |
| } |
| |
| // Legacy API. |
| /** |
| * Log an error using the default tag for this WifiLog instance. |
| * @param msg the message to be logged |
| * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. |
| */ |
| void e(String msg); |
| |
| /** |
| * Log a warning using the default tag for this WifiLog instance. |
| * @param msg the message to be logged |
| * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. |
| */ |
| void w(String msg); |
| |
| /** |
| * Log an informational message using the default tag for this WifiLog instance. |
| * @param msg the message to be logged |
| * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. |
| */ |
| void i(String msg); |
| |
| /** |
| * Log a debug message using the default tag for this WifiLog instance. |
| * @param msg the message to be logged |
| * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. |
| */ |
| void d(String msg); |
| |
| /** |
| * Log a verbose message using the default tag for this WifiLog instance. |
| * @param msg the message to be logged |
| * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. |
| */ |
| void v(String msg); |
| } |