diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java new file mode 100644 index 000000000..d6b401b62 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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.ide.eclipse.tests.functests.layoutRendering; + +import com.android.SdkConstants; +import com.android.ide.common.rendering.LayoutLibrary; +import com.android.ide.common.rendering.api.ActionBarCallback; +import com.android.ide.common.rendering.api.AdapterBinding; +import com.android.ide.common.rendering.api.HardwareConfig; +import com.android.ide.common.rendering.api.ILayoutPullParser; +import com.android.ide.common.rendering.api.IProjectCallback; +import com.android.ide.common.rendering.api.RenderSession; +import com.android.ide.common.rendering.api.ResourceReference; +import com.android.ide.common.rendering.api.ResourceValue; +import com.android.ide.common.rendering.api.SessionParams; +import com.android.ide.common.rendering.api.SessionParams.RenderingMode; +import com.android.ide.common.resources.ResourceItem; +import com.android.ide.common.resources.ResourceRepository; +import com.android.ide.common.resources.ResourceResolver; +import com.android.ide.common.resources.configuration.DensityQualifier; +import com.android.ide.common.resources.configuration.FolderConfiguration; +import com.android.ide.common.resources.configuration.KeyboardStateQualifier; +import com.android.ide.common.resources.configuration.NavigationMethodQualifier; +import com.android.ide.common.resources.configuration.NavigationStateQualifier; +import com.android.ide.common.resources.configuration.ScreenDimensionQualifier; +import com.android.ide.common.resources.configuration.ScreenHeightQualifier; +import com.android.ide.common.resources.configuration.ScreenOrientationQualifier; +import com.android.ide.common.resources.configuration.ScreenRatioQualifier; +import com.android.ide.common.resources.configuration.ScreenSizeQualifier; +import com.android.ide.common.resources.configuration.ScreenWidthQualifier; +import com.android.ide.common.resources.configuration.SmallestScreenWidthQualifier; +import com.android.ide.common.resources.configuration.TextInputMethodQualifier; +import com.android.ide.common.resources.configuration.TouchScreenQualifier; +import com.android.ide.common.sdk.LoadStatus; +import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; +import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; +import com.android.ide.eclipse.tests.SdkLoadingTestCase; +import com.android.io.FolderWrapper; +import com.android.resources.Density; +import com.android.resources.Keyboard; +import com.android.resources.KeyboardState; +import com.android.resources.Navigation; +import com.android.resources.NavigationState; +import com.android.resources.ResourceType; +import com.android.resources.ScreenOrientation; +import com.android.resources.ScreenRatio; +import com.android.resources.ScreenSize; +import com.android.resources.TouchScreen; +import com.android.sdklib.IAndroidTarget; +import com.android.util.Pair; + +import org.kxml2.io.KXmlParser; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.imageio.ImageIO; + +public class ApiDemosRenderingTest extends SdkLoadingTestCase { + + /** + * Custom parser that implements {@link ILayoutPullParser} (which itself extends + * {@link XmlPullParser}). + */ + private final static class TestParser extends KXmlParser implements ILayoutPullParser { + /** + * Since we're not going to go through the result of the rendering/layout, we can return + * null for the View Key. + */ + @Override + public Object getViewCookie() { + return null; + } + + @Override + public ILayoutPullParser getParser(String layoutName) { + return null; + } + } + + private final static class ProjectCallBack implements IProjectCallback { + // resource id counter. + // We start at 0x7f000000 to avoid colliding with the framework id + // since we have no access to the project R.java and we need to generate them automatically. + private int mIdCounter = 0x7f000000; + + // in some cases, the id that getResourceValue(String type, String name) returns + // will be sent back to get the type/name. This map stores the id/type/name we generate + // to be able to do the reverse resolution. + private Map<Integer, Pair<ResourceType, String>> mResourceMap = + new HashMap<Integer, Pair<ResourceType, String>>(); + + private boolean mCustomViewAttempt = false; + + @Override + public String getNamespace() { + // TODO: read from the ApiDemos manifest. + return "com.example.android.apis"; + } + + @Override + @SuppressWarnings("unchecked") + public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs) + throws ClassNotFoundException, Exception { + mCustomViewAttempt = true; + return null; + } + + @Override + public Integer getResourceId(ResourceType type, String name) { + Integer result = ++mIdCounter; + mResourceMap.put(result, Pair.of(type, name)); + return result; + } + + @Override + public Pair<ResourceType, String> resolveResourceId(int id) { + return mResourceMap.get(id); + } + + @Override + public String resolveResourceId(int[] id) { + return null; + } + + @Override + public ILayoutPullParser getParser(String layoutName) { + return null; + } + + @Override + public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie, + ResourceReference itemRef, int fullPosition, int typePosition, + int fullChildPosition, int typeChildPosition, + ResourceReference viewRef, ViewAttribute viewAttribute, Object defaultValue) { + return null; + } + + @Override + public AdapterBinding getAdapterBinding(ResourceReference adapterView, + Object adapterCookie, Object viewObject) { + return null; + } + + @Override + public ILayoutPullParser getParser(ResourceValue layoutResource) { + return null; + } + + @Override + public ActionBarCallback getActionBarCallback() { + return new ActionBarCallback(); + } + } + + public void testApiDemos() throws IOException, XmlPullParserException { + findApiDemos(); + } + + private void findApiDemos() throws IOException, XmlPullParserException { + IAndroidTarget[] targets = getSdk().getTargets(); + + for (IAndroidTarget target : targets) { + String path = target.getPath(IAndroidTarget.SAMPLES); + File samples = new File(path); + if (samples.isDirectory()) { + File[] files = samples.listFiles(); + for (File file : files) { + if ("apidemos".equalsIgnoreCase(file.getName())) { + testSample(target, file); + return; + } + } + } + } + + fail("Failed to find ApiDemos!"); + } + + private void testSample(IAndroidTarget target, File sampleProject) throws IOException, XmlPullParserException { + AndroidTargetData data = getSdk().getTargetData(target); + if (data == null) { + fail("No AndroidData!"); + } + + LayoutLibrary layoutLib = data.getLayoutLibrary(); + if (layoutLib.getStatus() != LoadStatus.LOADED) { + fail("Fail to load the bridge: " + layoutLib.getLoadMessage()); + } + + FolderWrapper resFolder = new FolderWrapper(sampleProject, SdkConstants.FD_RES); + if (resFolder.exists() == false) { + fail("Sample project has no res folder!"); + } + + // look for the layout folder + File layoutFolder = new File(resFolder, SdkConstants.FD_RES_LAYOUT); + if (layoutFolder.isDirectory() == false) { + fail("Sample project has no layout folder!"); + } + + // first load the project's target framework resource + ResourceRepository framework = ResourceManager.getInstance().loadFrameworkResources(target); + + // now load the project resources + ResourceRepository project = new ResourceRepository(resFolder, false) { + @Override + protected ResourceItem createResourceItem(String name) { + return new ResourceItem(name); + } + + }; + + // Create a folder configuration that will be used for the rendering: + FolderConfiguration config = getConfiguration(); + + // get the configured resources + Map<ResourceType, Map<String, ResourceValue>> configuredFramework = + framework.getConfiguredResources(config); + Map<ResourceType, Map<String, ResourceValue>> configuredProject = + project.getConfiguredResources(config); + + boolean saveFiles = System.getenv("save_file") != null; + + // loop on the layouts and render them + File[] layouts = layoutFolder.listFiles(); + for (File layout : layouts) { + // create a parser for the layout file + TestParser parser = new TestParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + parser.setInput(new FileReader(layout)); + + System.out.println("Rendering " + layout.getName()); + + ProjectCallBack projectCallBack = new ProjectCallBack(); + + ResourceResolver resolver = ResourceResolver.create( + configuredProject, configuredFramework, + "Theme", false /*isProjectTheme*/); + + HardwareConfig hardwareConfig = new HardwareConfig( + 320, + 480, + Density.MEDIUM, + 160, //xdpi + 160, // ydpi + ScreenSize.NORMAL, + ScreenOrientation.PORTRAIT, + false /*software buttons */); + + RenderSession session = layoutLib.createSession(new SessionParams( + parser, + RenderingMode.NORMAL, + null /*projectKey*/, + hardwareConfig, + resolver, + projectCallBack, + 1, // minSdkVersion + 1, // targetSdkVersion + null //logger + )); + + if (session.getResult().isSuccess() == false) { + if (projectCallBack.mCustomViewAttempt == false) { + System.out.println("FAILED"); + fail(String.format("Rendering %1$s: %2$s", layout.getName(), + session.getResult().getErrorMessage())); + } else { + System.out.println("Ignore custom views for now"); + } + } else { + if (saveFiles) { + File tmp = File.createTempFile(layout.getName(), ".png"); + ImageIO.write(session.getImage(), "png", tmp); + } + System.out.println("Success!"); + } + } + } + + /** + * Returns a config. This must be a valid config like a device would return. This is to + * prevent issues where some resources don't exist in all cases and not in the default + * (for instance only available in hdpi and mdpi but not in default). + * @return + */ + private FolderConfiguration getConfiguration() { + FolderConfiguration config = new FolderConfiguration(); + + // this matches an ADP1. + config.addQualifier(new SmallestScreenWidthQualifier(320)); + config.addQualifier(new ScreenWidthQualifier(320)); + config.addQualifier(new ScreenHeightQualifier(480)); + config.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL)); + config.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG)); + config.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT)); + config.addQualifier(new DensityQualifier(Density.MEDIUM)); + config.addQualifier(new TouchScreenQualifier(TouchScreen.FINGER)); + config.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN)); + config.addQualifier(new TextInputMethodQualifier(Keyboard.QWERTY)); + config.addQualifier(new NavigationStateQualifier(NavigationState.HIDDEN)); + config.addQualifier(new NavigationMethodQualifier(Navigation.TRACKBALL)); + config.addQualifier(new ScreenDimensionQualifier(480, 320)); + + config.updateScreenWidthAndHeight(); + + return config; + } +} |