• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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