Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a49635b authored by Xavier Ducrohet's avatar Xavier Ducrohet
Browse files

LayoutLib: Delegate for Display and IWindowManager implementation.

This allows ViewConfiguration to be properly implemented which is now
required for the rendering to happen.

Change-Id: I55629689fa8f5f874b43fcac2aa0789ce02d58f4
parent 77eaa109
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 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 android.view;

import com.android.layoutlib.bridge.android.BridgeWindowManager;
import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.os.RemoteException;

/**
 * Delegate used to provide new implementation of a select few methods of {@link Display}
 *
 * Through the layoutlib_create tool, the original  methods of Display have been replaced
 * by calls to methods of the same name in this delegate class.
 *
 */
public class Display_Delegate {

    // ---- Overridden methods ----

    @LayoutlibDelegate
    public static IWindowManager getWindowManager() {
        return RenderAction.getCurrentContext().getIWindowManager();
    }

    // ---- Native methods ----

    @LayoutlibDelegate
    /*package*/ static int getDisplayCount() {
        return 1;
    }

    @LayoutlibDelegate
    /** @hide Returns the actual screen size, not including any decor. */
    /*package*/ static int getRealWidth(Display theDisplay) {
        // always dynamically query for the current window manager
        return RenderAction.getCurrentContext().getIWindowManager().getMetrics().widthPixels;
    }

    @LayoutlibDelegate
    /** @hide Returns the actual screen size, not including any decor. */
    /*package*/ static int getRealHeight(Display theDisplay) {
        // always dynamically query for the current window manager
        return RenderAction.getCurrentContext().getIWindowManager().getMetrics().heightPixels;
    }

    @LayoutlibDelegate
    /** @hide special for when we are faking the screen size. */
    /*package*/ static int getRawWidth(Display theDisplay) {
        // same as real since we're not faking compatibility mode.
        return getRealWidth(theDisplay);
    }

    @LayoutlibDelegate
    /** @hide special for when we are faking the screen size. */
    /*package*/ static int getRawHeight(Display theDisplay) {
        // same as real since we're not faking compatibility mode.
        return getRealHeight(theDisplay);
    }

    @LayoutlibDelegate
    /*package*/ static int getOrientation(Display theDisplay) {
        try {
            // always dynamically query for the current window manager
            return getWindowManager().getRotation();
        } catch (RemoteException e) {
            // this will never been thrown since this is not a true RPC.
        }

        return Surface.ROTATION_0;
    }

    @LayoutlibDelegate
    /*package*/ static void nativeClassInit() {
        // not needed for now.
    }

    @LayoutlibDelegate
    /*package*/ static void init(Display theDisplay, int display) {
        // always dynamically query for the current window manager
        BridgeWindowManager wm = RenderAction.getCurrentContext().getIWindowManager();
        theDisplay.mDensity = wm.getMetrics().density;
        theDisplay.mDpiX = wm.getMetrics().xdpi;
        theDisplay.mDpiY = wm.getMetrics().ydpi;
    }
}
+17 −13
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;

