RenderSessionImpl.java revision 442aee6bc1abfb143dcfa1ba60d696e576d066c4
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 197062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.ide.common.rendering.api.AdapterBinding; 2064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.ide.common.rendering.api.HardwareConfig; 21ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.IAnimationListener; 22ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ILayoutPullParser; 23b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport com.android.ide.common.rendering.api.LayoutlibCallback; 240d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 25ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderSession; 267062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceReference; 27ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceValue; 28ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 29ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status; 30d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams; 31b32414fe256a6fe1d65e7a1443cd6ea77db8bd95Xavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams.RenderingMode; 3245d9520182663e47a1878ce51be756219799b2c9Deepanshu Guptaimport com.android.ide.common.rendering.api.StyleResourceValue; 33d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport com.android.ide.common.rendering.api.ViewInfo; 3470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport com.android.ide.common.rendering.api.ViewType; 353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.internal.util.XmlUtils; 3641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.ActionMenuItemView; 3741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.BridgeMenuItemImpl; 3841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.IconMenuItemView; 3941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.ListMenuItemView; 4041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.MenuItemImpl; 4141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.MenuView; 42ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 44ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; 453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser; 46a4a2d3d5936bcdda1409796179725d354e5f4400Andrew Shulaevimport com.android.layoutlib.bridge.android.RenderParamsFlags; 47432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Guptaimport com.android.layoutlib.bridge.android.support.RecyclerViewUtil; 48841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Guptaimport com.android.layoutlib.bridge.bars.AppCompatActionBar; 49b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport com.android.layoutlib.bridge.bars.BridgeActionBar; 5082ca7fe915ed30a7e30eb3de3ce816a9ad0867d6Deepanshu Guptaimport com.android.layoutlib.bridge.bars.Config; 51b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport com.android.layoutlib.bridge.bars.FrameworkActionBar; 5264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.layoutlib.bridge.bars.NavigationBar; 5364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.layoutlib.bridge.bars.StatusBar; 54799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohetimport com.android.layoutlib.bridge.bars.TitleBar; 557062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeAdapter; 567062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; 5785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Guptaimport com.android.resources.Density; 581b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohetimport com.android.resources.ResourceType; 5964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.resources.ScreenOrientation; 60947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohetimport com.android.util.Pair; 613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 62799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohetimport org.xmlpull.v1.XmlPullParserException; 63799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 64994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.animation.AnimationThread; 6533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.Animator; 66ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport android.animation.AnimatorInflater; 6733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.LayoutTransition; 6862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohetimport android.animation.LayoutTransition.TransitionListener; 69442aee6bc1abfb143dcfa1ba60d696e576d066c4Deepanshu Guptaimport android.annotation.NonNull; 70442aee6bc1abfb143dcfa1ba60d696e576d066c4Deepanshu Guptaimport android.annotation.Nullable; 713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.app.Fragment_Delegate; 723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap; 733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap_Delegate; 743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Canvas; 753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.drawable.Drawable; 768a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Guptaimport android.preference.Preference_Delegate; 773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.DisplayMetrics; 783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.TypedValue; 79994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.view.AttachInfo_Accessor; 80994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.view.BridgeInflater; 8176f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.IWindowManager; 8264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport android.view.IWindowManagerImpl; 8376f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.Surface; 843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View; 853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View.MeasureSpec; 86d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport android.view.ViewGroup; 87ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport android.view.ViewGroup.LayoutParams; 886208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohetimport android.view.ViewGroup.MarginLayoutParams; 8970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport android.view.ViewParent; 9076f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.WindowManagerGlobal_Delegate; 917062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AbsListView; 927062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AbsSpinner; 9370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport android.widget.ActionMenuView; 947062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AdapterView; 957062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.ExpandableListView; 963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.FrameLayout; 97f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.LinearLayout; 987062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.ListView; 9962c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohetimport android.widget.QuickContactBadge; 1003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.TabHost; 101f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.TabHost.TabSpec; 102d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport android.widget.TabWidget; 1033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1044c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohetimport java.awt.AlphaComposite; 1053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Color; 1063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Graphics2D; 1073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.image.BufferedImage; 1083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.ArrayList; 1093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.List; 1103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.Map; 1113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 112b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND; 113b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION; 114b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED; 115b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; 116b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN; 117b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Guptaimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 118b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta 1193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet/** 120ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * Class implementing the render session. 121952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * <p/> 122ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * A session is a stateful representation of a layout file. It is initialized with data coming 123ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then 1243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * be done on the layout. 1253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1260fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohetpublic class RenderSessionImpl extends RenderAction<SessionParams> { 1273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; 1293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; 1303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // scene state 132ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private RenderSession mScene; 1333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeXmlBlockParser mBlockParser; 1343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeInflater mInflater; 1356a5b91fceb1913cab6416bef99d7b28530d16ecfXavier Ducrohet private ResourceValue mWindowBackground; 136799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private ViewGroup mViewRoot; 137799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private FrameLayout mContentRoot; 1381392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private Canvas mCanvas; 1391392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenWidth = -1; 1401392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenHeight = -1; 141799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private boolean mIsAlphaChannelImage; 142799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private boolean mWindowIsFloating; 14345d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta private Boolean mIsThemeAppCompat; 144a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 145a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mStatusBarSize; 14664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private int mNavigationBarSize; 14764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; 148799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private int mTitleBarSize; 149799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private int mActionBarSize; 150a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // information being returned through the API 1533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BufferedImage mImage; 154e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet private List<ViewInfo> mViewInfoList; 15585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private List<ViewInfo> mSystemViewInfoList; 1563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final class PostInflateException extends Exception { 1583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final long serialVersionUID = 1L; 1593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public PostInflateException(String message) { 1613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet super(message); 1623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Creates a layout scene with all the information coming from the layout bridge API. 1673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 1688d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)}, 1698d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * which act as a 170ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * call to {@link RenderSessionImpl#acquire(long)} 1713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 1728d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * @see Bridge#createSession(SessionParams) 1733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 174b32414fe256a6fe1d65e7a1443cd6ea77db8bd95Xavier Ducrohet public RenderSessionImpl(SessionParams params) { 1750fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet super(new SessionParams(params)); 176ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 177ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 178ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 179ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 180ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * inflater, and parser. 181ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 182ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 183ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 184ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @return whether the scene was prepared 185ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 186ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #acquire(long) 187ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #release() 188ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 1890fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet @Override 190ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result init(long timeout) { 1910fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Result result = super.init(timeout); 192952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 193ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet return result; 194ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1960fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 1970fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 1983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 199835ad76e300033f1d9cccd214bd7d61d78d0240aDeepanshu Gupta 2000fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet RenderResources resources = getParams().getResources(); 2010fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet DisplayMetrics metrics = getContext().getMetrics(); 2023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 203a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // use default of true in case it's not found to use alpha by default 20445d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta mIsAlphaChannelImage = getBooleanThemeValue(resources, "windowIsFloating", true, true); 20545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta // FIXME: Find out why both variables are taking the same value. 20645d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", true, true); 207ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 208a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findBackground(resources); 209a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findStatusBar(resources, metrics); 210799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet findActionBar(resources, metrics); 21164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet findNavigationBar(resources, metrics); 2123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 21376f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet // FIXME: find those out, and possibly add them to the render params 21476f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet boolean hasNavigationBar = true; 215952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection ConstantConditions 21676f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(), 21776f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet metrics, Surface.ROTATION_0, 2181e3c4a072f4476cedb958d75e2a6edf3bde8378fJohn Spurlock hasNavigationBar); 21976f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet WindowManagerGlobal_Delegate.setWindowManagerService(iwm); 22076f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet 2213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // build the inflater and parser. 222b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta mInflater = new BridgeInflater(context, params.getLayoutlibCallback()); 2230fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet context.setBridgeInflater(mInflater); 224ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 225a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet mBlockParser = new BridgeXmlBlockParser( 226a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet params.getLayoutDescription(), context, false /* platformResourceFlag */); 227ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2283054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return SUCCESS.createResult(); 2293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 2303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 2323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Inflates the layout. 2333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 234ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 235ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 236ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 237ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #init(long)} was not called. 2383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 239ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result inflate() { 240ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 241ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 2433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2440fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 24564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 2460fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 247510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta boolean isRtl = Bridge.isLocaleRtl(params.getLocale()); 24885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; 24964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 250cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet // the view group that receives the window background. 251952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ViewGroup backgroundView; 252cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 2530fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet if (mWindowIsFloating || params.isForceNoDecor()) { 254cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); 25585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mViewRoot.setLayoutDirection(layoutDirection); 256799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else { 257bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta int simulatedPlatformVersion = params.getSimulatedPlatformVersion(); 25864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { 25964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet /* 26064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet * This is a special case where the navigation bar is on the right. 26164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+---+ 26264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Status bar (always) | | 26364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+ | 26464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | (Layout with background drawable) | | 26564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 26664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | Title/Action bar (optional) | | | 26764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 26864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | Content, vertical extending | | | 26964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | | | | 27064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 27164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+---+ 27264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 27364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet So we create a horizontal layout, with the nav bar on the right, 27464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet and the left part is the normal layout below without the nav bar at 27564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet the bottom 27664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet */ 27764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 27885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 27964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mViewRoot = topLayout; 28064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.setOrientation(LinearLayout.HORIZONTAL); 28164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 282bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta if (Config.showOnScreenNavBar(simulatedPlatformVersion)) { 283f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta try { 284f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 285bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported(), 286bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 287f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta topLayout.addView(navigationBar); 288f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta } catch (XmlPullParserException ignored) { 289f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta } 29064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 29164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 29264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 293799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet /* 294799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * we're creating the following layout 295799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * 296799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 29764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Status bar (always) | 298799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 299cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | (Layout with background drawable) | 300cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 301cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | Title/Action bar (optional) | | 302cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 303cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | Content, vertical extending | | 304cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | | | 305cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 306799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 30764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Navigation bar for soft buttons, maybe see above| 308799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 309799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 310799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet */ 311799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 3120fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 313799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet topLayout.setOrientation(LinearLayout.VERTICAL); 31485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 31564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // if we don't already have a view root this is it 31664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (mViewRoot == null) { 31764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mViewRoot = topLayout; 31864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } else { 31985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int topLayoutWidth = 32085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta params.getHardwareConfig().getScreenWidth() - mNavigationBarSize; 32164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 32285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayoutWidth, LayoutParams.MATCH_PARENT); 32364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.setLayoutParams(layoutParams); 32464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 32564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // this is the case of soft buttons + vertical bar. 32664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // this top layout is the first layout in the horizontal layout. see above) 327510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta if (isRtl && params.isRtlSupported()) { 328510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // If RTL is enabled, layoutlib will mirror the layouts. So, add the 329510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // topLayout to the right of Navigation Bar and layoutlib will draw it 330510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // to the left. 331510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta mViewRoot.addView(topLayout); 332510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta } else { 333510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // Add the top layout to the left of the Navigation Bar. 334510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta mViewRoot.addView(topLayout, 0); 335510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta } 33664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 337799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 338799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mStatusBarSize > 0) { 339799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // system bar 340799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 34185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(), 342f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta layoutDirection, params.isRtlSupported(), 343bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 34485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.addView(statusBar); 345952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 346799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 347799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 348799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 349799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 350cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet LinearLayout backgroundLayout = new LinearLayout(context); 351cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundView = backgroundLayout; 352cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.setOrientation(LinearLayout.VERTICAL); 353cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 354fa7ed38ae9c180ff12a7312e6ec740b5ba313a97Deepanshu Gupta LayoutParams.MATCH_PARENT, 0); 355cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet layoutParams.weight = 1; 356cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.setLayoutParams(layoutParams); 357cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet topLayout.addView(backgroundLayout); 358cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 359cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 360799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // if the theme says no title/action bar, then the size will be 0 361799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mActionBarSize > 0) { 362841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta BridgeActionBar actionBar = createActionBar(context, params, backgroundLayout); 363952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta actionBar.createMenuPopup(); 364952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta mContentRoot = actionBar.getContentRoot(); 365799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else if (mTitleBarSize > 0) { 366799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 36785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta TitleBar titleBar = createTitleBar(context, 368bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta params.getAppLabel(), 369bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 370cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.addView(titleBar); 371952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 372799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 373799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 374799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 375799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 376799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // content frame 37785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (mContentRoot == null) { 37885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mContentRoot = new FrameLayout(context); 37985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutParams = new LinearLayout.LayoutParams( 38085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, 0); 38185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutParams.weight = 1; 38285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mContentRoot.setLayoutParams(layoutParams); 38385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta backgroundLayout.addView(mContentRoot); 38485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 385799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 386bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta if (Config.showOnScreenNavBar(simulatedPlatformVersion) && 387f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta mNavigationBarOrientation == LinearLayout.HORIZONTAL && 38864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize > 0) { 389799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // system bar 390799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 39185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 392bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported(), 393bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta simulatedPlatformVersion); 39464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.addView(navigationBar); 395952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 396799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 397799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 398799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 399799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 400799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 4013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // Sets the project callback (custom view loader) to the fragment delegate so that 4033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // it can instantiate the custom Fragment. 404b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback()); 4053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 406a4a2d3d5936bcdda1409796179725d354e5f4400Andrew Shulaev String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG); 4078a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta boolean isPreference = "PreferenceScreen".equals(rootTag); 4088a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta View view; 4098a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta if (isPreference) { 4108a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta view = Preference_Delegate.inflatePreference(getContext(), mBlockParser, 4118a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta mContentRoot); 4128a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta } else { 4138a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta view = mInflater.inflate(mBlockParser, mContentRoot); 4148a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta } 4153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4167062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // done with the parser, pop it. 4177062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet context.popParser(); 4187062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 419b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta Fragment_Delegate.setLayoutlibCallback(null); 4203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // set the AttachInfo on the root view. 422994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohet AttachInfo_Accessor.setAttachInfo(mViewRoot); 4233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 424a2378f55b81e7d29f451d7f65527de49417a3f0cXavier Ducrohet // post-inflate process. For now this supports TabHost/TabWidget 425b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null); 426a2378f55b81e7d29f451d7f65527de49417a3f0cXavier Ducrohet 4273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the background drawable 428952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (mWindowBackground != null) { 4290fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); 43064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet backgroundView.setBackground(d); 4313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 433ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 4343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (PostInflateException e) { 435ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(e.getMessage(), e); 4363bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 4373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 4383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 4393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 4403bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 4413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 443ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(t.getMessage(), t); 4443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 4483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Renders the scene. 4493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 450ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 451ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 4524c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * @param freshRender whether the render is a new one and should erase the existing bitmap (in 4534c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * the case where bitmaps are reused). This is typically needed when not playing 4544c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * animations.) 4554c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * 456ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 457ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 4581392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet * 4598d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * @see SessionParams#getRenderingMode() 460799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#render(long) 4613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 4624c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet public Result render(boolean freshRender) { 463ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 464ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 4650fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 4660fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 4673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 4683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (mViewRoot == null) { 469ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_NOT_INFLATED.createResult(); 4703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4720fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet RenderingMode renderingMode = params.getRenderingMode(); 47364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 474e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet 4751392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // only do the screen measure when needed. 4761392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet boolean newRenderSize = false; 4771392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (mMeasuredScreenWidth == -1) { 4781392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet newRenderSize = true; 47964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mMeasuredScreenWidth = hardwareConfig.getScreenWidth(); 48064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); 4811392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 4821392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode != RenderingMode.NORMAL) { 4838ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int widthMeasureSpecMode = renderingMode.isHorizExpand() ? 4848ae691c1148038995d1185716f629b82c582897fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4858ae691c1148038995d1185716f629b82c582897fXavier Ducrohet : MeasureSpec.EXACTLY; 4868ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int heightMeasureSpecMode = renderingMode.isVertExpand() ? 4878ae691c1148038995d1185716f629b82c582897fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4888ae691c1148038995d1185716f629b82c582897fXavier Ducrohet : MeasureSpec.EXACTLY; 4898ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4908ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // We used to compare the measured size of the content to the screen size but 4918ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // this does not work anymore due to the 2 following issues: 4928ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // - If the content is in a decor (system bar, title/action bar), the root view 4938ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // will not resize even with the UNSPECIFIED because of the embedded layout. 4948ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // - If there is no decor, but a dialog frame, then the dialog padding prevents 4958ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // comparing the size of the content to the screen frame (as it would not 4968ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // take into account the dialog padding). 4978ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4988ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // The solution is to first get the content size in a normal rendering, inside 4998ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // the decor or the dialog padding. 5008ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // Then measure only the content with UNSPECIFIED to see the size difference 5018ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // and apply this to the screen size. 5028ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 5038ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // first measure the full layout, with EXACTLY to get the size of the 5048ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // content as it is inside the decor/dialog 505952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 5068ae691c1148038995d1185716f629b82c582897fXavier Ducrohet Pair<Integer, Integer> exactMeasure = measureView( 5078ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mViewRoot, mContentRoot.getChildAt(0), 5088ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 5098ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 5108ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 5118ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // now measure the content only using UNSPECIFIED (where applicable, based on 5128ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // the rendering mode). This will give us the size the content needs. 513952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 5148ae691c1148038995d1185716f629b82c582897fXavier Ducrohet Pair<Integer, Integer> result = measureView( 5158ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mContentRoot, mContentRoot.getChildAt(0), 5168ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, widthMeasureSpecMode, 5178ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, heightMeasureSpecMode); 5188ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 5198ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // now look at the difference and add what is needed. 5201392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isHorizExpand()) { 5218ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int measuredWidth = exactMeasure.getFirst(); 5228ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int neededWidth = result.getFirst(); 5238ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (neededWidth > measuredWidth) { 5248ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth += neededWidth - measuredWidth; 5251392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 526e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 5273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5281392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isVertExpand()) { 5298ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int measuredHeight = exactMeasure.getSecond(); 5308ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int neededHeight = result.getSecond(); 5318ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (neededHeight > measuredHeight) { 5328ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight += neededHeight - measuredHeight; 5331392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 534e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 5353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5363bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5388ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // measure again with the size we need 5393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // This must always be done before the call to layout 5408ae691c1148038995d1185716f629b82c582897fXavier Ducrohet measureView(mViewRoot, null /*measuredView*/, 5418ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 5428ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 5433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // now do the layout. 545a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 5463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 547f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.isLayoutOnly()) { 548f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // delete the canvas and image to reset them on the next full rendering 549f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = null; 550f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mCanvas = null; 551f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } else { 552994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohet AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot); 553f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 554f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // draw the views 555f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create the BufferedImage into which the layout will be rendered. 556f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet boolean newImage = false; 557e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez 558e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // When disableBitmapCaching is true, we do not reuse mImage and 559e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // we create a new one in every render. 560e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // This is useful when mImage is just a wrapper of Graphics2D so 561e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // it doesn't get cached. 562e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag( 563a4a2d3d5936bcdda1409796179725d354e5f4400Andrew Shulaev RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING)); 564e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez if (newRenderSize || mCanvas == null || disableBitmapCaching) { 565f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.getImageFactory() != null) { 566f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = params.getImageFactory().getImage( 567f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, 568f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenHeight); 569f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } else { 570f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = new BufferedImage( 571f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, 572f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenHeight, 573f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet BufferedImage.TYPE_INT_ARGB); 574f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet newImage = true; 575f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 576f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 577f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.isBgColorOverridden()) { 578f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // since we override the content, it's the same as if it was a new image. 579f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet newImage = true; 580f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet Graphics2D gc = mImage.createGraphics(); 581f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setColor(new Color(params.getOverrideBgColor(), true)); 582f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setComposite(AlphaComposite.Src); 583f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 584f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.dispose(); 585f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 586f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 587f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create an Android bitmap around the BufferedImage 588f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, 58964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet true /*isMutable*/, hardwareConfig.getDensity()); 590f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 591e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez if (mCanvas == null) { 592e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez // create a Canvas around the Android bitmap 593e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez mCanvas = new Canvas(bitmap); 594e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez } else { 595e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez mCanvas.setBitmap(bitmap); 596e12b3f96291cf0e3dc60d9db9ac3d3859325f3d4Diego Perez } 59764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue()); 5981392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 5993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 600952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (freshRender && !newImage) { 6011392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet Graphics2D gc = mImage.createGraphics(); 6024c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet gc.setComposite(AlphaComposite.Src); 6033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 604f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setColor(new Color(0x00000000, true)); 605f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.fillRect(0, 0, 606f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, mMeasuredScreenHeight); 607a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 608f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // done 609f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.dispose(); 610f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 611a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 612f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mViewRoot.draw(mCanvas); 6134c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet } 6144c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet 61541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), 61641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta false); 6173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 6183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // success! 619ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 6203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 6213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 6223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 6233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 6243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 6253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 6263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 627ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 6283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 6293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 6303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 6313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 6328ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * Executes {@link View#measure(int, int)} on a given view with the given parameters (used 6338ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}. 6348ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * 6358ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height) 6368ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}). 6378ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * 6388ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param viewToMeasure the view on which to execute measure(). 6398ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param measuredView if non null, the view to query for its measured width/height. 6408ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param width the width to use in the MeasureSpec. 6418ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param widthMode the MeasureSpec mode to use for the width. 6428ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param height the height to use in the MeasureSpec. 6438ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param heightMode the MeasureSpec mode to use for the height. 6448ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @return the measured width/height if measuredView is non-null, null otherwise. 6458ae691c1148038995d1185716f629b82c582897fXavier Ducrohet */ 646952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") // For the use of Pair 6478ae691c1148038995d1185716f629b82c582897fXavier Ducrohet private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, 6488ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int width, int widthMode, int height, int heightMode) { 6498ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode); 6508ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode); 6518ae691c1148038995d1185716f629b82c582897fXavier Ducrohet viewToMeasure.measure(w_spec, h_spec); 6528ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6538ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (measuredView != null) { 6548ae691c1148038995d1185716f629b82c582897fXavier Ducrohet return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight()); 6558ae691c1148038995d1185716f629b82c582897fXavier Ducrohet } 6568ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6578ae691c1148038995d1185716f629b82c582897fXavier Ducrohet return null; 6588ae691c1148038995d1185716f629b82c582897fXavier Ducrohet } 6598ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6608ae691c1148038995d1185716f629b82c582897fXavier Ducrohet /** 661ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Animate an object 662ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * <p> 663ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 664ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 665ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 666ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 66733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 668799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#animate(Object, String, boolean, IAnimationListener) 669ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 670ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result animate(Object targetObject, String animationName, 671ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet boolean isFrameworkAnimation, IAnimationListener listener) { 672ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 673ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 6740fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 6750fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 676ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // find the animation file. 677952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ResourceValue animationResource; 678ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet int animationId = 0; 679ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (isFrameworkAnimation) { 6800fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationResource = context.getRenderResources().getFrameworkResource( 6811b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 682ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 683947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName); 684ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 685ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } else { 6860fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationResource = context.getRenderResources().getProjectResource( 6871b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 688ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 689b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta animationId = context.getLayoutlibCallback().getResourceId( 6901b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 691ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 692ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 693ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 694ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 695ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet try { 6960fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Animator anim = AnimatorInflater.loadAnimator(context, animationId); 697ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (anim != null) { 698ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet anim.setTarget(targetObject); 699ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 70033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new PlayAnimationThread(anim, this, animationName, listener).start(); 701ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 702ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 703ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 704ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } catch (Exception e) { 705b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get the real cause of the exception. 706b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet Throwable t = e; 707b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet while (t.getCause() != null) { 708b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet t = t.getCause(); 709b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 710b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 711ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 712ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 713ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 714ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 715ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_ANIM_NOT_FOUND.createResult(); 716b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 717b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 71833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 71933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Insert a new child into an existing parent. 72033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 72133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 72233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 72333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 72433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 72533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 726799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener) 72733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 728ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml, 72933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final int index, IAnimationListener listener) { 730b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 731b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 7320fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 7330fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 734b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // create a block parser for the XML 735a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( 736a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet childXml, context, false /* platformResourceFlag */); 737b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 738b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // inflate the child without adding it to the root since we want to control where it'll 739b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get added. We do pass the parentView however to ensure that the layoutParams will 740b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // be created correctly. 74133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); 742a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet blockParser.ensurePopped(); 743b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 74433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 74533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 74633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 74733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "insertChild", listener) { 74833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 74933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 750ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 75133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(new LayoutTransition()); 75233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return addView(parentView, child, index); 75333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 75433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 75533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 75633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 75733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(null); 75833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 75933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 76033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 76133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 762ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(child); 7631392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 7641392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 76533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // add it to the parentView in the correct location 766ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = addView(parentView, child, index); 767952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 76833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 76933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 770b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 7714c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 7721766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet if (result.isSuccess()) { 77333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(child); 7741766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet } 7751766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet 7761766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet return result; 777b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 778b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 77933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 78033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Adds a given view to a given parent at a given index. 78133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 78233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param parent the parent to receive the view 78333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to add to the parent 78433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the index where to do the add. 78533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 786ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 787ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 78833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 78933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 790ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result addView(ViewGroup parent, View view, int index) { 79133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 79233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.addView(view, index); 793ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 79433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 79533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 796ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 79733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 79833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 79933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 80033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 80133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a view to a new parent at a given location 80233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 80333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 80433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 80533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 80633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 80733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 808799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener) 80933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 81062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public Result moveChild(final ViewGroup newParentView, final View childView, final int index, 81124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Map<String, String> layoutParamsMap, final IAnimationListener listener) { 812b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 813b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 81433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 81533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 816ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet LayoutParams layoutParams = null; 81733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (layoutParamsMap != null) { 81833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // need to create a new LayoutParams object for the new parent. 81962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet layoutParams = newParentView.generateLayoutParams( 82033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new BridgeLayoutParamsMapAttributes(layoutParamsMap)); 82133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 8221392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 82362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // get the current parent of the view that needs to be moved. 82462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet final ViewGroup previousParent = (ViewGroup) childView.getParent(); 82562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 82633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 82733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final LayoutParams params = layoutParams; 828ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 82924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // there is no support for animating views across layouts, so in case the new and old 83024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // parent views are different we fake the animation through a no animation thread. 83124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousParent != newParentView) { 83224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new Thread("not animated moveChild") { 83324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 83424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void run() { 83524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, 83624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet params); 837952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 83824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 83924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 84024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 84124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // ready to do the work, acquire the scene. 84224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet result = acquire(250); 843952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 84424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 84524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return; 84624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 84724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 84824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet try { 8494c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 85024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (result.isSuccess()) { 85124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.onNewFrame(RenderSessionImpl.this.getSession()); 85224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 85324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } finally { 85424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet release(); 85524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 85624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 85724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 85862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 85924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 86024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } else { 86124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 86262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 86324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 86424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public Result preAnimation() { 86524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // set up the transition for the parent. 86624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition transition = new LayoutTransition(); 86724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(transition); 8685562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet 86924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // tweak the animation durations and start delays (to match the duration of 87024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // animation playing just before). 87124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // Note: Cannot user Animation.setDuration() directly. Have to set it 87224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // on the LayoutTransition. 87324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.DISAPPEARING, 100); 87424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_DISAPPEARING plays after DISAPPEARING 87524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100); 876ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 87724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100); 87824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 87924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100); 88024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_APPEARING plays after CHANGE_APPEARING 88124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.APPEARING, 100); 88224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 88324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.APPEARING, 100); 88424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 88524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return moveView(previousParent, newParentView, childView, index, params); 88624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 88724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 88824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 88924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void postAnimation() { 89024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(null); 89124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParentView.setLayoutTransition(null); 89224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 89324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 89424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 89533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 89633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 897ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(layoutParams); 898b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 899b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 90062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, layoutParams); 901952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 90233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 90333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 904b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 9054c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 906ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet if (layoutParams != null && result.isSuccess()) { 90733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(layoutParams); 908ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet } 909ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 910ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet return result; 911b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 912b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 91333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 91433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a View from its current parent to a new given parent at a new given location, with 91533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * an optional new {@link LayoutParams} instance 91633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 91762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param previousParent the previous parent, still owning the child at the time of the call. 91862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param newParent the new parent 91924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet * @param movedView the view to move 92033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the new location in the new parent 92133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param params an option (can be null) {@link LayoutParams} instance. 92233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 923ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 924ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 92533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 92633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 92724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private Result moveView(ViewGroup previousParent, final ViewGroup newParent, 92824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet final View movedView, final int index, final LayoutParams params) { 9291392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet try { 93062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // check if there is a transition on the previousParent. 93124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition previousTransition = previousParent.getLayoutTransition(); 93224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousTransition != null) { 9335562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // in this case there is an animation. This means we have to wait for the child's 9345562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent reference to be null'ed out so that we can add it to the new parent. 9355562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // It is technically removed right before the DISAPPEARING animation is done (if 9365562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // the animation of this type is not null, otherwise it's after which is impossible 9375562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // to handle). 9385562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // Because there is no move animation, if the new parent is the same as the old 9395562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before 9405562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // adding the child or the child will appear in its new location before the 9415562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // other children have made room for it. 94262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 94362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add a listener to the transition to be notified of the actual removal. 94424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousTransition.addTransitionListener(new TransitionListener() { 94524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private int mChangeDisappearingCount = 0; 94662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 947d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 94862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void startTransition(LayoutTransition transition, ViewGroup container, 94962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 95024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 95124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount++; 95224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 95362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 95433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 955d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 95662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void endTransition(LayoutTransition transition, ViewGroup container, 95762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 95824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 95924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount--; 96024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 96124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 96224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING && 96324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount == 0) { 96462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 96562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 96624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 96762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 96824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 96962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 97062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 97162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 97262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet }); 97362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 97462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // remove the view from the current parent. 97524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 97662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 97762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // and return since adding the view to the new parent is done in the listener. 97862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 97933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } else { 98062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // standard code with no animation. pretty simple. 98124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 98233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 98362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 98462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 98524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 98662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 98724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 98862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 98962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 99062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 99162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 9921392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } catch (UnsupportedOperationException e) { 9931392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 994ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 995b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 99633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 99733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 99833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 99933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a child from its current parent. 100033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 100133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 100233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 100333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 100433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 100533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 1006799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#removeChild(Object, IAnimationListener) 100733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 1008ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result removeChild(final View childView, IAnimationListener listener) { 100933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet checkLock(); 1010b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 10111392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet invalidateRenderingSize(); 10121392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 101333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final ViewGroup parent = (ViewGroup) childView.getParent(); 101433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 101533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 101633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 101733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 101833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 1019ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 102033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(new LayoutTransition()); 102133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return removeView(parent, childView); 102233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 102333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 102433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 102533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 102633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(null); 102733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 102833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 102933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 103033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 1031ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 103233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 103333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 1034ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = removeView(parent, childView); 1035952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 103633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 103733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 103833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 10394c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet return render(false /*freshRender*/); 1040ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1041ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1042ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 104333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a given view from its current parent. 104433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 104533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to remove from its parent 104633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 1047ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 1048ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 104933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 105033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 1051ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result removeView(ViewGroup parent, View view) { 105233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 105333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.removeView(view); 1054ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 105533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 105633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 1057ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 105833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 105933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 106033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 1061ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1062a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findBackground(RenderResources resources) { 1063952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!getParams().isBgColorOverridden()) { 106441fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet mWindowBackground = resources.findItemInTheme("windowBackground", 106541fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 1066a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mWindowBackground != null) { 1067a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mWindowBackground = resources.resolveResValue(mWindowBackground); 1068a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1069a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1070a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 107264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private boolean hasSoftwareButtons() { 107364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet return getParams().getHardwareConfig().hasSoftwareButtons(); 1074a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1076a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { 107764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet boolean windowFullscreen = getBooleanThemeValue(resources, 10782464a94e51e32f38613b86d4b1a995e2cf2d33e3Deepanshu Gupta "windowFullscreen", false, true); 1079a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1080952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!windowFullscreen && !mWindowIsFloating) { 108164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // default value 108264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; 1083a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 108464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // get the real value 108564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 108664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet "status_bar_height"); 1087a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 108864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (value != null) { 108964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("status_bar_height", 109064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet value.getValue(), true /*requireUnit*/); 109164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (typedValue != null) { 109264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute the pixel value based on the display metrics 109364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mStatusBarSize = (int)typedValue.getDimension(metrics); 1094a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1095a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1096a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1097a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1098a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1099799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private void findActionBar(RenderResources resources, DisplayMetrics metrics) { 1100799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mWindowIsFloating) { 1101799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet return; 1102a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1103a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1104a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowActionBar = getBooleanThemeValue(resources, 110545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta "windowActionBar", true, !isThemeAppCompat(resources)); 1106a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1107a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's a value and it's false (default is true) 1108a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowActionBar) { 11093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default size of the window title bar 1111799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT; 11123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get value from the theme. 111441fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme("actionBarSize", 111541fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 11163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // resolve it 1118a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 11193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 11213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the numerical value, if available 1122d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(), 1123d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet true /*requireUnit*/); 11243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 11253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 1126799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mActionBarSize = (int)typedValue.getDimension(metrics); 11273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1129799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else { 1130799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // action bar overrides title bar so only look for this one if action bar is hidden 1131531a6693ac4a950e4c3ab6135112fcabd1887addDeepanshu Gupta boolean windowNoTitle = getBooleanThemeValue(resources, "windowNoTitle", false, true); 11323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1133952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!windowNoTitle) { 1134a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1135799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // default size of the window title bar 1136799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT; 1137a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1138799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // get value from the theme. 113941fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme("windowTitleSize", 114041fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 1141a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1142799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // resolve it 1143799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet value = resources.resolveResValue(value); 11443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1145799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (value != null) { 1146799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // get the numerical value, if available 1147d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("windowTitleSize", 1148d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet value.getValue(), true /*requireUnit*/); 1149799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (typedValue != null) { 1150799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // compute the pixel value based on the display metrics 1151799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mTitleBarSize = (int)typedValue.getDimension(metrics); 1152799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 1153a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1154a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1155799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 1156a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1157a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1158a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 115964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { 1160952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (hasSoftwareButtons() && !mWindowIsFloating) { 11613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default value 116364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize = 48; // ?? 116464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 116564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = getParams().getHardwareConfig(); 116664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 116764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet boolean barOnBottom = true; 116864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 116964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { 117064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute the dp of the screen. 117164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet int shortSize = hardwareConfig.getScreenHeight(); 117264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 117364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute in dp 1174952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / 1175952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta hardwareConfig.getDensity().getDpiValue(); 117664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 1177952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // 0-599dp: "phone" UI with bar on the side 1178952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // 600+dp: "tablet" UI with bar on the bottom 1179952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta barOnBottom = shortSizeDp >= 600; 118064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 118164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 118264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (barOnBottom) { 118364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarOrientation = LinearLayout.HORIZONTAL; 118464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } else { 118564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarOrientation = LinearLayout.VERTICAL; 118664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 11873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1188089143ffed72bb47fd8d870f29caffb646138781Xavier Ducrohet // get the real value 11891b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 119064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); 1191a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 11923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 119364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", 1194d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet value.getValue(), true /*requireUnit*/); 11953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 11963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 119764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize = (int)typedValue.getDimension(metrics); 11983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1200a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1201a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1202a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 120345d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta private boolean isThemeAppCompat(RenderResources resources) { 120445d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta // Ideally, we should check if the corresponding activity extends 120545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta // android.support.v7.app.ActionBarActivity, and not care about the theme name at all. 120645d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta if (mIsThemeAppCompat == null) { 120745d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta StyleResourceValue defaultTheme = resources.getDefaultTheme(); 1208841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // We can't simply check for parent using resources.themeIsParentOf() since the 1209841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // inheritance structure isn't really what one would expect. The first common parent 1210841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21). 1211841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta boolean isThemeAppCompat = false; 1212841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta for (int i = 0; i < 50; i++) { 12133da4ded958f2e1d5a7ffbddd62b46cf179e61fe9Diego Perez if (defaultTheme == null) { 12143da4ded958f2e1d5a7ffbddd62b46cf179e61fe9Diego Perez break; 12153da4ded958f2e1d5a7ffbddd62b46cf179e61fe9Diego Perez } 1216841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta // for loop ensures that we don't run into cyclic theme inheritance. 1217841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta if (defaultTheme.getName().startsWith("Theme.AppCompat")) { 1218841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta isThemeAppCompat = true; 1219841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta break; 1220841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 1221841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta defaultTheme = resources.getParent(defaultTheme); 1222841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 1223841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta mIsThemeAppCompat = isThemeAppCompat; 122445d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta } 122545d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta return mIsThemeAppCompat; 122645d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta } 122745d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta 122841fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet /** 122945d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta * Looks for an attribute in the current theme. 123041fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * 123141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param resources the render resources 123241fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param name the name of the attribute 123341fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param defaultValue the default value. 123445d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta * @param isFrameworkAttr if the attribute is in android namespace 123541fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @return the value of the attribute or the default one if not found. 123641fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet */ 1237a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean getBooleanThemeValue(RenderResources resources, 123845d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta String name, boolean defaultValue, boolean isFrameworkAttr) { 1239a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 124045d9520182663e47a1878ce51be756219799b2c9Deepanshu Gupta ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr); 1241a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1242a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // because it may reference something else, we resolve it. 1243a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 12443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1245a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's no value, return the default. 1246a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (value == null || value.getValue() == null) { 1247a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return defaultValue; 12483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1250a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); 12513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1254952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * Post process on a view hierarchy that was just inflated. 1255952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * <p/> 1256952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the 12573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically 12583bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * based on the content of the {@link FrameLayout}. 12593bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param view the root view to process. 1260b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta * @param layoutlibCallback callback to the project. 12618a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta * @param skip the view and it's children are not processed. 12623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1263952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") // For the use of Pair 1264b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip) 12653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 12668a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta if (view == skip) { 12678a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta return; 12688a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta } 12693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view instanceof TabHost) { 1270b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta setupTabHost((TabHost) view, layoutlibCallback); 127162c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet } else if (view instanceof QuickContactBadge) { 127262c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet QuickContactBadge badge = (QuickContactBadge) view; 127362c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet badge.setImageToDefault(); 12747062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else if (view instanceof AdapterView<?>) { 12757062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // get the view ID. 12767062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet int id = view.getId(); 12777062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12787062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet BridgeContext context = getContext(); 12797062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12807062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // get a ResourceReference from the integer ID. 12817062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ResourceReference listRef = context.resolveId(id); 12827062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12837062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (listRef != null) { 12847062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet SessionParams params = getParams(); 12857062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet AdapterBinding binding = params.getAdapterBindings().get(listRef); 12867062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12877062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // if there was no adapter binding, trying to get it from the call back. 12887062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (binding == null) { 1289b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta binding = layoutlibCallback.getAdapterBinding( 1290b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta listRef, context.getViewKey(view), view); 12917062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12927062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12937062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (binding != null) { 12947062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12957062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (view instanceof AbsListView) { 12967062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) && 12977062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet view instanceof ListView) { 12987062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ListView list = (ListView) view; 12997062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13007062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet boolean skipCallbackParser = false; 13017062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13027062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet int count = binding.getHeaderCount(); 13038a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta for (int i = 0; i < count; i++) { 13047062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 13057062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding.getHeaderAt(i), 1306b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta list, false, skipCallbackParser); 13077062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (pair.getFirst() != null) { 13087062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list.addHeaderView(pair.getFirst()); 13097062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13107062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13117062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet skipCallbackParser |= pair.getSecond(); 13127062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13137062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13147062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet count = binding.getFooterCount(); 13158a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta for (int i = 0; i < count; i++) { 13167062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 13177062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding.getFooterAt(i), 1318b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta list, false, skipCallbackParser); 13197062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (pair.getFirst() != null) { 13207062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list.addFooterView(pair.getFirst()); 13217062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13227062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13237062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet skipCallbackParser |= pair.getSecond(); 13247062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13257062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13267062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 13277062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (view instanceof ExpandableListView) { 13287062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((ExpandableListView) view).setAdapter( 1329b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta new FakeExpandableAdapter(listRef, binding, layoutlibCallback)); 13307062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else { 13317062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((AbsListView) view).setAdapter( 1332b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta new FakeAdapter(listRef, binding, layoutlibCallback)); 13337062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13347062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else if (view instanceof AbsSpinner) { 13357062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((AbsSpinner) view).setAdapter( 1336b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta new FakeAdapter(listRef, binding, layoutlibCallback)); 13377062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13387062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 13397062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 1340432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta } else if (isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) { 1341432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta RecyclerViewUtil.setAdapter(view, getContext(), getParams()); 13423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } else if (view instanceof ViewGroup) { 13438a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta ViewGroup group = (ViewGroup) view; 13443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = group.getChildCount(); 13458a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta for (int c = 0; c < count; c++) { 13463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View child = group.getChildAt(c); 1347b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta postInflateProcess(child, layoutlibCallback, skip); 13483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1353432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta * Check if the object is an instance of a class named {@code className}. This doesn't work 1354432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta * for interfaces. 1355432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta */ 1356432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta public static boolean isInstanceOf(Object object, String className) { 1357432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta Class superClass = object.getClass(); 1358432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta while (superClass != null) { 1359432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta String name = superClass.getName(); 1360432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta if (name.equals(className)) { 1361432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta return true; 1362432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta } 1363432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta superClass = superClass.getSuperclass(); 1364432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta } 1365432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta return false; 1366432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta } 1367432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta 1368432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta /** 13693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Sets up a {@link TabHost} object. 13703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param tabHost the TabHost to setup. 1371b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta * @param layoutlibCallback The project callback object to access the project R class. 13723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @throws PostInflateException 13733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1374b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback) 13753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 13763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // look for the TabWidget, and the FrameLayout. They have their own specific names 13773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View v = tabHost.findViewById(android.R.id.tabs); 13783bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 13803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 13813bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n"); 13823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1384952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!(v instanceof TabWidget)) { 13853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 13863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n" + 13873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName())); 13883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet v = tabHost.findViewById(android.R.id.tabcontent); 13913bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 1393952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty) 1394952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection SpellCheckingInspection 13953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 13963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\"."); 13973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1399952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!(v instanceof FrameLayout)) { 1400952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection SpellCheckingInspection 14013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 14023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" + 14033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName())); 14043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 14063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet FrameLayout content = (FrameLayout)v; 14073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1408952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // now process the content of the frameLayout and dynamically create tabs for it. 14093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = content.getChildCount(); 14103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 14113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // this must be called before addTab() so that the TabHost searches its TabWidget 14123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // and FrameLayout. 14133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet tabHost.setup(); 14143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1415f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (count == 0) { 1416f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye // Create a dummy child to get a single tab 14176257175afa5c892cb0a7cd14d958418c1720cb84Deepanshu Gupta TabSpec spec = tabHost.newTabSpec("tag") 14186257175afa5c892cb0a7cd14d958418c1720cb84Deepanshu Gupta .setIndicator("Tab Label", tabHost.getResources() 14196257175afa5c892cb0a7cd14d958418c1720cb84Deepanshu Gupta .getDrawable(android.R.drawable.ic_menu_info_details, null)) 1420f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye .setContent(new TabHost.TabContentFactory() { 1421d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 1422f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye public View createTabContent(String tag) { 14230fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet return new LinearLayout(getContext()); 1424f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1425f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye }); 1426f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(spec); 1427f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1428952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // for each child of the frameLayout, add a new TabSpec 1429f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye for (int i = 0 ; i < count ; i++) { 1430f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye View child = content.getChildAt(i); 1431f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String tabSpec = String.format("tab_spec%d", i+1); 14328a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta @SuppressWarnings("ConstantConditions") // child cannot be null. 1433f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye int id = child.getId(); 1434952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 1435b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id); 1436f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String name; 1437f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (resource != null) { 1438947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet name = resource.getSecond(); 1439f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1440f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye name = String.format("Tab %d", i+1); // default name if id is unresolved. 1441f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1442f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id)); 14433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14443bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 144785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 144885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the 144985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * bounds of all the views. 145085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 145185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param view the root View 145285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset for the view bounds. 145385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 145485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 145585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * content frame. 145685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 145785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @return {@code ViewInfo} containing the bounds of the view and it children otherwise. 145885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 145985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo visit(View view, int offset, boolean setExtendedInfo, 146085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isContentFrame) { 146185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo result = createViewInfo(view, offset, setExtendedInfo, isContentFrame); 1462799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 146385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view instanceof ViewGroup) { 146485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewGroup group = ((ViewGroup) view); 146585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result.setChildren(visitAllChildren(group, isContentFrame ? 0 : offset, 146685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta setExtendedInfo, isContentFrame)); 146785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 146885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 146985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1470799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 147185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 147285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo} 14738d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with 147485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * the children of the {@code mContentRoot}. 147585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 147685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param viewGroup the root View 147785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset from the top for the content view frame. 147885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 147985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 148085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * content frame. {@code false} if the {@code ViewInfo} to be created is 148185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * part of the system decor. 148285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 148385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset, 148485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean setExtendedInfo, boolean isContentFrame) { 148585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (viewGroup == null) { 148685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return null; 1487799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 1488799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 148985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (!isContentFrame) { 149085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta offset += viewGroup.getTop(); 149185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1492799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 149385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int childCount = viewGroup.getChildCount(); 149485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (viewGroup == mContentRoot) { 149585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> childrenWithoutOffset = new ArrayList<ViewInfo>(childCount); 149685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> childrenWithOffset = new ArrayList<ViewInfo>(childCount); 149785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta for (int i = 0; i < childCount; i++) { 149885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo[] childViewInfo = visitContentRoot(viewGroup.getChildAt(i), offset, 14996208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet setExtendedInfo); 150085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta childrenWithoutOffset.add(childViewInfo[0]); 150185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta childrenWithOffset.add(childViewInfo[1]); 1502799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 150385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mViewInfoList = childrenWithOffset; 150485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return childrenWithoutOffset; 150585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 150685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> children = new ArrayList<ViewInfo>(childCount); 150785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta for (int i = 0; i < childCount; i++) { 150885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo, 150985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta isContentFrame)); 151085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 151185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return children; 1512799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 151385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1514799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 151585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 151685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the 151785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * bounds of all the views. It returns two {@code ViewInfo} objects with the same children, 151885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * one with the {@code offset} and other without the {@code offset}. The offset is needed to 151985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * get the right bounds if the {@code ViewInfo} hierarchy is accessed from 152085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the 152185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * offset is not needed. 152285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 152385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at 152485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * index 1 is with the offset. 152585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 1526432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta @NonNull 152785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo[] visitContentRoot(View view, int offset, boolean setExtendedInfo) { 152885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo[] result = new ViewInfo[2]; 152985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view == null) { 153085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 153185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 153285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 153385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[0] = createViewInfo(view, 0, setExtendedInfo, true); 153485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[1] = createViewInfo(view, offset, setExtendedInfo, true); 153585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view instanceof ViewGroup) { 153685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> children = visitAllChildren((ViewGroup) view, 0, setExtendedInfo, true); 153785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[0].setChildren(children); 153885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[1].setChildren(children); 153985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 154085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 1541799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 15423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 15433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 154485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children 154585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not 154685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * set. 154785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset for the view bounds. Used only if view is part of the content frame. 15483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 154985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo createViewInfo(View view, int offset, boolean setExtendedInfo, 155085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isContentFrame) { 15513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view == null) { 15523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return null; 15533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 15543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 155585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo result; 155685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (isContentFrame) { 155770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // The view is part of the layout added by the user. Hence, 155870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // the ViewCookie may be obtained only through the Context. 155985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result = new ViewInfo(view.getClass().getName(), 156070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta getContext().getViewKey(view), 156185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getLeft(), view.getTop() + offset, view.getRight(), 156285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getBottom() + offset, view, view.getLayoutParams()); 156385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 156470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // We are part of the system decor. 156570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta SystemViewInfo r = new SystemViewInfo(view.getClass().getName(), 156641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta getViewKey(view), 156785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getLeft(), view.getTop(), view.getRight(), 156885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getBottom(), view, view.getLayoutParams()); 156970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta result = r; 157070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // We currently mark three kinds of views: 157170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 1. Menus in the Action Bar 157270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 2. Menus in the Overflow popup. 157370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 3. The overflow popup button. 157470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (view instanceof ListMenuItemView) { 157570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 2. 157670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // All menus in the popup are of type ListMenuItemView. 157770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU); 157870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } else { 157970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 3. 158070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ViewGroup.LayoutParams lp = view.getLayoutParams(); 158170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (lp instanceof ActionMenuView.LayoutParams && 158270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ((ActionMenuView.LayoutParams) lp).isOverflowButton) { 158370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_OVERFLOW); 158470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } else { 158570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 1. 158670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // A view is a menu in the Action Bar is it is not the overflow button and of 158770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // its parent is of type ActionMenuView. We can also check if the view is 158870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // instanceof ActionMenuItemView but that will fail for menus using 158970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // actionProviderClass. 159070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ViewParent parent = view.getParent(); 159170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta while (parent != mViewRoot && parent instanceof ViewGroup) { 159270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (parent instanceof ActionMenuView) { 159370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_MENU); 159470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta break; 159570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 159670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta parent = parent.getParent(); 159770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 159870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 159970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 160085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 16013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 16026208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet if (setExtendedInfo) { 16036208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet MarginLayoutParams marginParams = null; 16046208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet LayoutParams params = view.getLayoutParams(); 16056208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet if (params instanceof MarginLayoutParams) { 16066208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams = (MarginLayoutParams) params; 16076208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet } 16086208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet result.setExtendedInfo(view.getBaseline(), 16096208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.leftMargin : 0, 16106208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.topMargin : 0, 16116208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.rightMargin : 0, 16126208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.bottomMargin : 0); 16136208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet } 16146208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet 16153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return result; 16163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 16173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 161870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta /* (non-Javadoc) 161941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta * The cookie for menu items are stored in menu item and not in the map from View stored in 162041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta * BridgeContext. 162141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta */ 1622432578acb80cf2fa827ddb9595cf46edf0b340b0Deepanshu Gupta @Nullable 162341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta private Object getViewKey(View view) { 162441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta BridgeContext context = getContext(); 162541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (!(view instanceof MenuView.ItemView)) { 162641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return context.getViewKey(view); 162741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 162841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta MenuItemImpl menuItem; 162941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (view instanceof ActionMenuItemView) { 163041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((ActionMenuItemView) view).getItemData(); 163141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else if (view instanceof ListMenuItemView) { 163241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((ListMenuItemView) view).getItemData(); 163341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else if (view instanceof IconMenuItemView) { 163441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((IconMenuItemView) view).getItemData(); 163541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else { 163641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = null; 163741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 163841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (menuItem instanceof BridgeMenuItemImpl) { 163941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return ((BridgeMenuItemImpl) menuItem).getViewCookie(); 164041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 164141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta 164241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return null; 164341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 164441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta 1645620f80a7ee9796c2c41ec0a42d10d2913fc50c90Diego Perez public void invalidateRenderingSize() { 164685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mMeasuredScreenWidth = mMeasuredScreenHeight = -1; 164785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 164885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 1649799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet /** 165085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the status bar with wifi and battery icons. 1651799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet */ 165285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private StatusBar createStatusBar(BridgeContext context, Density density, int direction, 1653f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta boolean isRtlSupported, int platformVersion) throws XmlPullParserException { 165485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta StatusBar statusBar = new StatusBar(context, density, 1655f18273f698024ffa23ce457e7d30c683e7027680Deepanshu Gupta direction, isRtlSupported, platformVersion); 165685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta statusBar.setLayoutParams( 165785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta new LinearLayout.LayoutParams( 165885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, mStatusBarSize)); 165985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return statusBar; 166085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1661e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 166285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 166385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the navigation bar with back, home and recent buttons. 166485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 166585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isRtl true if the current locale is right-to-left 166685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isRtlSupported true is the project manifest declares that the application 166785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * is RTL aware. 166885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 166985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private NavigationBar createNavigationBar(BridgeContext context, Density density, 1670bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta boolean isRtl, boolean isRtlSupported, int simulatedPlatformVersion) 1671bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta throws XmlPullParserException { 167285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = new NavigationBar(context, 167385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta density, mNavigationBarOrientation, isRtl, 1674bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta isRtlSupported, simulatedPlatformVersion); 167585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (mNavigationBarOrientation == LinearLayout.VERTICAL) { 167685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, 167785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT)); 167885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 167985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 168085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mNavigationBarSize)); 1681e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 168285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return navigationBar; 1683e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 1684e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 1685bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta private TitleBar createTitleBar(BridgeContext context, String title, 1686bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta int simulatedPlatformVersion) 168785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta throws XmlPullParserException { 1688bf50447839d4cdb1765d308a67aca43bb77cedbcDeepanshu Gupta TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); 168985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta titleBar.setLayoutParams( 169085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize)); 169185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return titleBar; 169285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1693e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 169485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 169585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the action bar. Also queries the project callback for missing information. 169685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 1697841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta private BridgeActionBar createActionBar(BridgeContext context, SessionParams params, 1698cc1ce2c8d83464c7be38e3281bf8da3963505a9bDeepanshu Gupta ViewGroup parentView) { 1699841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta if (mIsThemeAppCompat == Boolean.TRUE) { 1700841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta return new AppCompatActionBar(context, params, parentView); 1701841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } else { 1702841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta return new FrameworkActionBar(context, params, parentView); 1703841330d24b2403832c91d379795f5bcbd938c3b7Deepanshu Gupta } 17041392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 17051392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 17063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public BufferedImage getImage() { 17073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return mImage; 17083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 17093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1710a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet public boolean isAlphaChannelImage() { 1711a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return mIsAlphaChannelImage; 1712a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1713a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1714e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet public List<ViewInfo> getViewInfos() { 1715e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet return mViewInfoList; 17163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 17172d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet 171885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta public List<ViewInfo> getSystemViewInfos() { 171985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return mSystemViewInfoList; 172085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 172185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 1722ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Map<String, String> getDefaultProperties(Object viewObject) { 17230fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet return getContext().getDefaultPropMap(viewObject); 17242d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet } 1725b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1726ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public void setScene(RenderSession session) { 1727ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet mScene = session; 1728b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 1729b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1730ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public RenderSession getSession() { 1731b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet return mScene; 1732b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 17333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet} 1734