diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk index 8a81d0b684dbb..565feb68e6b55 100644 --- a/tools/layoutlib/bridge/tests/Android.mk +++ b/tools/layoutlib/bridge/tests/Android.mk @@ -17,7 +17,9 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Only compile source java files in this lib. -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := \ + $(call all-java-files-under, src) \ + $(call all-java-files-under, res/testApp/MyApplication/src/main/myapplication.widgets) LOCAL_JAVA_RESOURCE_DIRS := res LOCAL_MODULE := layoutlib-tests diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ImageUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ImageUtils.java index 8f9fa8a2bcf65..d81b4ba65022b 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ImageUtils.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ImageUtils.java @@ -64,7 +64,7 @@ public class ImageUtils { double scale = THUMBNAIL_SIZE / (double)maxDimension; BufferedImage thumbnail = scale(image, scale, scale); - InputStream is = ImageUtils.class.getResourceAsStream(relativePath); + InputStream is = ImageUtils.class.getClassLoader().getResourceAsStream(relativePath); if (is == null) { String message = "Unable to load golden thumbnail: " + relativePath + "\n"; message = saveImageAndAppendMessage(thumbnail, message, relativePath); diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index 5423e876e23fe..24cbbca02b77a 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -121,7 +121,7 @@ public class Main { private static final String PLATFORM_DIR; private static final String TEST_RES_DIR; /** Location of the app to test inside {@link #TEST_RES_DIR}*/ - private static final String APP_TEST_DIR = "/testApp/MyApplication"; + private static final String APP_TEST_DIR = "testApp/MyApplication"; /** Location of the app's res dir inside {@link #TEST_RES_DIR}*/ private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res"; private static final String APP_CLASSES_LOCATION = @@ -138,8 +138,7 @@ public class Main { // Default class loader with access to the app classes private ClassLoader mDefaultClassLoader = - new URLClassLoader(new URL[]{this.getClass().getResource(APP_CLASSES_LOCATION)}, - getClass().getClassLoader()); + new ModuleClassLoader(APP_CLASSES_LOCATION, getClass().getClassLoader()); @Rule public TestWatcher sRenderMessageWatcher = new TestWatcher() { @@ -313,7 +312,8 @@ public class Main { sFrameworkRepo.loadPublicResources(getLogger()); sProjectResources = - new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) { + new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES), + false) { @NonNull @Override protected ResourceItem createResourceItem(@NonNull String name) { diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ModuleClassLoader.java new file mode 100644 index 0000000000000..3fac7782b3ae9 --- /dev/null +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/ModuleClassLoader.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 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.intensive; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import libcore.io.Streams; + +/** + * Module class loader that loads classes from the test project. + */ +public class ModuleClassLoader extends ClassLoader { + private final Map> mClasses = new HashMap<>(); + private String myModuleRoot; + + /** + * @param moduleRoot The path to the module root + * @param parent The parent class loader + */ + public ModuleClassLoader(String moduleRoot, ClassLoader parent) { + super(parent); + myModuleRoot = moduleRoot + (moduleRoot.endsWith("/") ? "" : "/"); + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + try { + return super.findClass(name); + } catch (ClassNotFoundException ignored) { + } + + Class clazz = mClasses.get(name); + if (clazz == null) { + String path = name.replace('.', '/').concat(".class"); + try { + byte[] b = Streams.readFully(getResourceAsStream(myModuleRoot + path)); + clazz = defineClass(name, b, 0, b.length); + mClasses.put(name, clazz); + } catch (IOException ignore) { + throw new ClassNotFoundException(name + " not found"); + } + } + + return clazz; + } +} diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java index 111049474461a..bc8083f9c40fa 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java @@ -42,9 +42,11 @@ public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{ * @param layoutPath Must start with '/' and be relative to test resources. */ public LayoutPullParser(String layoutPath) { - assert layoutPath.startsWith("/"); + if (layoutPath.startsWith("/")) { + layoutPath = layoutPath.substring(1); + } try { - init(getClass().getResourceAsStream(layoutPath)); + init(getClass().getClassLoader().getResourceAsStream(layoutPath)); } catch (XmlPullParserException e) { throw new IOError(e); }