/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.layoutlib.bridge;

import com.android.internal.util.XmlUtils;
import com.android.layoutlib.api.ILayoutBridge;
import com.android.layoutlib.api.ILayoutLog;
import com.android.layoutlib.api.ILayoutResult;
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
import com.android.layoutlib.api.IXmlPullParser;
import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
import com.android.layoutlib.bridge.LayoutResult.LayoutViewInfo;
import com.android.ninepatch.NinePatch;
import com.android.tools.layoutlib.create.OverrideMethod;
import com.android.tools.layoutlib.create.MethodAdapter;

import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.TypedValue;
import android.view.BridgeInflater;
import android.view.IWindow;
import android.view.IWindowSession;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Main entry point of the LayoutLib Bridge.
 * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
 * {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}.
 */
public final class Bridge implements ILayoutBridge {
    
    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
    
    public static class StaticMethodNotImplementedException extends RuntimeException {
        public StaticMethodNotImplementedException(String msg) {
            super(msg);
        }
    }

    /**
     * Maps from id to resource name/type.
     */
    private final static Map<Integer, String[]> sRMap = new HashMap<Integer, String[]>();
    /**
     * Same as sRMap except for int[] instead of int resources.
     */
    private final static Map<int[], String> sRArrayMap = new HashMap<int[], String>();
    /**
     * Reverse map compared to sRMap, resource type -> (resource name -> id)
     */
    private final static Map<String, Map<String, Integer>> sRFullMap =
        new HashMap<String, Map<String,Integer>>();
    
    private final static Map<Object, Map<String, Bitmap>> sProjectBitmapCache =
        new HashMap<Object, Map<String, Bitmap>>();
    private final static Map<Object, Map<String, NinePatch>> sProject9PatchCache =
        new HashMap<Object, Map<String, NinePatch>>();

    private final static Map<String, Bitmap> sFrameworkBitmapCache = new HashMap<String, Bitmap>();
    private final static Map<String, NinePatch> sFramework9PatchCache =
        new HashMap<String, NinePatch>();
    
    private static Map<String, Map<String, Integer>> sEnumValueMap;

    /**
     * A default logger than prints to stdout/stderr.
     */
    private final static ILayoutLog sDefaultLogger = new ILayoutLog() {
        public void error(String message) {
            System.err.println(message);
        }

        public void error(Throwable t) {
            String message = t.getMessage();
            if (message == null) {
                message = t.getClass().getName();
            }

            System.err.println(message);
        }

        public void warning(String message) {
            System.out.println(message);
        }
    };

    /**
     * Logger defined during a compute layout operation.
     * <p/>
     * This logger is generally set to {@link #sDefaultLogger} except during rendering
     * operations when it might be set to a specific provided logger.
     * <p/>
     * To change this value, use a block synchronized on {@link #sDefaultLogger}.
     */
    private static ILayoutLog sLogger = sDefaultLogger;

    /*
     * (non-Javadoc)
     * @see com.android.layoutlib.api.ILayoutBridge#getApiLevel()
     */
    public int getApiLevel() {
        return API_CURRENT;
    }

