1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2008 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage com.android.tools.layoutlib.create; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.HashMap; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Allows stub methods from LayoutLib to be overriden at runtime. 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Implementation note: all types required by this class(inner/outer classes & interfaces) 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Otherwise they won't be accessible in layoutlib.jar at runtime. 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic final class OverrideMethod { 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Map of method overridden. */ 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>(); 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Default listener for all method not listed in sMethods. Nothing if null. */ 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static MethodListener sDefaultListener = null; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sets the default listener for all methods not specifically handled. 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Null means to do nothing. 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 39d2a411840c58eaee05499bab0190e3f3656e2e84Deepanshu Gupta @SuppressWarnings("UnusedDeclaration") // Used by Bridge by reflection for debug purposes. 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static void setDefaultListener(MethodListener listener) { 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sDefaultListener = listener; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Defines or reset a listener for the given method signature. 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param signature The signature of the method being invoked, composed of the 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * binary class name followed by the method descriptor (aka argument 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V" 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param listener The new listener. Removes it if null. 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static void setMethodListener(String signature, MethodListener listener) { 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (listener == null) { 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sMethods.remove(signature); 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sMethods.put(signature, listener); 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Invokes the specific listener for the given signature or the default one if defined. 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This version invokes the method listener for the void return type. 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * by the stubbed methods generated by the LayoutLib_create tool. 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param signature The signature of the method being invoked, composed of the 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * binary class name followed by the method descriptor (aka argument 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V". 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param isNative True if the method was a native method. 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param caller The calling object. Null for static methods, "this" for instance methods. 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static void invokeV(String signature, boolean isNative, Object caller) { 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodListener i = sMethods.get(signature); 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != null) { 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i.onInvokeV(signature, isNative, caller); 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sDefaultListener != null) { 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sDefaultListener.onInvokeV(signature, isNative, caller); 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Invokes the specific listener for the int return type. 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #invokeV(String, boolean, Object) 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static int invokeI(String signature, boolean isNative, Object caller) { 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodListener i = sMethods.get(signature); 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != null) { 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i.onInvokeI(signature, isNative, caller); 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sDefaultListener != null) { 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sDefaultListener.onInvokeI(signature, isNative, caller); 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Invokes the specific listener for the long return type. 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #invokeV(String, boolean, Object) 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static long invokeL(String signature, boolean isNative, Object caller) { 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodListener i = sMethods.get(signature); 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != null) { 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i.onInvokeL(signature, isNative, caller); 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sDefaultListener != null) { 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sDefaultListener.onInvokeL(signature, isNative, caller); 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Invokes the specific listener for the float return type. 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #invokeV(String, boolean, Object) 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static float invokeF(String signature, boolean isNative, Object caller) { 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodListener i = sMethods.get(signature); 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != null) { 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i.onInvokeF(signature, isNative, caller); 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sDefaultListener != null) { 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sDefaultListener.onInvokeF(signature, isNative, caller); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Invokes the specific listener for the double return type. 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #invokeV(String, boolean, Object) 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static double invokeD(String signature, boolean isNative, Object caller) { 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodListener i = sMethods.get(signature); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != null) { 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i.onInvokeD(signature, isNative, caller); 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sDefaultListener != null) { 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sDefaultListener.onInvokeD(signature, isNative, caller); 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Invokes the specific listener for the object return type. 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #invokeV(String, boolean, Object) 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static Object invokeA(String signature, boolean isNative, Object caller) { 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodListener i = sMethods.get(signature); 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != null) { 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i.onInvokeA(signature, isNative, caller); 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sDefaultListener != null) { 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sDefaultListener.onInvokeA(signature, isNative, caller); 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 153