1 // Copyright 2020 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.base.metrics; 6 7 /** Holds the {@link CachingUmaRecorder} used by {@link RecordHistogram}. */ 8 public class UmaRecorderHolder { UmaRecorderHolder()9 private UmaRecorderHolder() {} 10 11 /** The instance held by this class. */ 12 private static CachingUmaRecorder sRecorder = new CachingUmaRecorder(); 13 14 /** Set up native UMA Recorder */ 15 private static boolean sSetUpNativeUmaRecorder = true; 16 17 /** Whether onLibraryLoaded() was called. */ 18 private static boolean sNativeInitialized; 19 20 /** Returns the held {@link UmaRecorder}. */ get()21 public static UmaRecorder get() { 22 return sRecorder; 23 } 24 25 /** 26 * Set a new {@link UmaRecorder} delegate for the {@link CachingUmaRecorder}. 27 * Returns after the cache has been flushed to the new delegate. 28 * <p> 29 * It should be used in processes that don't or haven't loaded native yet. This should never 30 * be called after calling {@link #onLibraryLoaded()}. 31 * 32 * @param recorder the new UmaRecorder that metrics will be forwarded to. 33 */ setNonNativeDelegate(UmaRecorder recorder)34 public static void setNonNativeDelegate(UmaRecorder recorder) { 35 UmaRecorder previous = sRecorder.setDelegate(recorder); 36 assert !(previous instanceof NativeUmaRecorder) 37 : "A NativeUmaRecorder has already been set"; 38 } 39 40 /** 41 * Whether a native UMA Recorder should be set up. 42 * @param setUpNativeUmaRecorder indicates whether a native UMA recorder should be set up. 43 * Defaults to true if unset. 44 */ setUpNativeUmaRecorder(boolean setUpNativeUmaRecorder)45 public static void setUpNativeUmaRecorder(boolean setUpNativeUmaRecorder) { 46 sSetUpNativeUmaRecorder = setUpNativeUmaRecorder; 47 } 48 49 /** 50 * Starts forwarding metrics to the native code. Returns after the cache has been flushed. 51 */ onLibraryLoaded()52 public static void onLibraryLoaded() { 53 if (!sSetUpNativeUmaRecorder) return; 54 55 assert !sNativeInitialized; 56 sNativeInitialized = true; 57 sRecorder.setDelegate(new NativeUmaRecorder()); 58 } 59 60 /** 61 * Reset globals for tests. 62 */ resetForTesting()63 public static void resetForTesting() { 64 // Prevent hitting cache size limits from tests running without ever switching to the native 65 // recorder. Also guards against tests that use setNonNativeDelegate() to inject a mock from 66 // forgetting to reset it. 67 if (!sNativeInitialized) { 68 sRecorder = new CachingUmaRecorder(); 69 } 70 } 71 } 72