    /*
     * (non-Javadoc)
     * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map)
     */
    public boolean init(
            String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {

        return sinit(fontOsLocation, enumValueMap);
    }
    
    private static synchronized boolean sinit(String fontOsLocation,
            Map<String, Map<String, Integer>> enumValueMap) {

        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
        // on static (native) methods which prints the signature on the console and
        // throws an exception.
        // This is useful when testing the rendering in ADT to identify static native 
        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
        // which is generally OK yet might be a problem, so this is how you'd find out.
        //
        // Currently layoutlib_create only overrides static native method.
        // Static non-natives are not overridden and thus do not get here.
        final String debug = System.getenv("DEBUG_LAYOUT");
        if (debug != null && !debug.equals("0") && !debug.equals("false")) {

            OverrideMethod.setDefaultListener(new MethodAdapter() {
                @Override
                public void onInvokeV(String signature, boolean isNative, Object caller) {
                    if (sLogger != null) {
                        synchronized (sDefaultLogger) {
                            sLogger.error("Missing Stub: " + signature +
                                    (isNative ? " (native)" : ""));
                        }
                    }

                    if (debug.equalsIgnoreCase("throw")) {
                        // Throwing this exception doesn't seem that useful. It breaks
                        // the layout editor yet doesn't display anything meaningful to the
                        // user. Having the error in the console is just as useful. We'll
                        // throw it only if the environment variable is "throw" or "THROW".
                        throw new StaticMethodNotImplementedException(signature);
                    }
                }
            });
        }

        // Override View.isInEditMode to return true.
        //
        // This allows custom views that are drawn in the Graphical Layout Editor to adapt their
        // rendering for preview. Most important this let custom views know that they can't expect
        // the rest of their activities to be alive.
        OverrideMethod.setMethodListener("android.view.View#isInEditMode()Z",
            new MethodAdapter() {
                @Override
                public int onInvokeI(String signature, boolean isNative, Object caller) {
                    return 1;
                }
            }
        );

        // load the fonts.
        FontLoader fontLoader = FontLoader.create(fontOsLocation);
        if (fontLoader != null) {
            Typeface.init(fontLoader);
        } else {
            return false;
        }
        
        sEnumValueMap = enumValueMap;

        // now parse com.android.internal.R (and only this one as android.R is a subset of
        // the internal version), and put the content in the maps.
        try {
            // WARNING: this only works because the class is already loaded, and therefore
            // the objects returned by Field.get() are the same as the ones used by
            // the code accessing the R class.
            // int[] does not implement equals/hashCode, and if the parsing used a different class
            // loader for the R class, this would NOT work.
            Class<?> r = com.android.internal.R.class;
            
            for (Class<?> inner : r.getDeclaredClasses()) {
                String resType = inner.getSimpleName();

                Map<String, Integer> fullMap = new HashMap<String, Integer>();
                sRFullMap.put(resType, fullMap);
                
                for (Field f : inner.getDeclaredFields()) {
                    // only process static final fields. Since the final attribute may have
                    // been altered by layoutlib_create, we only check static
                    int modifiers = f.getModifiers();
                    if (Modifier.isStatic(modifiers)) {
                        Class<?> type = f.getType();
                        if (type.isArray() && type.getComponentType() == int.class) {
                            // if the object is an int[] we put it in sRArrayMap
                            sRArrayMap.put((int[]) f.get(null), f.getName());
                        } else if (type == int.class) {
                            Integer value = (Integer) f.get(null); 
                            sRMap.put(value, new String[] { f.getName(), resType });
                            fullMap.put(f.getName(), value);
                        } else {
                            assert false;
                        }
                    }
                }
            }
        } catch (IllegalArgumentException e) {
            // FIXME: log/return the error (there's no logger object at this point!)
            e.printStackTrace();
            return false;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    /*
     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
     * (non-Javadoc)
     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
     */
    @Deprecated
    public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
            Object projectKey,
            int screenWidth, int screenHeight, String themeName,
            Map<String, Map<String, IResourceValue>> projectResources,
            Map<String, Map<String, IResourceValue>> frameworkResources,
            IProjectCallback customViewLoader, ILayoutLog logger) {
        boolean isProjectTheme = false;
        if (themeName.charAt(0) == '*') {
            themeName = themeName.substring(1);
            isProjectTheme = true;
        }
        
        return computeLayout(layoutDescription, projectKey, screenWidth, screenHeight, themeName, isProjectTheme,
                projectResources, frameworkResources, customViewLoader, logger);
    }

    /*
     * (non-Javadoc)
     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
     */
    public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
            Object projectKey,
            int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
            Map<String, Map<String, IResourceValue>> projectResources,
            Map<String, Map<String, IResourceValue>> frameworkResources,
            IProjectCallback customViewLoader, ILayoutLog logger) {
        if (logger == null) {
            logger = sDefaultLogger;
        }
        
        synchronized (sDefaultLogger) {
            sLogger = logger;
        }
        
        // find the current theme and compute the style inheritance map
        Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
            new HashMap<IStyleResourceValue, IStyleResourceValue>();
        
        IStyleResourceValue currentTheme = computeStyleMaps(themeName, isProjectTheme,
                projectResources.get(BridgeConstants.RES_STYLE),
                frameworkResources.get(BridgeConstants.RES_STYLE), styleParentMap);
        
        BridgeContext context = new BridgeContext(projectKey, currentTheme, projectResources,
                frameworkResources, styleParentMap, customViewLoader, logger);
        BridgeInflater inflater = new BridgeInflater(context, customViewLoader);
        context.setBridgeInflater(inflater);
        
        IResourceValue windowBackground = null;
        int screenOffset = 0;
        if (currentTheme != null) {
            windowBackground = context.findItemInStyle(currentTheme, "windowBackground");
            windowBackground = context.resolveResValue(windowBackground);

            screenOffset = getScreenOffset(currentTheme, context);
        }
        
        // we need to make sure the Looper has been initialized for this thread.
        // this is required for View that creates Handler objects.
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
        
        BridgeXmlBlockParser parser = new BridgeXmlBlockParser(layoutDescription,
                context, false /* platformResourceFlag */);
        
        ViewGroup root = new FrameLayout(context);
        
        try {
            View view = inflater.inflate(parser, root);
            
            // set the AttachInfo on the root view.
            AttachInfo info = new AttachInfo(new WindowSession(), new Window(),
                    new Handler(), null);
            info.mHasWindowFocus = true;
            info.mWindowVisibility = View.VISIBLE;
            info.mInTouchMode = false; // this is so that we can display selections.
            root.dispatchAttachedToWindow(info, 0);

            // get the background drawable
            if (windowBackground != null) {
                Drawable d = ResourceHelper.getDrawable(windowBackground.getValue(),
                        context, true /* isFramework */);
                root.setBackgroundDrawable(d);
            }

            int w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
            int h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
                    MeasureSpec.EXACTLY);

            // measure the views
            view.measure(w_spec, h_spec);
            view.layout(0, screenOffset, screenWidth, screenHeight);
            
            // draw them
            BridgeCanvas canvas = new BridgeCanvas(screenWidth, screenHeight - screenOffset,
                    logger);
            
            root.draw(canvas);
            canvas.dispose();
            
            return new LayoutResult(visit(((ViewGroup)view).getChildAt(0), context),
                    canvas.getImage());
        } catch (Throwable e) {
            // get the real cause of the exception.
            Throwable t = e;
            while (t.getCause() != null) {
                t = t.getCause();
            }

            // log it
            logger.error(t);

            // then return with an ERROR status and the message from the real exception
            return new LayoutResult(ILayoutResult.ERROR,
                    t.getClass().getSimpleName() + ": " + t.getMessage());
        } finally {
            // Remove the global logger
            synchronized (sDefaultLogger) {
                sLogger = sDefaultLogger;
            }
        }
    }

