RenderSessionImpl.java revision e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4
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_NOT_INFLATED; 22ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; 23ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN; 24ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 25ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet 267062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.ide.common.rendering.api.AdapterBinding; 2764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.ide.common.rendering.api.HardwareConfig; 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; 310d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 32ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderSession; 337062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceReference; 34ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceValue; 35ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 36ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status; 37d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams; 38b32414fe256a6fe1d65e7a1443cd6ea77db8bd95Xavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams.RenderingMode; 3945d9520182663e47a1878ce51be756219799b2c9Deepanshu Guptaimport com.android.ide.common.rendering.api.StyleResourceValue; 40d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport com.android.ide.common.rendering.api.ViewInfo; 4170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport com.android.ide.common.rendering.api.ViewType; 423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.internal.util.XmlUtils; 4341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.ActionMenuItemView; 4441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.BridgeMenuItemImpl; 4541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.IconMenuItemView; 4641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.ListMenuItemView; 4741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.MenuItemImpl; 4841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.MenuView; 49ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 51ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; 523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser; 538a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Guptaimport com.android.layoutlib.bridge.android.SessionParamsFlags; 54841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Guptaimport com.android.layoutlib.bridge.bars.BridgeActionBar; 55841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Guptaimport com.android.layoutlib.bridge.bars.AppCompatActionBar; 5682ca7fe915ed30a7e30eb3de3ce816a9ad0867d6Deepanshu Guptaimport com.android.layoutlib.bridge.bars.Config; 5764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.layoutlib.bridge.bars.NavigationBar; 5864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.layoutlib.bridge.bars.StatusBar; 59799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohetimport com.android.layoutlib.bridge.bars.TitleBar; 60841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Guptaimport com.android.layoutlib.bridge.bars.FrameworkActionBar; 617062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeAdapter; 627062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; 6385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Guptaimport com.android.resources.Density; 641b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohetimport com.android.resources.ResourceType; 6564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.resources.ScreenOrientation; 66947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohetimport com.android.util.Pair; 673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 68799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohetimport org.xmlpull.v1.XmlPullParserException; 69799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 70994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.animation.AnimationThread; 7133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.Animator; 72ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport android.animation.AnimatorInflater; 7333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.LayoutTransition; 7462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohetimport android.animation.LayoutTransition.TransitionListener; 753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.app.Fragment_Delegate; 763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap; 773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap_Delegate; 783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Canvas; 793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.drawable.Drawable; 808a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Guptaimport android.preference.Preference_Delegate; 813bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.DisplayMetrics; 823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.TypedValue; 83994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.view.AttachInfo_Accessor; 84994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.view.BridgeInflater; 8576f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.IWindowManager; 8664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport android.view.IWindowManagerImpl; 8776f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.Surface; 883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View; 893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View.MeasureSpec; 90d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport android.view.ViewGroup; 91ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport android.view.ViewGroup.LayoutParams; 926208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohetimport android.view.ViewGroup.MarginLayoutParams; 9370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport android.view.ViewParent; 9476f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.WindowManagerGlobal_Delegate; 957062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AbsListView; 967062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AbsSpinner; 9770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport android.widget.ActionMenuView; 987062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AdapterView; 997062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.ExpandableListView; 1003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.FrameLayout; 101f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.LinearLayout; 1027062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.ListView; 10362c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohetimport android.widget.QuickContactBadge; 1043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.TabHost; 105f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.TabHost.TabSpec; 106d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport android.widget.TabWidget; 1073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1084c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohetimport java.awt.AlphaComposite; 1093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Color; 1103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Graphics2D; 1113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.image.BufferedImage; 1123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.ArrayList; 1133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.List; 1143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.Map; 1153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet/** 117ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * Class implementing the render session. 118952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * <p/> 119ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * A session is a stateful representation of a layout file. It is initialized with data coming 120ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then 1213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * be done on the layout. 1223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1230fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohetpublic class RenderSessionImpl extends RenderAction<SessionParams> { 1243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; 1263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; 1273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // scene state 129ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private RenderSession mScene; 1303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeXmlBlockParser mBlockParser; 1313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeInflater mInflater; 1326a5b91fceb1913cab6416bef99d7b28530d16ecfXavier Ducrohet private ResourceValue mWindowBackground; 133799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private ViewGroup mViewRoot; 134799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private FrameLayout mContentRoot; 1351392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private Canvas mCanvas; 1361392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenWidth = -1; 1371392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenHeight = -1; 138799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private boolean mIsAlphaChannelImage; 139799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private boolean mWindowIsFloating; 14045d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta private Boolean mIsThemeAppCompat; 141a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 142a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mStatusBarSize; 14364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private int mNavigationBarSize; 14464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; 145799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private int mTitleBarSize; 146799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private int mActionBarSize; 147a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // information being returned through the API 1503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BufferedImage mImage; 151e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet private List<ViewInfo> mViewInfoList; 15285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private List<ViewInfo> mSystemViewInfoList; 1533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final class PostInflateException extends Exception { 1553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final long serialVersionUID = 1L; 1563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public PostInflateException(String message) { 1583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet super(message); 1593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Creates a layout scene with all the information coming from the layout bridge API. 1643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 1658d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)}, 1668d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * which act as a 167ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * call to {@link RenderSessionImpl#acquire(long)} 1683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 1698d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * @see Bridge#createSession(SessionParams) 1703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 171b32414fe256a6fe1d65e7a1443cd6ea77db8bd95Xavier Ducrohet public RenderSessionImpl(SessionParams params) { 1720fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet super(new SessionParams(params)); 173ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 174ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 175ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 176ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 177ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * inflater, and parser. 178ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 179ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 180ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 181ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @return whether the scene was prepared 182ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 183ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #acquire(long) 184ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #release() 185ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 1860fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet @Override 187ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result init(long timeout) { 1880fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Result result = super.init(timeout); 189952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 190ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet return result; 191ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1930fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 1940fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 1953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 196835ad76e300033f1d9cccd214bd7d61d78d0240aDeepanshu Gupta 1970fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet RenderResources resources = getParams().getResources(); 1980fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet DisplayMetrics metrics = getContext().getMetrics(); 1993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 200a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // use default of true in case it's not found to use alpha by default 20145d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta mIsAlphaChannelImage = getBooleanThemeValue(resources, "windowIsFloating", true, true); 20245d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta // FIXME: Find out why both variables are taking the same value. 20345d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", true, true); 204ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 205a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findBackground(resources); 206a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findStatusBar(resources, metrics); 207799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet findActionBar(resources, metrics); 20864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet findNavigationBar(resources, metrics); 2093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 21076f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet // FIXME: find those out, and possibly add them to the render params 21176f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet boolean hasNavigationBar = true; 212952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection ConstantConditions 21376f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(), 21476f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet metrics, Surface.ROTATION_0, 2151e3c4a072f4476cedb958d75e2a6edf3bde8378fJohn Spurlock hasNavigationBar); 21676f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet WindowManagerGlobal_Delegate.setWindowManagerService(iwm); 21776f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet 2183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // build the inflater and parser. 2190fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet mInflater = new BridgeInflater(context, params.getProjectCallback()); 2200fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet context.setBridgeInflater(mInflater); 221ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 222a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet mBlockParser = new BridgeXmlBlockParser( 223a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet params.getLayoutDescription(), context, false /* platformResourceFlag */); 224ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2253054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return SUCCESS.createResult(); 2263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 2273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 2293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Inflates the layout. 2303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 231ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 232ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 233ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 234ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #init(long)} was not called. 2353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 236ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result inflate() { 237ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 238ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 2403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2410fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 24264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 2430fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 244510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta boolean isRtl = Bridge.isLocaleRtl(params.getLocale()); 24585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; 24664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 247cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet // the view group that receives the window background. 248952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ViewGroup backgroundView; 249cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 2500fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet if (mWindowIsFloating || params.isForceNoDecor()) { 251cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); 25285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mViewRoot.setLayoutDirection(layoutDirection); 253799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else { 254bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta int simulatedPlatformVersion = params.getSimulatedPlatformVersion(); 25564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { 25664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet /* 25764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet * This is a special case where the navigation bar is on the right. 25864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+---+ 25964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Status bar (always) | | 26064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+ | 26164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | (Layout with background drawable) | | 26264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 26364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | Title/Action bar (optional) | | | 26464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 26564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | Content, vertical extending | | | 26664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | | | | 26764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 26864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+---+ 26964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 27064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet So we create a horizontal layout, with the nav bar on the right, 27164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet and the left part is the normal layout below without the nav bar at 27264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet the bottom 27364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet */ 27464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 27585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 27664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mViewRoot = topLayout; 27764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.setOrientation(LinearLayout.HORIZONTAL); 27864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 279bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta if (Config.showOnScreenNavBar(simulatedPlatformVersion)) { 280f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta try { 281f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 282bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported(), 283bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 284f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta topLayout.addView(navigationBar); 285f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta } catch (XmlPullParserException ignored) { 286f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta } 28764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 28864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 28964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 290799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet /* 291799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * we're creating the following layout 292799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * 293799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 29464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Status bar (always) | 295799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 296cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | (Layout with background drawable) | 297cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 298cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | Title/Action bar (optional) | | 299cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 300cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | Content, vertical extending | | 301cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | | | 302cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 303799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 30464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Navigation bar for soft buttons, maybe see above| 305799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 306799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 307799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet */ 308799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 3090fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 310799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet topLayout.setOrientation(LinearLayout.VERTICAL); 31185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 31264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // if we don't already have a view root this is it 31364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (mViewRoot == null) { 31464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mViewRoot = topLayout; 31564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } else { 31685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int topLayoutWidth = 31785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta params.getHardwareConfig().getScreenWidth() - mNavigationBarSize; 31864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 31985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayoutWidth, LayoutParams.MATCH_PARENT); 32064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.setLayoutParams(layoutParams); 32164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 32264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // this is the case of soft buttons + vertical bar. 32364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // this top layout is the first layout in the horizontal layout. see above) 324510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta if (isRtl && params.isRtlSupported()) { 325510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // If RTL is enabled, layoutlib will mirror the layouts. So, add the 326510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // topLayout to the right of Navigation Bar and layoutlib will draw it 327510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // to the left. 328510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta mViewRoot.addView(topLayout); 329510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta } else { 330510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // Add the top layout to the left of the Navigation Bar. 331510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta mViewRoot.addView(topLayout, 0); 332510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta } 33364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 334799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 335799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mStatusBarSize > 0) { 336799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // system bar 337799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 33885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(), 339f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta layoutDirection, params.isRtlSupported(), 340bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 34185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.addView(statusBar); 342952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 343799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 344799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 345799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 346799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 347cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet LinearLayout backgroundLayout = new LinearLayout(context); 348cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundView = backgroundLayout; 349cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.setOrientation(LinearLayout.VERTICAL); 350cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 351fa7ed38ae9c180ff12a7312e6ec740b5ba313a97Deepanshu Gupta LayoutParams.MATCH_PARENT, 0); 352cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet layoutParams.weight = 1; 353cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.setLayoutParams(layoutParams); 354cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet topLayout.addView(backgroundLayout); 355cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 356cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 357799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // if the theme says no title/action bar, then the size will be 0 358799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mActionBarSize > 0) { 359841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta BridgeActionBar actionBar = createActionBar(context, params, backgroundLayout); 360952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta actionBar.createMenuPopup(); 361952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta mContentRoot = actionBar.getContentRoot(); 362799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else if (mTitleBarSize > 0) { 363799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 36485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta TitleBar titleBar = createTitleBar(context, 365bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta params.getAppLabel(), 366bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 367cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.addView(titleBar); 368952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 369799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 370799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 371799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 372799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 373799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // content frame 37485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (mContentRoot == null) { 37585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mContentRoot = new FrameLayout(context); 37685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutParams = new LinearLayout.LayoutParams( 37785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, 0); 37885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutParams.weight = 1; 37985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mContentRoot.setLayoutParams(layoutParams); 38085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta backgroundLayout.addView(mContentRoot); 38185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 382799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 383bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta if (Config.showOnScreenNavBar(simulatedPlatformVersion) && 384f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta mNavigationBarOrientation == LinearLayout.HORIZONTAL && 38564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize > 0) { 386799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // system bar 387799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 38885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 389bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported(), 390bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 39164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.addView(navigationBar); 392952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 393799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 394799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 395799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 396799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 397799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 3983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // Sets the project callback (custom view loader) to the fragment delegate so that 4003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // it can instantiate the custom Fragment. 4010fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Fragment_Delegate.setProjectCallback(params.getProjectCallback()); 4023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4038a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta String rootTag = params.getFlag(SessionParamsFlags.FLAG_KEY_ROOT_TAG); 4048a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta boolean isPreference = "PreferenceScreen".equals(rootTag); 4058a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta View view; 4068a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta if (isPreference) { 4078a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta view = Preference_Delegate.inflatePreference(getContext(), mBlockParser, 4088a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta mContentRoot); 4098a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta } else { 4108a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta view = mInflater.inflate(mBlockParser, mContentRoot); 4118a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta } 4123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4137062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // done with the parser, pop it. 4147062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet context.popParser(); 4157062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 4163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Fragment_Delegate.setProjectCallback(null); 4173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // set the AttachInfo on the root view. 419994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohet AttachInfo_Accessor.setAttachInfo(mViewRoot); 4203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 421a2378f55b81e7d29f451d7f65527de49417a3f0cXavier Ducrohet // post-inflate process. For now this supports TabHost/TabWidget 4228a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta postInflateProcess(view, params.getProjectCallback(), isPreference ? view : null); 423a2378f55b81e7d29f451d7f65527de49417a3f0cXavier Ducrohet 4243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the background drawable 425952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (mWindowBackground != null) { 4260fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); 42764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet backgroundView.setBackground(d); 4283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 430ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 4313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (PostInflateException e) { 432ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(e.getMessage(), e); 4333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 4343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 4353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 4363bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 4373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 4383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 440ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(t.getMessage(), t); 4413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 4453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Renders the scene. 4463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 447ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 448ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 4494c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * @param freshRender whether the render is a new one and should erase the existing bitmap (in 4504c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * the case where bitmaps are reused). This is typically needed when not playing 4514c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * animations.) 4524c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * 453ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 454ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 4551392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet * 4568d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * @see SessionParams#getRenderingMode() 457799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#render(long) 4583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 4594c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet public Result render(boolean freshRender) { 460ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 461ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 4620fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 4630fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 4643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 4653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (mViewRoot == null) { 466ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_NOT_INFLATED.createResult(); 4673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4690fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet RenderingMode renderingMode = params.getRenderingMode(); 47064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 471e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet 4721392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // only do the screen measure when needed. 4731392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet boolean newRenderSize = false; 4741392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (mMeasuredScreenWidth == -1) { 4751392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet newRenderSize = true; 47664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mMeasuredScreenWidth = hardwareConfig.getScreenWidth(); 47764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); 4781392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 4791392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode != RenderingMode.NORMAL) { 4808ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int widthMeasureSpecMode = renderingMode.isHorizExpand() ? 4818ae691c1148038995d1185716f629b82c582897fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4828ae691c1148038995d1185716f629b82c582897fXavier Ducrohet : MeasureSpec.EXACTLY; 4838ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int heightMeasureSpecMode = renderingMode.isVertExpand() ? 4848ae691c1148038995d1185716f629b82c582897fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4858ae691c1148038995d1185716f629b82c582897fXavier Ducrohet : MeasureSpec.EXACTLY; 4868ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4878ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // We used to compare the measured size of the content to the screen size but 4888ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // this does not work anymore due to the 2 following issues: 4898ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // - If the content is in a decor (system bar, title/action bar), the root view 4908ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // will not resize even with the UNSPECIFIED because of the embedded layout. 4918ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // - If there is no decor, but a dialog frame, then the dialog padding prevents 4928ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // comparing the size of the content to the screen frame (as it would not 4938ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // take into account the dialog padding). 4948ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4958ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // The solution is to first get the content size in a normal rendering, inside 4968ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // the decor or the dialog padding. 4978ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // Then measure only the content with UNSPECIFIED to see the size difference 4988ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // and apply this to the screen size. 4998ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 5008ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // first measure the full layout, with EXACTLY to get the size of the 5018ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // content as it is inside the decor/dialog 502952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 5038ae691c1148038995d1185716f629b82c582897fXavier Ducrohet Pair<Integer, Integer> exactMeasure = measureView( 5048ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mViewRoot, mContentRoot.getChildAt(0), 5058ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 5068ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 5078ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 5088ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // now measure the content only using UNSPECIFIED (where applicable, based on 5098ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // the rendering mode). This will give us the size the content needs. 510952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 5118ae691c1148038995d1185716f629b82c582897fXavier Ducrohet Pair<Integer, Integer> result = measureView( 5128ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mContentRoot, mContentRoot.getChildAt(0), 5138ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, widthMeasureSpecMode, 5148ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, heightMeasureSpecMode); 5158ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 5168ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // now look at the difference and add what is needed. 5171392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isHorizExpand()) { 5188ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int measuredWidth = exactMeasure.getFirst(); 5198ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int neededWidth = result.getFirst(); 5208ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (neededWidth > measuredWidth) { 5218ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth += neededWidth - measuredWidth; 5221392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 523e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 5243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5251392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isVertExpand()) { 5268ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int measuredHeight = exactMeasure.getSecond(); 5278ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int neededHeight = result.getSecond(); 5288ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (neededHeight > measuredHeight) { 5298ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight += neededHeight - measuredHeight; 5301392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 531e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 5323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5358ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // measure again with the size we need 5363bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // This must always be done before the call to layout 5378ae691c1148038995d1185716f629b82c582897fXavier Ducrohet measureView(mViewRoot, null /*measuredView*/, 5388ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 5398ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 5403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // now do the layout. 542a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 5433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 544f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.isLayoutOnly()) { 545f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // delete the canvas and image to reset them on the next full rendering 546f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = null; 547f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mCanvas = null; 548f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } else { 549994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohet AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot); 550f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 551f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // draw the views 552f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create the BufferedImage into which the layout will be rendered. 553f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet boolean newImage = false; 554e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez 555e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // When disableBitmapCaching is true, we do not reuse mImage and 556e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // we create a new one in every render. 557e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // This is useful when mImage is just a wrapper of Graphics2D so 558e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // it doesn't get cached. 559e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag( 560e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez SessionParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING)); 561e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez if (newRenderSize || mCanvas == null || disableBitmapCaching) { 562f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.getImageFactory() != null) { 563f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = params.getImageFactory().getImage( 564f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, 565f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenHeight); 566f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } else { 567f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = new BufferedImage( 568f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, 569f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenHeight, 570f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet BufferedImage.TYPE_INT_ARGB); 571f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet newImage = true; 572f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 573f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 574f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.isBgColorOverridden()) { 575f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // since we override the content, it's the same as if it was a new image. 576f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet newImage = true; 577f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet Graphics2D gc = mImage.createGraphics(); 578f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setColor(new Color(params.getOverrideBgColor(), true)); 579f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setComposite(AlphaComposite.Src); 580f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 581f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.dispose(); 582f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 583f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 584f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create an Android bitmap around the BufferedImage 585f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, 58664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet true /*isMutable*/, hardwareConfig.getDensity()); 587f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 588e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez if (mCanvas == null) { 589e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // create a Canvas around the Android bitmap 590e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez mCanvas = new Canvas(bitmap); 591e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez } else { 592e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez mCanvas.setBitmap(bitmap); 593e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez } 59464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue()); 5951392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 5963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 597952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (freshRender && !newImage) { 5981392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet Graphics2D gc = mImage.createGraphics(); 5994c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet gc.setComposite(AlphaComposite.Src); 6003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 601f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setColor(new Color(0x00000000, true)); 602f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.fillRect(0, 0, 603f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, mMeasuredScreenHeight); 604a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 605f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // done 606f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.dispose(); 607f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 608a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 609f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mViewRoot.draw(mCanvas); 6104c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet } 6114c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet 61241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), 61341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta false); 6143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 6153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // success! 616ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 6173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 6183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 6193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 6203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 6213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 6223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 6233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 624ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 6253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 6263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 6273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 6283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 6298ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * Executes {@link View#measure(int, int)} on a given view with the given parameters (used 6308ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}. 6318ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * 6328ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height) 6338ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}). 6348ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * 6358ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param viewToMeasure the view on which to execute measure(). 6368ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param measuredView if non null, the view to query for its measured width/height. 6378ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param width the width to use in the MeasureSpec. 6388ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param widthMode the MeasureSpec mode to use for the width. 6398ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param height the height to use in the MeasureSpec. 6408ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param heightMode the MeasureSpec mode to use for the height. 6418ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @return the measured width/height if measuredView is non-null, null otherwise. 6428ae691c1148038995d1185716f629b82c582897fXavier Ducrohet */ 643952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") // For the use of Pair 6448ae691c1148038995d1185716f629b82c582897fXavier Ducrohet private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, 6458ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int width, int widthMode, int height, int heightMode) { 6468ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode); 6478ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode); 6488ae691c1148038995d1185716f629b82c582897fXavier Ducrohet viewToMeasure.measure(w_spec, h_spec); 6498ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6508ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (measuredView != null) { 6518ae691c1148038995d1185716f629b82c582897fXavier Ducrohet return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight()); 6528ae691c1148038995d1185716f629b82c582897fXavier Ducrohet } 6538ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6548ae691c1148038995d1185716f629b82c582897fXavier Ducrohet return null; 6558ae691c1148038995d1185716f629b82c582897fXavier Ducrohet } 6568ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6578ae691c1148038995d1185716f629b82c582897fXavier Ducrohet /** 658ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Animate an object 659ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * <p> 660ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 661ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 662ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 663ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 66433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 665799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#animate(Object, String, boolean, IAnimationListener) 666ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 667ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result animate(Object targetObject, String animationName, 668ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet boolean isFrameworkAnimation, IAnimationListener listener) { 669ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 670ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 6710fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 6720fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 673ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // find the animation file. 674952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ResourceValue animationResource; 675ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet int animationId = 0; 676ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (isFrameworkAnimation) { 6770fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationResource = context.getRenderResources().getFrameworkResource( 6781b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 679ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 680947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName); 681ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 682ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } else { 6830fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationResource = context.getRenderResources().getProjectResource( 6841b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 685ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 6860fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationId = context.getProjectCallback().getResourceId( 6871b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 688ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 689ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 690ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 691ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 692ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet try { 6930fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Animator anim = AnimatorInflater.loadAnimator(context, animationId); 694ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (anim != null) { 695ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet anim.setTarget(targetObject); 696ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 69733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new PlayAnimationThread(anim, this, animationName, listener).start(); 698ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 699ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 700ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 701ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } catch (Exception e) { 702b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get the real cause of the exception. 703b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet Throwable t = e; 704b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet while (t.getCause() != null) { 705b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet t = t.getCause(); 706b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 707b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 708ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 709ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 710ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 711ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 712ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_ANIM_NOT_FOUND.createResult(); 713b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 714b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 71533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 71633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Insert a new child into an existing parent. 71733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 71833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 71933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 72033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 72133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 72233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 723799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener) 72433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 725ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml, 72633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final int index, IAnimationListener listener) { 727b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 728b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 7290fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 7300fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 731b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // create a block parser for the XML 732a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( 733a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet childXml, context, false /* platformResourceFlag */); 734b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 735b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // inflate the child without adding it to the root since we want to control where it'll 736b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get added. We do pass the parentView however to ensure that the layoutParams will 737b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // be created correctly. 73833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); 739a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet blockParser.ensurePopped(); 740b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 74133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 74233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 74333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 74433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "insertChild", listener) { 74533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 74633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 747ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 74833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(new LayoutTransition()); 74933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return addView(parentView, child, index); 75033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 75133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 75233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 75333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 75433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(null); 75533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 75633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 75733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 75833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 759ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(child); 7601392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 7611392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 76233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // add it to the parentView in the correct location 763ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = addView(parentView, child, index); 764952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 76533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 76633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 767b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 7684c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 7691766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet if (result.isSuccess()) { 77033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(child); 7711766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet } 7721766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet 7731766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet return result; 774b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 775b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 77633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 77733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Adds a given view to a given parent at a given index. 77833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 77933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param parent the parent to receive the view 78033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to add to the parent 78133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the index where to do the add. 78233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 783ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 784ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 78533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 78633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 787ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result addView(ViewGroup parent, View view, int index) { 78833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 78933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.addView(view, index); 790ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 79133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 79233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 793ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 79433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 79533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 79633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 79733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 79833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a view to a new parent at a given location 79933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 80033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 80133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 80233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 80333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 80433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 805799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener) 80633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 80762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public Result moveChild(final ViewGroup newParentView, final View childView, final int index, 80824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Map<String, String> layoutParamsMap, final IAnimationListener listener) { 809b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 810b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 81133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 81233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 813ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet LayoutParams layoutParams = null; 81433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (layoutParamsMap != null) { 81533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // need to create a new LayoutParams object for the new parent. 81662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet layoutParams = newParentView.generateLayoutParams( 81733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new BridgeLayoutParamsMapAttributes(layoutParamsMap)); 81833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 8191392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 82062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // get the current parent of the view that needs to be moved. 82162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet final ViewGroup previousParent = (ViewGroup) childView.getParent(); 82262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 82333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 82433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final LayoutParams params = layoutParams; 825ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 82624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // there is no support for animating views across layouts, so in case the new and old 82724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // parent views are different we fake the animation through a no animation thread. 82824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousParent != newParentView) { 82924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new Thread("not animated moveChild") { 83024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 83124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void run() { 83224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, 83324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet params); 834952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 83524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 83624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 83724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 83824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // ready to do the work, acquire the scene. 83924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet result = acquire(250); 840952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 84124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 84224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return; 84324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 84424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 84524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet try { 8464c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 84724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (result.isSuccess()) { 84824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.onNewFrame(RenderSessionImpl.this.getSession()); 84924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 85024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } finally { 85124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet release(); 85224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 85324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 85424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 85562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 85624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 85724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } else { 85824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 85962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 86024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 86124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public Result preAnimation() { 86224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // set up the transition for the parent. 86324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition transition = new LayoutTransition(); 86424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(transition); 8655562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet 86624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // tweak the animation durations and start delays (to match the duration of 86724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // animation playing just before). 86824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // Note: Cannot user Animation.setDuration() directly. Have to set it 86924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // on the LayoutTransition. 87024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.DISAPPEARING, 100); 87124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_DISAPPEARING plays after DISAPPEARING 87224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100); 873ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 87424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100); 87524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 87624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100); 87724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_APPEARING plays after CHANGE_APPEARING 87824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.APPEARING, 100); 87924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 88024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.APPEARING, 100); 88124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 88224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return moveView(previousParent, newParentView, childView, index, params); 88324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 88424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 88524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 88624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void postAnimation() { 88724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(null); 88824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParentView.setLayoutTransition(null); 88924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 89024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 89124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 89233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 89333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 894ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(layoutParams); 895b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 896b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 89762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, layoutParams); 898952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 89933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 90033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 901b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 9024c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 903ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet if (layoutParams != null && result.isSuccess()) { 90433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(layoutParams); 905ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet } 906ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 907ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet return result; 908b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 909b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 91033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 91133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a View from its current parent to a new given parent at a new given location, with 91233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * an optional new {@link LayoutParams} instance 91333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 91462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param previousParent the previous parent, still owning the child at the time of the call. 91562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param newParent the new parent 91624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet * @param movedView the view to move 91733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the new location in the new parent 91833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param params an option (can be null) {@link LayoutParams} instance. 91933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 920ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 921ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 92233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 92333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 92424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private Result moveView(ViewGroup previousParent, final ViewGroup newParent, 92524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet final View movedView, final int index, final LayoutParams params) { 9261392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet try { 92762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // check if there is a transition on the previousParent. 92824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition previousTransition = previousParent.getLayoutTransition(); 92924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousTransition != null) { 9305562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // in this case there is an animation. This means we have to wait for the child's 9315562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent reference to be null'ed out so that we can add it to the new parent. 9325562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // It is technically removed right before the DISAPPEARING animation is done (if 9335562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // the animation of this type is not null, otherwise it's after which is impossible 9345562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // to handle). 9355562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // Because there is no move animation, if the new parent is the same as the old 9365562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before 9375562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // adding the child or the child will appear in its new location before the 9385562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // other children have made room for it. 93962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 94062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add a listener to the transition to be notified of the actual removal. 94124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousTransition.addTransitionListener(new TransitionListener() { 94224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private int mChangeDisappearingCount = 0; 94362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 944d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 94562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void startTransition(LayoutTransition transition, ViewGroup container, 94662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 94724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 94824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount++; 94924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 95062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 95133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 952d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 95362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void endTransition(LayoutTransition transition, ViewGroup container, 95462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 95524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 95624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount--; 95724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 95824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 95924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING && 96024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount == 0) { 96162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 96262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 96324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 96462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 96524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 96662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 96762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 96862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 96962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet }); 97062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 97162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // remove the view from the current parent. 97224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 97362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 97462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // and return since adding the view to the new parent is done in the listener. 97562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 97633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } else { 97762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // standard code with no animation. pretty simple. 97824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 97933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 98062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 98162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 98224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 98362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 98424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 98562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 98662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 98762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 98862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 9891392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } catch (UnsupportedOperationException e) { 9901392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 991ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 992b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 99333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 99433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 99533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 99633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a child from its current parent. 99733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 99833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 99933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 100033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 100133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 100233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 1003799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#removeChild(Object, IAnimationListener) 100433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 1005ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result removeChild(final View childView, IAnimationListener listener) { 100633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet checkLock(); 1007b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 10081392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet invalidateRenderingSize(); 10091392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 101033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final ViewGroup parent = (ViewGroup) childView.getParent(); 101133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 101233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 101333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 101433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 101533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 1016ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 101733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(new LayoutTransition()); 101833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return removeView(parent, childView); 101933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 102033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 102133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 102233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 102333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(null); 102433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 102533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 102633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 102733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 1028ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 102933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 103033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 1031ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = removeView(parent, childView); 1032952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 103333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 103433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 103533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 10364c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet return render(false /*freshRender*/); 1037ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1038ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1039ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 104033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a given view from its current parent. 104133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 104233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to remove from its parent 104333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 1044ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 1045ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 104633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 104733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 1048ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result removeView(ViewGroup parent, View view) { 104933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 105033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.removeView(view); 1051ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 105233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 105333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 1054ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 105533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 105633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 105733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 1058ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1059a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findBackground(RenderResources resources) { 1060952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!getParams().isBgColorOverridden()) { 106141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet mWindowBackground = resources.findItemInTheme("windowBackground", 106241fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 1063a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mWindowBackground != null) { 1064a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mWindowBackground = resources.resolveResValue(mWindowBackground); 1065a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1066a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1067a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 106964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private boolean hasSoftwareButtons() { 107064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet return getParams().getHardwareConfig().hasSoftwareButtons(); 1071a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1073a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { 107464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet boolean windowFullscreen = getBooleanThemeValue(resources, 107545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta "windowFullscreen", false, !isThemeAppCompat(resources)); 1076a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1077952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!windowFullscreen && !mWindowIsFloating) { 107864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // default value 107964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; 1080a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 108164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // get the real value 108264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 108364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet "status_bar_height"); 1084a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 108564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (value != null) { 108664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("status_bar_height", 108764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet value.getValue(), true /*requireUnit*/); 108864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (typedValue != null) { 108964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute the pixel value based on the display metrics 109064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mStatusBarSize = (int)typedValue.getDimension(metrics); 1091a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1092a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1093a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1094a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1095a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1096799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private void findActionBar(RenderResources resources, DisplayMetrics metrics) { 1097799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mWindowIsFloating) { 1098799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet return; 1099a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1100a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1101a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowActionBar = getBooleanThemeValue(resources, 110245d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta "windowActionBar", true, !isThemeAppCompat(resources)); 1103a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1104a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's a value and it's false (default is true) 1105a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowActionBar) { 11063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default size of the window title bar 1108799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT; 11093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get value from the theme. 111141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme("actionBarSize", 111241fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 11133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // resolve it 1115a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 11163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 11183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the numerical value, if available 1119d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(), 1120d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet true /*requireUnit*/); 11213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 11223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 1123799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mActionBarSize = (int)typedValue.getDimension(metrics); 11243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1126799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else { 1127799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // action bar overrides title bar so only look for this one if action bar is hidden 1128799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet boolean windowNoTitle = getBooleanThemeValue(resources, 112945d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta "windowNoTitle", false, !isThemeAppCompat(resources)); 11303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1131952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!windowNoTitle) { 1132a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1133799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // default size of the window title bar 1134799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT; 1135a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1136799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // get value from the theme. 113741fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme("windowTitleSize", 113841fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 1139a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1140799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // resolve it 1141799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet value = resources.resolveResValue(value); 11423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1143799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (value != null) { 1144799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // get the numerical value, if available 1145d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("windowTitleSize", 1146d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet value.getValue(), true /*requireUnit*/); 1147799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (typedValue != null) { 1148799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // compute the pixel value based on the display metrics 1149799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mTitleBarSize = (int)typedValue.getDimension(metrics); 1150799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 1151a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1152a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1153799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 1154a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1155a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1156a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 115764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { 1158952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (hasSoftwareButtons() && !mWindowIsFloating) { 11593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default value 116164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize = 48; // ?? 116264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 116364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = getParams().getHardwareConfig(); 116464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 116564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet boolean barOnBottom = true; 116664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 116764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { 116864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute the dp of the screen. 116964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet int shortSize = hardwareConfig.getScreenHeight(); 117064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 117164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute in dp 1172952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / 1173952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta hardwareConfig.getDensity().getDpiValue(); 117464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 1175952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // 0-599dp: "phone" UI with bar on the side 1176952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // 600+dp: "tablet" UI with bar on the bottom 1177952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta barOnBottom = shortSizeDp >= 600; 117864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 117964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 118064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (barOnBottom) { 118164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarOrientation = LinearLayout.HORIZONTAL; 118264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } else { 118364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarOrientation = LinearLayout.VERTICAL; 118464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 11853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1186089143ffed72bb47fd8d870f29caffb646138781Xavier Ducrohet // get the real value 11871b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 118864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); 1189a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 11903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 119164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", 1192d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet value.getValue(), true /*requireUnit*/); 11933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 11943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 119564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize = (int)typedValue.getDimension(metrics); 11963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1198a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1199a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1200a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 120145d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta private boolean isThemeAppCompat(RenderResources resources) { 120245d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta // Ideally, we should check if the corresponding activity extends 120345d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta // android.support.v7.app.ActionBarActivity, and not care about the theme name at all. 120445d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta if (mIsThemeAppCompat == null) { 120545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta StyleResourceValue defaultTheme = resources.getDefaultTheme(); 1206841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // We can't simply check for parent using resources.themeIsParentOf() since the 1207841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // inheritance structure isn't really what one would expect. The first common parent 1208841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21). 1209841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta boolean isThemeAppCompat = false; 1210841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta for (int i = 0; i < 50; i++) { 1211841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // for loop ensures that we don't run into cyclic theme inheritance. 1212841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta if (defaultTheme.getName().startsWith("Theme.AppCompat")) { 1213841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta isThemeAppCompat = true; 1214841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta break; 1215841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 1216841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta defaultTheme = resources.getParent(defaultTheme); 1217841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta if (defaultTheme == null) { 1218841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta break; 1219841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 1220841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 1221841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta mIsThemeAppCompat = isThemeAppCompat; 122245d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta } 122345d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta return mIsThemeAppCompat; 122445d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta } 122545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta 122641fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet /** 122745d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta * Looks for an attribute in the current theme. 122841fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * 122941fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param resources the render resources 123041fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param name the name of the attribute 123141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param defaultValue the default value. 123245d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta * @param isFrameworkAttr if the attribute is in android namespace 123341fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @return the value of the attribute or the default one if not found. 123441fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet */ 1235a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean getBooleanThemeValue(RenderResources resources, 123645d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta String name, boolean defaultValue, boolean isFrameworkAttr) { 1237a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 123845d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr); 1239a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1240a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // because it may reference something else, we resolve it. 1241a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 12423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1243a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's no value, return the default. 1244a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (value == null || value.getValue() == null) { 1245a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return defaultValue; 12463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1248a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); 12493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1252952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * Post process on a view hierarchy that was just inflated. 1253952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * <p/> 1254952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the 12553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically 12563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * based on the content of the {@link FrameLayout}. 12573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param view the root view to process. 12583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param projectCallback callback to the project. 12598a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta * @param skip the view and it's children are not processed. 12603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1261952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") // For the use of Pair 12628a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta private void postInflateProcess(View view, IProjectCallback projectCallback, View skip) 12633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 12648a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta if (view == skip) { 12658a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta return; 12668a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta } 12673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view instanceof TabHost) { 12688a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta setupTabHost((TabHost) view, projectCallback); 126962c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet } else if (view instanceof QuickContactBadge) { 127062c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet QuickContactBadge badge = (QuickContactBadge) view; 127162c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet badge.setImageToDefault(); 12727062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else if (view instanceof AdapterView<?>) { 12737062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // get the view ID. 12747062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet int id = view.getId(); 12757062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12767062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet BridgeContext context = getContext(); 12777062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12787062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // get a ResourceReference from the integer ID. 12797062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ResourceReference listRef = context.resolveId(id); 12807062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12817062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (listRef != null) { 12827062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet SessionParams params = getParams(); 12837062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet AdapterBinding binding = params.getAdapterBindings().get(listRef); 12847062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12857062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // if there was no adapter binding, trying to get it from the call back. 12867062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (binding == null) { 12877062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding = params.getProjectCallback().getAdapterBinding(listRef, 12887062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet context.getViewKey(view), view); 12897062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12907062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12917062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (binding != null) { 12927062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12937062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (view instanceof AbsListView) { 12947062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) && 12957062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet view instanceof ListView) { 12967062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ListView list = (ListView) view; 12977062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12987062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet boolean skipCallbackParser = false; 12997062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13007062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet int count = binding.getHeaderCount(); 13018a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta for (int i = 0; i < count; i++) { 13027062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 13037062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding.getHeaderAt(i), 13047062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list, false /*attachToRoot*/, skipCallbackParser); 13057062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (pair.getFirst() != null) { 13067062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list.addHeaderView(pair.getFirst()); 13077062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13087062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13097062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet skipCallbackParser |= pair.getSecond(); 13107062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13117062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13127062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet count = binding.getFooterCount(); 13138a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta for (int i = 0; i < count; i++) { 13147062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 13157062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding.getFooterAt(i), 13167062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list, false /*attachToRoot*/, skipCallbackParser); 13177062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (pair.getFirst() != null) { 13187062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list.addFooterView(pair.getFirst()); 13197062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13207062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13217062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet skipCallbackParser |= pair.getSecond(); 13227062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13237062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13247062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13257062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (view instanceof ExpandableListView) { 13267062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((ExpandableListView) view).setAdapter( 13277062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet new FakeExpandableAdapter( 13287062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet listRef, binding, params.getProjectCallback())); 13297062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else { 13307062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((AbsListView) view).setAdapter( 13317062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet new FakeAdapter( 13327062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet listRef, binding, params.getProjectCallback())); 13337062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13347062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else if (view instanceof AbsSpinner) { 13357062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((AbsSpinner) view).setAdapter( 13367062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet new FakeAdapter( 13377062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet listRef, binding, params.getProjectCallback())); 13387062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13397062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13407062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } else if (view instanceof ViewGroup) { 13428a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta ViewGroup group = (ViewGroup) view; 13433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = group.getChildCount(); 13448a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta for (int c = 0; c < count; c++) { 13453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View child = group.getChildAt(c); 13468a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta postInflateProcess(child, projectCallback, skip); 13473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 13523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Sets up a {@link TabHost} object. 13533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param tabHost the TabHost to setup. 13543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param projectCallback The project callback object to access the project R class. 13553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @throws PostInflateException 13563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 13573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback) 13583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 13593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // look for the TabWidget, and the FrameLayout. They have their own specific names 13603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View v = tabHost.findViewById(android.R.id.tabs); 13613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 13633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 13643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n"); 13653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1367952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!(v instanceof TabWidget)) { 13683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 13693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n" + 13703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName())); 13713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet v = tabHost.findViewById(android.R.id.tabcontent); 13743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 1376952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty) 1377952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection SpellCheckingInspection 13783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 13793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\"."); 13803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13813bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1382952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!(v instanceof FrameLayout)) { 1383952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection SpellCheckingInspection 13843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 13853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" + 13863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName())); 13873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet FrameLayout content = (FrameLayout)v; 13903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1391952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // now process the content of the frameLayout and dynamically create tabs for it. 13923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = content.getChildCount(); 13933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // this must be called before addTab() so that the TabHost searches its TabWidget 13953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // and FrameLayout. 13963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet tabHost.setup(); 13973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1398f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (count == 0) { 1399f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye // Create a dummy child to get a single tab 1400f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label", 1401f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details)) 1402f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye .setContent(new TabHost.TabContentFactory() { 1403d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 1404f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye public View createTabContent(String tag) { 14050fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet return new LinearLayout(getContext()); 1406f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1407f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye }); 1408f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(spec); 1409f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1410952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // for each child of the frameLayout, add a new TabSpec 1411f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye for (int i = 0 ; i < count ; i++) { 1412f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye View child = content.getChildAt(i); 1413f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String tabSpec = String.format("tab_spec%d", i+1); 14148a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta @SuppressWarnings("ConstantConditions") // child cannot be null. 1415f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye int id = child.getId(); 1416952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 1417947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id); 1418f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String name; 1419f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (resource != null) { 1420947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet name = resource.getSecond(); 1421f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1422f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye name = String.format("Tab %d", i+1); // default name if id is unresolved. 1423f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1424f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id)); 14253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 142985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 143085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the 143185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * bounds of all the views. 143285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 143385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param view the root View 143485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset for the view bounds. 143585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 143685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 143785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * content frame. 143885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 143985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @return {@code ViewInfo} containing the bounds of the view and it children otherwise. 144085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 144185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo visit(View view, int offset, boolean setExtendedInfo, 144285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isContentFrame) { 144385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo result = createViewInfo(view, offset, setExtendedInfo, isContentFrame); 1444799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 144585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view instanceof ViewGroup) { 144685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewGroup group = ((ViewGroup) view); 144785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result.setChildren(visitAllChildren(group, isContentFrame ? 0 : offset, 144885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta setExtendedInfo, isContentFrame)); 144985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 145085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 145185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1452799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 145385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 145485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo} 14558d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with 145685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * the children of the {@code mContentRoot}. 145785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 145885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param viewGroup the root View 145985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset from the top for the content view frame. 146085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 146185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 146285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * content frame. {@code false} if the {@code ViewInfo} to be created is 146385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * part of the system decor. 146485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 146585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset, 146685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean setExtendedInfo, boolean isContentFrame) { 146785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (viewGroup == null) { 146885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return null; 1469799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 1470799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 147185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (!isContentFrame) { 147285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta offset += viewGroup.getTop(); 147385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1474799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 147585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int childCount = viewGroup.getChildCount(); 147685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (viewGroup == mContentRoot) { 147785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> childrenWithoutOffset = new ArrayList<ViewInfo>(childCount); 147885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> childrenWithOffset = new ArrayList<ViewInfo>(childCount); 147985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta for (int i = 0; i < childCount; i++) { 148085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo[] childViewInfo = visitContentRoot(viewGroup.getChildAt(i), offset, 14816208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet setExtendedInfo); 148285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta childrenWithoutOffset.add(childViewInfo[0]); 148385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta childrenWithOffset.add(childViewInfo[1]); 1484799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 148585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mViewInfoList = childrenWithOffset; 148685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return childrenWithoutOffset; 148785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 148885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> children = new ArrayList<ViewInfo>(childCount); 148985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta for (int i = 0; i < childCount; i++) { 149085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo, 149185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta isContentFrame)); 149285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 149385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return children; 1494799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 149585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1496799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 149785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 149885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the 149985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * bounds of all the views. It returns two {@code ViewInfo} objects with the same children, 150085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * one with the {@code offset} and other without the {@code offset}. The offset is needed to 150185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * get the right bounds if the {@code ViewInfo} hierarchy is accessed from 150285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the 150385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * offset is not needed. 150485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 150585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at 150685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * index 1 is with the offset. 150785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 150885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo[] visitContentRoot(View view, int offset, boolean setExtendedInfo) { 150985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo[] result = new ViewInfo[2]; 151085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view == null) { 151185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 151285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 151385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 151485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[0] = createViewInfo(view, 0, setExtendedInfo, true); 151585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[1] = createViewInfo(view, offset, setExtendedInfo, true); 151685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view instanceof ViewGroup) { 151785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> children = visitAllChildren((ViewGroup) view, 0, setExtendedInfo, true); 151885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[0].setChildren(children); 151985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[1].setChildren(children); 152085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 152185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 1522799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 15233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 15243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 152585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children 152685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not 152785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * set. 152885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset for the view bounds. Used only if view is part of the content frame. 15293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 153085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo createViewInfo(View view, int offset, boolean setExtendedInfo, 153185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isContentFrame) { 15323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view == null) { 15333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return null; 15343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 15353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 153685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo result; 153785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (isContentFrame) { 153870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // The view is part of the layout added by the user. Hence, 153970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // the ViewCookie may be obtained only through the Context. 154085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result = new ViewInfo(view.getClass().getName(), 154170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta getContext().getViewKey(view), 154285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getLeft(), view.getTop() + offset, view.getRight(), 154385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getBottom() + offset, view, view.getLayoutParams()); 154485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 154570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // We are part of the system decor. 154670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta SystemViewInfo r = new SystemViewInfo(view.getClass().getName(), 154741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta getViewKey(view), 154885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getLeft(), view.getTop(), view.getRight(), 154985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getBottom(), view, view.getLayoutParams()); 155070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta result = r; 155170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // We currently mark three kinds of views: 155270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 1. Menus in the Action Bar 155370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 2. Menus in the Overflow popup. 155470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 3. The overflow popup button. 155570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (view instanceof ListMenuItemView) { 155670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 2. 155770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // All menus in the popup are of type ListMenuItemView. 155870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU); 155970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } else { 156070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 3. 156170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ViewGroup.LayoutParams lp = view.getLayoutParams(); 156270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (lp instanceof ActionMenuView.LayoutParams && 156370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ((ActionMenuView.LayoutParams) lp).isOverflowButton) { 156470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_OVERFLOW); 156570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } else { 156670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 1. 156770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // A view is a menu in the Action Bar is it is not the overflow button and of 156870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // its parent is of type ActionMenuView. We can also check if the view is 156970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // instanceof ActionMenuItemView but that will fail for menus using 157070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // actionProviderClass. 157170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ViewParent parent = view.getParent(); 157270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta while (parent != mViewRoot && parent instanceof ViewGroup) { 157370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (parent instanceof ActionMenuView) { 157470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_MENU); 157570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta break; 157670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 157770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta parent = parent.getParent(); 157870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 157970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 158070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 158185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 15823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 15836208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet if (setExtendedInfo) { 15846208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet MarginLayoutParams marginParams = null; 15856208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet LayoutParams params = view.getLayoutParams(); 15866208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet if (params instanceof MarginLayoutParams) { 15876208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams = (MarginLayoutParams) params; 15886208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet } 15896208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet result.setExtendedInfo(view.getBaseline(), 15906208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.leftMargin : 0, 15916208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.topMargin : 0, 15926208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.rightMargin : 0, 15936208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.bottomMargin : 0); 15946208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet } 15956208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet 15963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return result; 15973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 15983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 159970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta /* (non-Javadoc) 160041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta * The cookie for menu items are stored in menu item and not in the map from View stored in 160141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta * BridgeContext. 160241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta */ 160341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta private Object getViewKey(View view) { 160441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta BridgeContext context = getContext(); 160541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (!(view instanceof MenuView.ItemView)) { 160641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return context.getViewKey(view); 160741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 160841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta MenuItemImpl menuItem; 160941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (view instanceof ActionMenuItemView) { 161041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((ActionMenuItemView) view).getItemData(); 161141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else if (view instanceof ListMenuItemView) { 161241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((ListMenuItemView) view).getItemData(); 161341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else if (view instanceof IconMenuItemView) { 161441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((IconMenuItemView) view).getItemData(); 161541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else { 161641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = null; 161741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 161841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (menuItem instanceof BridgeMenuItemImpl) { 161941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return ((BridgeMenuItemImpl) menuItem).getViewCookie(); 162041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 162141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta 162241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return null; 162341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 162441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta 1625620f80a7ee9796c2c41ec0a42d10d2913fc50c90Diego Perez public void invalidateRenderingSize() { 162685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mMeasuredScreenWidth = mMeasuredScreenHeight = -1; 162785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 162885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 1629799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet /** 163085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the status bar with wifi and battery icons. 1631799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet */ 163285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private StatusBar createStatusBar(BridgeContext context, Density density, int direction, 1633f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta boolean isRtlSupported, int platformVersion) throws XmlPullParserException { 163485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta StatusBar statusBar = new StatusBar(context, density, 1635f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta direction, isRtlSupported, platformVersion); 163685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta statusBar.setLayoutParams( 163785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta new LinearLayout.LayoutParams( 163885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, mStatusBarSize)); 163985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return statusBar; 164085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1641e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 164285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 164385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the navigation bar with back, home and recent buttons. 164485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 164585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isRtl true if the current locale is right-to-left 164685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isRtlSupported true is the project manifest declares that the application 164785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * is RTL aware. 164885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 164985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private NavigationBar createNavigationBar(BridgeContext context, Density density, 1650bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta boolean isRtl, boolean isRtlSupported, int simulatedPlatformVersion) 1651bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta throws XmlPullParserException { 165285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = new NavigationBar(context, 165385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta density, mNavigationBarOrientation, isRtl, 1654bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta isRtlSupported, simulatedPlatformVersion); 165585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (mNavigationBarOrientation == LinearLayout.VERTICAL) { 165685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, 165785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT)); 165885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 165985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 166085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mNavigationBarSize)); 1661e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 166285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return navigationBar; 1663e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 1664e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 1665bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta private TitleBar createTitleBar(BridgeContext context, String title, 1666bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta int simulatedPlatformVersion) 166785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta throws XmlPullParserException { 1668bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); 166985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta titleBar.setLayoutParams( 167085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize)); 167185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return titleBar; 167285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1673e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 167485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 167585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the action bar. Also queries the project callback for missing information. 167685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 1677841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta private BridgeActionBar createActionBar(BridgeContext context, SessionParams params, 1678cc1ce2c8d83464c7be38e3281bf8da3963505a9bDeepanshu Gupta ViewGroup parentView) { 1679841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta if (mIsThemeAppCompat == Boolean.TRUE) { 1680841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta return new AppCompatActionBar(context, params, parentView); 1681841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } else { 1682841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta return new FrameworkActionBar(context, params, parentView); 1683841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 16841392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 16851392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 16863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public BufferedImage getImage() { 16873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return mImage; 16883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 16893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1690a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet public boolean isAlphaChannelImage() { 1691a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return mIsAlphaChannelImage; 1692a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1693a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1694e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet public List<ViewInfo> getViewInfos() { 1695e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet return mViewInfoList; 16963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 16972d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet 169885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta public List<ViewInfo> getSystemViewInfos() { 169985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return mSystemViewInfoList; 170085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 170185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 1702ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Map<String, String> getDefaultProperties(Object viewObject) { 17030fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet return getContext().getDefaultPropMap(viewObject); 17042d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet } 1705b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1706ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public void setScene(RenderSession session) { 1707ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet mScene = session; 1708b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 1709b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1710ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public RenderSession getSession() { 1711b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet return mScene; 1712b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 17133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet} 1714