diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderService.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderService.java | 668 |
1 files changed, 0 insertions, 668 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderService.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderService.java deleted file mode 100644 index 3b9e2fc0f..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderService.java +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Copyright (C) 2011 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.adt.internal.editors.layout.gle2; - -import static com.android.SdkConstants.LAYOUT_RESOURCE_PREFIX; - -import com.android.annotations.NonNull; -import com.android.ide.common.api.IClientRulesEngine; -import com.android.ide.common.api.INode; -import com.android.ide.common.api.Rect; -import com.android.ide.common.rendering.HardwareConfigHelper; -import com.android.ide.common.rendering.LayoutLibrary; -import com.android.ide.common.rendering.RenderSecurityManager; -import com.android.ide.common.rendering.api.AssetRepository; -import com.android.ide.common.rendering.api.Capability; -import com.android.ide.common.rendering.api.DrawableParams; -import com.android.ide.common.rendering.api.HardwareConfig; -import com.android.ide.common.rendering.api.IImageFactory; -import com.android.ide.common.rendering.api.ILayoutPullParser; -import com.android.ide.common.rendering.api.LayoutLog; -import com.android.ide.common.rendering.api.RenderSession; -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.rendering.api.Result; -import com.android.ide.common.rendering.api.SessionParams; -import com.android.ide.common.rendering.api.SessionParams.RenderingMode; -import com.android.ide.common.rendering.api.ViewInfo; -import com.android.ide.common.resources.ResourceResolver; -import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.editors.layout.ContextPullParser; -import com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback; -import com.android.ide.eclipse.adt.internal.editors.layout.UiElementPullParser; -import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configuration; -import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationChooser; -import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Locale; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.IncludeFinder.Reference; -import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeFactory; -import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy; -import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo.ActivityAttributes; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.devices.Device; -import com.google.common.base.Charsets; -import com.google.common.io.Files; - -import org.eclipse.core.resources.IProject; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.awt.Toolkit; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * The {@link RenderService} provides rendering and layout information for - * Android layouts. This is a wrapper around the layout library. - */ -public class RenderService { - private static final Object RENDERING_LOCK = new Object(); - - /** Reference to the file being edited. Can also be used to access the {@link IProject}. */ - private final GraphicalEditorPart mEditor; - - // The following fields are inferred from the editor and not customizable by the - // client of the render service: - - private final IProject mProject; - private final ProjectCallback mProjectCallback; - private final ResourceResolver mResourceResolver; - private final int mMinSdkVersion; - private final int mTargetSdkVersion; - private final LayoutLibrary mLayoutLib; - private final IImageFactory mImageFactory; - private final HardwareConfigHelper mHardwareConfigHelper; - private final Locale mLocale; - - // The following fields are optional or configurable using the various chained - // setters: - - private UiDocumentNode mModel; - private Reference mIncludedWithin; - private RenderingMode mRenderingMode = RenderingMode.NORMAL; - private LayoutLog mLogger; - private Integer mOverrideBgColor; - private boolean mShowDecorations = true; - private Set<UiElementNode> mExpandNodes = Collections.<UiElementNode>emptySet(); - private final Object mCredential; - - /** Use the {@link #create} factory instead */ - private RenderService(GraphicalEditorPart editor, Object credential) { - mEditor = editor; - mCredential = credential; - - mProject = editor.getProject(); - LayoutCanvas canvas = editor.getCanvasControl(); - mImageFactory = canvas.getImageOverlay(); - ConfigurationChooser chooser = editor.getConfigurationChooser(); - Configuration config = chooser.getConfiguration(); - FolderConfiguration folderConfig = config.getFullConfig(); - - Device device = config.getDevice(); - assert device != null; // Should only attempt render with configuration that has device - mHardwareConfigHelper = new HardwareConfigHelper(device); - mHardwareConfigHelper.setOrientation( - folderConfig.getScreenOrientationQualifier().getValue()); - - mLayoutLib = editor.getReadyLayoutLib(true /*displayError*/); - mResourceResolver = editor.getResourceResolver(); - mProjectCallback = editor.getProjectCallback(true /*reset*/, mLayoutLib); - mMinSdkVersion = editor.getMinSdkVersion(); - mTargetSdkVersion = editor.getTargetSdkVersion(); - mLocale = config.getLocale(); - } - - private RenderService(GraphicalEditorPart editor, - Configuration configuration, ResourceResolver resourceResolver, - Object credential) { - mEditor = editor; - mCredential = credential; - - mProject = editor.getProject(); - LayoutCanvas canvas = editor.getCanvasControl(); - mImageFactory = canvas.getImageOverlay(); - FolderConfiguration folderConfig = configuration.getFullConfig(); - - Device device = configuration.getDevice(); - assert device != null; - mHardwareConfigHelper = new HardwareConfigHelper(device); - mHardwareConfigHelper.setOrientation( - folderConfig.getScreenOrientationQualifier().getValue()); - - mLayoutLib = editor.getReadyLayoutLib(true /*displayError*/); - mResourceResolver = resourceResolver != null ? resourceResolver : editor.getResourceResolver(); - mProjectCallback = editor.getProjectCallback(true /*reset*/, mLayoutLib); - mMinSdkVersion = editor.getMinSdkVersion(); - mTargetSdkVersion = editor.getTargetSdkVersion(); - mLocale = configuration.getLocale(); - } - - private RenderSecurityManager createSecurityManager() { - String projectPath = null; - String sdkPath = null; - if (RenderSecurityManager.RESTRICT_READS) { - projectPath = AdtUtils.getAbsolutePath(mProject).toFile().getPath(); - Sdk sdk = Sdk.getCurrent(); - sdkPath = sdk != null ? sdk.getSdkOsLocation() : null; - } - RenderSecurityManager securityManager = new RenderSecurityManager(sdkPath, projectPath); - securityManager.setLogger(AdtPlugin.getDefault()); - - // Make sure this is initialized before we attempt to use it from layoutlib - Toolkit.getDefaultToolkit(); - - return securityManager; - } - - /** - * Returns true if this configuration supports the given rendering - * capability - * - * @param target the target to look up the layout library for - * @param capability the capability to check - * @return true if the capability is supported - */ - public static boolean supports( - @NonNull IAndroidTarget target, - @NonNull Capability capability) { - Sdk sdk = Sdk.getCurrent(); - if (sdk != null) { - AndroidTargetData targetData = sdk.getTargetData(target); - if (targetData != null) { - LayoutLibrary layoutLib = targetData.getLayoutLibrary(); - if (layoutLib != null) { - return layoutLib.supports(capability); - } - } - } - - return false; - } - - /** - * Creates a new {@link RenderService} associated with the given editor. - * - * @param editor the editor to provide configuration data such as the render target - * @return a {@link RenderService} which can perform rendering services - */ - public static RenderService create(GraphicalEditorPart editor) { - // Delegate to editor such that it can pass its credential to the service - return editor.createRenderService(); - } - - /** - * Creates a new {@link RenderService} associated with the given editor. - * - * @param editor the editor to provide configuration data such as the render target - * @param credential the sandbox credential - * @return a {@link RenderService} which can perform rendering services - */ - @NonNull - public static RenderService create(GraphicalEditorPart editor, Object credential) { - return new RenderService(editor, credential); - } - - /** - * Creates a new {@link RenderService} associated with the given editor. - * - * @param editor the editor to provide configuration data such as the render target - * @param configuration the configuration to use (and fallback to editor for the rest) - * @param resolver a resource resolver to use to look up resources - * @return a {@link RenderService} which can perform rendering services - */ - public static RenderService create(GraphicalEditorPart editor, - Configuration configuration, ResourceResolver resolver) { - // Delegate to editor such that it can pass its credential to the service - return editor.createRenderService(configuration, resolver); - } - - /** - * Creates a new {@link RenderService} associated with the given editor. - * - * @param editor the editor to provide configuration data such as the render target - * @param configuration the configuration to use (and fallback to editor for the rest) - * @param resolver a resource resolver to use to look up resources - * @param credential the sandbox credential - * @return a {@link RenderService} which can perform rendering services - */ - public static RenderService create(GraphicalEditorPart editor, - Configuration configuration, ResourceResolver resolver, Object credential) { - return new RenderService(editor, configuration, resolver, credential); - } - - /** - * Renders the given model, using this editor's theme and screen settings, and returns - * the result as a {@link RenderSession}. - * - * @param model the model to be rendered, which can be different than the editor's own - * {@link #getModel()}. - * @param width the width to use for the layout, or -1 to use the width of the screen - * associated with this editor - * @param height the height to use for the layout, or -1 to use the height of the screen - * associated with this editor - * @param explodeNodes a set of nodes to explode, or null for none - * @param overrideBgColor If non-null, use the given color as a background to render over - * rather than the normal background requested by the theme - * @param noDecor If true, don't draw window decorations like the system bar - * @param logger a logger where rendering errors are reported - * @param renderingMode the {@link RenderingMode} to use for rendering - * @return the resulting rendered image wrapped in an {@link RenderSession} - */ - - /** - * Sets the {@link LayoutLog} to be used during rendering. If none is specified, a - * silent logger will be used. - * - * @param logger the log to be used - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setLog(LayoutLog logger) { - mLogger = logger; - return this; - } - - /** - * Sets the model to be rendered, which can be different than the editor's own - * {@link GraphicalEditorPart#getModel()}. - * - * @param model the model to be rendered - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setModel(UiDocumentNode model) { - mModel = model; - return this; - } - - /** - * Overrides the width and height to be used during rendering (which might be adjusted if - * the {@link #setRenderingMode(RenderingMode)} is {@link RenderingMode#FULL_EXPAND}. - * - * A value of -1 will make the rendering use the normal width and height coming from the - * {@link Configuration#getDevice()} object. - * - * @param overrideRenderWidth the width in pixels of the layout to be rendered - * @param overrideRenderHeight the height in pixels of the layout to be rendered - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setOverrideRenderSize(int overrideRenderWidth, int overrideRenderHeight) { - mHardwareConfigHelper.setOverrideRenderSize(overrideRenderWidth, overrideRenderHeight); - return this; - } - - /** - * Sets the max width and height to be used during rendering (which might be adjusted if - * the {@link #setRenderingMode(RenderingMode)} is {@link RenderingMode#FULL_EXPAND}. - * - * A value of -1 will make the rendering use the normal width and height coming from the - * {@link Configuration#getDevice()} object. - * - * @param maxRenderWidth the max width in pixels of the layout to be rendered - * @param maxRenderHeight the max height in pixels of the layout to be rendered - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setMaxRenderSize(int maxRenderWidth, int maxRenderHeight) { - mHardwareConfigHelper.setMaxRenderSize(maxRenderWidth, maxRenderHeight); - return this; - } - - /** - * Sets the {@link RenderingMode} to be used during rendering. If none is specified, - * the default is {@link RenderingMode#NORMAL}. - * - * @param renderingMode the rendering mode to be used - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setRenderingMode(RenderingMode renderingMode) { - mRenderingMode = renderingMode; - return this; - } - - /** - * Sets the overriding background color to be used, if any. The color should be a - * bitmask of AARRGGBB. The default is null. - * - * @param overrideBgColor the overriding background color to be used in the rendering, - * in the form of a AARRGGBB bitmask, or null to use no custom background. - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setOverrideBgColor(Integer overrideBgColor) { - mOverrideBgColor = overrideBgColor; - return this; - } - - /** - * Sets whether the rendering should include decorations such as a system bar, an - * application bar etc depending on the SDK target and theme. The default is true. - * - * @param showDecorations true if the rendering should include system bars etc. - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setDecorations(boolean showDecorations) { - mShowDecorations = showDecorations; - return this; - } - - /** - * Sets the nodes to expand during rendering. These will be padded with approximately - * 20 pixels and also highlighted by the {@link EmptyViewsOverlay}. The default is an - * empty collection. - * - * @param nodesToExpand the nodes to be expanded - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setNodesToExpand(Set<UiElementNode> nodesToExpand) { - mExpandNodes = nodesToExpand; - return this; - } - - /** - * Sets the {@link Reference} to an outer layout that this layout should be rendered - * within. The outer layout <b>must</b> contain an include tag which points to this - * layout. The default is null. - * - * @param includedWithin a reference to an outer layout to render this layout within - * @return this (such that chains of setters can be stringed together) - */ - public RenderService setIncludedWithin(Reference includedWithin) { - mIncludedWithin = includedWithin; - return this; - } - - /** Initializes any remaining optional fields after all setters have been called */ - private void finishConfiguration() { - if (mLogger == null) { - // Silent logging - mLogger = new LayoutLog(); - } - } - - /** - * Renders the model and returns the result as a {@link RenderSession}. - * @return the {@link RenderSession} resulting from rendering the current model - */ - public RenderSession createRenderSession() { - assert mModel != null : "Incomplete service config"; - finishConfiguration(); - - if (mResourceResolver == null) { - // Abort the rendering if the resources are not found. - return null; - } - - HardwareConfig hardwareConfig = mHardwareConfigHelper.getConfig(); - - UiElementPullParser modelParser = new UiElementPullParser(mModel, - false, mExpandNodes, hardwareConfig.getDensity(), mProject); - ILayoutPullParser topParser = modelParser; - - // Code to support editing included layout - // first reset the layout parser just in case. - mProjectCallback.setLayoutParser(null, null); - - if (mIncludedWithin != null) { - // Outer layout name: - String contextLayoutName = mIncludedWithin.getName(); - - // Find the layout file. - ResourceValue contextLayout = mResourceResolver.findResValue( - LAYOUT_RESOURCE_PREFIX + contextLayoutName, false /* forceFrameworkOnly*/); - if (contextLayout != null) { - File layoutFile = new File(contextLayout.getValue()); - if (layoutFile.isFile()) { - try { - // Get the name of the layout actually being edited, without the extension - // as it's what IXmlPullParser.getParser(String) will receive. - String queryLayoutName = mEditor.getLayoutResourceName(); - mProjectCallback.setLayoutParser(queryLayoutName, modelParser); - topParser = new ContextPullParser(mProjectCallback, layoutFile); - topParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - String xmlText = Files.toString(layoutFile, Charsets.UTF_8); - topParser.setInput(new StringReader(xmlText)); - } catch (IOException e) { - AdtPlugin.log(e, null); - } catch (XmlPullParserException e) { - AdtPlugin.log(e, null); - } - } - } - } - - SessionParams params = new SessionParams( - topParser, - mRenderingMode, - mProject /* projectKey */, - hardwareConfig, - mResourceResolver, - mProjectCallback, - mMinSdkVersion, - mTargetSdkVersion, - mLogger); - - // Request margin and baseline information. - // TODO: Be smarter about setting this; start without it, and on the first request - // for an extended view info, re-render in the same session, and then set a flag - // which will cause this to create extended view info each time from then on in the - // same session - params.setExtendedViewInfoMode(true); - - params.setLocale(mLocale.toLocaleId()); - params.setAssetRepository(new AssetRepository()); - - ManifestInfo manifestInfo = ManifestInfo.get(mProject); - try { - params.setRtlSupport(manifestInfo.isRtlSupported()); - } catch (Exception e) { - // ignore. - } - if (!mShowDecorations) { - params.setForceNoDecor(); - } else { - try { - params.setAppLabel(manifestInfo.getApplicationLabel()); - params.setAppIcon(manifestInfo.getApplicationIcon()); - String activity = mEditor.getConfigurationChooser().getConfiguration().getActivity(); - if (activity != null) { - ActivityAttributes info = manifestInfo.getActivityAttributes(activity); - if (info != null) { - if (info.getLabel() != null) { - params.setAppLabel(info.getLabel()); - } - if (info.getIcon() != null) { - params.setAppIcon(info.getIcon()); - } - } - } - } catch (Exception e) { - // ignore. - } - } - - if (mOverrideBgColor != null) { - params.setOverrideBgColor(mOverrideBgColor.intValue()); - } - - // set the Image Overlay as the image factory. - params.setImageFactory(mImageFactory); - - mProjectCallback.setLogger(mLogger); - mProjectCallback.setResourceResolver(mResourceResolver); - RenderSecurityManager securityManager = createSecurityManager(); - try { - securityManager.setActive(true, mCredential); - synchronized (RENDERING_LOCK) { - return mLayoutLib.createSession(params); - } - } catch (RuntimeException t) { - // Exceptions from the bridge - mLogger.error(null, t.getLocalizedMessage(), t, null); - throw t; - } finally { - securityManager.dispose(mCredential); - mProjectCallback.setLogger(null); - mProjectCallback.setResourceResolver(null); - } - } - - /** - * Renders the given resource value (which should refer to a drawable) and returns it - * as an image - * - * @param drawableResourceValue the drawable resource value to be rendered, or null - * @return the image, or null if something went wrong - */ - public BufferedImage renderDrawable(ResourceValue drawableResourceValue) { - if (drawableResourceValue == null) { - return null; - } - - finishConfiguration(); - - HardwareConfig hardwareConfig = mHardwareConfigHelper.getConfig(); - - DrawableParams params = new DrawableParams(drawableResourceValue, mProject, hardwareConfig, - mResourceResolver, mProjectCallback, mMinSdkVersion, - mTargetSdkVersion, mLogger); - params.setAssetRepository(new AssetRepository()); - params.setForceNoDecor(); - Result result = mLayoutLib.renderDrawable(params); - if (result != null && result.isSuccess()) { - Object data = result.getData(); - if (data instanceof BufferedImage) { - return (BufferedImage) data; - } - } - - return null; - } - - /** - * Measure the children of the given parent node, applying the given filter to the - * pull parser's attribute values. - * - * @param parent the parent node to measure children for - * @param filter the filter to apply to the attribute values - * @return a map from node children of the parent to new bounds of the nodes - */ - public Map<INode, Rect> measureChildren(INode parent, - final IClientRulesEngine.AttributeFilter filter) { - finishConfiguration(); - HardwareConfig hardwareConfig = mHardwareConfigHelper.getConfig(); - - final NodeFactory mNodeFactory = mEditor.getCanvasControl().getNodeFactory(); - UiElementNode parentNode = ((NodeProxy) parent).getNode(); - UiElementPullParser topParser = new UiElementPullParser(parentNode, - false, Collections.<UiElementNode>emptySet(), hardwareConfig.getDensity(), - mProject) { - @Override - public String getAttributeValue(String namespace, String localName) { - if (filter != null) { - Object cookie = getViewCookie(); - if (cookie instanceof UiViewElementNode) { - NodeProxy node = mNodeFactory.create((UiViewElementNode) cookie); - if (node != null) { - String value = filter.getAttribute(node, namespace, localName); - if (value != null) { - return value; - } - // null means no preference, not "unset". - } - } - } - - return super.getAttributeValue(namespace, localName); - } - - /** - * The parser usually assumes that the top level node is a document node that - * should be skipped, and that's not the case when we render in the middle of - * the tree, so override {@link UiElementPullParser#onNextFromStartDocument} - * to change this behavior - */ - @Override - public void onNextFromStartDocument() { - mParsingState = START_TAG; - } - }; - - SessionParams params = new SessionParams( - topParser, - RenderingMode.FULL_EXPAND, - mProject /* projectKey */, - hardwareConfig, - mResourceResolver, - mProjectCallback, - mMinSdkVersion, - mTargetSdkVersion, - mLogger); - params.setLayoutOnly(); - params.setForceNoDecor(); - params.setAssetRepository(new AssetRepository()); - - RenderSession session = null; - mProjectCallback.setLogger(mLogger); - mProjectCallback.setResourceResolver(mResourceResolver); - RenderSecurityManager securityManager = createSecurityManager(); - try { - securityManager.setActive(true, mCredential); - synchronized (RENDERING_LOCK) { - session = mLayoutLib.createSession(params); - } - if (session.getResult().isSuccess()) { - assert session.getRootViews().size() == 1; - ViewInfo root = session.getRootViews().get(0); - List<ViewInfo> children = root.getChildren(); - Map<INode, Rect> map = new HashMap<INode, Rect>(children.size()); - for (ViewInfo info : children) { - if (info.getCookie() instanceof UiViewElementNode) { - UiViewElementNode uiNode = (UiViewElementNode) info.getCookie(); - NodeProxy node = mNodeFactory.create(uiNode); - map.put(node, new Rect(info.getLeft(), info.getTop(), - info.getRight() - info.getLeft(), - info.getBottom() - info.getTop())); - } - } - - return map; - } - } catch (RuntimeException t) { - // Exceptions from the bridge - mLogger.error(null, t.getLocalizedMessage(), t, null); - throw t; - } finally { - securityManager.dispose(mCredential); - mProjectCallback.setLogger(null); - mProjectCallback.setResourceResolver(null); - if (session != null) { - session.dispose(); - } - } - - return null; - } -} |