aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java135
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java40
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java121
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java48
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkLoadingTestCase.java117
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java61
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java328
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java131
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java263
9 files changed, 0 insertions, 1244 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java
deleted file mode 100644
index c86f4cf5f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Platform;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.logging.Logger;
-
-/**
- * Helper class for retrieving test data
- * <p/>
- * All tests which need to retrieve paths to test data files should go through this class.
- */
-public class AdtTestData {
-
- /** singleton instance */
- private static AdtTestData sInstance = null;
- private static final Logger sLogger = Logger.getLogger(AdtTestData.class.getName());
-
- /** The prefered directory separator to use. */
- private static final String DIR_SEP_STR = "/";
- private static final char DIR_SEP_CHAR = '/';
-
- /** The absolute file path to the plugin's contents. */
- private String mOsRootDataPath;
-
- private AdtTestData() {
- // can set test_data env variable to override default behavior of
- // finding data using class loader
- // useful when running in plugin environment, where test data is inside
- // bundled jar, and must be extracted to temp filesystem location to be
- // accessed normally
- mOsRootDataPath = System.getProperty("test_data");
- if (mOsRootDataPath == null) {
- sLogger.info("Cannot find test_data environment variable, init to class loader");
- URL url = this.getClass().getClassLoader().getResource("."); //$NON-NLS-1$
-
- if (Platform.isRunning()) {
- sLogger.info("Running as an Eclipse Plug-in JUnit test, using FileLocator");
- try {
- mOsRootDataPath = FileLocator.resolve(url).getFile();
- if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- // Fix the path returned by the URL resolver
- // so that it actually works on Windows.
-
- // First, Windows paths don't start with a / especially
- // if they contain a drive spec such as C:/...
- int pos = mOsRootDataPath.indexOf(':');
- if (pos > 0 && mOsRootDataPath.charAt(0) == '/') {
- mOsRootDataPath = mOsRootDataPath.substring(1);
- }
-
- // Looking for "." probably inserted a /./, so clean it up
- mOsRootDataPath = mOsRootDataPath.replace("/./", "/");
- }
- } catch (IOException e) {
- sLogger.warning("IOException while using FileLocator, reverting to url");
- mOsRootDataPath = url.getFile();
- }
- } else {
- sLogger.info("Running as an plain JUnit test, using url as-is");
- mOsRootDataPath = url.getFile();
- }
- }
-
- if (mOsRootDataPath.equals(AdtConstants.WS_SEP)) {
- sLogger.warning("Resource data not found using class loader!, Defaulting to no path");
- }
-
- if (File.separatorChar == '\\') {
- // On Windows, uniformize all separators to use the / convention
- mOsRootDataPath.replace('\\', DIR_SEP_CHAR);
- }
-
- if (!mOsRootDataPath.endsWith(File.separator) && !mOsRootDataPath.endsWith(DIR_SEP_STR)) {
- sLogger.info("Fixing test_data env variable (does not end with path separator)");
- mOsRootDataPath += DIR_SEP_STR;
- }
- }
-
- /** Get the singleton instance of AdtTestData */
- public static AdtTestData getInstance() {
- if (sInstance == null) {
- sInstance = new AdtTestData();
- }
- return sInstance;
- }
-
- /**
- * Returns the absolute file path to a file located in this plugin.
- *
- * @param osRelativePath {@link String} path to file contained in plugin. Must
- * use path separators appropriate to host OS
- *
- * @return absolute OS path to test file
- */
- public String getTestFilePath(String osRelativePath) {
- File path = new File(mOsRootDataPath, osRelativePath);
-
- if (!path.exists()) {
- // On Windows at least this ends up using the wrong plugin path.
- String pkgAdt = AdtPlugin .class.getPackage().getName();
- String pkgTests = AdtTestData.class.getPackage().getName();
-
- if (mOsRootDataPath.contains(pkgAdt)) {
- path = new File(mOsRootDataPath.replace(pkgAdt, pkgTests), osRelativePath);
- }
-
- assert path.exists();
- }
-
- return path.getAbsolutePath();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java
deleted file mode 100644
index 5386142a8..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import junit.framework.TestSuite;
-
-
-/**
- * Container TestSuite for all eclipse tests, both functional and unit
- */
-public class AllTests extends TestSuite {
-
- public AllTests() {
-
- }
-
- /**
- * Returns a suite of test cases to be run.
- */
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(FuncTests.suite());
- suite.addTest(UnitTests.suite());
- return suite;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java
deleted file mode 100644
index 6bbc955ee..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import org.eclipse.core.runtime.Plugin;
-
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.Enumeration;
-
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Class for collecting all test cases in an eclipse plugin
- *
- */
-public class EclipseTestCollector {
-
- /**
- * Constructor
- */
- public EclipseTestCollector() {
-
- }
-
- /**
- * Searches through given plugin, adding all TestCase classes to given suite
- * @param suite - TestSuite to add to
- * @param plugin - Plugin to search for tests
- * @param expectedPackage - expected package for tests. Only test classes
- * that start with this package name will be added to suite
- */
- @SuppressWarnings({"cast", "unchecked"})
- public void addTestCases(TestSuite suite, Plugin plugin, String expectedPackage) {
- if (plugin != null) {
- Enumeration<?> entries = plugin.getBundle().findEntries("/", "*.class", true);
-
- while (entries.hasMoreElements()) {
- URL entry = (URL)entries.nextElement();
- String filePath = entry.getPath().replace(".class", "");
- try {
- Class<?> testClass = getClass(filePath, expectedPackage);
- if (isTestClass(testClass)) {
- // In Eclipse 3.6 RCP Windows-x64, the signature has changed from
- // addTestSuite(Class)
- // to:
- // addTestSuite(Class<? extends TestCase>)
- // which is enough to create an error. To solve it, we cast into the
- // generics expected by the JUnit framework used by 3.6 and suppress the
- // warnings generated by the compiler under 3.5
- suite.addTestSuite((Class<? extends TestCase>)testClass);
- }
- }
- catch (ClassNotFoundException e) {
- // ignore, this is not the class we're looking for
- //sLogger.log(Level.INFO, "Could not load class " + filePath);
- }
- }
- }
- }
-
- /**
- * Returns true if given class should be added to suite
- */
- protected boolean isTestClass(Class<?> testClass) {
- return TestCase.class.isAssignableFrom(testClass) &&
- Modifier.isPublic(testClass.getModifiers()) &&
- hasPublicConstructor(testClass);
- }
-
- /**
- * Returns true if given class has a public constructor
- */
- @SuppressWarnings({"unchecked", "cast"})
- protected boolean hasPublicConstructor(Class<?> testClass) {
- try {
- // In Eclipse 3.6 RCP Windows-x64, the signature has changed from
- // getTestConstructor(Class)
- // to:
- // getTestConstructor(Class<? extends TestCase>)
- // which is enough to create an error. To solve it, we cast into the
- // generics expected by the JUnit framework used by 3.6 and suppress the
- // warnings generated by the compiler under 3.5
- TestSuite.getTestConstructor((Class<? extends TestCase>) testClass);
- } catch(NoSuchMethodException e) {
- return false;
- }
- return true;
- }
-
- /**
- * Load the class given by the plugin aka bundle file path
- * @param filePath - path of class in bundle
- * @param expectedPackage - expected package of class
- * @throws ClassNotFoundException
- */
- protected Class<?> getClass(String filePath, String expectedPackage) throws ClassNotFoundException {
- String dotPath = filePath.replace('/', '.');
- // remove the output folders, by finding where package name starts
- int index = dotPath.indexOf(expectedPackage);
- if (index == -1) {
- throw new ClassNotFoundException();
- }
- String packagePath = dotPath.substring(index);
- return Class.forName(packagePath);
- }
-}
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
deleted file mode 100644
index efa880126..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.eclipse.tests.functests.layoutRendering.ApiDemosRenderingTest;
-
-import junit.framework.TestSuite;
-
-/**
- * Container TestSuite for all eclipse tests to be run
- */
-
-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();
-
- // TODO: uncomment this when 'gen' folder error on create is fixed
- // 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/SdkLoadingTestCase.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkLoadingTestCase.java
deleted file mode 100644
index 65ce8e1d7..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/SdkLoadingTestCase.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-import com.android.ide.common.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.testutils.SdkTestCase;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-
-/**
- * A test case which uses the SDK loaded by the ADT plugin.
- */
-public abstract class SdkLoadingTestCase extends SdkTestCase {
-
- private Sdk mSdk;
-
- protected SdkLoadingTestCase() {
- }
-
- /**
- * Retrieve the {@link Sdk} under test.
- */
- protected Sdk getSdk() {
- if (mSdk == null) {
- mSdk = loadSdk();
- assertNotNull(mSdk);
- validateSdk(mSdk);
- }
- return mSdk;
- }
-
- /**
- * Gets the current SDK from ADT, waiting if necessary.
- */
- private Sdk loadSdk() {
- AdtPlugin adt = AdtPlugin.getDefault();
-
- // We'll never get an AdtPlugin object when running this with the
- // non-Eclipse jUnit test runner.
- if (adt == null) {
- return null;
- }
-
- // We'll never break out of the SDK load-wait-loop if the AdtPlugin doesn't
- // actually have a valid SDK location because it won't have started an async load:
- String sdkLocation = AdtPrefs.getPrefs().getOsSdkFolder();
- assertTrue("No valid SDK installation is set; for tests you typically need to set the"
- + " environment variable ADT_TEST_SDK_PATH to point to an SDK folder",
- sdkLocation != null && sdkLocation.length() > 0);
-
- Object sdkLock = Sdk.getLock();
- LoadStatus loadStatus = LoadStatus.LOADING;
- // wait for ADT to load the SDK on a separate thread
- // loop max of 600 times * 200 ms = 2 minutes
- final int maxWait = 600;
- for (int i=0; i < maxWait && loadStatus == LoadStatus.LOADING; i++) {
- try {
- Thread.sleep(200);
- }
- catch (InterruptedException e) {
- // ignore
- }
- synchronized (sdkLock) {
- loadStatus = adt.getSdkLoadStatus();
- }
- }
- Sdk sdk = null;
- synchronized (sdkLock) {
- assertEquals(LoadStatus.LOADED, loadStatus);
- sdk = Sdk.getCurrent();
- }
- assertNotNull(sdk);
- return sdk;
- }
-
- protected boolean validateSdk(IAndroidTarget target) {
- return true;
- }
-
- /**
- * Checks that the provided sdk contains one or more valid targets.
- * @param sdk the {@link Sdk} to validate.
- */
- private void validateSdk(Sdk sdk) {
- assertTrue("sdk has no targets", sdk.getTargets().length > 0);
- for (IAndroidTarget target : sdk.getTargets()) {
- if (!validateSdk(target)) {
- continue;
- }
- if (false) { // This takes forEVER
- IStatus status = new AndroidTargetParser(target).run(new NullProgressMonitor());
- if (status.getCode() != IStatus.OK) {
- fail("Failed to parse targets data");
- }
- }
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java
deleted file mode 100644
index 15d38715c..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests;
-
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * Container TestSuite for all eclipse unit tests to be run
- *
- * Uses Eclipse OSGI to find and then run all junit.junit.framework.Tests in
- * this plugin, excluding tests in the FuncTests.FUNC_TEST_PACKAGE package
- *
- * Since it uses Eclipse OSGI, it must be run in a Eclipse plugin environment
- * i.e. from Eclipse workbench, this suite must be run using the
- * "JUnit Plug-in Test" launch configuration as opposed to as a "JUnit Test"
- *
- */
-public class UnitTests {
- private static final String TEST_PACKAGE = "com.android";
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- UnitTestCollector collector = new UnitTestCollector();
- // since this plugin is a fragment which runs insde adt, gather tests from AdtPlugin
- collector.addTestCases(suite, AdtPlugin.getDefault(), TEST_PACKAGE);
-
- return suite;
- }
-
- /**
- * Specialized test collector which will skip adding functional tests
- */
- private static class UnitTestCollector extends EclipseTestCollector {
- /**
- * Override parent class to exclude functional tests
- */
- @Override
- protected boolean isTestClass(Class<?> testClass) {
- return super.isTestClass(testClass) &&
- !testClass.getPackage().getName().startsWith(FuncTests.FUNC_TEST_PACKAGE);
- }
- }
-}
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
deleted file mode 100644
index d6b401b62..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * 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;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java
deleted file mode 100644
index 141e7e000..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.sampleProjects;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.xml.AndroidManifest;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-/**
- * Helper class for modifying an AndroidManifest.
- * <p/>
- * TODO: consider merging this with AndroidManifestParser.
- */
-class AndroidManifestWriter {
-
- private static final Logger sLogger = Logger.getLogger(AndroidManifestWriter.class.getName());
-
- private final Document mDoc;
- private final String mOsManifestFilePath;
-
- private AndroidManifestWriter(Document doc, String osManifestFilePath) {
- mDoc = doc;
- mOsManifestFilePath = osManifestFilePath;
- }
-
- /**
- * Sets the minimum SDK version for this manifest
- * @param minSdkVersion - the minimim sdk version to use
- * @returns <code>true</code> on success, false otherwise
- */
- public boolean setMinSdkVersion(String minSdkVersion) {
- Element usesSdkElement = null;
- NodeList nodeList = mDoc.getElementsByTagName(AndroidManifest.NODE_USES_SDK);
- if (nodeList.getLength() > 0) {
- usesSdkElement = (Element) nodeList.item(0);
- } else {
- usesSdkElement = mDoc.createElement(AndroidManifest.NODE_USES_SDK);
- mDoc.getDocumentElement().appendChild(usesSdkElement);
- }
- Attr minSdkAttr = mDoc.createAttributeNS(SdkConstants.NS_RESOURCES,
- AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
- String prefix = mDoc.lookupPrefix(SdkConstants.NS_RESOURCES);
- minSdkAttr.setPrefix(prefix);
- minSdkAttr.setValue(minSdkVersion);
- usesSdkElement.setAttributeNodeNS(minSdkAttr);
- return saveXmlToFile();
- }
-
- private boolean saveXmlToFile() {
- try {
- // Prepare the DOM document for writing
- Source source = new DOMSource(mDoc);
-
- // Prepare the output file
- File file = new File(mOsManifestFilePath);
- Result result = new StreamResult(file);
-
- // Write the DOM document to the file
- Transformer xformer = TransformerFactory.newInstance().newTransformer();
- xformer.transform(source, result);
- } catch (TransformerConfigurationException e) {
- sLogger.log(Level.SEVERE, "Failed to write xml file", e);
- return false;
- } catch (TransformerException e) {
- sLogger.log(Level.SEVERE, "Failed to write xml file", e);
- return false;
- }
- return true;
- }
-
- /**
- * Parses the manifest file, and collects data.
- *
- * @param osManifestFilePath The OS path of the manifest file to parse.
- * @return an {@link AndroidManifestHelper} or null if parsing failed
- */
- public static AndroidManifestWriter parse(String osManifestFilePath) {
- try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- docFactory.setNamespaceAware(true);
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- Document doc = docBuilder.parse(osManifestFilePath);
- return new AndroidManifestWriter(doc, osManifestFilePath);
- } catch (ParserConfigurationException e) {
- sLogger.log(Level.SEVERE, "Error parsing file", e);
- return null;
- } catch (SAXException e) {
- sLogger.log(Level.SEVERE, "Error parsing file", e);
- return null;
- } catch (IOException e) {
- sLogger.log(Level.SEVERE, "Error parsing file", e);
- return null;
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
deleted file mode 100644
index 3fb705dfb..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.ide.eclipse.tests.functests.sampleProjects;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreator;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-import com.android.ide.eclipse.tests.SdkLoadingTestCase;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.operation.IRunnableContext;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.swt.widgets.Display;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Test case that verifies all SDK sample projects can be imported, and built in
- * Eclipse.
- * <p/>
- * TODO: add support for deploying apps onto emulator and verifying successful
- * execution there
- *
- */
-public class SampleProjectTest extends SdkLoadingTestCase {
-
- private static final Logger sLogger = Logger.getLogger(SampleProjectTest.class.getName());
-
- /**
- * Finds all samples projects in set SDK and verify they can be built in Eclipse.
- * <p/>
- * TODO: add install and run on emulator test
- * @throws CoreException
- */
- public void testSamples() throws CoreException {
- // TODO: For reporting purposes, it would be better if a separate test success or failure
- // could be reported for each sample
- IAndroidTarget[] targets = getSdk().getTargets();
- for (IAndroidTarget target : targets) {
- doTestSamplesForTarget(target);
- }
- }
-
- private void doTestSamplesForTarget(IAndroidTarget target) throws CoreException {
- String path = target.getPath(IAndroidTarget.SAMPLES);
- File samples = new File(path);
- if (samples.isDirectory()) {
- File[] files = samples.listFiles();
- for (File file : files) {
- if (file.isDirectory()) {
- doTestSampleProject(file.getName(), file.getAbsolutePath(), target);
- }
- }
- }
- }
-
- /**
- * Tests the sample project with the given name
- *
- * @param target - SDK target of project
- * @param name - name of sample project to test
- * @param path - absolute file system path
- * @throws CoreException
- */
- private void doTestSampleProject(String name, String path, IAndroidTarget target)
- throws CoreException {
- IProject iproject = null;
- try {
- sLogger.log(Level.INFO, String.format("Testing sample %s for target %s", name,
- target.getName()));
-
- prepareProject(path, target);
-
- IRunnableContext context = new IRunnableContext() {
- @Override
- public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
- throws InvocationTargetException, InterruptedException {
- runnable.run(new NullProgressMonitor());
- }
- };
- NewProjectWizardState state = new NewProjectWizardState(Mode.SAMPLE);
- state.projectName = name;
- state.target = target;
- state.packageName = "com.android.samples";
- state.activityName = name;
- state.applicationName = name;
- state.chosenSample = new File(path);
- state.useDefaultLocation = false;
- state.createActivity = false;
-
- NewProjectCreator creator = new NewProjectCreator(state, context);
- creator.createAndroidProjects();
- iproject = validateProjectExists(name);
- validateNoProblems(iproject);
- }
- catch (CoreException e) {
- sLogger.log(Level.SEVERE,
- String.format("Unexpected exception when creating sample project %s " +
- "for target %s", name, target.getName()));
- throw e;
- } finally {
- if (iproject != null) {
- iproject.delete(false, true, new NullProgressMonitor());
- }
- }
- }
-
- private void prepareProject(String path, IAndroidTarget target) {
- if (target.getVersion().isPreview()) {
- // need to explicitly set preview's version in manifest for project to compile
- final String manifestPath = path + File.separatorChar +
- SdkConstants.FN_ANDROID_MANIFEST_XML;
- AndroidManifestWriter manifestWriter =
- AndroidManifestWriter.parse(manifestPath);
- assertNotNull(String.format("could not read manifest %s", manifestPath),
- manifestWriter);
- assertTrue(manifestWriter.setMinSdkVersion(target.getVersion().getApiString()));
- }
- }
-
- private IProject validateProjectExists(String name) {
- IProject iproject = getIProject(name);
- assertTrue(String.format("%s project not created", name), iproject.exists());
- assertTrue(String.format("%s project not opened", name), iproject.isOpen());
- return iproject;
- }
-
- private IProject getIProject(String name) {
- IProject iproject = ResourcesPlugin.getWorkspace().getRoot()
- .getProject(name);
- return iproject;
- }
-
- private void validateNoProblems(IProject iproject) throws CoreException {
- waitForBuild(iproject);
-
- boolean hasErrors = false;
- StringBuilder failureBuilder = new StringBuilder(String.format("%s project has errors:",
- iproject.getName()));
- IMarker[] markers = iproject.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
- if (markers != null && markers.length > 0) {
- // the project has marker(s). even though they are "problem" we
- // don't know their severity. so we loop on them and figure if they
- // are warnings or errors
- for (IMarker m : markers) {
- int s = m.getAttribute(IMarker.SEVERITY, -1);
- if (s == IMarker.SEVERITY_ERROR) {
- hasErrors = true;
- failureBuilder.append("\n");
- failureBuilder.append(m.getAttribute(IMarker.MESSAGE, ""));
- }
- }
- }
- failureBuilder.append("Project location: " + AdtUtils.getAbsolutePath(iproject));
- assertFalse(failureBuilder.toString(), hasErrors);
- }
-
- /**
- * Waits for build to complete.
- *
- * @param iproject
- */
- private void waitForBuild(final IProject iproject) {
-
- final BuiltProjectDeltaVisitor deltaVisitor = new BuiltProjectDeltaVisitor(iproject);
- IResourceChangeListener newBuildListener = new IResourceChangeListener() {
-
- @Override
- public void resourceChanged(IResourceChangeEvent event) {
- try {
- event.getDelta().accept(deltaVisitor);
- }
- catch (CoreException e) {
- fail();
- }
- }
-
- };
- iproject.getWorkspace().addResourceChangeListener(newBuildListener,
- IResourceChangeEvent.POST_BUILD);
-
- // poll build listener to determine when build is done
- // loop max of 1200 times * 50 ms = 60 seconds
- final int maxWait = 1200;
- for (int i=0; i < maxWait; i++) {
- if (deltaVisitor.isProjectBuilt()) {
- return;
- }
- try {
- Thread.sleep(50);
- }
- catch (InterruptedException e) {
- // ignore
- }
- if (Display.getCurrent() != null) {
- Display.getCurrent().readAndDispatch();
- }
- }
-
- sLogger.log(Level.SEVERE, "expected build event never happened?");
- fail(String.format("Expected build event never happened for %s", iproject.getName()));
- }
-
- /**
- * Scans a given IResourceDelta looking for a "build event" change for given IProject
- *
- */
- private class BuiltProjectDeltaVisitor implements IResourceDeltaVisitor {
-
- private IProject mIProject;
- private boolean mIsBuilt;
-
- public BuiltProjectDeltaVisitor(IProject iproject) {
- mIProject = iproject;
- mIsBuilt = false;
- }
-
- @Override
- public boolean visit(IResourceDelta delta) {
- if (mIProject.equals(delta.getResource())) {
- setBuilt(true);
- return false;
- }
- return true;
- }
-
- private synchronized void setBuilt(boolean b) {
- mIsBuilt = b;
- }
-
- public synchronized boolean isProjectBuilt() {
- return mIsBuilt;
- }
- }
-}