Loading tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.util.LongSparseLongArray; /** * Delegate used to provide new implementation the native methods of {@link VirtualRefBasePtr} * * Through the layoutlib_create tool, the original native methods of VirtualRefBasePtr have been * replaced by calls to methods of the same name in this delegate class. * */ @SuppressWarnings("unused") public class VirtualRefBasePtr_Delegate { private static final DelegateManager<Object> sManager = new DelegateManager<>(Object.class); private static final LongSparseLongArray sRefCount = new LongSparseLongArray(); @LayoutlibDelegate /*package*/ static synchronized void nIncStrong(long ptr) { long counter = sRefCount.get(ptr); sRefCount.put(ptr, ++counter); } @LayoutlibDelegate /*package*/ static synchronized void nDecStrong(long ptr) { long counter = sRefCount.get(ptr); if (counter > 1) { sRefCount.put(ptr, --counter); } else { sRefCount.delete(ptr); sManager.removeJavaReferenceFor(ptr); } } } tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java +34 −18 Original line number Diff line number Diff line Loading @@ -22,9 +22,11 @@ import com.android.layoutlib.bridge.util.SparseWeakArray; import android.annotation.Nullable; import android.util.SparseArray; import java.io.PrintStream; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** * Manages native delegates. Loading Loading @@ -73,14 +75,14 @@ import java.util.List; public final class DelegateManager<T> { @SuppressWarnings("FieldCanBeLocal") private final Class<T> mClass; private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>(); private static final SparseWeakArray<Object> sDelegates = new SparseWeakArray<>(); /** list used to store delegates when their main object holds a reference to them. * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed * @see #addNewDelegate(Object) * @see #removeJavaReferenceFor(long) */ private final List<T> mJavaReferences = new ArrayList<T>(); private int mDelegateCounter = 0; private static final List<Object> sJavaReferences = new ArrayList<>(); private static final AtomicLong sDelegateCounter = new AtomicLong(1); public DelegateManager(Class<T> theClass) { mClass = theClass; Loading @@ -97,9 +99,12 @@ public final class DelegateManager<T> { * @return the delegate or null if not found. */ @Nullable public synchronized T getDelegate(long native_object) { public T getDelegate(long native_object) { if (native_object > 0) { T delegate = mDelegates.get(native_object); Object delegate; synchronized (DelegateManager.class) { delegate = sDelegates.get(native_object); } if (Debug.DEBUG) { if (delegate == null) { Loading @@ -109,7 +114,8 @@ public final class DelegateManager<T> { } assert delegate != null; return delegate; //noinspection unchecked return (T)delegate; } return null; } Loading @@ -119,12 +125,13 @@ public final class DelegateManager<T> { * @param newDelegate the delegate to add * @return a unique native int to identify the delegate */ public synchronized long addNewDelegate(T newDelegate) { long native_object = ++mDelegateCounter; mDelegates.put(native_object, newDelegate); assert !mJavaReferences.contains(newDelegate); mJavaReferences.add(newDelegate); public long addNewDelegate(T newDelegate) { long native_object = sDelegateCounter.getAndIncrement(); synchronized (DelegateManager.class) { sDelegates.put(native_object, newDelegate); assert !sJavaReferences.contains(newDelegate); sJavaReferences.add(newDelegate); } if (Debug.DEBUG) { System.out.println( Loading @@ -140,7 +147,8 @@ public final class DelegateManager<T> { * Removes the main reference on the given delegate. * @param native_object the native integer representing the delegate. */ public synchronized void removeJavaReferenceFor(long native_object) { public void removeJavaReferenceFor(long native_object) { synchronized (DelegateManager.class) { T delegate = getDelegate(native_object); if (Debug.DEBUG) { Loading @@ -148,6 +156,14 @@ public final class DelegateManager<T> { " with int " + native_object); } mJavaReferences.remove(delegate); sJavaReferences.remove(delegate); } } public synchronized static void dump(PrintStream out) { for (Object reference : sJavaReferences) { int idx = sDelegates.indexOfValue(reference); out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName()); } } } tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +17 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.io.FolderWrapper; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.impl.RenderAction; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator; import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback; import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser; Loading @@ -52,6 +53,7 @@ import android.util.DisplayMetrics; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.net.URL; import java.util.Arrays; import java.util.concurrent.TimeUnit; Loading Loading @@ -298,6 +300,16 @@ public class Main { renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012); } private static void gc() { // See RuntimeUtil#gc in jlibs (http://jlibs.in/) Object obj = new Object(); WeakReference ref = new WeakReference<Object>(obj); obj = null; while(ref.get() != null) { System.gc(); } } @AfterClass public static void tearDown() { sLayoutLibLog = null; Loading @@ -305,6 +317,11 @@ public class Main { sProjectResources = null; sLogger = null; sBridge = null; gc(); System.out.println("Objects still linked from the DelegateManager:"); DelegateManager.dump(System.out); } /** Test expand_layout.xml */ Loading tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,7 @@ public final class CreateInfo implements ICreateInfo { "android.text.StaticLayout", "android.util.PathParser", "android.view.Display", "com.android.internal.util.VirtualRefBasePtr", "com.android.internal.view.animation.NativeInterpolatorFactoryHelper", "libcore.icu.ICU", }; Loading Loading
tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.util; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.util.LongSparseLongArray; /** * Delegate used to provide new implementation the native methods of {@link VirtualRefBasePtr} * * Through the layoutlib_create tool, the original native methods of VirtualRefBasePtr have been * replaced by calls to methods of the same name in this delegate class. * */ @SuppressWarnings("unused") public class VirtualRefBasePtr_Delegate { private static final DelegateManager<Object> sManager = new DelegateManager<>(Object.class); private static final LongSparseLongArray sRefCount = new LongSparseLongArray(); @LayoutlibDelegate /*package*/ static synchronized void nIncStrong(long ptr) { long counter = sRefCount.get(ptr); sRefCount.put(ptr, ++counter); } @LayoutlibDelegate /*package*/ static synchronized void nDecStrong(long ptr) { long counter = sRefCount.get(ptr); if (counter > 1) { sRefCount.put(ptr, --counter); } else { sRefCount.delete(ptr); sManager.removeJavaReferenceFor(ptr); } } }
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java +34 −18 Original line number Diff line number Diff line Loading @@ -22,9 +22,11 @@ import com.android.layoutlib.bridge.util.SparseWeakArray; import android.annotation.Nullable; import android.util.SparseArray; import java.io.PrintStream; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** * Manages native delegates. Loading Loading @@ -73,14 +75,14 @@ import java.util.List; public final class DelegateManager<T> { @SuppressWarnings("FieldCanBeLocal") private final Class<T> mClass; private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>(); private static final SparseWeakArray<Object> sDelegates = new SparseWeakArray<>(); /** list used to store delegates when their main object holds a reference to them. * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed * @see #addNewDelegate(Object) * @see #removeJavaReferenceFor(long) */ private final List<T> mJavaReferences = new ArrayList<T>(); private int mDelegateCounter = 0; private static final List<Object> sJavaReferences = new ArrayList<>(); private static final AtomicLong sDelegateCounter = new AtomicLong(1); public DelegateManager(Class<T> theClass) { mClass = theClass; Loading @@ -97,9 +99,12 @@ public final class DelegateManager<T> { * @return the delegate or null if not found. */ @Nullable public synchronized T getDelegate(long native_object) { public T getDelegate(long native_object) { if (native_object > 0) { T delegate = mDelegates.get(native_object); Object delegate; synchronized (DelegateManager.class) { delegate = sDelegates.get(native_object); } if (Debug.DEBUG) { if (delegate == null) { Loading @@ -109,7 +114,8 @@ public final class DelegateManager<T> { } assert delegate != null; return delegate; //noinspection unchecked return (T)delegate; } return null; } Loading @@ -119,12 +125,13 @@ public final class DelegateManager<T> { * @param newDelegate the delegate to add * @return a unique native int to identify the delegate */ public synchronized long addNewDelegate(T newDelegate) { long native_object = ++mDelegateCounter; mDelegates.put(native_object, newDelegate); assert !mJavaReferences.contains(newDelegate); mJavaReferences.add(newDelegate); public long addNewDelegate(T newDelegate) { long native_object = sDelegateCounter.getAndIncrement(); synchronized (DelegateManager.class) { sDelegates.put(native_object, newDelegate); assert !sJavaReferences.contains(newDelegate); sJavaReferences.add(newDelegate); } if (Debug.DEBUG) { System.out.println( Loading @@ -140,7 +147,8 @@ public final class DelegateManager<T> { * Removes the main reference on the given delegate. * @param native_object the native integer representing the delegate. */ public synchronized void removeJavaReferenceFor(long native_object) { public void removeJavaReferenceFor(long native_object) { synchronized (DelegateManager.class) { T delegate = getDelegate(native_object); if (Debug.DEBUG) { Loading @@ -148,6 +156,14 @@ public final class DelegateManager<T> { " with int " + native_object); } mJavaReferences.remove(delegate); sJavaReferences.remove(delegate); } } public synchronized static void dump(PrintStream out) { for (Object reference : sJavaReferences) { int idx = sDelegates.indexOfValue(reference); out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName()); } } }
tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +17 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.io.FolderWrapper; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.impl.RenderAction; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator; import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback; import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser; Loading @@ -52,6 +53,7 @@ import android.util.DisplayMetrics; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.net.URL; import java.util.Arrays; import java.util.concurrent.TimeUnit; Loading Loading @@ -298,6 +300,16 @@ public class Main { renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012); } private static void gc() { // See RuntimeUtil#gc in jlibs (http://jlibs.in/) Object obj = new Object(); WeakReference ref = new WeakReference<Object>(obj); obj = null; while(ref.get() != null) { System.gc(); } } @AfterClass public static void tearDown() { sLayoutLibLog = null; Loading @@ -305,6 +317,11 @@ public class Main { sProjectResources = null; sLogger = null; sBridge = null; gc(); System.out.println("Objects still linked from the DelegateManager:"); DelegateManager.dump(System.out); } /** Test expand_layout.xml */ Loading
tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,7 @@ public final class CreateInfo implements ICreateInfo { "android.text.StaticLayout", "android.util.PathParser", "android.view.Display", "com.android.internal.util.VirtualRefBasePtr", "com.android.internal.view.animation.NativeInterpolatorFactoryHelper", "libcore.icu.ICU", }; Loading