    /*
     * (non-Javadoc)
     * @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object)
     */
    public void clearCaches(Object projectKey) {
        if (projectKey != null) {
            sProjectBitmapCache.remove(projectKey);
            sProject9PatchCache.remove(projectKey);
        }
    }
    
    /**
     * Returns details of a framework resource from its integer value.
     * @param value the integer value
     * @return an array of 2 strings containing the resource name and type, or null if the id
     * does not match any resource. 
     */
    public static String[] resolveResourceValue(int value) {
        return sRMap.get(value);
        
    }
    
    /**
     * Returns the name of a framework resource whose value is an int array.
     * @param array
     */
    public static String resolveResourceValue(int[] array) {
        return sRArrayMap.get(array);
    }
    
    /**
     * Returns the integer id of a framework resource, from a given resource type and resource name.
     * @param type the type of the resource
     * @param name the name of the resource.
     * @return an {@link Integer} containing the resource id, or null if no resource were found.
     */
    public static Integer getResourceValue(String type, String name) {
        Map<String, Integer> map = sRFullMap.get(type);
        if (map != null) {
            return map.get(name);
        }
        
        return null;
    }
    
    static Map<String, Integer> getEnumValues(String attributeName) {
        if (sEnumValueMap != null) {
            return sEnumValueMap.get(attributeName);
        }
        
        return null;
    }

