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