• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.layoutlib.create;
18 
19 import java.util.HashMap;
20 
21 /**
22  * Allows stub methods from LayoutLib to be overriden at runtime.
23  * <p/>
24  * Implementation note: all types required by this class(inner/outer classes & interfaces)
25  * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java;
26  * Otherwise they won't be accessible in layoutlib.jar at runtime.
27  */
28 public final class OverrideMethod {
29 
30     /** Map of method overridden. */
31     private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>();
32     /** Default listener for all method not listed in sMethods. Nothing if null. */
33     private static MethodListener sDefaultListener = null;
34 
35     /**
36      * Sets the default listener for all methods not specifically handled.
37      * Null means to do nothing.
38      */
setDefaultListener(MethodListener listener)39     public static void setDefaultListener(MethodListener listener) {
40         sDefaultListener = listener;
41     }
42 
43     /**
44      * Defines or reset a listener for the given method signature.
45      *
46      * @param signature The signature of the method being invoked, composed of the
47      *                  binary class name followed by the method descriptor (aka argument
48      *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
49      * @param listener The new listener. Removes it if null.
50      */
setMethodListener(String signature, MethodListener listener)51     public static void setMethodListener(String signature, MethodListener listener) {
52         if (listener == null) {
53             sMethods.remove(signature);
54         } else {
55             sMethods.put(signature, listener);
56         }
57     }
58 
59     /**
60      * Invokes the specific listener for the given signature or the default one if defined.
61      * <p/>
62      * This version invokes the method listener for the void return type.
63      * <p/>
64      * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called
65      * by the stubbed methods generated by the LayoutLib_create tool.
66      *
67      * @param signature The signature of the method being invoked, composed of the
68      *                  binary class name followed by the method descriptor (aka argument
69      *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
70      * @param isNative True if the method was a native method.
71      * @param caller The calling object. Null for static methods, "this" for instance methods.
72      */
invokeV(String signature, boolean isNative, Object caller)73     public static void invokeV(String signature, boolean isNative, Object caller) {
74         MethodListener i = sMethods.get(signature);
75         if (i != null) {
76             i.onInvokeV(signature, isNative, caller);
77         } else if (sDefaultListener != null) {
78             sDefaultListener.onInvokeV(signature, isNative, caller);
79         }
80     }
81 
82     /**
83      * Invokes the specific listener for the int return type.
84      * @see #invokeV(String, boolean, Object)
85      */
invokeI(String signature, boolean isNative, Object caller)86     public static int invokeI(String signature, boolean isNative, Object caller) {
87         MethodListener i = sMethods.get(signature);
88         if (i != null) {
89             return i.onInvokeI(signature, isNative, caller);
90         } else if (sDefaultListener != null) {
91             return sDefaultListener.onInvokeI(signature, isNative, caller);
92         }
93         return 0;
94     }
95 
96     /**
97      * Invokes the specific listener for the long return type.
98      * @see #invokeV(String, boolean, Object)
99      */
invokeL(String signature, boolean isNative, Object caller)100     public static long invokeL(String signature, boolean isNative, Object caller) {
101         MethodListener i = sMethods.get(signature);
102         if (i != null) {
103             return i.onInvokeL(signature, isNative, caller);
104         } else if (sDefaultListener != null) {
105             return sDefaultListener.onInvokeL(signature, isNative, caller);
106         }
107         return 0;
108     }
109 
110     /**
111      * Invokes the specific listener for the float return type.
112      * @see #invokeV(String, boolean, Object)
113      */
invokeF(String signature, boolean isNative, Object caller)114     public static float invokeF(String signature, boolean isNative, Object caller) {
115         MethodListener i = sMethods.get(signature);
116         if (i != null) {
117             return i.onInvokeF(signature, isNative, caller);
118         } else if (sDefaultListener != null) {
119             return sDefaultListener.onInvokeF(signature, isNative, caller);
120         }
121         return 0;
122     }
123 
124     /**
125      * Invokes the specific listener for the double return type.
126      * @see #invokeV(String, boolean, Object)
127      */
invokeD(String signature, boolean isNative, Object caller)128     public static double invokeD(String signature, boolean isNative, Object caller) {
129         MethodListener i = sMethods.get(signature);
130         if (i != null) {
131             return i.onInvokeD(signature, isNative, caller);
132         } else if (sDefaultListener != null) {
133             return sDefaultListener.onInvokeD(signature, isNative, caller);
134         }
135         return 0;
136     }
137 
138     /**
139      * Invokes the specific listener for the object return type.
140      * @see #invokeV(String, boolean, Object)
141      */
invokeA(String signature, boolean isNative, Object caller)142     public static Object invokeA(String signature, boolean isNative, Object caller) {
143         MethodListener i = sMethods.get(signature);
144         if (i != null) {
145             return i.onInvokeA(signature, isNative, caller);
146         } else if (sDefaultListener != null) {
147             return sDefaultListener.onInvokeA(signature, isNative, caller);
148         }
149         return null;
150     }
151 }
152