    /**
     * Visits a View and its children and generate a {@link ILayoutViewInfo} containing the
     * bounds of all the views.
     * @param view the root View
     * @param context the context.
     */
    private ILayoutViewInfo visit(View view, BridgeContext context) {
        if (view == null) {
            return null;
        }

        LayoutViewInfo result = new LayoutViewInfo(view.getClass().getName(),
                context.getViewKey(view),
                view.getLeft(), view.getTop(), view.getRight(), view.getBottom());

        if (view instanceof ViewGroup) {
            ViewGroup group = ((ViewGroup) view);
            int n = group.getChildCount();
            ILayoutViewInfo[] children = new ILayoutViewInfo[n];
            for (int i = 0; i < group.getChildCount(); i++) {
                children[i] = visit(group.getChildAt(i), context);
            }
            result.setChildren(children);
        }

        return result;
    }
    
    /**
     * Compute style information from the given list of style for the project and framework.
     * @param themeName the name of the current theme.  In order to differentiate project and
     * platform themes sharing the same name, all project themes must be prepended with
     * a '*' character.
     * @param isProjectTheme Is this a project theme 
     * @param inProjectStyleMap the project style map
     * @param inFrameworkStyleMap the framework style map
     * @param outInheritanceMap the map of style inheritance. This is filled by the method
     * @return the {@link IStyleResourceValue} matching <var>themeName</var>
     */
    private IStyleResourceValue computeStyleMaps(
            String themeName, boolean isProjectTheme, Map<String,
            IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
        
        if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
            // first, get the theme
            IResourceValue theme = null;
            
            // project theme names have been prepended with a *
            if (isProjectTheme) {
                theme = inProjectStyleMap.get(themeName);
            } else {
                theme = inFrameworkStyleMap.get(themeName);
            }
            
            if (theme instanceof IStyleResourceValue) {
                // compute the inheritance map for both the project and framework styles
                computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap,
                        inFrameworkStyleMap, outInheritanceMap);
    
                // Compute the style inheritance for the framework styles/themes.
                // Since, for those, the style parent values do not contain 'android:'
                // we want to force looking in the framework style only to avoid using
                // similarly named styles from the project.
                // To do this, we pass null in lieu of the project style map.
                computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */,
                        inFrameworkStyleMap, outInheritanceMap);
    
