RenderSessionImpl.java revision 1b5ef2d19e1d7cb491c1c79f867e38ec0bde2770
13bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet/* 23bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Copyright (C) 2010 The Android Open Source Project 33bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 43bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 53bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * you may not use this file except in compliance with the License. 63bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * You may obtain a copy of the License at 73bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 83bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 93bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Unless required by applicable law or agreed to in writing, software 113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * See the License for the specific language governing permissions and 143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * limitations under the License. 153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetpackage com.android.layoutlib.bridge.impl; 183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 19ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND; 20ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION; 21ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED; 22ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED; 23ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT; 24ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; 25ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN; 26ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 27ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet 28ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.IAnimationListener; 29ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ILayoutPullParser; 30ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback; 31907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog; 32ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Params; 330d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 34ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderSession; 35ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceValue; 36ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 37ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.StyleResourceValue; 38ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ViewInfo; 39ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Params.RenderingMode; 400d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider; 41ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status; 423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.internal.util.XmlUtils; 43ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeInflater; 46ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; 473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeWindow; 483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeWindowSession; 493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser; 50a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohetimport com.android.resources.Density; 511b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohetimport com.android.resources.ResourceType; 52a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohetimport com.android.resources.ScreenSize; 533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.Animator; 55ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport android.animation.AnimatorInflater; 5633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.LayoutTransition; 5762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohetimport android.animation.LayoutTransition.TransitionListener; 583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.app.Fragment_Delegate; 593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap; 603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap_Delegate; 613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Canvas; 623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.drawable.Drawable; 633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.os.Handler; 643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.DisplayMetrics; 653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.TypedValue; 663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View; 673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.ViewGroup; 683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View.AttachInfo; 693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View.MeasureSpec; 70ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport android.view.ViewGroup.LayoutParams; 713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.FrameLayout; 72f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.LinearLayout; 7362c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohetimport android.widget.QuickContactBadge; 743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.TabHost; 753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.TabWidget; 76f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.TabHost.TabSpec; 773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 784c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohetimport java.awt.AlphaComposite; 793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Color; 803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Graphics2D; 813bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.image.BufferedImage; 823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.ArrayList; 833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.List; 843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.Map; 85ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport java.util.concurrent.TimeUnit; 86ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport java.util.concurrent.locks.ReentrantLock; 873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet/** 89ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * Class implementing the render session. 903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 91ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * A session is a stateful representation of a layout file. It is initialized with data coming 92ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then 933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * be done on the layout. 943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 960d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohetpublic class RenderSessionImpl extends FrameworkResourceIdProvider { 973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; 993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; 1003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 101ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 102ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * The current context being rendered. This is set through {@link #acquire(long)} and 103ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #init(long)}, and unset in {@link #release()}. 104ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 105ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet private static BridgeContext sCurrentContext = null; 106ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 107ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private final Params mParams; 1083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // scene state 110ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private RenderSession mScene; 1113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeContext mContext; 1123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeXmlBlockParser mBlockParser; 1133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeInflater mInflater; 1146a5b91fceb1913cab6416bef99d7b28530d16ecfXavier Ducrohet private ResourceValue mWindowBackground; 1153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private FrameLayout mViewRoot; 1161392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private Canvas mCanvas; 1171392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenWidth = -1; 1181392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenHeight = -1; 119a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean mIsAlphaChannelImage = true; 120a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 121a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mStatusBarSize; 122a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mTopBarSize; 123a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mSystemBarSize; 124a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mTopOffset; 125a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mTotalBarSize; 126a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // information being returned through the API 1293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BufferedImage mImage; 130e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet private List<ViewInfo> mViewInfoList; 1313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final class PostInflateException extends Exception { 1333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final long serialVersionUID = 1L; 1343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public PostInflateException(String message) { 1363bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet super(message); 1373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Creates a layout scene with all the information coming from the layout bridge API. 1423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 143ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init()}, which act as a 144ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * call to {@link RenderSessionImpl#acquire(long)} 1453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 1463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams) 1473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 148ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public RenderSessionImpl(Params params) { 1493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // copy the params. 150ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet mParams = new Params(params); 151ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 152ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 153ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 154ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 155ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * inflater, and parser. 156ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 157ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 158ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 159ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @return whether the scene was prepared 160ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 161ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #acquire(long) 162ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #release() 163ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 164ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result init(long timeout) { 165ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 166ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // the result. 167ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = acquireLock(timeout); 168ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (result != null) { 169ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet return result; 170ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // setup the display Metrics. 1733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet DisplayMetrics metrics = new DisplayMetrics(); 1743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.densityDpi = mParams.getDensity(); 1753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.density = mParams.getDensity() / (float) DisplayMetrics.DENSITY_DEFAULT; 1763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.scaledDensity = metrics.density; 1773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.widthPixels = mParams.getScreenWidth(); 1783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.heightPixels = mParams.getScreenHeight(); 1793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.xdpi = mParams.getXdpi(); 1803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet metrics.ydpi = mParams.getYdpi(); 1813bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1820d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet RenderResources resources = mParams.getResources(); 1833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // build the context 1850d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, 1860d8c2a8b1c307453a54211fdcebb68b564344feaXavier Ducrohet mParams.getProjectCallback(), mParams.getTargetSdkVersion()); 1873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 188a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // use default of true in case it's not found to use alpha by default 189a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mIsAlphaChannelImage = getBooleanThemeValue(resources, 190a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowIsFloating", true /*defaultValue*/); 191a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 192ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1930d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet setUp(); 1943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 195a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findBackground(resources); 196a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findStatusBar(resources, metrics); 197a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findTopBar(resources, metrics); 198a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findSystemBar(resources, metrics); 1993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 200a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mTopOffset = mStatusBarSize + mTopBarSize; 201a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mTotalBarSize = mTopOffset + mSystemBarSize; 2023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // build the inflater and parser. 2043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mInflater = new BridgeInflater(mContext, mParams.getProjectCallback()); 2053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mContext.setBridgeInflater(mInflater); 2063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mInflater.setFactory2(mContext); 2073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mBlockParser = new BridgeXmlBlockParser(mParams.getLayoutDescription(), 2093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mContext, false /* platformResourceFlag */); 210ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 211ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 2123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 2133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 215ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Prepares the scene for action. 216ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * <p> 217ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * This call is blocking if another rendering/inflating is currently happening, and will return 218ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * whether the preparation worked. 219ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 220ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * The preparation can fail if another rendering took too long and the timeout was elapsed. 221ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 222ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * More than one call to this from the same thread will have no effect and will return 223ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Result#SUCCESS}. 224ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 225ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * After scene actions have taken place, only one call to {@link #release()} must be 226ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * done. 227ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 228ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 229ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 230ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @return whether the scene was prepared 231ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 232ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #release() 233ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 234ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if {@link #init(long)} was never called. 235ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 236ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result acquire(long timeout) { 237ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (mContext == null) { 238ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet throw new IllegalStateException("After scene creation, #init() must be called"); 239ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 240ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 241ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 242ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // the result. 243ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = acquireLock(timeout); 244ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (result != null) { 245ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet return result; 246ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 2473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2480d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet setUp(); 249ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2503054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return SUCCESS.createResult(); 2513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 2523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 254ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Acquire the lock so that the scene can be acted upon. 2553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 256ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * This returns null if the lock was just acquired, otherwise it returns 257ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Result#SUCCESS} if the lock already belonged to that thread, or another 258ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * instance (see {@link Result#getStatus()}) if an error occurred. 259ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 260ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 261ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @return null if the lock was just acquire or another result depending on the state. 262ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 263ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 264ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene. 2653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 266ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result acquireLock(long timeout) { 267ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 268ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 269ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet try { 270ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS); 271ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 272ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (acquired == false) { 2733054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return ERROR_TIMEOUT.createResult(); 274ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 275ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } catch (InterruptedException e) { 2763054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return ERROR_LOCK_INTERRUPTED.createResult(); 277ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 278ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } else { 279ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // This thread holds the lock already. Checks that this wasn't for a different context. 280ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // If this is called by init, mContext will be null and so should sCurrentContext 281ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // anyway 282ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (mContext != sCurrentContext) { 283ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet throw new IllegalStateException("Acquiring different scenes from same thread without releases"); 284ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 2853054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return SUCCESS.createResult(); 286ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 2873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 288ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet return null; 289ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 290ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 291ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 292ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Cleans up the scene after an action. 293ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 294ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet public void release() { 295ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 296ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 297ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // with the use of finally blocks, it is possible to find ourself calling this 298ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // without a successful call to prepareScene. This test makes sure that unlock() will 299ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // not throw IllegalMonitorStateException. 300ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (lock.isHeldByCurrentThread()) { 3010d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet tearDown(); 302ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet lock.unlock(); 303ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 3043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 3053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 3070d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet * Sets up the session for rendering. 3080d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet * <p/> 3090d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet * The counterpart is {@link #tearDown()}. 3100d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet */ 3110d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet private void setUp() { 3120d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet // make sure the Resources object references the context (and other objects) for this 3130d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet // scene 3140d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext.initResources(); 3150d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet sCurrentContext = mContext; 3160d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 3170d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet LayoutLog currentLog = mParams.getLog(); 3180d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet Bridge.setLog(currentLog); 3190d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(this); 3200d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext.getRenderResources().setLogger(currentLog); 3210d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet } 3220d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 3230d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet /** 3240d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet * Tear down the session after rendering. 3250d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet * <p/> 3260d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet * The counterpart is {@link #setUp()}. 3270d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet */ 3280d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet private void tearDown() { 3290d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet // Make sure to remove static references, otherwise we could not unload the lib 3300d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext.disposeResources(); 3310d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet sCurrentContext = null; 3320d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 3330d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet Bridge.setLog(null); 3340d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(null); 3350d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet mContext.getRenderResources().setLogger(null); 3360d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 3370d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet } 3380d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 3390d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet /** 3403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Inflates the layout. 3413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 342ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 343ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 344ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 345ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #init(long)} was not called. 3463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 347ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result inflate() { 348ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 349ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 3503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 3513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mViewRoot = new FrameLayout(mContext); 3533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // Sets the project callback (custom view loader) to the fragment delegate so that 3553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // it can instantiate the custom Fragment. 3563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Fragment_Delegate.setProjectCallback(mParams.getProjectCallback()); 3573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View view = mInflater.inflate(mBlockParser, mViewRoot); 3593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // post-inflate process. For now this supports TabHost/TabWidget 3613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet postInflateProcess(view, mParams.getProjectCallback()); 3623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Fragment_Delegate.setProjectCallback(null); 3643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // set the AttachInfo on the root view. 3663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(), 3673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet new Handler(), null); 3683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet info.mHasWindowFocus = true; 3693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet info.mWindowVisibility = View.VISIBLE; 3703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet info.mInTouchMode = false; // this is so that we can display selections. 37190f9956c17660c35ee6fe934815c16e97bf0d3f8Xavier Ducrohet info.mHardwareAccelerated = false; 3723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mViewRoot.dispatchAttachedToWindow(info, 0); 3733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the background drawable 3753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (mWindowBackground != null) { 3763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Drawable d = ResourceHelper.getDrawable(mWindowBackground, 3773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mContext, true /* isFramework */); 3783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mViewRoot.setBackgroundDrawable(d); 3793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 3803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 381ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 3823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (PostInflateException e) { 383ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(e.getMessage(), e); 3843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 3853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 3863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 3873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 3883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 3893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 3903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 391ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(t.getMessage(), t); 3923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 3933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 3943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 3963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Renders the scene. 3973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 398ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 399ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 4004c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * @param freshRender whether the render is a new one and should erase the existing bitmap (in 4014c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * the case where bitmaps are reused). This is typically needed when not playing 4024c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * animations.) 4034c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * 404ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 405ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 4061392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet * 4071392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet * @see SceneParams#getRenderingMode() 40833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @see LayoutScene#render(long) 4093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 4104c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet public Result render(boolean freshRender) { 411ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 412ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 4133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 4143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (mViewRoot == null) { 415ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_NOT_INFLATED.createResult(); 4163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // measure the views 4183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet int w_spec, h_spec; 4193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 420e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet RenderingMode renderingMode = mParams.getRenderingMode(); 421e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet 4221392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // only do the screen measure when needed. 4231392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet boolean newRenderSize = false; 4241392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (mMeasuredScreenWidth == -1) { 4251392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet newRenderSize = true; 4261392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mMeasuredScreenWidth = mParams.getScreenWidth(); 427a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenHeight = mParams.getScreenHeight() - mTotalBarSize; 4281392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 4291392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode != RenderingMode.NORMAL) { 4301392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // measure the full size needed by the layout. 4311392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, 4321392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet renderingMode.isHorizExpand() ? 4331392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4341392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet : MeasureSpec.EXACTLY); 435a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight, 4361392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet renderingMode.isVertExpand() ? 4371392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4381392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet : MeasureSpec.EXACTLY); 4391392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mViewRoot.measure(w_spec, h_spec); 4401392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 4411392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isHorizExpand()) { 4421392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth(); 4431392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (neededWidth > mMeasuredScreenWidth) { 4441392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mMeasuredScreenWidth = neededWidth; 4451392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 446e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 4473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4481392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isVertExpand()) { 4491392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight(); 450a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (neededHeight > mMeasuredScreenHeight) { 451a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenHeight = neededHeight; 4521392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 453e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 4543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // remeasure with the size we need 4583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // This must always be done before the call to layout 4591392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, MeasureSpec.EXACTLY); 460a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight, 4613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet MeasureSpec.EXACTLY); 4623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet mViewRoot.measure(w_spec, h_spec); 4633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // now do the layout. 465a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 4663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // draw the views 4683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // create the BufferedImage into which the layout will be rendered. 4694c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet boolean newImage = false; 4701392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (newRenderSize || mCanvas == null) { 4711392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (mParams.getImageFactory() != null) { 472a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mImage = mParams.getImageFactory().getImage( 473a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenWidth, 474a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenHeight + mTotalBarSize); 4751392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } else { 476a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mImage = new BufferedImage( 477a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenWidth, 478a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenHeight + mTotalBarSize, 479a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet BufferedImage.TYPE_INT_ARGB); 4804c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet newImage = true; 4811392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 4823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 483ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet if (mParams.isBgColorOverridden()) { 4844c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet // since we override the content, it's the same as if it was a new image. 4854c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet newImage = true; 4861392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet Graphics2D gc = mImage.createGraphics(); 487ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet gc.setColor(new Color(mParams.getOverrideBgColor(), true)); 4884c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet gc.setComposite(AlphaComposite.Src); 489a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.fillRect(0, 0, mMeasuredScreenWidth, 490a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenHeight + mTotalBarSize); 4911392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet gc.dispose(); 4921392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 4933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4941392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // create an Android bitmap around the BufferedImage 4951392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, 4961392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet true /*isMutable*/, 497a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet Density.getEnum(mParams.getDensity())); 4983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4991392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // create a Canvas around the Android bitmap 5001392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mCanvas = new Canvas(bitmap); 5011392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mCanvas.setDensity(mParams.getDensity()); 502a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mCanvas.translate(0, mTopOffset); 5031392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 5043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5054c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet if (freshRender && newImage == false) { 5064c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet Graphics2D gc = mImage.createGraphics(); 5074c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet gc.setComposite(AlphaComposite.Src); 508a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 509a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mStatusBarSize > 0) { 510a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.setColor(new Color(0xFF3C3C3C, true)); 511a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.fillRect(0, 0, mMeasuredScreenWidth, mStatusBarSize); 512a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 513a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 514a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mTopBarSize > 0) { 515a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.setColor(new Color(0xFF7F7F7F, true)); 516a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.fillRect(0, mStatusBarSize, mMeasuredScreenWidth, mTopOffset); 517a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 518a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 519a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // erase the rest 520a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.setColor(new Color(0x00000000, true)); 521a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.fillRect(0, mTopOffset, 522a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenWidth, mMeasuredScreenHeight + mTopOffset); 523a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 524a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mSystemBarSize > 0) { 525a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.setColor(new Color(0xFF3C3C3C, true)); 526a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet gc.fillRect(0, mMeasuredScreenHeight + mTopOffset, 527a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mMeasuredScreenWidth, mMeasuredScreenHeight + mTotalBarSize); 528a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 529a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 530a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // done 5314c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet gc.dispose(); 5324c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet } 5334c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet 5341392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mViewRoot.draw(mCanvas); 5351392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 536a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mViewInfoList = visitAllChildren((ViewGroup)mViewRoot, mContext, mTopOffset); 5373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // success! 539ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 5403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 5413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 5423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 5433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 5443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 5453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 547ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 5483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 552ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Animate an object 553ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * <p> 554ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 555ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 556ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 557ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 55833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 55933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @see LayoutScene#animate(Object, String, boolean, IAnimationListener) 560ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 561ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result animate(Object targetObject, String animationName, 562ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet boolean isFrameworkAnimation, IAnimationListener listener) { 563ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 564ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 565ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // find the animation file. 5666a5b91fceb1913cab6416bef99d7b28530d16ecfXavier Ducrohet ResourceValue animationResource = null; 567ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet int animationId = 0; 568ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (isFrameworkAnimation) { 5690d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet animationResource = mContext.getRenderResources().getFrameworkResource( 5701b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 571ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 5721b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet animationId = Bridge.getResourceValue(ResourceType.ANIMATOR, animationName); 573ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 574ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } else { 5750d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet animationResource = mContext.getRenderResources().getProjectResource( 5761b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 577ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 578551346323dace2bdb2509a7f5c9a0a200794b29cXavier Ducrohet animationId = mContext.getProjectCallback().getResourceValue( 5791b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 580ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 581ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 582ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 583ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 584ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet try { 58533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet Animator anim = AnimatorInflater.loadAnimator(mContext, animationId); 586ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (anim != null) { 587ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet anim.setTarget(targetObject); 588ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 58933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new PlayAnimationThread(anim, this, animationName, listener).start(); 590ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 591ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 592ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 593ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } catch (Exception e) { 594b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get the real cause of the exception. 595b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet Throwable t = e; 596b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet while (t.getCause() != null) { 597b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet t = t.getCause(); 598b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 599b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 600ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 601ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 602ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 603ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 604ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_ANIM_NOT_FOUND.createResult(); 605b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 606b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 60733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 60833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Insert a new child into an existing parent. 60933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 61033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 61133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 61233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 61333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 61433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 615ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @see LayoutScene#insertChild(Object, ILayoutPullParser, int, IAnimationListener) 61633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 617ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml, 61833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final int index, IAnimationListener listener) { 619b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 620b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 621b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // create a block parser for the XML 622b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, mContext, 623b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet false /* platformResourceFlag */); 624b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 625b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // inflate the child without adding it to the root since we want to control where it'll 626b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get added. We do pass the parentView however to ensure that the layoutParams will 627b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // be created correctly. 62833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); 629b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 63033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 63133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 63233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 63333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "insertChild", listener) { 63433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 63533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 636ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 63733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(new LayoutTransition()); 63833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return addView(parentView, child, index); 63933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 64033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 64133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 64233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 64333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(null); 64433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 64533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 64633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 64733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 648ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(child); 6491392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 6501392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 65133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // add it to the parentView in the correct location 652ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = addView(parentView, child, index); 65333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (result.isSuccess() == false) { 65433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 65533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 656b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 6574c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 6581766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet if (result.isSuccess()) { 65933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(child); 6601766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet } 6611766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet 6621766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet return result; 663b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 664b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 66533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 66633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Adds a given view to a given parent at a given index. 66733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 66833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param parent the parent to receive the view 66933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to add to the parent 67033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the index where to do the add. 67133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 672ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 673ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 67433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 67533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 676ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result addView(ViewGroup parent, View view, int index) { 67733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 67833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.addView(view, index); 679ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 68033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 68133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 682ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 68333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 68433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 68533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 68633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 68733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a view to a new parent at a given location 68833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 68933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 69033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 69133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 69233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 69333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 69433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @see LayoutScene#moveChild(Object, Object, int, Map, IAnimationListener) 69533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 69662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public Result moveChild(final ViewGroup newParentView, final View childView, final int index, 69724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Map<String, String> layoutParamsMap, final IAnimationListener listener) { 698b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 699b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 70033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 70133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 702ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet LayoutParams layoutParams = null; 70333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (layoutParamsMap != null) { 70433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // need to create a new LayoutParams object for the new parent. 70562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet layoutParams = newParentView.generateLayoutParams( 70633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new BridgeLayoutParamsMapAttributes(layoutParamsMap)); 70733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 7081392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 70962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // get the current parent of the view that needs to be moved. 71062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet final ViewGroup previousParent = (ViewGroup) childView.getParent(); 71162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 71233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 71333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final LayoutParams params = layoutParams; 714ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 71524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // there is no support for animating views across layouts, so in case the new and old 71624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // parent views are different we fake the animation through a no animation thread. 71724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousParent != newParentView) { 71824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new Thread("not animated moveChild") { 71924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 72024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void run() { 72124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, 72224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet params); 72324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (result.isSuccess() == false) { 72424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 72524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 72624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 72724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // ready to do the work, acquire the scene. 72824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet result = acquire(250); 72924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (result.isSuccess() == false) { 73024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 73124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return; 73224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 73324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 73424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet try { 7354c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 73624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (result.isSuccess()) { 73724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.onNewFrame(RenderSessionImpl.this.getSession()); 73824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 73924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } finally { 74024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet release(); 74124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 74224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 74324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 74462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 74524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 74624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } else { 74724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 74862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 74924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 75024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public Result preAnimation() { 75124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // set up the transition for the parent. 75224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition transition = new LayoutTransition(); 75324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(transition); 7545562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet 75524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // tweak the animation durations and start delays (to match the duration of 75624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // animation playing just before). 75724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // Note: Cannot user Animation.setDuration() directly. Have to set it 75824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // on the LayoutTransition. 75924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.DISAPPEARING, 100); 76024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_DISAPPEARING plays after DISAPPEARING 76124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100); 762ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 76324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100); 76424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 76524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100); 76624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_APPEARING plays after CHANGE_APPEARING 76724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.APPEARING, 100); 76824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 76924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.APPEARING, 100); 77024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 77124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return moveView(previousParent, newParentView, childView, index, params); 77224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 77324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 77424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 77524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void postAnimation() { 77624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(null); 77724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParentView.setLayoutTransition(null); 77824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 77924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 78024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 78133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 78233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 783ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(layoutParams); 784b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 785b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 78662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, layoutParams); 78733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (result.isSuccess() == false) { 78833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 78933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 790b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 7914c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 792ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet if (layoutParams != null && result.isSuccess()) { 79333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(layoutParams); 794ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet } 795ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 796ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet return result; 797b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 798b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 79933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 80033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a View from its current parent to a new given parent at a new given location, with 80133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * an optional new {@link LayoutParams} instance 80233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 80362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param previousParent the previous parent, still owning the child at the time of the call. 80462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param newParent the new parent 80524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet * @param movedView the view to move 80633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the new location in the new parent 80733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param params an option (can be null) {@link LayoutParams} instance. 80833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 809ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 810ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 81133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 81233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 81324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private Result moveView(ViewGroup previousParent, final ViewGroup newParent, 81424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet final View movedView, final int index, final LayoutParams params) { 8151392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet try { 81662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // check if there is a transition on the previousParent. 81724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition previousTransition = previousParent.getLayoutTransition(); 81824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousTransition != null) { 8195562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // in this case there is an animation. This means we have to wait for the child's 8205562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent reference to be null'ed out so that we can add it to the new parent. 8215562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // It is technically removed right before the DISAPPEARING animation is done (if 8225562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // the animation of this type is not null, otherwise it's after which is impossible 8235562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // to handle). 8245562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // Because there is no move animation, if the new parent is the same as the old 8255562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before 8265562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // adding the child or the child will appear in its new location before the 8275562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // other children have made room for it. 82862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 82962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add a listener to the transition to be notified of the actual removal. 83024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousTransition.addTransitionListener(new TransitionListener() { 83124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private int mChangeDisappearingCount = 0; 83262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 83362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void startTransition(LayoutTransition transition, ViewGroup container, 83462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 83524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 83624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount++; 83724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 83862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 83933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 84062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void endTransition(LayoutTransition transition, ViewGroup container, 84162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 84224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 84324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount--; 84424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 84524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 84624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING && 84724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount == 0) { 84862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 84962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 85024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 85162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 85224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 85362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 85462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 85562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 85662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet }); 85762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 85862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // remove the view from the current parent. 85924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 86062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 86162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // and return since adding the view to the new parent is done in the listener. 86262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 86333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } else { 86462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // standard code with no animation. pretty simple. 86524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 86633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 86762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 86862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 86924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 87062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 87124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 87262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 87362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 87462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 87562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 8761392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } catch (UnsupportedOperationException e) { 8771392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 878ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 879b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 88033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 88133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 88233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 88333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a child from its current parent. 88433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 88533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 88633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 88733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 88833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 88933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 89033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @see LayoutScene#removeChild(Object, IAnimationListener) 89133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 892ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result removeChild(final View childView, IAnimationListener listener) { 89333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet checkLock(); 894b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 8951392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet invalidateRenderingSize(); 8961392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 89733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final ViewGroup parent = (ViewGroup) childView.getParent(); 89833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 89933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 90033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 90133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 90233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 903ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 90433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(new LayoutTransition()); 90533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return removeView(parent, childView); 90633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 90733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 90833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 90933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 91033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(null); 91133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 91233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 91333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 91433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 915ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 91633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 91733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 918ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = removeView(parent, childView); 91933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (result.isSuccess() == false) { 92033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 92133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 92233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 9234c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet return render(false /*freshRender*/); 924ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 925ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 926ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 92733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a given view from its current parent. 92833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 92933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to remove from its parent 93033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 931ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 932ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 93333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 93433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 935ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result removeView(ViewGroup parent, View view) { 93633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 93733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.removeView(view); 938ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 93933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 94033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 941ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 94233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 94333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 94433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 94533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 946907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet * Returns the log associated with the session. 947907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet * @return the log or null if there are none. 948907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet */ 949907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet public LayoutLog getLog() { 950907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet if (mParams != null) { 951907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet return mParams.getLog(); 952907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet } 953907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet 954907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet return null; 955907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet } 956907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet 957907c716cce7b8fa785d9005081d25d3ecc2d5365Xavier Ducrohet /** 958ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Checks that the lock is owned by the current thread and that the current context is the one 959ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * from this scene. 960ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 961ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 962ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 963ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 964ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet private void checkLock() { 965ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 966ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 967ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); 968ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 969ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (sCurrentContext != mContext) { 970ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet throw new IllegalStateException("Thread acquired a scene but is rendering a different one"); 971ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 972ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 973ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 974a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findBackground(RenderResources resources) { 975a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mParams.isBgColorOverridden() == false) { 976a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mWindowBackground = resources.findItemInTheme("windowBackground"); 977a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mWindowBackground != null) { 978a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mWindowBackground = resources.resolveResValue(mWindowBackground); 979a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 980a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 981a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 9823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 983a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean isTabletUi() { 984a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return mParams.getConfigScreenSize() == ScreenSize.XLARGE; 985a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 9863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 987a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean isHCApp() { 988a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet RenderResources resources = mContext.getRenderResources(); 989a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 990a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // the app must say it targets 11+ and the theme name must extend Theme.Holo or 991a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // Theme.Holo.Light (which does not extend Theme.Holo, but Theme.Light) 992a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mParams.getTargetSdkVersion() < 11) { 993a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return false; 994a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 995a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 996a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet StyleResourceValue currentTheme = resources.getCurrentTheme(); 997a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet StyleResourceValue holoTheme = resources.getTheme("Theme.Holo", true /*frameworkTheme*/); 998a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 999a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (currentTheme == holoTheme || 1000a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet resources.themeIsParentOf(holoTheme, currentTheme)) { 1001a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return true; 1002a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1003a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1004a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet StyleResourceValue holoLightTheme = resources.getTheme("Theme.Holo.Light", 1005a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet true /*frameworkTheme*/); 1006a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1007a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (currentTheme == holoLightTheme || 1008a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet resources.themeIsParentOf(holoLightTheme, currentTheme)) { 1009a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return true; 1010a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1011a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1012a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return false; 1013a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1014a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1015a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { 1016a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (isTabletUi() == false) { 1017a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowFullscreen = getBooleanThemeValue(resources, 1018a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowFullscreen", false /*defaultValue*/); 1019a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1020a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowFullscreen == false) { 1021a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // default value 1022a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; 1023a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1024a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // get the real value 10251b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 1026a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "status_bar_height"); 1027a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1028a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (value != null) { 1029a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue(value.getValue()); 1030a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (typedValue != null) { 1031a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // compute the pixel value based on the display metrics 1032a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mStatusBarSize = (int)typedValue.getDimension(metrics); 1033a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1034a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1035a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1036a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1037a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1038a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1039a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findTopBar(RenderResources resources, DisplayMetrics metrics) { 1040a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowIsFloating = getBooleanThemeValue(resources, 1041a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowIsFloating", true /*defaultValue*/); 1042a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1043a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowIsFloating == false) { 1044a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (isHCApp()) { 1045a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findActionBar(resources, metrics); 1046a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } else { 1047a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findTitleBar(resources, metrics); 1048a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1049a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1050a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1051a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1052a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findActionBar(RenderResources resources, DisplayMetrics metrics) { 1053a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowActionBar = getBooleanThemeValue(resources, 1054a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowActionBar", true /*defaultValue*/); 1055a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1056a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's a value and it's false (default is true) 1057a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowActionBar) { 10583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default size of the window title bar 1060a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mTopBarSize = DEFAULT_TITLE_BAR_HEIGHT; 10613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get value from the theme. 1063a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet ResourceValue value = resources.findItemInTheme("actionBarSize"); 10643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // resolve it 1066a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 10673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 10693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the numerical value, if available 10703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue(value.getValue()); 10713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 10723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 1073a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mTopBarSize = (int)typedValue.getDimension(metrics); 10743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 10753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 10763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1077a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1079a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findTitleBar(RenderResources resources, DisplayMetrics metrics) { 1080a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowNoTitle = getBooleanThemeValue(resources, 1081a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowNoTitle", false /*defaultValue*/); 10823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1083a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowNoTitle == false) { 1084a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1085a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // default size of the window title bar 1086a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mTopBarSize = DEFAULT_TITLE_BAR_HEIGHT; 1087a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1088a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // get value from the theme. 1089a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet ResourceValue value = resources.findItemInTheme("windowTitleSize"); 1090a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1091a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // resolve it 1092a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 10933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1094a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (value != null) { 1095a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // get the numerical value, if available 1096a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue(value.getValue()); 1097a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (typedValue != null) { 1098a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // compute the pixel value based on the display metrics 1099a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mTopBarSize = (int)typedValue.getDimension(metrics); 1100a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1101a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1102a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1103a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1104a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1105a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findSystemBar(RenderResources resources, DisplayMetrics metrics) { 1106a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (isTabletUi() && getBooleanThemeValue( 1107a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet resources, "windowIsFloating", true /*defaultValue*/) == false) { 11083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default value 1110a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mSystemBarSize = 56; // ?? 11113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1112089143ffed72bb47fd8d870f29caffb646138781Xavier Ducrohet // get the real value 11131b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 1114a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "status_bar_height"); 1115a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 11163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 11173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue(value.getValue()); 11183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 11193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 1120a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mSystemBarSize = (int)typedValue.getDimension(metrics); 11213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1123a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1124a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1125a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1126a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean getBooleanThemeValue(RenderResources resources, 1127a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet String name, boolean defaultValue) { 1128a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1129a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // get the title bar flag from the current theme. 1130a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet ResourceValue value = resources.findItemInTheme(name); 1131a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1132a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // because it may reference something else, we resolve it. 1133a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 11343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1135a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's no value, return the default. 1136a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (value == null || value.getValue() == null) { 1137a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return defaultValue; 11383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1140a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); 11413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 11443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Post process on a view hierachy that was just inflated. 11453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the 11463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically 11473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * based on the content of the {@link FrameLayout}. 11483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param view the root view to process. 11493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param projectCallback callback to the project. 11503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 11513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private void postInflateProcess(View view, IProjectCallback projectCallback) 11523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 11533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view instanceof TabHost) { 11543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet setupTabHost((TabHost)view, projectCallback); 115562c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet } else if (view instanceof QuickContactBadge) { 115662c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet QuickContactBadge badge = (QuickContactBadge) view; 115762c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet badge.setImageToDefault(); 11583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } else if (view instanceof ViewGroup) { 11593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet ViewGroup group = (ViewGroup)view; 11603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = group.getChildCount(); 11613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet for (int c = 0 ; c < count ; c++) { 11623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View child = group.getChildAt(c); 11633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet postInflateProcess(child, projectCallback); 11643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 11693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Sets up a {@link TabHost} object. 11703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param tabHost the TabHost to setup. 11713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param projectCallback The project callback object to access the project R class. 11723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @throws PostInflateException 11733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 11743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback) 11753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 11763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // look for the TabWidget, and the FrameLayout. They have their own specific names 11773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View v = tabHost.findViewById(android.R.id.tabs); 11783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 11803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 11813bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n"); 11823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if ((v instanceof TabWidget) == false) { 11853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 11863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n" + 11873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName())); 11883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet v = tabHost.findViewById(android.R.id.tabcontent); 11913bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 11933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty) 11943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 11953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\"."); 11963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if ((v instanceof FrameLayout) == false) { 11993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 12003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" + 12013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName())); 12023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet FrameLayout content = (FrameLayout)v; 12053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // now process the content of the framelayout and dynamically create tabs for it. 12073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = content.getChildCount(); 12083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // this must be called before addTab() so that the TabHost searches its TabWidget 12103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // and FrameLayout. 12113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet tabHost.setup(); 12123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1213f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (count == 0) { 1214f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye // Create a dummy child to get a single tab 1215f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label", 1216f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details)) 1217f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye .setContent(new TabHost.TabContentFactory() { 1218f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye public View createTabContent(String tag) { 1219f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye return new LinearLayout(mContext); 1220f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1221f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye }); 1222f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(spec); 1223f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye return; 1224f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1225f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye // for each child of the framelayout, add a new TabSpec 1226f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye for (int i = 0 ; i < count ; i++) { 1227f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye View child = content.getChildAt(i); 1228f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String tabSpec = String.format("tab_spec%d", i+1); 1229f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye int id = child.getId(); 1230f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String[] resource = projectCallback.resolveResourceValue(id); 1231f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String name; 1232f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (resource != null) { 1233f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye name = resource[0]; // 0 is resource name, 1 is resource type. 1234f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1235f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye name = String.format("Tab %d", i+1); // default name if id is unresolved. 1236f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1237f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id)); 12383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 12443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Visits a View and its children and generate a {@link ViewInfo} containing the 12453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * bounds of all the views. 12463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param view the root View 12473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param context the context. 12483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1249a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private ViewInfo visit(View view, BridgeContext context, int offset) { 12503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view == null) { 12513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return null; 12523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet ViewInfo result = new ViewInfo(view.getClass().getName(), 12553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet context.getViewKey(view), 1256a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset, 12572d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet view, view.getLayoutParams()); 12583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view instanceof ViewGroup) { 12603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet ViewGroup group = ((ViewGroup) view); 1261a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet result.setChildren(visitAllChildren(group, context, 0 /*offset*/)); 12623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return result; 12653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1267a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, BridgeContext context, 1268a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet int offset) { 1269e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet if (viewGroup == null) { 1270e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet return null; 1271e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 1272e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 1273e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet List<ViewInfo> children = new ArrayList<ViewInfo>(); 1274e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet for (int i = 0; i < viewGroup.getChildCount(); i++) { 1275a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet children.add(visit(viewGroup.getChildAt(i), context, offset)); 1276e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 1277e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet return children; 1278e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 1279e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 1280e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 12811392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private void invalidateRenderingSize() { 12821392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet mMeasuredScreenWidth = mMeasuredScreenHeight = -1; 12831392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 12841392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 12853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public BufferedImage getImage() { 12863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return mImage; 12873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1289a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet public boolean isAlphaChannelImage() { 1290a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return mIsAlphaChannelImage; 1291a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1292a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1293e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet public List<ViewInfo> getViewInfos() { 1294e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet return mViewInfoList; 12953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12962d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet 1297ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Map<String, String> getDefaultProperties(Object viewObject) { 12982d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet return mContext.getDefaultPropMap(viewObject); 12992d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet } 1300b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1301ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public void setScene(RenderSession session) { 1302ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet mScene = session; 1303b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 1304b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1305ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public RenderSession getSession() { 1306b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet return mScene; 1307b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 13080d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 13090d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet // --- FrameworkResourceIdProvider methods 13100d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet 13110d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet @Override 13121b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet public Integer getId(ResourceType resType, String resName) { 13130d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet return Bridge.getResourceValue(resType, resName); 13140d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohet } 13153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet} 1316