DelegateManager.java revision 4f291d33e14e62b3301acc056a82fe206c74835f
14f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet/* 24f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Copyright (C) 2010 The Android Open Source Project 34f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 44f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 54f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * you may not use this file except in compliance with the License. 64f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * You may obtain a copy of the License at 74f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 84f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 94f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 104f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Unless required by applicable law or agreed to in writing, software 114f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 124f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * See the License for the specific language governing permissions and 144f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * limitations under the License. 154f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet */ 164f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 174f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohetpackage com.android.layoutlib.bridge; 184f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 194f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohetimport android.util.SparseArray; 204f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 214f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet/** 224f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Manages native delegates. 234f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 244f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * This is used in conjunction with layoublib_create: certain Android java classes are mere 254f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * wrappers around a heavily native based implementation, and we need a way to run these classes 264f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * in our Eclipse rendering framework without bringing all the native code from the Android 274f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * platform. 284f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 294f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Thus we instruct layoutlib_create to modify the bytecode of these classes to replace their 304f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * native methods by "delegate calls". 314f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 324f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * For example, a native method android.graphics.Matrix.init(...) will actually become 334f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * a call to android.graphics.Matrix_Delegate.init(...). 344f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 354f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * The Android java classes that use native code uses an int (Java side) to reference native 364f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * objects. This int is generally directly the pointer to the C structure counterpart. 374f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Typically a creation method will return such an int, and then this int will be passed later 384f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * to a Java method to identify the C object to manipulate. 394f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 404f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Since we cannot use the Java object reference as the int directly, DelegateManager manages the 414f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * int -> Delegate class link. 424f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 434f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Native methods usually always have the int as parameters. The first thing the delegate method 444f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * will do is call {@link #getDelegate(int)} to get the Java object matching the int. 454f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 464f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Typical native init methods are returning a new int back to the Java class, so 474f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * {@link #addDelegate(Object)} does the same. 484f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * 494f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * @param <T> the delegate class to manage 504f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet */ 514f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohetpublic final class DelegateManager<T> { 524f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 534f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet private final SparseArray<T> mDelegates = new SparseArray<T>(); 544f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet private int mDelegateCounter = 0; 554f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 564f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet /** 574f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Returns the delegate from the given native int. 584f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * @param native_object the native int. 594f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * @return the delegate or null if not found. 604f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet */ 614f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet public T getDelegate(int native_object) { 624f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet synchronized (mDelegates) { 634f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet return mDelegates.get(native_object); 644f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet } 654f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet } 664f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 674f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet /** 684f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Adds a delegate to the manager and returns the native int used to identify it. 694f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * @param newDelegate the delegate to add 704f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * @return a unique native int to identify the delegate 714f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet */ 724f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet public int addDelegate(T newDelegate) { 734f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet synchronized (mDelegates) { 744f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet int native_object = ++mDelegateCounter; 754f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet mDelegates.put(native_object, newDelegate); 764f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet return native_object; 774f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet } 784f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet } 794f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet 804f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet /** 814f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * Removes the delegate matching the given native int. 824f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet * @param native_object the native int. 834f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet */ 844f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet public void removeDelegate(int native_object) { 854f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet synchronized (mDelegates) { 864f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet mDelegates.remove(native_object); 874f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet } 884f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet } 894f291d33e14e62b3301acc056a82fe206c74835fXavier Ducrohet} 90