Merge "Implement VirtualRefBasePtr native methods" into nyc-dev
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,9 +22,11 @@ import com.android.layoutlib.bridge.util.SparseWeakArray;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages native delegates.
|
* Manages native delegates.
|
||||||
@@ -73,14 +75,14 @@ import java.util.List;
|
|||||||
public final class DelegateManager<T> {
|
public final class DelegateManager<T> {
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
private final Class<T> mClass;
|
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.
|
/** 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
|
* This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
|
||||||
* @see #addNewDelegate(Object)
|
* @see #addNewDelegate(Object)
|
||||||
* @see #removeJavaReferenceFor(long)
|
* @see #removeJavaReferenceFor(long)
|
||||||
*/
|
*/
|
||||||
private final List<T> mJavaReferences = new ArrayList<T>();
|
private static final List<Object> sJavaReferences = new ArrayList<>();
|
||||||
private int mDelegateCounter = 0;
|
private static final AtomicLong sDelegateCounter = new AtomicLong(1);
|
||||||
|
|
||||||
public DelegateManager(Class<T> theClass) {
|
public DelegateManager(Class<T> theClass) {
|
||||||
mClass = theClass;
|
mClass = theClass;
|
||||||
@@ -97,9 +99,12 @@ public final class DelegateManager<T> {
|
|||||||
* @return the delegate or null if not found.
|
* @return the delegate or null if not found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public synchronized T getDelegate(long native_object) {
|
public T getDelegate(long native_object) {
|
||||||
if (native_object > 0) {
|
if (native_object > 0) {
|
||||||
T delegate = mDelegates.get(native_object);
|
Object delegate;
|
||||||
|
synchronized (DelegateManager.class) {
|
||||||
|
delegate = sDelegates.get(native_object);
|
||||||
|
}
|
||||||
|
|
||||||
if (Debug.DEBUG) {
|
if (Debug.DEBUG) {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
@@ -109,7 +114,8 @@ public final class DelegateManager<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert delegate != null;
|
assert delegate != null;
|
||||||
return delegate;
|
//noinspection unchecked
|
||||||
|
return (T)delegate;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -119,12 +125,13 @@ public final class DelegateManager<T> {
|
|||||||
* @param newDelegate the delegate to add
|
* @param newDelegate the delegate to add
|
||||||
* @return a unique native int to identify the delegate
|
* @return a unique native int to identify the delegate
|
||||||
*/
|
*/
|
||||||
public synchronized long addNewDelegate(T newDelegate) {
|
public long addNewDelegate(T newDelegate) {
|
||||||
long native_object = ++mDelegateCounter;
|
long native_object = sDelegateCounter.getAndIncrement();
|
||||||
|
synchronized (DelegateManager.class) {
|
||||||
mDelegates.put(native_object, newDelegate);
|
sDelegates.put(native_object, newDelegate);
|
||||||
assert !mJavaReferences.contains(newDelegate);
|
assert !sJavaReferences.contains(newDelegate);
|
||||||
mJavaReferences.add(newDelegate);
|
sJavaReferences.add(newDelegate);
|
||||||
|
}
|
||||||
|
|
||||||
if (Debug.DEBUG) {
|
if (Debug.DEBUG) {
|
||||||
System.out.println(
|
System.out.println(
|
||||||
@@ -140,7 +147,8 @@ public final class DelegateManager<T> {
|
|||||||
* Removes the main reference on the given delegate.
|
* Removes the main reference on the given delegate.
|
||||||
* @param native_object the native integer representing the 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);
|
T delegate = getDelegate(native_object);
|
||||||
|
|
||||||
if (Debug.DEBUG) {
|
if (Debug.DEBUG) {
|
||||||
@@ -148,6 +156,14 @@ public final class DelegateManager<T> {
|
|||||||
" with int " + native_object);
|
" 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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.android.io.FolderWrapper;
|
|||||||
import com.android.layoutlib.bridge.Bridge;
|
import com.android.layoutlib.bridge.Bridge;
|
||||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||||
import com.android.layoutlib.bridge.impl.RenderAction;
|
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.ConfigGenerator;
|
||||||
import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
|
import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
|
||||||
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
|
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
|
||||||
@@ -52,6 +53,7 @@ import android.util.DisplayMetrics;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -298,6 +300,16 @@ public class Main {
|
|||||||
renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
|
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
|
@AfterClass
|
||||||
public static void tearDown() {
|
public static void tearDown() {
|
||||||
sLayoutLibLog = null;
|
sLayoutLibLog = null;
|
||||||
@@ -305,6 +317,11 @@ public class Main {
|
|||||||
sProjectResources = null;
|
sProjectResources = null;
|
||||||
sLogger = null;
|
sLogger = null;
|
||||||
sBridge = null;
|
sBridge = null;
|
||||||
|
|
||||||
|
gc();
|
||||||
|
|
||||||
|
System.out.println("Objects still linked from the DelegateManager:");
|
||||||
|
DelegateManager.dump(System.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test expand_layout.xml */
|
/** Test expand_layout.xml */
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ public final class CreateInfo implements ICreateInfo {
|
|||||||
"android.text.StaticLayout",
|
"android.text.StaticLayout",
|
||||||
"android.util.PathParser",
|
"android.util.PathParser",
|
||||||
"android.view.Display",
|
"android.view.Display",
|
||||||
|
"com.android.internal.util.VirtualRefBasePtr",
|
||||||
"com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
|
"com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
|
||||||
"libcore.icu.ICU",
|
"libcore.icu.ICU",
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user