@@ -91,7 +92,11 @@ public final class BridgeContext extends Activity {
    private final Object mProjectKey;
    private final DisplayMetrics mMetrics;
    private final RenderResources mRenderResources;
    private final Configuration mConfig;
    private final ApplicationInfo mApplicationInfo;
    private final IProjectCallback mProjectCallback;

    private final BridgeWindowManager mIWindowManager;

    private final Map<Object, Map<String, String>> mDefaultPropMaps =
        new IdentityHashMap<Object, Map<String,String>>();
@@ -105,7 +110,6 @@ public final class BridgeContext extends Activity {
    private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache;
    private BridgeInflater mBridgeInflater;

    private final IProjectCallback mProjectCallback;
    private BridgeContentResolver mContentResolver;

    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
@@ -113,28 +117,25 @@ public final class BridgeContext extends Activity {
    /**
     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
     * @param metrics the {@link DisplayMetrics}.
     * @param themeName The name of the theme to use.
     * @param projectResources the resources of the project. The map contains (String, map) pairs
     * where the string is the type of the resource reference used in the layout file, and the
     * map contains (String, {@link }) pairs where the key is the resource name,
     * and the value is the resource value.
     * @param frameworkResources the framework resources. The map contains (String, map) pairs
     * where the string is the type of the resource reference used in the layout file, and the map
     * contains (String, {@link ResourceValue}) pairs where the key is the resource name, and the
     * value is the resource value.
     * @param styleInheritanceMap
     * @param renderResources the configured resources (both framework and projects) for this
     * render.
     * @param projectCallback
     * @param config the Configuration object for this render.
     * @param targetSdkVersion the targetSdkVersion of the application.
     */
    public BridgeContext(Object projectKey, DisplayMetrics metrics,
            RenderResources renderResources,
            IProjectCallback projectCallback,
            Configuration config,
            int targetSdkVersion) {
        mProjectKey = projectKey;
        mMetrics = metrics;
        mProjectCallback = projectCallback;

        mRenderResources = renderResources;
        mConfig = config;

        mIWindowManager = new BridgeWindowManager(mConfig, metrics, Surface.ROTATION_0);

        mFragments.mCurState = Fragment.CREATED;
        mFragments.mActivity = this;
@@ -151,13 +152,12 @@ public final class BridgeContext extends Activity {
     */
    public void initResources() {
        AssetManager assetManager = AssetManager.getSystem();
        Configuration config = new Configuration();

        mSystemResources = BridgeResources.initSystem(
                this,
                assetManager,
                mMetrics,
                config,
                mConfig,
                mProjectCallback);
        mTheme = mSystemResources.newTheme();
    }
@@ -197,6 +197,10 @@ public final class BridgeContext extends Activity {
        return mRenderResources;
    }

    public BridgeWindowManager getIWindowManager() {
        return mIWindowManager;
    }

    public Map<String, String> getDefaultPropMap(Object key) {
        return mDefaultPropMaps.get(key);
    }
+455 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 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.android;

import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;

import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Display_Delegate;
import android.view.IApplicationToken;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
import android.view.IWindowManager;
import android.view.IWindowSession;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;

import java.util.List;

/**
 * Basic implementation of {@link IWindowManager} so that {@link Display} (and
 * {@link Display_Delegate}) can return a valid instance.
 */
public class BridgeWindowManager implements IWindowManager {

    private final Configuration mConfig;
    private final DisplayMetrics mMetrics;
    private final int mRotation;

    public BridgeWindowManager(Configuration config, DisplayMetrics metrics, int rotation) {
        mConfig = config;
        mMetrics = metrics;
        mRotation = rotation;
    }

    // custom API.

    public DisplayMetrics getMetrics() {
        return mMetrics;
    }

    // ---- implementation of IWindowManager that we care about ----

    public int getRotation() throws RemoteException {
        return mRotation;
    }

    public int getMaximumSizeDimension() throws RemoteException {
        return 0;
    }

    public void getDisplaySize(Point arg0) throws RemoteException {
    }

    // ---- unused implementation of IWindowManager ----

    public boolean canStatusBarHide() throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4)
            throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void addWindowToken(IBinder arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void clearForcedDisplaySize() throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void closeSystemDialogs(String arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void executeAppTransition() throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void exitKeyguardSecurely(IOnKeyguardExitResult arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void freezeRotation() throws RemoteException {
        // TODO Auto-generated method stub

    }

    public float getAnimationScale(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public float[] getAnimationScales() throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public int getAppOrientation(IApplicationToken arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getDPadKeycodeState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getDPadScancodeState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }


    public InputDevice getInputDevice(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public int[] getInputDeviceIds() throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public int getKeycodeState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getKeycodeStateForDevice(int arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }


    public int getPendingAppTransition() throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }


    public int getScancodeState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getScancodeStateForDevice(int arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getSwitchState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getSwitchStateForDevice(int arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getTrackballKeycodeState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getTrackballScancodeState(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public boolean hasKeys(int[] arg0, boolean[] arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean inKeyguardRestrictedInputMode() throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean injectInputEventNoWait(InputEvent arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean injectKeyEvent(KeyEvent arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean injectPointerEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean injectTrackballEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean isKeyguardLocked() throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean isKeyguardSecure() throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public boolean isViewServerRunning() throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public InputChannel monitorInput(String arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public void moveAppToken(int arg0, IBinder arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void moveAppTokensToBottom(List<IBinder> arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void moveAppTokensToTop(List<IBinder> arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1)
            throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public void overridePendingAppTransition(String arg0, int arg1, int arg2)
            throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void prepareAppTransition(int arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void reenableKeyguard(IBinder arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void removeAppToken(IBinder arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void removeWindowToken(IBinder arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void resumeKeyDispatching(IBinder arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public Bitmap screenshotApplications(IBinder arg0, int arg1, int arg2) throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public void setAnimationScale(int arg0, float arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setAnimationScales(float[] arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setAppGroupId(IBinder arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setAppOrientation(IApplicationToken arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
            CharSequence arg4, int arg5, int arg6, int arg7, IBinder arg8, boolean arg9)
            throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setAppVisibility(IBinder arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setAppWillBeHidden(IBinder arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setEventDispatching(boolean arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setFocusedApp(IBinder arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setForcedDisplaySize(int arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setInTouchMode(boolean arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setNewConfiguration(Configuration arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setPointerSpeed(int arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setRotation(int arg0, boolean arg1, int arg2) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void setStrictModeVisualIndicatorPreference(String arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void showStrictModeViolation(boolean arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void startAppFreezingScreen(IBinder arg0, int arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public boolean startViewServer(int arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public void statusBarVisibilityChanged(int arg0) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public void stopAppFreezingScreen(IBinder arg0, boolean arg1) throws RemoteException {
        // TODO Auto-generated method stub

    }

    public boolean stopViewServer() throws RemoteException {
        // TODO Auto-generated method stub
        return false;
    }

    public void thawRotation() throws RemoteException {
        // TODO Auto-generated method stub

    }

    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1)
            throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }

    public int watchRotation(IRotationWatcher arg0) throws RemoteException {
        // TODO Auto-generated method stub
        return 0;
    }

    public IBinder asBinder() {
        // TODO Auto-generated method stub
        return null;
    }

}
+63 −7
Original line number Diff line number Diff line
@@ -27,10 +27,14 @@ import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.resources.Density;
import com.android.resources.ResourceType;
import com.android.resources.ScreenSize;

import android.content.res.Configuration;
import android.os.HandlerThread_Delegate;
import android.util.DisplayMetrics;
import android.view.ViewConfiguration;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@@ -94,24 +98,29 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
        // setup the display Metrics.
        DisplayMetrics metrics = new DisplayMetrics();
        metrics.densityDpi = mParams.getDensity().getDpiValue();
        metrics.density = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
        metrics.scaledDensity = metrics.density;
        metrics.widthPixels = mParams.getScreenWidth();
        metrics.heightPixels = mParams.getScreenHeight();
        metrics.xdpi = mParams.getXdpi();
        metrics.ydpi = mParams.getYdpi();

        metrics.density = metrics.noncompatDensity =
                metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;

        metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;

        metrics.widthPixels = metrics.noncompatWidthPixels = mParams.getScreenWidth();
        metrics.heightPixels = metrics.noncompatHeightPixels = mParams.getScreenHeight();
        metrics.xdpi = metrics.noncompatXdpi = mParams.getXdpi();
        metrics.ydpi = metrics.noncompatYdpi = mParams.getYdpi();

        RenderResources resources = mParams.getResources();

        // build the context
        mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
                mParams.getProjectCallback(), mParams.getTargetSdkVersion());
                mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion());

        setUp();

        return SUCCESS.createResult();
    }


    /**
     * Prepares the scene for action.
     * <p>
@@ -233,6 +242,9 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
        // quit HandlerThread created during this session.
        HandlerThread_Delegate.cleanUp(sCurrentContext);

        // clear the stored ViewConfiguration since the map is per density and not per context.
        ViewConfiguration.sConfigurations.clear();

        sCurrentContext = null;

        Bridge.setLog(null);
@@ -281,6 +293,50 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
        }
    }

    private Configuration getConfiguration() {
        Configuration config = new Configuration();

        ScreenSize screenSize = mParams.getConfigScreenSize();
        if (screenSize != null) {
            switch (screenSize) {
                case SMALL:
                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL;
                    break;
                case NORMAL:
                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL;
                    break;
                case LARGE:
                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
                    break;
                case XLARGE:
                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
                    break;
            }
        }

        Density density = mParams.getDensity();
        if (density == null) {
            density = Density.MEDIUM;
        }

        config.screenWidthDp = mParams.getScreenWidth() / density.getDpiValue();
        config.screenHeightDp = mParams.getScreenHeight() / density.getDpiValue();
        if (config.screenHeightDp < config.screenWidthDp) {
            config.smallestScreenWidthDp = config.screenHeightDp;
        } else {
            config.smallestScreenWidthDp = config.screenWidthDp;
        }

        // never run in compat mode:
        config.compatScreenWidthDp = config.screenWidthDp;
        config.compatScreenHeightDp = config.screenHeightDp;

        // TODO: fill in more config info.

        return config;
    }


    // --- FrameworkResourceIdProvider methods

    @Override
+1 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="src" path="src"/>
	<classpathentry kind="src" path="res"/>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
Loading