aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2009-08-12 21:02:09 -0700
committerXavier Ducrohet <xav@android.com>2009-08-13 11:47:54 -0700
commitf74673d6091de43565702a009e598e8e9e34a812 (patch)
treef96e2d0b9aa497a6a9c3bb16cf3ffc88bdc8ba14 /eclipse
parent28d7fe78211540e2977afb51d2ea8af45bdd08bb (diff)
downloadsdk-f74673d6091de43565702a009e598e8e9e34a812.zip
sdk-f74673d6091de43565702a009e598e8e9e34a812.tar.gz
sdk-f74673d6091de43565702a009e598e8e9e34a812.tar.bz2
Add a functional test that renders all the layouts of ApiDemos
Diffstat (limited to 'eclipse')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java171
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/.classpath1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/build.properties4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java13
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java242
7 files changed, 363 insertions, 88 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
index 3cb06fd..88693b0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
@@ -52,13 +52,13 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
/** List of the qualifier object helping for the parsing of folder names */
private final ResourceQualifier[] mQualifiers;
-
+
/**
* Map associating project resource with project objects.
*/
private final HashMap<IProject, ProjectResources> mMap =
new HashMap<IProject, ProjectResources>();
-
+
/**
* Sets up the resource manager with the global resource monitor.
* @param monitor The global resource monitor
@@ -68,10 +68,10 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
int mask = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED;
monitor.addFolderListener(sThis, mask);
monitor.addFileListener(sThis, mask);
-
+
CompiledResourcesMonitor.setupMonitor(monitor);
}
-
+
/**
* Returns the singleton instance.
*/
@@ -87,15 +87,15 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
public ProjectResources getProjectResources(IProject project) {
return mMap.get(project);
}
-
+
/**
* Processes folder event.
*/
public void folderChanged(IFolder folder, int kind) {
ProjectResources resources;
-
+
final IProject project = folder.getProject();
-
+
try {
if (project.hasNature(AndroidConstants.NATURE) == false) {
return;
@@ -104,18 +104,18 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
// can't get the project nature? return!
return;
}
-
+
switch (kind) {
case IResourceDelta.ADDED:
// checks if the folder is under res.
IPath path = folder.getFullPath();
-
+
// the path will be project/res/<something>
if (path.segmentCount() == 3) {
if (isInResFolder(path)) {
// get the project and its resource object.
resources = mMap.get(project);
-
+
// if it doesn't exist, we create it.
if (resources == null) {
resources = new ProjectResources(false /* isFrameworkRepository */);
@@ -146,23 +146,23 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
break;
}
}
-
+
/* (non-Javadoc)
* Sent when a file changed. Depending on the file being changed, and the type of change (ADDED,
* REMOVED, CHANGED), the file change is processed to update the resource manager data.
- *
+ *
* @param file The file that changed.
* @param markerDeltas The marker deltas for the file.
* @param kind The change kind. This is equivalent to
* {@link IResourceDelta#accept(IResourceDeltaVisitor)}
- *
+ *
* @see IFileListener#fileChanged
*/
public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
ProjectResources resources;
-
+
final IProject project = file.getProject();
-
+
try {
if (project.hasNature(AndroidConstants.NATURE) == false) {
return;
@@ -171,22 +171,22 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
// can't get the project nature? return!
return;
}
-
+
switch (kind) {
case IResourceDelta.ADDED:
// checks if the file is under res/something.
IPath path = file.getFullPath();
-
+
if (path.segmentCount() == 4) {
if (isInResFolder(path)) {
// get the project and its resources
resources = mMap.get(project);
-
+
IContainer container = file.getParent();
if (container instanceof IFolder && resources != null) {
-
+
ResourceFolder folder = resources.getResourceFolder((IFolder)container);
-
+
if (folder != null) {
processFile(new IFileWrapper(file), folder);
}
@@ -201,7 +201,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
IContainer container = file.getParent();
if (container instanceof IFolder) {
ResourceFolder resFolder = resources.getResourceFolder((IFolder)container);
-
+
// we get the delete on the folder before the file, so it is possible
// the associated ResourceFolder doesn't exist anymore.
if (resFolder != null) {
@@ -221,7 +221,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
IContainer container = file.getParent();
if (container instanceof IFolder) {
ResourceFolder resFolder = resources.getResourceFolder((IFolder)container);
-
+
// we get the delete on the folder before the file, so it is possible
// the associated ResourceFolder doesn't exist anymore.
if (resFolder != null) {
@@ -249,7 +249,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
public void projectOpenedWithWorkspace(IProject project) {
createProject(project);
}
-
+
/**
* Returns the {@link ResourceFolder} for the given file or <code>null</code> if none exists.
*/
@@ -258,62 +258,85 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
if (container.getType() == IResource.FOLDER) {
IFolder parent = (IFolder)container;
IProject project = file.getProject();
-
+
ProjectResources resources = getProjectResources(project);
if (resources != null) {
return resources.getResourceFolder(parent);
}
}
-
+
return null;
}
-
+
/**
* Loads and returns the resources for a given {@link IAndroidTarget}
* @param androidTarget the target from which to load the framework resources
*/
public ProjectResources loadFrameworkResources(IAndroidTarget androidTarget) {
String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES);
-
+
File frameworkRes = new File(osResourcesPath);
if (frameworkRes.isDirectory()) {
ProjectResources resources = new ProjectResources(true /* isFrameworkRepository */);
try {
- File[] files = frameworkRes.listFiles();
- for (File file : files) {
- if (file.isDirectory()) {
- ResourceFolder resFolder = processFolder(new FolderWrapper(file),
- resources);
-
- if (resFolder != null) {
- // now we process the content of the folder
- File[] children = file.listFiles();
-
- for (File childRes : children) {
- if (childRes.isFile()) {
- processFile(new FileWrapper(childRes), resFolder);
- }
- }
- }
-
- }
- }
-
- // now that we have loaded the files, we need to force load the resources from them
- resources.loadAll();
-
+ loadResources(resources, frameworkRes);
return resources;
-
} catch (IOException e) {
// since we test that folders are folders, and files are files, this shouldn't
// happen. We can ignore it.
}
}
-
+
return null;
}
-
+
+ /**
+ * Loads the resources from a folder, and fills the given {@link ProjectResources}.
+ * <p/>
+ * This is mostly a utility method that should not be used to process actual Eclipse projects
+ * (Those are loaded with {@link #createProject(IProject)} for new project or
+ * {@link #processFolder(IAbstractFolder, ProjectResources)} and
+ * {@link #processFile(IAbstractFile, ResourceFolder)} for folder/file modifications)<br>
+ * This method will process files/folders with implementations of {@link IAbstractFile} and
+ * {@link IAbstractFolder} based on {@link File} instead of {@link IFile} and {@link IFolder}
+ * respectively. This is not proper for handling {@link IProject}s.
+ * </p>
+ * This is used to load the framework resources, or to do load project resources when
+ * setting rendering tests.
+ *
+ *
+ * @param resources The {@link ProjectResources} files to load. It is expected that the
+ * framework flag has been properly setup. This is filled up with the content of the folder.
+ * @param folder The folder to read the resources from. This is the top level resource folder
+ * (res/)
+ * @throws IOException
+ */
+ public void loadResources(ProjectResources resources, File folder) throws IOException {
+ File[] files = folder.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+ ResourceFolder resFolder = processFolder(new FolderWrapper(file),
+ resources);
+
+ if (resFolder != null) {
+ // now we process the content of the folder
+ File[] children = file.listFiles();
+
+ for (File childRes : children) {
+ if (childRes.isFile()) {
+ processFile(new FileWrapper(childRes), resFolder);
+ }
+ }
+ }
+
+ }
+ }
+
+ // now that we have loaded the files, we need to force load the resources from them
+ resources.loadAll();
+ }
+
/**
* Initial project parsing to gather resource info.
* @param project
@@ -328,33 +351,33 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
// can't check the nature of the project? ignore it.
return;
}
-
+
IFolder resourceFolder = project.getFolder(SdkConstants.FD_RESOURCES);
-
+
ProjectResources projectResources = mMap.get(project);
if (projectResources == null) {
projectResources = new ProjectResources(false /* isFrameworkRepository */);
mMap.put(project, projectResources);
}
-
+
if (resourceFolder != null && resourceFolder.exists()) {
try {
IResource[] resources = resourceFolder.members();
-
+
for (IResource res : resources) {
if (res.getType() == IResource.FOLDER) {
IFolder folder = (IFolder)res;
ResourceFolder resFolder = processFolder(new IFolderWrapper(folder),
projectResources);
-
+
if (resFolder != null) {
// now we process the content of the folder
IResource[] files = folder.members();
-
+
for (IResource fileRes : files) {
if (fileRes.getType() == IResource.FILE) {
IFile file = (IFile)fileRes;
-
+
processFile(new IFileWrapper(file), resFolder);
}
}
@@ -383,10 +406,10 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
// Because the order of the qualifier is fixed, we do not reset the first qualifier
// after each sucessful segment.
// If we run out of qualifier before processing all the segments, we fail.
-
+
int qualifierIndex = 0;
int qualifierCount = mQualifiers.length;
-
+
for (int i = 1 ; i < folderSegments.length; i++) {
String seg = folderSegments[i];
if (seg.length() > 0) {
@@ -394,12 +417,12 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
mQualifiers[qualifierIndex].checkAndSet(seg, config) == false) {
qualifierIndex++;
}
-
+
// if we reached the end of the qualifier we didn't find a matching qualifier.
if (qualifierIndex == qualifierCount) {
return null;
}
-
+
} else {
return null;
}
@@ -407,7 +430,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
return config;
}
-
+
/**
* Processes a folder and adds it to the list of the project resources.
* @param folder the folder to process
@@ -420,18 +443,18 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
// get the enum for the resource type.
ResourceFolderType type = ResourceFolderType.getTypeByName(folderSegments[0]);
-
+
if (type != null) {
// get the folder configuration.
FolderConfiguration config = getConfig(folderSegments);
-
+
if (config != null) {
ResourceFolder configuredFolder = project.add(type, config, folder);
return configuredFolder;
}
}
-
+
return null;
}
@@ -443,16 +466,16 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
private void processFile(IAbstractFile file, ResourceFolder folder) {
// get the type of the folder
ResourceFolderType type = folder.getType();
-
+
// look for this file if it's already been created
ResourceFile resFile = folder.getFile(file);
-
+
if (resFile != null) {
// invalidate the file
resFile.touch();
} else {
// create a ResourceFile for it.
-
+
// check if that's a single or multi resource type folder. For now we define this by
// the number of possible resource type output by files in the folder. This does
// not make the difference between several resource types from a single file or
@@ -460,13 +483,13 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
// resource. The former is handled by MultiResourceFile properly while we don't
// handle the latter. If we were to add this behavior we'd have to change this call.
ResourceType[] types = FolderTypeRelationship.getRelatedResourceTypes(type);
-
+
if (types.length == 1) {
resFile = new SingleResourceFile(file, folder);
} else {
resFile = new MultiResourceFile(file, folder);
}
-
+
// add it to the folder
folder.addFile(resFile);
}
@@ -480,7 +503,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
private boolean isInResFolder(IPath path) {
return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
}
-
+
/**
* Private constructor to enforce singleton design.
*/
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/.classpath b/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
index 6f2a534..5762668 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
@@ -6,5 +6,6 @@
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
<classpathentry kind="lib" path="/adt/sdklib.jar" sourcepath="/SdkLib"/>
+ <classpathentry kind="lib" path="/adt/layoutlib_api.jar" sourcepath="/layoutlib_api"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
index a8ec3da..a93bdef 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
@@ -16,4 +16,6 @@ Require-Bundle: org.eclipse.ui,
Bundle-ActivationPolicy: lazy
Bundle-Vendor: The Android Open Source Project
Bundle-ClassPath: kxml2-2.3.0.jar,
- .
+ .,
+ layoutlib_api.jar,
+ sdklib.jar
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/build.properties b/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
index cbfd993..8649a77 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
@@ -7,4 +7,6 @@ bin.includes = META-INF/,\
prefs.template,\
unittest.xml,\
kxml2-2.3.0.jar,\
- unittests/data/
+ unittests/data/,\
+ sdklib.jar,\
+ layoutlib_api.jar
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
index 63f17ab..4322727 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2008 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
@@ -18,7 +18,7 @@ package com.android.ide.eclipse.tests;
import junit.framework.TestCase;
/**
- * Generic superclass for Eclipse Android functional test cases, that provides
+ * Generic superclass for Eclipse Android functional test cases, that provides
* common facilities
*/
public class FuncTestCase extends TestCase {
@@ -27,12 +27,15 @@ public class FuncTestCase extends TestCase {
/**
* Constructor
- *
+ *
* @throws IllegalArgumentException if environment variable "sdk_home" is
* not set
*/
protected FuncTestCase() {
mOsSdkLocation = System.getProperty("sdk_home");
+ if (mOsSdkLocation == null) {
+ mOsSdkLocation = System.getenv("sdk_home");
+ }
if (mOsSdkLocation == null || mOsSdkLocation.length() < 1) {
throw new IllegalArgumentException(
"Environment variable sdk_home is not set");
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
index 08405e8..02c9247 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2008 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
@@ -15,6 +15,7 @@
*/
package com.android.ide.eclipse.tests;
+import com.android.ide.eclipse.tests.functests.layoutRendering.ApiDemosRenderingTest;
import com.android.ide.eclipse.tests.functests.sampleProjects.SampleProjectTest;
import junit.framework.TestSuite;
@@ -28,18 +29,19 @@ public class FuncTests extends TestSuite {
static final String FUNC_TEST_PACKAGE = "com.android.ide.eclipse.tests.functests";
public FuncTests() {
-
+
}
-
+
/**
* Returns a suite of test cases to be run.
* Needed for JUnit3 compliant command line test runner
*/
public static TestSuite suite() {
TestSuite suite = new TestSuite();
-
+
suite.addTestSuite(SampleProjectTest.class);
-
+ suite.addTestSuite(ApiDemosRenderingTest.class);
+
return suite;
}
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 0000000..14e0080
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
+import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
+import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
+import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
+import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
+import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
+import com.android.ide.eclipse.adt.internal.sdk.Sdk;
+import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
+import com.android.ide.eclipse.tests.FuncTestCase;
+import com.android.layoutlib.api.ILayoutResult;
+import com.android.layoutlib.api.IProjectCallback;
+import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.api.IXmlPullParser;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+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 FuncTestCase {
+
+ /**
+ * Custom parser that implements {@link IXmlPullParser} (which itself extends
+ * {@link XmlPullParser}).
+ */
+ private final static class TestParser extends KXmlParser implements IXmlPullParser {
+ /**
+ * Since we're not going to go through the result of the rendering/layout, we can return
+ * null for the View Key.
+ */
+ public Object getViewKey() {
+ 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, String[]> mResourceMap = new HashMap<Integer, String[]>();
+
+ private boolean mCustomViewAttempt = false;
+
+ public String getNamespace() {
+ // TODO: read from the ApiDemos manifest.
+ return "com.example.android.apis";
+ }
+
+ public Integer getResourceValue(String type, String name) {
+ Integer result = ++mIdCounter;
+ mResourceMap.put(result, new String[] { name, type });
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
+ throws ClassNotFoundException, Exception {
+ mCustomViewAttempt = true;
+ return null;
+ }
+
+ public String[] resolveResourceValue(int id) {
+ return mResourceMap.get(id);
+ }
+
+ public String resolveResourceValue(int[] id) {
+ return null;
+ }
+
+ }
+
+ private Sdk mSdk;
+
+ public void testApiDemos() throws IOException, XmlPullParserException {
+ loadSdk();
+ findApiDemos();
+ }
+
+ /**
+ * Loads the {@link Sdk}.
+ */
+ private void loadSdk() {
+ mSdk = Sdk.loadSdk(this.getOsSdkLocation());
+
+ int n = mSdk.getTargets().length;
+ if (n > 0) {
+ for (IAndroidTarget target : mSdk.getTargets()) {
+ IStatus status = new AndroidTargetParser(target).run(new NullProgressMonitor());
+ if (status.getCode() != IStatus.OK) {
+ fail("Failed to parse targets data");
+ }
+ }
+ }
+ }
+
+ private void findApiDemos() throws IOException, XmlPullParserException {
+ IAndroidTarget[] targets = mSdk.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 = mSdk.getTargetData(target);
+ if (data == null) {
+ fail("No AndroidData!");
+ }
+
+ LayoutBridge bridge = data.getLayoutBridge();
+ if (bridge.status != LoadStatus.LOADED || bridge.bridge == null) {
+ fail("Fail to load the bridge");
+ }
+
+ File resFolder = new File(sampleProject, SdkConstants.FD_RES);
+ if (resFolder.isDirectory() == false) {
+ fail("Sample project has no res folder!");
+ }
+
+ // look for the layout folder
+ File layoutFolder = new File(resFolder, SdkConstants.FD_LAYOUT);
+ if (layoutFolder.isDirectory() == false) {
+ fail("Sample project has no layout folder!");
+ }
+
+ // first load the project's target framework resource
+ ProjectResources framework = ResourceManager.getInstance().loadFrameworkResources(target);
+
+ // now load the project resources
+ ProjectResources project = new ProjectResources(false /* isFrameworkRepository */);
+ ResourceManager.getInstance().loadResources(project, resFolder);
+
+
+ // Create a folder configuration that will be used for the rendering:
+ FolderConfiguration config = getConfiguration();
+
+ // get the configured resources
+ Map<String, Map<String, IResourceValue>> configuredFramework =
+ framework.getConfiguredResources(config);
+ Map<String, Map<String, IResourceValue>> 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();
+
+ ILayoutResult result = bridge.bridge.computeLayout(
+ parser,
+ null /*projectKey*/,
+ 320,
+ 480,
+ 160, //density
+ 160, //xdpi
+ 160, // ydpi
+ "Theme", //themeName
+ false, //isProjectTheme
+ configuredProject,
+ configuredFramework,
+ projectCallBack,
+ null //logger
+ );
+
+ if (result.getSuccess() != ILayoutResult.SUCCESS) {
+ if (projectCallBack.mCustomViewAttempt == false) {
+ System.out.println("FAILED");
+ fail(String.format("Rendering %1$s: %2$s", layout.getName(),
+ result.getErrorMessage()));
+ } else {
+ System.out.println("Ignore custom views for now");
+ }
+ } else {
+ if (saveFiles) {
+ File tmp = File.createTempFile(layout.getName(), ".png");
+ ImageIO.write(result.getImage(), "png", tmp);
+ }
+ System.out.println("Success!");
+ }
+ }
+ }
+
+ private FolderConfiguration getConfiguration() {
+ FolderConfiguration config = new FolderConfiguration();
+
+ return config;
+ }
+}