Home | History | Annotate | Download | only in wifi
      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 
     17 package com.android.server.wifi;
     18 
     19 import android.annotation.NonNull;
     20 
     21 import com.google.errorprone.annotations.CompileTimeConstant;
     22 
     23 import javax.annotation.CheckReturnValue;
     24 
     25 /**
     26  * Provides an abstraction of logging back-ends.
     27  *
     28  * The abstraction is designed to
     29  * a) minimize the cost of disabled log messages,
     30  * b) allow callers to tag message parameters as containing sensitive
     31  *    information,
     32  * c) avoid the use of format codes, and
     33  * d) easily support additional data types.
     34  *
     35  * Implementations of WifiLog may or may not be thread-safe.
     36  * Implementations of LogMessage are expected _not_ to be thread-safe,
     37  * as LogMessage instances are not expected to be shared between threads.
     38  */
     39 @SuppressWarnings("NonFinalCompileTimeConstant")  // See below.
     40 public interface WifiLog {
     41     // Explanation of SuppressWarnings above:
     42     //
     43     // We use @CompileTimeConstant to verify that our callers do not stringify
     44     // arguments into the |format| parameter. And, by default, error-prone
     45     // requires that CompileTimeConstant parameters are declared final.
     46     //
     47     // However, declaring an interface parameter as final has no effect, since
     48     // classes implementing the interface are free to declare their parameters
     49     // as non-final. Moreover, to avoid such confusing situations (interface says
     50     // final, implementation does not), checkstyle rejects |final| qualification
     51     // of method parameters in interface methods.
     52     //
     53     // To avoid making empty promises. we override error-prone's default behavior,
     54     // and allow the CompileTimeConstant parameters to be non-final.
     55 
     56     char PLACEHOLDER = '%';
     57 
     58     // New-style API.
     59     /**
     60      * Allocate an error-level log message, which the caller will fill with
     61      * additional parameters according to |format|. After filling the message
     62      * with parameters, the caller must call flush(), to actually log the message.
     63      *
     64      * Error-level messages should be used when a malfunction has occurred,
     65      * and the malfunction is likely to cause an externally visible problem.
     66      * For example: we failed to initialize the Wifi interface.
     67      *
     68      * Typical usage is as follows:
     69      *     WifiDevice() {
     70      *         mLog = new LogcatLog("ModuleName");
     71      *     }
     72      *
     73      *     void start() {
     74      *         // ...
     75      *         mLog.err("error % while starting interface %").c(errNum).c(ifaceName).flush();
     76      *     }
     77      *
     78      *     void stop() {
     79      *         // ...
     80      *         mLog.err("error % while stopping interface %").c(errNum).c(ifaceName).flush();
     81      *     }
     82      */
     83     @CheckReturnValue
     84     @NonNull
     85     LogMessage err(@CompileTimeConstant @NonNull String format);
     86 
     87     /**
     88      * Like {@link #err(String) err()}, except that a warning-level message is
     89      * allocated.
     90      *
     91      * Warning-level messages should be used when a malfunction has occurred,
     92      * but the malfunction is _unlikely_ to cause an externally visible problem
     93      * on its own. For example: if we fail to start the debugging subsystem.
     94      */
     95     @CheckReturnValue
     96     @NonNull
     97     LogMessage warn(@CompileTimeConstant @NonNull String format);
     98 
     99     /**
    100      * Like {@link #err(String) err()}, except that a info-level message is
    101      * allocated.
    102      *
    103      * Info-level messages should be used to report progress or status messages
    104      * that help understand the program's external behavior. For example: we
    105      * might log an info message before initiating a Wifi association.
    106      */
    107     @CheckReturnValue
    108     @NonNull
    109     LogMessage info(@CompileTimeConstant @NonNull String format);
    110 
    111     /**
    112      * Like {@link #err(String) err()}, except:
    113      * - a trace-level message is allocated
    114      * - the log message is prefixed with the caller's name
    115      *
    116      * Trace-level messages should be used to report progress or status messages
    117      * that help understand the program's internal behavior. For example:
    118      * "invoked with verbose=%".
    119      */
    120     @CheckReturnValue
    121     @NonNull
    122     LogMessage trace(@CompileTimeConstant @NonNull String format);
    123 
    124     /**
    125      * Like {@link #trace(String) trace(String)}, except that, rather than logging
    126      * the immediate caller, the |numFramesToIgnore + 1|-th caller will be logged.
    127      *
    128      * E.g. if numFramesToIgnore == 1, then the caller's caller will be logged.
    129      *
    130      * Trace-level messages should be used to report progress or status messages
    131      * that help understand the program's internal behavior. For example:
    132      * "invoked with verbose=%".
    133      */
    134     @CheckReturnValue
    135     @NonNull
    136     LogMessage trace(@NonNull String format, int numFramesToIgnore);
    137 
    138     /**
    139      * Like {@link #err(String) err()}, except that a dump-level message is
    140      * allocated.
    141      *
    142      * Dump-level messages should be used to report detailed internal state.
    143      */
    144     @CheckReturnValue
    145     @NonNull
    146     LogMessage dump(@CompileTimeConstant @NonNull String format);
    147 
    148     /**
    149      * Log a warning using the default tag for this WifiLog instance. Mark
    150      * the message as 'clean' (i.e. _not_ containing any sensitive data).
    151      *
    152      * NOTE: this method should only be used for literal strings. For messages with
    153      * parameters, use err().
    154      *
    155      * @param msg the message to be logged
    156      */
    157     void eC(@CompileTimeConstant String msg);
    158 
    159     /**
    160      * Like {@link #eC(String)} eC()}, except that a warning-level message
    161      * is logged.
    162      */
    163     void wC(@CompileTimeConstant String msg);
    164 
    165     /**
    166      * Like {@link #eC(String)} eC()}, except that an info-level message
    167      * is logged.
    168      */
    169     void iC(@CompileTimeConstant String msg);
    170 
    171     /**
    172      * Like {@link #eC(String)} eC()}, except that a trace-level message
    173      * is logged.
    174      */
    175     void tC(@CompileTimeConstant String msg);
    176 
    177     /**
    178      * Note: dC() is deliberately omitted, as "dumping" is inherently at
    179      * odds with the intention that the caller pass in a literal string.
    180      */
    181 
    182     /**
    183      * Represents a single log message.
    184      *
    185      * Implementations are expected _not_ to be thread-safe.
    186      */
    187     interface LogMessage {
    188         /**
    189          * Replace the first available placeholder in this LogMessage's format
    190          * with the specified value. Mark the value as 'raw', to inform the
    191          * logging daemon that the value may contain sensitive data.
    192          *
    193          * @return |this|, to allow chaining of calls
    194          */
    195         @CheckReturnValue
    196         @NonNull
    197         LogMessage r(String value);
    198 
    199         /**
    200          * Like {@link #r(String) r()}, except that the value is marked
    201          * as 'clean', to inform the logging daemon that the value does _not_
    202          * contain sensitive data.
    203          */
    204         @CheckReturnValue
    205         @NonNull
    206         LogMessage c(String value);
    207 
    208         /**
    209          * Like {@link #c(String) c(String)}, except that the value is a long.
    210          */
    211         @CheckReturnValue
    212         @NonNull
    213         LogMessage c(long value);
    214 
    215         /**
    216          * Like {@link #c(String) c(String)}, except that the value is a char.
    217          */
    218         @CheckReturnValue
    219         @NonNull
    220         LogMessage c(char value);
    221 
    222         /**
    223          * Like {@link #c(String) c(String)}, except that the value is a boolean.
    224          */
    225         @CheckReturnValue
    226         @NonNull
    227         LogMessage c(boolean value);
    228 
    229         /**
    230          * Write this LogMessage to the logging daemon. Writing the
    231          * message is best effort. More specifically:
    232          * 1) The operation is non-blocking. If were unable to write
    233          *    the log message to the IPC channel, the message is
    234          *    dropped silently.
    235          * 2) If the number of |value|s provided exceeds the number of
    236          *    placeholders in the |format|, then extraneous |value|s
    237          *    are silently dropped.
    238          * 3) If the number of placeholders in the |format| exceeds
    239          *    the number of |value|s provided, the message is sent to
    240          *    the logging daemon without generating an Exception.
    241          * 4) If the total message length exceeds the logging
    242          *    protocols maximum message length, the message is
    243          *    silently truncated.
    244          */
    245         void flush();
    246     }
    247 
    248     // Legacy API.
    249     /**
    250      * Log an error using the default tag for this WifiLog instance.
    251      * @param msg the message to be logged
    252      * TODO(b/30736737): Remove this method, once all code has migrated to alternatives.
    253      */
    254     void e(String msg);
    255 
    256     /**
    257      * Log a warning using the default tag for this WifiLog instance.
    258      * @param msg the message to be logged
    259      * TODO(b/30736737): Remove this method, once all code has migrated to alternatives.
    260      */
    261     void w(String msg);
    262 
    263     /**
    264      * Log an informational message using the default tag for this WifiLog instance.
    265      * @param msg the message to be logged
    266      * TODO(b/30736737): Remove this method, once all code has migrated to alternatives.
    267      */
    268     void i(String msg);
    269 
    270     /**
    271      * Log a debug message using the default tag for this WifiLog instance.
    272      * @param msg the message to be logged
    273      * TODO(b/30736737): Remove this method, once all code has migrated to alternatives.
    274      */
    275     void d(String msg);
    276 
    277     /**
    278      * Log a verbose message using the default tag for this WifiLog instance.
    279      * @param msg the message to be logged
    280      * TODO(b/30736737): Remove this method, once all code has migrated to alternatives.
    281      */
    282     void v(String msg);
    283 }
    284