1 /* 2 * Copyright (C) 2017 The Android Open Source Project 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 17 package com.android.systemui.util.leak; 18 19 import java.util.Collection; 20 import java.util.WeakHashMap; 21 22 /** 23 * Tracks instances of classes. 24 */ 25 public class TrackedObjects { 26 27 private final TrackedCollections mTrackedCollections; 28 private final WeakHashMap<Class<?>, TrackedClass<?>> mTrackedClasses = new WeakHashMap<>(); 29 TrackedObjects(TrackedCollections trackedCollections)30 public TrackedObjects(TrackedCollections trackedCollections) { 31 mTrackedCollections = trackedCollections; 32 } 33 34 /** 35 * @see LeakDetector#trackInstance(Object) 36 */ track(T object)37 public synchronized <T> void track(T object) { 38 Class<?> clazz = object.getClass(); 39 @SuppressWarnings("unchecked") 40 TrackedClass<T> trackedClass = (TrackedClass<T>) mTrackedClasses.get(clazz); 41 42 if (trackedClass == null) { 43 trackedClass = new TrackedClass<T>(); 44 mTrackedClasses.put(clazz, trackedClass); 45 } 46 47 trackedClass.track(object); 48 mTrackedCollections.track(trackedClass, clazz.getName()); 49 } 50 isTrackedObject(Collection<?> collection)51 public static boolean isTrackedObject(Collection<?> collection) { 52 return collection instanceof TrackedClass; 53 } 54 55 private static class TrackedClass<T> extends AbstractCollection<T> { 56 final WeakIdentityHashMap<T, Void> instances = new WeakIdentityHashMap<>(); 57 track(T object)58 void track(T object) { 59 instances.put(object, null); 60 } 61 62 @Override size()63 public int size() { 64 return instances.size(); 65 } 66 67 @Override isEmpty()68 public boolean isEmpty() { 69 return instances.isEmpty(); 70 } 71 72 } 73 74 } 75