From 071dee288ca726c7c15754c2559403b9cbf950bd Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Thu, 11 Nov 2010 14:19:29 -0800 Subject: Misc fix in layoutlib bridge + View.isIneditMode as delegate. Change-Id: Ideab29167e933203da99d4270cebcb777726201f --- .../bridge/src/android/view/View_Delegate.java | 31 +++++ .../src/com/android/layoutlib/bridge/Bridge.java | 14 --- .../layoutlib/bridge/android/BridgeContext.java | 13 +- .../layoutlib/bridge/android/BridgeTypedArray.java | 2 - .../layoutlib/bridge/android/BridgeWindow.java | 3 +- .../layoutlib/bridge/impl/TempResourceValue.java | 4 +- .../android/layoutlib/bridge/TestDelegates.java | 132 +++++++++++++++++++++ .../layoutlib/bridge/TestNativeDelegate.java | 119 ------------------- .../android/tools/layoutlib/create/CreateInfo.java | 4 +- 9 files changed, 172 insertions(+), 150 deletions(-) create mode 100644 tools/layoutlib/bridge/src/android/view/View_Delegate.java create mode 100644 tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java delete mode 100644 tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestNativeDelegate.java (limited to 'tools') diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java new file mode 100644 index 0000000..ee6694c --- /dev/null +++ b/tools/layoutlib/bridge/src/android/view/View_Delegate.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 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 android.view; + +/** + * Delegate used to provide new implementation of a select few methods of {@link View} + * + * Through the layoutlib_create tool, the original methods of View have been replaced + * by calls to methods of the same name in this delegate class. + * + */ +public class View_Delegate { + + /*package*/ static boolean isInEditMode(View thisView) { + return true; + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index d2092d1..53da2ca 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -157,20 +157,6 @@ public final class Bridge extends LayoutBridge { }); } - // Override View.isInEditMode to return true. - // - // This allows custom views that are drawn in the Graphical Layout Editor to adapt their - // rendering for preview. Most important this let custom views know that they can't expect - // the rest of their activities to be alive. - OverrideMethod.setMethodListener("android.view.View#isInEditMode()Z", - new MethodAdapter() { - @Override - public int onInvokeI(String signature, boolean isNative, Object caller) { - return 1; - } - } - ); - // load the fonts. FontLoader fontLoader = FontLoader.create(fontOsLocation); if (fontLoader != null) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 2fa97a3..79aecff 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -1111,25 +1111,20 @@ public final class BridgeContext extends Activity { } - @SuppressWarnings("unused") @Override - public FileInputStream openFileInput(String arg0) - throws FileNotFoundException { + public FileInputStream openFileInput(String arg0) throws FileNotFoundException { // TODO Auto-generated method stub return null; } - @SuppressWarnings("unused") @Override - public FileOutputStream openFileOutput(String arg0, int arg1) - throws FileNotFoundException { + public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException { // TODO Auto-generated method stub return null; } @Override - public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, - CursorFactory arg2) { + public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) { // TODO Auto-generated method stub return null; } @@ -1217,14 +1212,12 @@ public final class BridgeContext extends Activity { } - @SuppressWarnings("unused") @Override public void setWallpaper(Bitmap arg0) throws IOException { // TODO Auto-generated method stub } - @SuppressWarnings("unused") @Override public void setWallpaper(InputStream arg0) throws IOException { // TODO Auto-generated method stub diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java index c3ab461..c8dc9e6 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java @@ -43,10 +43,8 @@ import java.util.Map; */ public final class BridgeTypedArray extends TypedArray { - @SuppressWarnings("hiding") private BridgeResources mResources; private BridgeContext mContext; - @SuppressWarnings("hiding") private IResourceValue[] mData; private String[] mNames; private final boolean mPlatformFile; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java index c04c9e8..4a7ab58 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java @@ -49,7 +49,8 @@ public final class BridgeWindow implements IWindow { // pass for now. } - public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException { + public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) + throws RemoteException { // pass for now. } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java index 4ab98ce..a3c5826 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java @@ -16,14 +16,14 @@ package com.android.layoutlib.bridge.impl; -import com.android.layoutlib.api.ILayoutBridge; import com.android.layoutlib.api.IResourceValue; +import com.android.layoutlib.api.LayoutBridge; /** * Basic implementation of IResourceValue for when it is needed to dynamically make a new * {@link IResourceValue} object. * - * Most of the time, implementations of IResourceValue come through the {@link ILayoutBridge} + * Most of the time, implementations of IResourceValue come through the {@link LayoutBridge} * API. */ public class TempResourceValue implements IResourceValue { diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java new file mode 100644 index 0000000..23b7e94 --- /dev/null +++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2010 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.layoutlib.bridge; + +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import com.android.tools.layoutlib.create.CreateInfo; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import junit.framework.TestCase; + +/** + * Tests that native delegate classes implement all the required methods. + * + * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that + * have their native methods reimplemented through a delegate. + * + * Since the reimplemented methods are not native anymore, we look for the annotation + * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same + * as the modified class with _Delegate added as a suffix). + * If the original native method is not static, then we make sure the delegate method also + * include the original class as first parameter (to access "this"). + * + */ +public class TestDelegates extends TestCase { + + public void testNativeDelegates() { + + final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES; + final int count = classes.length; + for (int i = 0 ; i < count ; i++) { + loadAndCompareClasses(classes[i], classes[i] + "_Delegate"); + } + } + + public void testMethodDelegates() { + final String[] methods = CreateInfo.DELEGATE_METHODS; + final int count = methods.length; + for (int i = 0 ; i < count ; i++) { + String methodName = methods[i]; + + // extract the class name + String className = methodName.substring(0, methodName.indexOf('#')); + + loadAndCompareClasses(className, className + "_Delegate"); + } + } + + private void loadAndCompareClasses(String originalClassName, String delegateClassName) { + // load the classes + try { + ClassLoader classLoader = TestDelegates.class.getClassLoader(); + Class originalClass = classLoader.loadClass(originalClassName); + Class delegateClass = classLoader.loadClass(delegateClassName); + + compare(originalClass, delegateClass); + } catch (ClassNotFoundException e) { + fail("Failed to load class: " + e.getMessage()); + } catch (SecurityException e) { + fail("Failed to load class: " + e.getMessage()); + } + } + + private void compare(Class originalClass, Class delegateClass) throws SecurityException { + Method[] originalMethods = originalClass.getDeclaredMethods(); + + for (Method originalMethod : originalMethods) { + // look for methods that were native: they have the LayoutlibDelegate annotation + if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) { + continue; + } + + // get the signature. + Class[] parameters = originalMethod.getParameterTypes(); + + // if the method is not static, then the class is added as the first parameter + // (for "this") + if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) { + + Class[] newParameters = new Class[parameters.length + 1]; + newParameters[0] = originalClass; + System.arraycopy(parameters, 0, newParameters, 1, parameters.length); + parameters = newParameters; + } + + try { + // try to load the method with the given parameter types. + Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(), + parameters); + + // check that the method is static + assertTrue((delegateMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC); + } catch (NoSuchMethodException e) { + // compute a full class name that's long but not too long. + StringBuilder sb = new StringBuilder(originalMethod.getName() + "("); + for (int j = 0; j < parameters.length; j++) { + Class theClass = parameters[j]; + sb.append(theClass.getName()); + int dimensions = 0; + while (theClass.isArray()) { + dimensions++; + theClass = theClass.getComponentType(); + } + for (int i = 0; i < dimensions; i++) { + sb.append("[]"); + } + if (j < (parameters.length - 1)) { + sb.append(","); + } + } + sb.append(")"); + + fail(String.format("Missing %1$s.%2$s", delegateClass.getName(), sb.toString())); + } + } + } +} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestNativeDelegate.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestNativeDelegate.java deleted file mode 100644 index a86b5c9..0000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestNativeDelegate.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2010 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.layoutlib.bridge; - -import com.android.tools.layoutlib.annotations.LayoutlibDelegate; -import com.android.tools.layoutlib.create.CreateInfo; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import junit.framework.TestCase; - -/** - * Tests that native delegate classes implement all the required methods. - * - * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that - * have their native methods reimplemented through a delegate. - * - * Since the reimplemented methods are not native anymore, we look for the annotation - * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same - * as the modified class with _Delegate added as a suffix). - * If the original native method is not static, then we make sure the delegate method also - * include the original class as first parameter (to access "this"). - * - */ -public class TestNativeDelegate extends TestCase { - - public void testNativeDelegates() { - - final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES; - final int count = classes.length; - for (int i = 0 ; i < count ; i++) { - loadAndCompareClasses(classes[i], classes[i] + "_Delegate"); - } - } - - private void loadAndCompareClasses(String originalClassName, String delegateClassName) { - // load the classes - try { - ClassLoader classLoader = TestNativeDelegate.class.getClassLoader(); - Class originalClass = classLoader.loadClass(originalClassName); - Class delegateClass = classLoader.loadClass(delegateClassName); - - compare(originalClass, delegateClass); - } catch (ClassNotFoundException e) { - fail("Failed to load class: " + e.getMessage()); - } catch (SecurityException e) { - fail("Failed to load class: " + e.getMessage()); - } - } - - private void compare(Class originalClass, Class delegateClass) throws SecurityException { - Method[] originalMethods = originalClass.getDeclaredMethods(); - - for (Method originalMethod : originalMethods) { - // look for methods that were native: they have the LayoutlibDelegate annotation - if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) { - continue; - } - - // get the signature. - Class[] parameters = originalMethod.getParameterTypes(); - - // if the method is not static, then the class is added as the first parameter - // (for "this") - if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) { - - Class[] newParameters = new Class[parameters.length + 1]; - newParameters[0] = originalClass; - System.arraycopy(parameters, 0, newParameters, 1, parameters.length); - parameters = newParameters; - } - - try { - // try to load the method with the given parameter types. - Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(), - parameters); - - // check that the method is static - assertTrue((delegateMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC); - } catch (NoSuchMethodException e) { - // compute a full class name that's long but not too long. - StringBuilder sb = new StringBuilder(originalMethod.getName() + "("); - for (int j = 0; j < parameters.length; j++) { - Class theClass = parameters[j]; - sb.append(theClass.getName()); - int dimensions = 0; - while (theClass.isArray()) { - dimensions++; - theClass = theClass.getComponentType(); - } - for (int i = 0; i < dimensions; i++) { - sb.append("[]"); - } - if (j < (parameters.length - 1)) { - sb.append(","); - } - } - sb.append(")"); - - fail(String.format("Missing %1$s.%2$s", delegateClass.getName(), sb.toString())); - } - } - } -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java index 1c95400..b9c7113 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -95,8 +95,8 @@ public final class CreateInfo implements ICreateInfo { */ private final static String[] DELEGATE_METHODS = new String[] { "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;", + "android.view.View#isInEditMode", // TODO: comment out once DelegateClass is working - // "android.view.View#isInEditMode", // "android.content.res.Resources$Theme#obtainStyledAttributes", }; @@ -126,7 +126,6 @@ public final class CreateInfo implements ICreateInfo { */ private final static String[] OVERRIDDEN_METHODS = new String[] { // TODO: remove once DelegateClass is working - "android.view.View#isInEditMode", "android.content.res.Resources$Theme#obtainStyledAttributes", }; @@ -141,6 +140,7 @@ public final class CreateInfo implements ICreateInfo { "android.os.ServiceManager", "android.os._Original_ServiceManager", "android.view.SurfaceView", "android.view._Original_SurfaceView", "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager", + "android.webkit.WebView", "android.webkit._Original_WebView", }; /** -- cgit v1.1