1 /* 2 * Copyright 2022 Google LLC 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 package com.google.android.libraries.mobiledatadownload.internal.logging; 17 18 import android.annotation.SuppressLint; 19 import android.util.Log; 20 import com.google.errorprone.annotations.CanIgnoreReturnValue; 21 import com.google.errorprone.annotations.FormatMethod; 22 import com.google.errorprone.annotations.FormatString; 23 import java.util.Locale; 24 import java.util.Random; 25 import javax.annotation.Nullable; 26 27 /** Utility class for logging with the "MDD" tag. */ 28 public class LogUtil { 29 public static final String TAG = "MDD"; 30 31 private static final Random random = new Random(); 32 33 @CanIgnoreReturnValue // pushed down from class to method; see <internal> getLogPriority()34 public static int getLogPriority() { 35 int level = Log.ASSERT; 36 while (level > Log.VERBOSE) { 37 if (!Log.isLoggable(TAG, level - 1)) { 38 break; 39 } 40 level--; 41 } 42 return level; 43 } 44 45 @CanIgnoreReturnValue // pushed down from class to method; see <internal> v(String msg)46 public static int v(String msg) { 47 if (Log.isLoggable(TAG, Log.VERBOSE)) { 48 return Log.v(TAG, msg); 49 } 50 return 0; 51 } 52 53 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 54 @FormatMethod v(@ormatString String format, Object obj0)55 public static int v(@FormatString String format, Object obj0) { 56 if (Log.isLoggable(TAG, Log.VERBOSE)) { 57 String msg = format(format, obj0); 58 return Log.v(TAG, msg); 59 } 60 return 0; 61 } 62 63 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 64 @FormatMethod v(@ormatString String format, Object obj0, Object obj1)65 public static int v(@FormatString String format, Object obj0, Object obj1) { 66 if (Log.isLoggable(TAG, Log.VERBOSE)) { 67 String msg = format(format, obj0, obj1); 68 return Log.v(TAG, msg); 69 } 70 return 0; 71 } 72 73 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 74 @FormatMethod v(@ormatString String format, Object... params)75 public static int v(@FormatString String format, Object... params) { 76 if (Log.isLoggable(TAG, Log.VERBOSE)) { 77 String msg = format(format, params); 78 return Log.v(TAG, msg); 79 } 80 return 0; 81 } 82 83 @CanIgnoreReturnValue // pushed down from class to method; see <internal> d(String msg)84 public static int d(String msg) { 85 if (Log.isLoggable(TAG, Log.DEBUG)) { 86 return Log.d(TAG, msg); 87 } 88 return 0; 89 } 90 91 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 92 @FormatMethod d(@ormatString String format, Object obj0)93 public static int d(@FormatString String format, Object obj0) { 94 if (Log.isLoggable(TAG, Log.DEBUG)) { 95 String msg = format(format, obj0); 96 return Log.d(TAG, msg); 97 } 98 return 0; 99 } 100 101 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 102 @FormatMethod d(@ormatString String format, Object obj0, Object obj1)103 public static int d(@FormatString String format, Object obj0, Object obj1) { 104 if (Log.isLoggable(TAG, Log.DEBUG)) { 105 String msg = format(format, obj0, obj1); 106 return Log.d(TAG, msg); 107 } 108 return 0; 109 } 110 111 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 112 @FormatMethod d(@ormatString String format, Object... params)113 public static int d(@FormatString String format, Object... params) { 114 if (Log.isLoggable(TAG, Log.DEBUG)) { 115 String msg = format(format, params); 116 return Log.d(TAG, msg); 117 } 118 return 0; 119 } 120 121 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 122 @FormatMethod d(@ullable Throwable tr, @FormatString String format, Object... params)123 public static int d(@Nullable Throwable tr, @FormatString String format, Object... params) { 124 if (Log.isLoggable(TAG, Log.DEBUG)) { 125 String msg = format(format, params); 126 return Log.d(TAG, msg, tr); 127 } 128 return 0; 129 } 130 131 @CanIgnoreReturnValue // pushed down from class to method; see <internal> i(String msg)132 public static int i(String msg) { 133 if (Log.isLoggable(TAG, Log.INFO)) { 134 return Log.i(TAG, msg); 135 } 136 return 0; 137 } 138 139 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 140 @FormatMethod i(@ormatString String format, Object obj0)141 public static int i(@FormatString String format, Object obj0) { 142 if (Log.isLoggable(TAG, Log.INFO)) { 143 String msg = format(format, obj0); 144 return Log.i(TAG, msg); 145 } 146 return 0; 147 } 148 149 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 150 @FormatMethod i(@ormatString String format, Object obj0, Object obj1)151 public static int i(@FormatString String format, Object obj0, Object obj1) { 152 if (Log.isLoggable(TAG, Log.INFO)) { 153 String msg = format(format, obj0, obj1); 154 return Log.i(TAG, msg); 155 } 156 return 0; 157 } 158 159 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 160 @FormatMethod i(@ormatString String format, Object... params)161 public static int i(@FormatString String format, Object... params) { 162 if (Log.isLoggable(TAG, Log.INFO)) { 163 String msg = format(format, params); 164 return Log.i(TAG, msg); 165 } 166 return 0; 167 } 168 169 @CanIgnoreReturnValue // pushed down from class to method; see <internal> e(String msg)170 public static int e(String msg) { 171 if (Log.isLoggable(TAG, Log.ERROR)) { 172 return Log.e(TAG, msg); 173 } 174 return 0; 175 } 176 177 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 178 @FormatMethod e(@ormatString String format, Object obj0)179 public static int e(@FormatString String format, Object obj0) { 180 if (Log.isLoggable(TAG, Log.ERROR)) { 181 String msg = format(format, obj0); 182 return Log.e(TAG, msg); 183 } 184 return 0; 185 } 186 187 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 188 @FormatMethod e(@ormatString String format, Object obj0, Object obj1)189 public static int e(@FormatString String format, Object obj0, Object obj1) { 190 if (Log.isLoggable(TAG, Log.ERROR)) { 191 String msg = format(format, obj0, obj1); 192 return Log.e(TAG, msg); 193 } 194 return 0; 195 } 196 197 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 198 @FormatMethod e(@ormatString String format, Object... params)199 public static int e(@FormatString String format, Object... params) { 200 if (Log.isLoggable(TAG, Log.ERROR)) { 201 String msg = format(format, params); 202 return Log.e(TAG, msg); 203 } 204 return 0; 205 } 206 207 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 208 @SuppressLint("LogTagMismatch") e(@ullable Throwable tr, String msg)209 public static int e(@Nullable Throwable tr, String msg) { 210 if (Log.isLoggable(TAG, Log.ERROR)) { 211 if (Log.isLoggable(TAG, Log.DEBUG)) { 212 return Log.e(TAG, msg, tr); 213 } else { 214 // If not DEBUG level, only print the throwable type and message. 215 msg = msg + ": " + tr; 216 return Log.e(TAG, msg); 217 } 218 } 219 return 0; 220 } 221 222 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 223 @FormatMethod e(@ullable Throwable tr, @FormatString String format, Object... params)224 public static int e(@Nullable Throwable tr, @FormatString String format, Object... params) { 225 return Log.isLoggable(TAG, Log.ERROR) ? e(tr, format(format, params)) : 0; 226 } 227 228 @CanIgnoreReturnValue // pushed down from class to method; see <internal> w(String msg)229 public static int w(String msg) { 230 if (Log.isLoggable(TAG, Log.WARN)) { 231 return Log.w(TAG, msg); 232 } 233 return 0; 234 } 235 236 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 237 @FormatMethod w(@ormatString String format, Object obj0)238 public static int w(@FormatString String format, Object obj0) { 239 if (Log.isLoggable(TAG, Log.WARN)) { 240 String msg = format(format, obj0); 241 return Log.w(TAG, msg); 242 } 243 return 0; 244 } 245 246 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 247 @FormatMethod w(@ormatString String format, Object obj0, Object obj1)248 public static int w(@FormatString String format, Object obj0, Object obj1) { 249 if (Log.isLoggable(TAG, Log.WARN)) { 250 String msg = format(format, obj0, obj1); 251 return Log.w(TAG, msg); 252 } 253 return 0; 254 } 255 256 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 257 @FormatMethod w(@ormatString String format, Object... params)258 public static int w(@FormatString String format, Object... params) { 259 if (Log.isLoggable(TAG, Log.WARN)) { 260 String msg = format(format, params); 261 return Log.w(TAG, msg); 262 } 263 return 0; 264 } 265 266 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 267 @SuppressLint("LogTagMismatch") 268 @FormatMethod w(@ullable Throwable tr, @FormatString String format, Object... params)269 public static int w(@Nullable Throwable tr, @FormatString String format, Object... params) { 270 if (Log.isLoggable(TAG, Log.WARN)) { 271 if (Log.isLoggable(TAG, Log.DEBUG)) { 272 String msg = format(format, params); 273 return Log.w(TAG, msg, tr); 274 } else { 275 // If not DEBUG level, only print the throwable type and message. 276 String msg = format(format, params) + ": " + tr; 277 return Log.w(TAG, msg); 278 } 279 } 280 return 0; 281 } 282 283 @CanIgnoreReturnValue // pushed down from class to method; see <internal> 284 @FormatMethod format(@ormatString String format, Object... args)285 private static String format(@FormatString String format, Object... args) { 286 return String.format(Locale.US, format, args); 287 } 288 289 @CanIgnoreReturnValue // pushed down from class to method; see <internal> shouldSampleInterval(long sampleInterval)290 public static boolean shouldSampleInterval(long sampleInterval) { 291 if (sampleInterval <= 0L) { 292 if (sampleInterval < 0L) { 293 LogUtil.e("Bad sample interval: %d", sampleInterval); 294 } 295 return false; 296 } else { 297 return (random.nextLong() % sampleInterval) == 0; 298 } 299 } 300 LogUtil()301 private LogUtil() {} 302 } 303