1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.net.impl; 6 7 import android.content.Context; 8 import android.os.Build; 9 import android.util.Log; // TODO(crbug/1394709): use org.chromium.base.Log instead 10 11 import androidx.annotation.Nullable; 12 import androidx.annotation.VisibleForTesting; 13 14 import org.chromium.net.impl.CronetLogger.CronetSource; 15 import org.chromium.net.telemetry.CronetLoggerImpl; 16 17 /** Takes care of instantiating the correct CronetLogger. */ 18 public final class CronetLoggerFactory { 19 private static final String TAG = CronetLoggerFactory.class.getSimpleName(); 20 private static final int SAMPLE_RATE_PER_SECOND = 1; 21 CronetLoggerFactory()22 private CronetLoggerFactory() {} 23 24 private static final CronetLogger sDefaultLogger = new NoOpLogger(); 25 private static CronetLogger sTestingLogger; 26 27 /** 28 * Bypasses CronetLoggerFactory logic and always creates a NoOpLogger. 29 * To be used only as a kill-switch for logging. 30 * @return a NoOpLogger instance. 31 */ createNoOpLogger()32 public static CronetLogger createNoOpLogger() { 33 return sDefaultLogger; 34 } 35 36 /** @return The correct CronetLogger to be used for logging. */ createLogger(Context ctx, CronetSource source)37 public static CronetLogger createLogger(Context ctx, CronetSource source) { 38 if (sTestingLogger != null) return sTestingLogger; 39 40 // The CronetLoggerImpl only works from apiLevel 30 41 if (!CronetManifest.isAppOptedInForTelemetry(ctx, source) 42 || Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { 43 return sDefaultLogger; 44 } 45 46 try { 47 return new CronetLoggerImpl(SAMPLE_RATE_PER_SECOND); 48 } catch (Exception e) { 49 // Pass - since we dont want any failure, catch any exception that might arise. 50 Log.e(TAG, "Exception creating an instance of CronetLoggerImpl", e); 51 } 52 return sDefaultLogger; 53 } 54 55 @VisibleForTesting setLoggerForTesting(@ullable CronetLogger testingLogger)56 public static void setLoggerForTesting(@Nullable CronetLogger testingLogger) { 57 sTestingLogger = testingLogger; 58 } 59 60 /** 61 * Utility class to safely use a custom CronetLogger for the duration of a test. 62 * To be used within a try-with-resources statement within the test. 63 */ 64 public static class SwapLoggerForTesting implements AutoCloseable { 65 /** 66 * Forces {@code CronetLoggerFactory#createLogger} to return @param testLogger instead of 67 * what it would have normally returned. 68 */ SwapLoggerForTesting(CronetLogger testLogger)69 public SwapLoggerForTesting(CronetLogger testLogger) { 70 CronetLoggerFactory.setLoggerForTesting(testLogger); 71 } 72 73 /** Restores CronetLoggerFactory to its original state. */ 74 @Override close()75 public void close() { 76 CronetLoggerFactory.setLoggerForTesting(null); 77 } 78 } 79 } 80