diff options
author | Tor Norbye <tnorbye@google.com> | 2011-04-18 15:01:58 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-04-18 15:01:58 -0700 |
commit | 0218b8eb348bdb65acadc11f3f48aec72c35c920 (patch) | |
tree | a2d75e87db1b59c2496b0011b55660632ee2ea1e | |
parent | b0f50e6ac987902891c2bbc6bfa4f51a46e31b73 (diff) | |
parent | ab02e0845abebb9dd36e6e3cf9a2b5ecfb34bdaa (diff) | |
download | sdk-0218b8eb348bdb65acadc11f3f48aec72c35c920.zip sdk-0218b8eb348bdb65acadc11f3f48aec72c35c920.tar.gz sdk-0218b8eb348bdb65acadc11f3f48aec72c35c920.tar.bz2 |
Merge "Cache resource resolver and manifest info"
6 files changed, 138 insertions, 79 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java index 05a1264..6592fa2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.editors.layout.gle2; import static com.android.ide.common.layout.LayoutConstants.ANDROID_STRING_PREFIX; +import static com.android.ide.common.layout.LayoutConstants.LAYOUT_PREFIX; import static com.android.ide.common.layout.LayoutConstants.SCROLL_VIEW; import static com.android.ide.common.layout.LayoutConstants.STRING_PREFIX; import static com.android.ide.eclipse.adt.AdtConstants.ANDROID_PKG; @@ -55,6 +56,7 @@ import com.android.ide.eclipse.adt.internal.editors.layout.configuration.LayoutC import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.IncludeFinder.Reference; import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine; +import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; import com.android.ide.eclipse.adt.internal.editors.ui.DecorComposite; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; @@ -236,6 +238,7 @@ public class GraphicalEditorPart extends EditorPart private TargetListener mTargetListener; private ConfigListener mConfigListener; + private ResourceResolver mResourceResolver; private ReloadListener mReloadListener; @@ -436,6 +439,7 @@ public class GraphicalEditorPart extends EditorPart */ public void onConfigurationChange() { mConfiguredFrameworkRes = mConfiguredProjectRes = null; + mResourceResolver = null; if (mEditedFile == null || mConfigComposite.getEditedConfig() == null) { return; @@ -511,6 +515,7 @@ public class GraphicalEditorPart extends EditorPart public void onThemeChange() { // Store the state in the current file mConfigComposite.storeState(); + mResourceResolver = null; recomputeLayout(); @@ -778,6 +783,7 @@ public class GraphicalEditorPart extends EditorPart // because the target changed we must reset the configured resources. mConfiguredFrameworkRes = mConfiguredProjectRes = null; + mResourceResolver = null; // make sure we remove the custom view loader, since its parent class loader is the // bridge class loader. @@ -796,7 +802,7 @@ public class GraphicalEditorPart extends EditorPart /** Refresh the configured project resources associated with this editor */ public void refreshProjectResources() { mConfiguredProjectRes = null; - mConfigListener.getConfiguredProjectResources(); + mResourceResolver = null; } /** @@ -1381,59 +1387,33 @@ public class GraphicalEditorPart extends EditorPart model.refreshUi(); } - private RenderSession renderWithBridge(IProject iProject, UiDocumentNode model, + private RenderSession renderWithBridge(IProject project, UiDocumentNode model, LayoutLibrary layoutLib, int width, int height, Set<UiElementNode> explodeNodes, Integer overrideBgColor, boolean noDecor, LayoutLog logger, Reference includeWithin, RenderingMode renderingMode) { ResourceManager resManager = ResourceManager.getInstance(); - ProjectResources projectRes = resManager.getProjectResources(iProject); + ProjectResources projectRes = resManager.getProjectResources(project); if (projectRes == null) { displayError("Missing project resources."); return null; } - // Get the resources of the file's project. - Map<ResourceType, Map<String, ResourceValue>> configuredProjectRes = - mConfigListener.getConfiguredProjectResources(); - - // Get the framework resources - Map<ResourceType, Map<String, ResourceValue>> frameworkResources = - mConfigListener.getConfiguredFrameworkResources(); - - // Abort the rendering if the resources are not found. - if (configuredProjectRes == null) { - displayError("Missing project resources for current configuration."); - return null; - } - - if (frameworkResources == null) { - displayError("Missing framework resources."); - return null; - } - // Lazily create the project callback the first time we need it if (mProjectCallback == null) { - mProjectCallback = new ProjectCallback(layoutLib, projectRes, iProject); + mProjectCallback = new ProjectCallback(layoutLib, projectRes, project); } else { // Also clears the set of missing/broken classes prior to rendering mProjectCallback.getMissingClasses().clear(); mProjectCallback.getUninstantiatableClasses().clear(); } - // get the selected theme - String theme = mConfigComposite.getTheme(); - if (theme == null) { - displayError("Missing theme."); - return null; - } - if (mUseExplodeMode) { // compute how many padding in x and y will bump the screen size List<UiElementNode> children = model.getUiChildren(); if (children.size() == 1) { ExplodedRenderingHelper helper = new ExplodedRenderingHelper( - children.get(0).getXmlNode(), iProject); + children.get(0).getXmlNode(), project); // there are 2 paddings for each view // left and right, or top and bottom. @@ -1447,10 +1427,9 @@ public class GraphicalEditorPart extends EditorPart Density density = mConfigComposite.getDensity(); float xdpi = mConfigComposite.getXDpi(); float ydpi = mConfigComposite.getYDpi(); - boolean isProjectTheme = mConfigComposite.isProjectTheme(); ILayoutPullParser modelParser = new UiElementPullParser(model, - mUseExplodeMode, explodeNodes, density, xdpi, iProject); + mUseExplodeMode, explodeNodes, density, xdpi, project); ILayoutPullParser topParser = modelParser; // Code to support editing included layout @@ -1460,9 +1439,8 @@ public class GraphicalEditorPart extends EditorPart String contextLayoutName = includeWithin.getName(); // Find the layout file. - Map<String, ResourceValue> layouts = configuredProjectRes.get( - ResourceType.LAYOUT); - ResourceValue contextLayout = layouts.get(contextLayoutName); + ResourceValue contextLayout = getResourceResolver().findResValue( + LAYOUT_PREFIX + contextLayoutName , false /* forceFrameworkOnly*/); if (contextLayout != null) { File layoutFile = new File(contextLayout.getValue()); if (layoutFile.isFile()) { @@ -1482,15 +1460,16 @@ public class GraphicalEditorPart extends EditorPart } } - // FIXME: make resource resolver persistent, and only update it when something changes. - ResourceResolver resolver = ResourceResolver.create( - configuredProjectRes, frameworkResources, - theme, isProjectTheme); + ResourceResolver resolver = getResourceResolver(); + if (resolver == null) { + // Abort the rendering if the resources are not found. + return null; + } SessionParams params = new SessionParams( topParser, renderingMode, - iProject /* projectKey */, + project /* projectKey */, width, height, density, xdpi, ydpi, resolver, @@ -1500,19 +1479,11 @@ public class GraphicalEditorPart extends EditorPart logger); if (noDecor) { params.setForceNoDecor(); - } - - // FIXME make persistent and only reload when the manifest (or at least resources) changes. - IFolderWrapper projectFolder = new IFolderWrapper(getProject()); - IAbstractFile manifest = AndroidManifest.getManifest(projectFolder); - if (manifest != null) { - try { - params.setAppIcon(AndroidManifest.getApplicationIcon(manifest)); - } catch (Exception e) { - // ignore. - } + } else { + ManifestInfo manifestInfo = ManifestInfo.get(project); try { - params.setAppLabel(AndroidManifest.getApplicationLabel(manifest)); + params.setAppLabel(manifestInfo.getApplicationLabel()); + params.setAppIcon(manifestInfo.getApplicationIcon()); } catch (Exception e) { // ignore. } @@ -1530,18 +1501,6 @@ public class GraphicalEditorPart extends EditorPart // set the Image Overlay as the image factory. params.setImageFactory(getCanvasControl().getImageOverlay()); - // --------------------------------------- - // Data binding DEBUG -// AdapterBinding binding = new AdapterBinding(3); -// binding.addHeader(new ResourceReference("header", false)); -// binding.addFooter(new ResourceReference("footer", false)); -// DataBindingItem item = new DataBindingItem("groupitem", false, 3); -// binding.addItem(item); -// item.addChild(new DataBindingItem("separator", false, 1)); -// item.addChild(new DataBindingItem("listitem", false, 3)); -// params.addAdapterBinding(new ResourceReference("listview"), binding); - // --------------------------------------- - try { mProjectCallback.setLogger(logger); return layoutLib.createSession(params); @@ -1564,7 +1523,7 @@ public class GraphicalEditorPart extends EditorPart * @return the image, or null if something went wrong */ BufferedImage renderThemeItem(String itemName, int width, int height) { - ResourceResolver resources = createResolver(); + ResourceResolver resources = getResourceResolver(); LayoutLibrary layoutLibrary = getLayoutLibrary(); IProject project = getProject(); ResourceValue drawableResourceValue = resources.findItemInTheme(itemName); @@ -1591,19 +1550,44 @@ public class GraphicalEditorPart extends EditorPart return null; } - public ResourceResolver createResolver() { - String theme = mConfigComposite.getTheme(); - boolean isProjectTheme = mConfigComposite.isProjectTheme(); - Map<ResourceType, Map<String, ResourceValue>> configuredProjectRes = - mConfigListener.getConfiguredProjectResources(); + /** + * Returns the {@link ResourceResolver} for this editor + * + * @return the resolver used to resolve resources for the current configuration of + * this editor, or null + */ + public ResourceResolver getResourceResolver() { + if (mResourceResolver == null) { + String theme = mConfigComposite.getTheme(); + if (theme == null) { + displayError("Missing theme."); + return null; + } + boolean isProjectTheme = mConfigComposite.isProjectTheme(); + + Map<ResourceType, Map<String, ResourceValue>> configuredProjectRes = + mConfigListener.getConfiguredProjectResources(); + + // Get the framework resources + Map<ResourceType, Map<String, ResourceValue>> frameworkResources = + mConfigListener.getConfiguredFrameworkResources(); + + if (configuredProjectRes == null) { + displayError("Missing project resources for current configuration."); + return null; + } + + if (frameworkResources == null) { + displayError("Missing framework resources."); + return null; + } - // Get the framework resources - Map<ResourceType, Map<String, ResourceValue>> frameworkResources = - mConfigListener.getConfiguredFrameworkResources(); + mResourceResolver = ResourceResolver.create( + configuredProjectRes, frameworkResources, + theme, isProjectTheme); + } - return ResourceResolver.create( - configuredProjectRes, frameworkResources, - theme, isProjectTheme); + return mResourceResolver; } /** @@ -1702,6 +1686,7 @@ public class GraphicalEditorPart extends EditorPart // force a reparse in case a value XML file changed. mConfiguredProjectRes = null; + mResourceResolver = null; // clear the cache in the bridge in case a bitmap/9-patch changed. LayoutLibrary layoutLib = getReadyLayoutLib(true /*displayError*/); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PreviewIconFactory.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PreviewIconFactory.java index 4d28df5..80cc87d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PreviewIconFactory.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PreviewIconFactory.java @@ -338,7 +338,7 @@ public class PreviewIconFactory { RGB background = null; RGB foreground = null; - ResourceResolver resources = mPalette.getEditor().createResolver(); + ResourceResolver resources = mPalette.getEditor().getResourceResolver(); StyleResourceValue theme = resources.getCurrentTheme(); if (theme != null) { background = resolveThemeColor(resources, "windowBackground"); //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java index 8e43c35..9e8114a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java @@ -515,7 +515,7 @@ public class ExtractStyleRefactoring extends VisualRefactoring { if (types.size() == 1) { String view = DescriptorsUtils.getBasename(types.iterator().next()); - ResourceResolver resolver = mEditor.getGraphicalEditor().createResolver(); + ResourceResolver resolver = mEditor.getGraphicalEditor().getResourceResolver(); // Look up the theme item name, which for a Button would be "buttonStyle", and so on. String n = Character.toLowerCase(view.charAt(0)) + view.substring(1) + "Style"; //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java index 5e71822..0feab55 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java @@ -18,6 +18,8 @@ package com.android.ide.eclipse.adt.internal.editors.manifest; import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_STYLE; import static com.android.sdklib.SdkConstants.NS_RESOURCES; +import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_ICON; +import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_LABEL; import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION; import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_NAME; import static com.android.sdklib.xml.AndroidManifest.ATTRIBUTE_PACKAGE; @@ -98,6 +100,8 @@ public class ManifestInfo { private IAbstractFile mManifestFile; private long mLastModified; private int mTargetSdk; + private String mApplicationIcon; + private String mApplicationLabel; /** * Qualified name for the per-project non-persistent property storing the @@ -167,6 +171,8 @@ public class ManifestInfo { mManifestTheme = null; mTargetSdk = 1; // Default when not specified mPackage = ""; //$NON-NLS-1$ + mApplicationIcon = null; + mApplicationLabel = null; Document document = null; try { @@ -194,6 +200,18 @@ public class ManifestInfo { } } + NodeList applications = root.getElementsByTagName(AndroidManifest.NODE_APPLICATION); + if (applications.getLength() > 0) { + assert applications.getLength() == 1; + Element application = (Element) applications.item(0); + if (application.hasAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON)) { + mApplicationIcon = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON); + } + if (application.hasAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL)) { + mApplicationLabel = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL); + } + } + // Look up target SDK String defaultTheme = root.getAttributeNS(NS_RESOURCES, ATTRIBUTE_THEME); if (defaultTheme == null || defaultTheme.length() == 0) { @@ -292,6 +310,26 @@ public class ManifestInfo { } /** + * Returns the application icon, or null + * + * @return the application icon, or null + */ + public String getApplicationIcon() { + sync(); + return mApplicationIcon; + } + + /** + * Returns the application label, or null + * + * @return the application label, or null + */ + public String getApplicationLabel() { + sync(); + return mApplicationLabel; + } + + /** * Returns the activity associated with the given layout file. Makes an educated guess * by peeking at the usages of the R.layout.name field corresponding to the layout and * if it finds a usage. diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java index aabe9f7..ead55f9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java @@ -89,6 +89,9 @@ public class AdtProjectTest extends SdkTestCase { super.setUp(); // Prevent preview icon computation during plugin test to make test faster + if (AdtPlugin.getDefault() == null) { + fail("This test must be run as an Eclipse plugin test, not a plain JUnit test!"); + } AdtPrefs.getPrefs().setPaletteModes("ICON_TEXT"); //$NON-NLS-1$ getProject(); diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfoTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfoTest.java index 66a2482..5eba812 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfoTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfoTest.java @@ -166,7 +166,40 @@ public class ManifestInfoTest extends AdtProjectTest { } + public void testGetApplicationLabelAndIcon() throws Exception { + ManifestInfo info = getManifestInfo( + "<manifest xmlns:android='http://schemas.android.com/apk/res/android'\n" + + " package='com.android.unittest'>\n" + + " <application android:icon=\"@drawable/icon\"\n" + + " android:label=\"@string/app_name\">\n" + + " </application>\n" + + "" + + "</manifest>\n"); + Map<String, String> map = info.getActivityThemes(); + assertEquals(map.toString(), 0, map.size()); + assertEquals("com.android.unittest", info.getPackage()); + + assertEquals("Theme", ResourceHelper.styleToTheme(info.getDefaultTheme(null, NORMAL))); + assertEquals("@drawable/icon", info.getApplicationIcon()); + assertEquals("@string/app_name", info.getApplicationLabel()); + } + public void testGetApplicationNoLabelOrIcon() throws Exception { + ManifestInfo info = getManifestInfo( + "<manifest xmlns:android='http://schemas.android.com/apk/res/android'\n" + + " package='com.android.unittest'>\n" + + " <application>\n" + + " </application>\n" + + "" + + "</manifest>\n"); + Map<String, String> map = info.getActivityThemes(); + assertEquals(map.toString(), 0, map.size()); + assertEquals("com.android.unittest", info.getPackage()); + + assertEquals("Theme", ResourceHelper.styleToTheme(info.getDefaultTheme(null, NORMAL))); + assertNull(info.getApplicationIcon()); + assertNull(info.getApplicationLabel()); + } private ManifestInfo getManifestInfo(String manifestContents) throws Exception { InputStream bstream = new ByteArrayInputStream( |