                return (IStyleResourceValue)theme;
            }
        }
        
        return null;
    }

    /**
     * Compute the parent style for all the styles in a given list.
     * @param styles the styles for which we compute the parent.
     * @param inProjectStyleMap the map of project styles.
     * @param inFrameworkStyleMap the map of framework styles.
     * @param outInheritanceMap the map of style inheritance. This is filled by the method.
     */
    private void computeStyleInheritance(Collection<IResourceValue> styles,
            Map<String, IResourceValue> inProjectStyleMap,
            Map<String, IResourceValue> inFrameworkStyleMap,
            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
        for (IResourceValue value : styles) {
            if (value instanceof IStyleResourceValue) {
                IStyleResourceValue style = (IStyleResourceValue)value;
                IStyleResourceValue parentStyle = null;

                // first look for a specified parent.
                String parentName = style.getParentStyle();
                
                // no specified parent? try to infer it from the name of the style.
                if (parentName == null) {
                    parentName = getParentName(value.getName());
                }

                if (parentName != null) {
                    parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap);
                    
                    if (parentStyle != null) {
                        outInheritanceMap.put(style, parentStyle);
                    }
                }
            }
        }
    }
    
    /**
     * Searches for and returns the {@link IStyleResourceValue} from a given name.
     * <p/>The format of the name can be:
     * <ul>
     * <li>[android:]&lt;name&gt;</li>
     * <li>[android:]style/&lt;name&gt;</li>
     * <li>@[android:]style/&lt;name&gt;</li>
     * </ul>
     * @param parentName the name of the style.
     * @param inProjectStyleMap the project style map. Can be <code>null</code>
     * @param inFrameworkStyleMap the framework style map.
     * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
     */
    private IStyleResourceValue getStyle(String parentName,
            Map<String, IResourceValue> inProjectStyleMap,
            Map<String, IResourceValue> inFrameworkStyleMap) {
        boolean frameworkOnly = false;
        
        String name = parentName;
        
        // remove the useless @ if it's there
        if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
            name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
        }
        
        // check for framework identifier.
        if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) {
            frameworkOnly = true;
            name = name.substring(BridgeConstants.PREFIX_ANDROID.length());
        }
        
        // at this point we could have the format style/<name>. we want only the name
        if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) {
            name = name.substring(BridgeConstants.REFERENCE_STYLE.length());
        }

        IResourceValue parent = null;
        
        // if allowed, search in the project resources.
        if (frameworkOnly == false && inProjectStyleMap != null) {
            parent = inProjectStyleMap.get(name);
        }

        // if not found, then look in the framework resources.
        if (parent == null) {
            parent = inFrameworkStyleMap.get(name);
        }
        
        // make sure the result is the proper class type and return it.
        if (parent instanceof IStyleResourceValue) {
            return (IStyleResourceValue)parent;
        }
        
        sLogger.error(String.format("Unable to resolve parent style name: ", parentName));
        
        return null;
    }
    
    /**
     * Computes the name of the parent style, or <code>null</code> if the style is a root style.
     */
    private String getParentName(String styleName) {
        int index = styleName.lastIndexOf('.');
        if (index != -1) {
            return styleName.substring(0, index);
        }
        
        return null;
    }
    
    /**
     * Returns the top screen offset. This depends on whether the current theme defines the user
     * of the title and status bars.
     * @return the pixel height offset
     */
    private int getScreenOffset(IStyleResourceValue currentTheme, BridgeContext context) {
        int offset = 0;

        // get the title bar flag from the current theme.
        IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle");
        
        // because it may reference something else, we resolve it.
        value = context.resolveResValue(value);

        // if there's a value and it's true (default is false)
        if (value == null || value.getValue() == null ||
                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
            // get value from the theme.
            value = context.findItemInStyle(currentTheme, "windowTitleSize");
            
            // resolve it
            value = context.resolveResValue(value);
            
            // default value
            offset = DEFAULT_TITLE_BAR_HEIGHT;

            // get the real value;
            if (value != null) {
                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
                if (typedValue != null) {
                    offset = (int)typedValue.getDimension(context.getResources().mMetrics);   
                }
            }
        }
        
        // get the fullscreen flag from the current theme.
        value = context.findItemInStyle(currentTheme, "windowFullscreen");
        
        // because it may reference something else, we resolve it.
        value = context.resolveResValue(value);
        
        if (value == null || value.getValue() == null ||
                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
            // FIXME: Right now this is hard-coded in the platform, but once there's a constant, we'll need to use it.
            offset += DEFAULT_STATUS_BAR_HEIGHT;
        }

        return offset;
    }

    /**
     * Returns the bitmap for a specific path, from a specific project cache, or from the
     * framework cache.
     * @param value the path of the bitmap
     * @param projectKey the key of the project, or null to query the framework cache.
     * @return the cached Bitmap or null if not found.
     */
    static Bitmap getCachedBitmap(String value, Object projectKey) {
        if (projectKey != null) {
            Map<String, Bitmap> map = sProjectBitmapCache.get(projectKey);
            if (map != null) {
                return map.get(value);
            }
            
            return null;
        }
        
        return sFrameworkBitmapCache.get(value);
    }

    /**
     * Sets a bitmap in a project cache or in the framework cache.
     * @param value the path of the bitmap
     * @param bmp the Bitmap object
     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
     */
    static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
        if (projectKey != null) {
            Map<String, Bitmap> map = sProjectBitmapCache.get(projectKey);

            if (map == null) {
                map = new HashMap<String, Bitmap>();
                sProjectBitmapCache.put(projectKey, map);
            }
            
            map.put(value, bmp);
        }
        
        sFrameworkBitmapCache.put(value, bmp);
    }

    /**
     * Returns the 9 patch for a specific path, from a specific project cache, or from the
     * framework cache.
     * @param value the path of the 9 patch
     * @param projectKey the key of the project, or null to query the framework cache.
     * @return the cached 9 patch or null if not found.
     */
    static NinePatch getCached9Patch(String value, Object projectKey) {
        if (projectKey != null) {
            Map<String, NinePatch> map = sProject9PatchCache.get(projectKey);
            
            if (map != null) {
                return map.get(value);
            }
            
            return null;
        }
        
        return sFramework9PatchCache.get(value);
    }

    /**
     * Sets a 9 patch in a project cache or in the framework cache.
     * @param value the path of the 9 patch
     * @param ninePatch the 9 patch object
     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
     */
    static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
        if (projectKey != null) {
            Map<String, NinePatch> map = sProject9PatchCache.get(projectKey);

            if (map == null) {
                map = new HashMap<String, NinePatch>();
                sProject9PatchCache.put(projectKey, map);
            }
            
            map.put(value, ninePatch);
        }
        
        sFramework9PatchCache.put(value, ninePatch);
    }
    
    /**
     * Implementation of {@link IWindowSession} so that mSession is not null in
     * the {@link SurfaceView}.
     */
    private static final class WindowSession implements IWindowSession {

        @SuppressWarnings("unused")
        public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
                throws RemoteException {
            // pass for now.
            return 0;
        }

        @SuppressWarnings("unused")
        public void finishDrawing(IWindow arg0) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void finishKey(IWindow arg0) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public boolean getInTouchMode() throws RemoteException {
            // pass for now.
            return false;
        }

        @SuppressWarnings("unused")
        public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
            // pass for now.
            return null;
        }

        @SuppressWarnings("unused")
        public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
            // pass for now.
            return null;
        }

        @SuppressWarnings("unused")
        public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
                boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Surface arg8)
                throws RemoteException {
            // pass for now.
            return 0;
        }

        public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
            // pass for now.
        }
        
        @SuppressWarnings("unused")
        public void remove(IWindow arg0) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void setInTouchMode(boolean arg0) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
            // pass for now.
        }

        public void setInsets(IWindow window, int touchable, Rect contentInsets,
                Rect visibleInsets) {
            // pass for now.
        }
        
        public IBinder asBinder() {
            // pass for now.
            return null;
        }
    }
    
    /**
     * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
     */
    private static final class Window implements IWindow {

        @SuppressWarnings("unused")
        public void dispatchAppVisibility(boolean arg0) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void dispatchGetNewSurface() throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void dispatchKey(KeyEvent arg0) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void dispatchPointer(MotionEvent arg0, long arg1) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void dispatchTrackball(MotionEvent arg0, long arg1) throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
                throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4)
                throws RemoteException {
            // pass for now.
        }

        @SuppressWarnings("unused")
        public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
            // pass for now.
        }

        public IBinder asBinder() {
            // pass for now.
            return null;
        }
    }

}
