1f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom/* 2f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * Copyright (C) 2010 The Android Open Source Project 3f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 4f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * you may not use this file except in compliance with the License. 6f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * You may obtain a copy of the License at 7f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 8f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 10f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 11f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * See the License for the specific language governing permissions and 14f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * limitations under the License. 15f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 16f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 17f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrompackage dalvik.system; 18f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 19f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom/** 202353846b64570fa5932028143a0af507d41a85c5Jesse Wilson * CloseGuard is a mechanism for flagging implicit finalizer cleanup of 21f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * resources that should have been cleaned up by explicit close 22f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * methods (aka "explicit termination methods" in Effective Java). 23f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * <p> 24f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * A simple example: <pre> {@code 25f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * class Foo { 26f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 2712f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * private final CloseGuard guard = CloseGuard.get(); 28f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 29f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * ... 30f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 3112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * public Foo() { 3212f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * ...; 3312f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * guard.open("cleanup"); 3412f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * } 3512f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * 36f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * public void cleanup() { 37f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * guard.close(); 38f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * ...; 39f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 40f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 4112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * protected void finalize() throws Throwable { 42f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * try { 4312f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * if (guard != null) { 4412f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * guard.warnIfOpen(); 4512f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * } 46f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * cleanup(); 47f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } finally { 48f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * super.finalize(); 49f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 50f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 51f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 52f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * }</pre> 53f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 542353846b64570fa5932028143a0af507d41a85c5Jesse Wilson * In usage where the resource to be explicitly cleaned up are 551292ca6a89af2492f9c1f52f7d4a555c75462482Brian Carlstrom * allocated after object construction, CloseGuard protection can 56f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * be deferred. For example: <pre> {@code 57f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * class Bar { 58f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 591292ca6a89af2492f9c1f52f7d4a555c75462482Brian Carlstrom * private final CloseGuard guard = CloseGuard.get(); 60f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 61f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * ... 62f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 6312f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * public Bar() { 6412f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * ...; 6512f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * } 6612f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * 67f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * public void connect() { 68f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * ...; 6912f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * guard.open("cleanup"); 70f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 71f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 72f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * public void cleanup() { 73f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * guard.close(); 74f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * ...; 75f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 76f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 7712f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * protected void finalize() throws Throwable { 78f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * try { 7912f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * if (guard != null) { 8012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * guard.warnIfOpen(); 8112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * } 82f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * cleanup(); 83f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } finally { 84f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * super.finalize(); 85f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 86f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 87f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * } 88f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * }</pre> 89f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 9012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * When used in a constructor calls to {@code open} should occur at 9112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * the end of the constructor since an exception that would cause 9212f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * abrupt termination of the constructor will mean that the user will 9312f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * not have a reference to the object to cleanup explicitly. When used 9412f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * in a method, the call to {@code open} should occur just after 9512f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * resource acquisition. 9612f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * 9712f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * <p> 9812f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * 9912f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * Note that the null check on {@code guard} in the finalizer is to 10012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * cover cases where a constructor throws an exception causing the 10112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * {@code guard} to be uninitialized. 10212f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * 103f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * @hide 104f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 105f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrompublic final class CloseGuard { 106f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 107f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom /** 108f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * Instance used when CloseGuard is disabled to avoid allocation. 109f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 110f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom private static final CloseGuard NOOP = new CloseGuard(); 111f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 112f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom /** 1134bfc26e99c8044a1d690003d4bb3d75348124f57Brad Fitzpatrick * Enabled by default so we can catch issues early in VM startup. 1144bfc26e99c8044a1d690003d4bb3d75348124f57Brad Fitzpatrick * Note, however, that Android disables this early in its startup, 1154bfc26e99c8044a1d690003d4bb3d75348124f57Brad Fitzpatrick * but enables it with DropBoxing for system apps on debug builds. 116b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom */ 1174bfc26e99c8044a1d690003d4bb3d75348124f57Brad Fitzpatrick private static volatile boolean ENABLED = true; 118b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom 119b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom /** 120f7ee236589ca1fe73615c4dc8a536ffe29a236ffBrian Carlstrom * Hook for customizing how CloseGuard issues are reported. 121b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom */ 1224bfc26e99c8044a1d690003d4bb3d75348124f57Brad Fitzpatrick private static volatile Reporter REPORTER = new DefaultReporter(); 123b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom 124b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom /** 12512f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * Returns a CloseGuard instance. If CloseGuard is enabled, {@code 12612f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * #open(String)} can be used to set up the instance to warn on 12712f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom * failure to close. If CloseGuard is disabled, a non-null no-op 1282353846b64570fa5932028143a0af507d41a85c5Jesse Wilson * instance is returned. 129f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 13012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom public static CloseGuard get() { 131b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom if (!ENABLED) { 132f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom return NOOP; 133f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 134f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom return new CloseGuard(); 135f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 136f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 137b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom /** 138b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom * Used to enable or disable CloseGuard. Note that CloseGuard only 139b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom * warns if it is enabled for both allocation and finalization. 140b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom */ 141b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom public static void setEnabled(boolean enabled) { 142b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom ENABLED = enabled; 143f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 144f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 145b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom /** 146b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom * Used to replace default Reporter used to warn of CloseGuard 147b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom * violations. Must be non-null. 148b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom */ 149b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom public static void setReporter(Reporter reporter) { 150b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom if (reporter == null) { 151b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom throw new NullPointerException("reporter == null"); 152b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom } 153b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom REPORTER = reporter; 154b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom } 155b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom 156b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom /** 157b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom * Returns non-null CloseGuard.Reporter. 158b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom */ 159b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom public static Reporter getReporter() { 160b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom return REPORTER; 161b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom } 162b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom 163f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom private CloseGuard() {} 164f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 165f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom /** 166f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * If CloseGuard is enabled, {@code open} initializes the instance 1672353846b64570fa5932028143a0af507d41a85c5Jesse Wilson * with a warning that the caller should have explicitly called the 168f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * {@code closer} method instead of relying on finalization. 169f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * 1702353846b64570fa5932028143a0af507d41a85c5Jesse Wilson * @param closer non-null name of explicit termination method 171f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * @throws NullPointerException if closer is null, regardless of 172f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * whether or not CloseGuard is enabled 173f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 174f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom public void open(String closer) { 175f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // always perform the check for valid API usage... 176f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (closer == null) { 177f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom throw new NullPointerException("closer == null"); 178f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 179f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // ...but avoid allocating an allocationSite if disabled 180b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom if (this == NOOP || !ENABLED) { 181f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom return; 182f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 183f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom String message = "Explicit termination method '" + closer + "' not called"; 184f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom allocationSite = new Throwable(message); 185f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 186f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 187f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom private Throwable allocationSite; 188f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 189f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom /** 190f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * Marks this CloseGuard instance as closed to avoid warnings on 191f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * finalization. 192f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 193f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom public void close() { 194f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom allocationSite = null; 195f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 196f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 197f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom /** 198f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * If CloseGuard is enabled, logs a warning if the caller did not 199f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * properly cleanup by calling an explicit close method 2008155888a2c4e7cc28596deec28433e1984cfaf11Brian Carlstrom * before finalization. If CloseGuard is disabled, no action is 201f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom * performed. 202f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 203f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom public void warnIfOpen() { 204b3f32d4d15177a0d2c064a8116d5cf5d07a217a9Brian Carlstrom if (allocationSite == null || !ENABLED) { 205f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom return; 206f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 207f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 208f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom String message = 209f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom ("A resource was acquired at attached stack trace but never released. " 210f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom + "See java.io.Closeable for information on avoiding resource leaks."); 211f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 212b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom REPORTER.report(message, allocationSite); 213b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom } 214b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom 215b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom /** 216b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom * Interface to allow customization of reporting behavior. 217b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom */ 218b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom public static interface Reporter { 219b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom public void report (String message, Throwable allocationSite); 220b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom } 221b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom 222b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom /** 223a7ef55258ac71153487357b861c7639d627df82fElliott Hughes * Default Reporter which reports CloseGuard violations to the log. 224b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom */ 225b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom private static final class DefaultReporter implements Reporter { 2268155888a2c4e7cc28596deec28433e1984cfaf11Brian Carlstrom @Override public void report (String message, Throwable allocationSite) { 227a7ef55258ac71153487357b861c7639d627df82fElliott Hughes System.logW(message, allocationSite); 228b81e1d9da6a4b039ffa55618fcccb013d3116261Brian Carlstrom } 229f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 230f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom} 231