RenderSessionImpl.java revision 70114b33f8054cc38090a2bbd213ebf15abee63d
13bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet/* 23bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Copyright (C) 2010 The Android Open Source Project 33bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 43bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 53bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * you may not use this file except in compliance with the License. 63bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * You may obtain a copy of the License at 73bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 83bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 93bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Unless required by applicable law or agreed to in writing, software 113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * See the License for the specific language governing permissions and 143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * limitations under the License. 153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetpackage com.android.layoutlib.bridge.impl; 183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 19ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND; 20ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION; 21ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED; 22ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; 23ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN; 24ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 25ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet 267062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.ide.common.rendering.api.AdapterBinding; 2764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.ide.common.rendering.api.HardwareConfig; 28ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.IAnimationListener; 29ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ILayoutPullParser; 30ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback; 310d829bd739dfcb3374971c776676bf2e53bab43cXavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 32ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderSession; 337062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceReference; 34ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceValue; 35ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 36ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status; 37d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams; 38b32414fe256a6fe1d65e7a1443cd6ea77db8bd95Xavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams.RenderingMode; 39d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport com.android.ide.common.rendering.api.ViewInfo; 4070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport com.android.ide.common.rendering.api.ViewType; 413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.internal.util.XmlUtils; 4241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.ActionMenuItemView; 4341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.BridgeMenuItemImpl; 4441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.IconMenuItemView; 4541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.ListMenuItemView; 4641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.MenuItemImpl; 4741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Guptaimport com.android.internal.view.menu.MenuView; 48ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 50ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; 513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser; 5264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.layoutlib.bridge.bars.NavigationBar; 5364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.layoutlib.bridge.bars.StatusBar; 54799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohetimport com.android.layoutlib.bridge.bars.TitleBar; 558d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Guptaimport com.android.layoutlib.bridge.bars.ActionBarLayout; 567062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeAdapter; 577062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; 5885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Guptaimport com.android.resources.Density; 591b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohetimport com.android.resources.ResourceType; 6064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport com.android.resources.ScreenOrientation; 61947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohetimport com.android.util.Pair; 623bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 63799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohetimport org.xmlpull.v1.XmlPullParserException; 64799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 65994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.animation.AnimationThread; 6633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.Animator; 67ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohetimport android.animation.AnimatorInflater; 6833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohetimport android.animation.LayoutTransition; 6962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohetimport android.animation.LayoutTransition.TransitionListener; 703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.app.Fragment_Delegate; 713bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap; 723bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Bitmap_Delegate; 733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.Canvas; 743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.graphics.drawable.Drawable; 753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.DisplayMetrics; 763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.util.TypedValue; 77994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.view.AttachInfo_Accessor; 78994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohetimport android.view.BridgeInflater; 7976f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.IWindowManager; 8064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohetimport android.view.IWindowManagerImpl; 8176f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.Surface; 823bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View; 833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.view.View.MeasureSpec; 84d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport android.view.ViewGroup; 85ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohetimport android.view.ViewGroup.LayoutParams; 866208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohetimport android.view.ViewGroup.MarginLayoutParams; 8770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport android.view.ViewParent; 8876f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohetimport android.view.WindowManagerGlobal_Delegate; 897062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AbsListView; 907062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AbsSpinner; 9170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Guptaimport android.widget.ActionMenuView; 927062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.AdapterView; 937062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.ExpandableListView; 943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.FrameLayout; 95f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.LinearLayout; 967062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohetimport android.widget.ListView; 9762c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohetimport android.widget.QuickContactBadge; 983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport android.widget.TabHost; 99f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbyeimport android.widget.TabHost.TabSpec; 100d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohetimport android.widget.TabWidget; 1013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1024c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohetimport java.awt.AlphaComposite; 1033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Color; 1043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.Graphics2D; 1053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.awt.image.BufferedImage; 1063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.ArrayList; 1073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.List; 1083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohetimport java.util.Map; 1093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet/** 111ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * Class implementing the render session. 112952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * <p/> 113ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * A session is a stateful representation of a layout file. It is initialized with data coming 114ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then 1153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * be done on the layout. 1163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1170fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohetpublic class RenderSessionImpl extends RenderAction<SessionParams> { 1183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; 1203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; 1213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // scene state 123ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private RenderSession mScene; 1243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeXmlBlockParser mBlockParser; 1253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BridgeInflater mInflater; 1266a5b91fceb1913cab6416bef99d7b28530d16ecfXavier Ducrohet private ResourceValue mWindowBackground; 127799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private ViewGroup mViewRoot; 128799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private FrameLayout mContentRoot; 1291392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private Canvas mCanvas; 1301392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenWidth = -1; 1311392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet private int mMeasuredScreenHeight = -1; 132799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private boolean mIsAlphaChannelImage; 133799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private boolean mWindowIsFloating; 134a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 135a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private int mStatusBarSize; 13664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private int mNavigationBarSize; 13764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; 138799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private int mTitleBarSize; 139799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private int mActionBarSize; 140a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1413bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // information being returned through the API 1433bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private BufferedImage mImage; 144e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet private List<ViewInfo> mViewInfoList; 14585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private List<ViewInfo> mSystemViewInfoList; 1463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1473bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final class PostInflateException extends Exception { 1483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private static final long serialVersionUID = 1L; 1493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public PostInflateException(String message) { 1513bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet super(message); 1523bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1533bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1543bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1563bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Creates a layout scene with all the information coming from the layout bridge API. 1573bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 1588d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)}, 1598d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * which act as a 160ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * call to {@link RenderSessionImpl#acquire(long)} 1613bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * 1628d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * @see Bridge#createSession(SessionParams) 1633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 164b32414fe256a6fe1d65e7a1443cd6ea77db8bd95Xavier Ducrohet public RenderSessionImpl(SessionParams params) { 1650fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet super(new SessionParams(params)); 166ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 167ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 168ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 169ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 170ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * inflater, and parser. 171ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 172ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 173ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 174ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @return whether the scene was prepared 175ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 176ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #acquire(long) 177ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @see #release() 178ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 1790fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet @Override 180ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result init(long timeout) { 1810fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Result result = super.init(timeout); 182952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 183ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet return result; 184ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1860fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 1870fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 1883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 189835ad76e300033f1d9cccd214bd7d61d78d0240aDeepanshu Gupta 1900fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet RenderResources resources = getParams().getResources(); 1910fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet DisplayMetrics metrics = getContext().getMetrics(); 1923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 193a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // use default of true in case it's not found to use alpha by default 194a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mIsAlphaChannelImage = getBooleanThemeValue(resources, 195a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowIsFloating", true /*defaultValue*/); 196a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 197799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", 198799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet true /*defaultValue*/); 199ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 200a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findBackground(resources); 201a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet findStatusBar(resources, metrics); 202799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet findActionBar(resources, metrics); 20364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet findNavigationBar(resources, metrics); 2043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 20576f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet // FIXME: find those out, and possibly add them to the render params 20676f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet boolean hasNavigationBar = true; 207952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection ConstantConditions 20876f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(), 20976f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet metrics, Surface.ROTATION_0, 2101e3c4a072f4476cedb958d75e2a6edf3bde8378fJohn Spurlock hasNavigationBar); 21176f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet WindowManagerGlobal_Delegate.setWindowManagerService(iwm); 21276f4c3e91d8579a580569c3d079da99511309727Xavier Ducrohet 2133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // build the inflater and parser. 2140fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet mInflater = new BridgeInflater(context, params.getProjectCallback()); 2150fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet context.setBridgeInflater(mInflater); 216ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 217a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet mBlockParser = new BridgeXmlBlockParser( 218a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet params.getLayoutDescription(), context, false /* platformResourceFlag */); 219ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2203054fe698a6be732e24128541a1db867ec606a59Xavier Ducrohet return SUCCESS.createResult(); 2213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 2223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 2243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Inflates the layout. 2253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 226ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 227ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 228ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 229ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #init(long)} was not called. 2303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 231ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result inflate() { 232ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 233ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 2343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 2353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 2360fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 23764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 2380fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 239510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta boolean isRtl = Bridge.isLocaleRtl(params.getLocale()); 24085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; 24164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 242cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet // the view group that receives the window background. 243952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ViewGroup backgroundView; 244cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 2450fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet if (mWindowIsFloating || params.isForceNoDecor()) { 246cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); 24785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mViewRoot.setLayoutDirection(layoutDirection); 248799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else { 24964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { 25064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet /* 25164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet * This is a special case where the navigation bar is on the right. 25264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+---+ 25364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Status bar (always) | | 25464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+ | 25564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | (Layout with background drawable) | | 25664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 25764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | Title/Action bar (optional) | | | 25864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 25964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | Content, vertical extending | | | 26064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | | | | | 26164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | +---------------------------------------------+ | | 26264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet +-------------------------------------------------+---+ 26364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 26464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet So we create a horizontal layout, with the nav bar on the right, 26564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet and the left part is the normal layout below without the nav bar at 26664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet the bottom 26764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet */ 26864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 26985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 27064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mViewRoot = topLayout; 27164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.setOrientation(LinearLayout.HORIZONTAL); 27264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 27364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet try { 27485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 27585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported()); 27664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.addView(navigationBar); 277952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 27864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 27964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 28064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 28164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 282799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet /* 283799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * we're creating the following layout 284799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * 285799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 28664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Status bar (always) | 287799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 288cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | (Layout with background drawable) | 289cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 290cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | Title/Action bar (optional) | | 291cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 292cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | Content, vertical extending | | 293cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | | | | 294cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet | +---------------------------------------------+ | 295799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 29664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet | Navigation bar for soft buttons, maybe see above| 297799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet +-------------------------------------------------+ 298799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 299799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet */ 300799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 3010fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 302799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet topLayout.setOrientation(LinearLayout.VERTICAL); 30385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 30464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // if we don't already have a view root this is it 30564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (mViewRoot == null) { 30664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mViewRoot = topLayout; 30764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } else { 30885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int topLayoutWidth = 30985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta params.getHardwareConfig().getScreenWidth() - mNavigationBarSize; 31064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 31185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayoutWidth, LayoutParams.MATCH_PARENT); 31264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.setLayoutParams(layoutParams); 31364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 31464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // this is the case of soft buttons + vertical bar. 31564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // this top layout is the first layout in the horizontal layout. see above) 316510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta if (isRtl && params.isRtlSupported()) { 317510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // If RTL is enabled, layoutlib will mirror the layouts. So, add the 318510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // topLayout to the right of Navigation Bar and layoutlib will draw it 319510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // to the left. 320510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta mViewRoot.addView(topLayout); 321510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta } else { 322510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta // Add the top layout to the left of the Navigation Bar. 323510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta mViewRoot.addView(topLayout, 0); 324510148f0699abceb44a3634a648a589cc84f6cbfDeepanshu Gupta } 32564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 326799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 327799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mStatusBarSize > 0) { 328799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // system bar 329799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 33085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(), 33185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutDirection, params.isRtlSupported()); 33285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta topLayout.addView(statusBar); 333952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 334799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 335799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 336799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 337799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 338cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet LinearLayout backgroundLayout = new LinearLayout(context); 339cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundView = backgroundLayout; 340cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.setOrientation(LinearLayout.VERTICAL); 341cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 342fa7ed38ae9c180ff12a7312e6ec740b5ba313a97Deepanshu Gupta LayoutParams.MATCH_PARENT, 0); 343cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet layoutParams.weight = 1; 344cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.setLayoutParams(layoutParams); 345cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet topLayout.addView(backgroundLayout); 346cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 347cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet 348799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // if the theme says no title/action bar, then the size will be 0 349799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mActionBarSize > 0) { 350952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ActionBarLayout actionBar = createActionBar(context, params); 351952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta backgroundLayout.addView(actionBar); 352952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta actionBar.createMenuPopup(); 353952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta mContentRoot = actionBar.getContentRoot(); 354799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else if (mTitleBarSize > 0) { 355799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 35685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta TitleBar titleBar = createTitleBar(context, 35764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet hardwareConfig.getDensity(), params.getAppLabel()); 358cd85db6ff592d37faf751d262d5b9c152adfd632Xavier Ducrohet backgroundLayout.addView(titleBar); 359952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 360799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 361799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 362799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 363799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 364799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // content frame 36585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (mContentRoot == null) { 36685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mContentRoot = new FrameLayout(context); 36785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutParams = new LinearLayout.LayoutParams( 36885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, 0); 36985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta layoutParams.weight = 1; 37085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mContentRoot.setLayoutParams(layoutParams); 37185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta backgroundLayout.addView(mContentRoot); 37285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 373799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 37464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (mNavigationBarOrientation == LinearLayout.HORIZONTAL && 37564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize > 0) { 376799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // system bar 377799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet try { 37885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 37985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported()); 38064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet topLayout.addView(navigationBar); 381952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta } catch (XmlPullParserException ignored) { 382799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 383799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 384799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 385799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 386799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 3873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // Sets the project callback (custom view loader) to the fragment delegate so that 3893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // it can instantiate the custom Fragment. 3900fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Fragment_Delegate.setProjectCallback(params.getProjectCallback()); 3913bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 392799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet View view = mInflater.inflate(mBlockParser, mContentRoot); 3933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3947062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // done with the parser, pop it. 3957062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet context.popParser(); 3967062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 3973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Fragment_Delegate.setProjectCallback(null); 3983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 3993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // set the AttachInfo on the root view. 400994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohet AttachInfo_Accessor.setAttachInfo(mViewRoot); 4013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 402a2378f55b81e7d29f451d7f65527de49417a3f0cXavier Ducrohet // post-inflate process. For now this supports TabHost/TabWidget 4030fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet postInflateProcess(view, params.getProjectCallback()); 404a2378f55b81e7d29f451d7f65527de49417a3f0cXavier Ducrohet 4053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the background drawable 406952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (mWindowBackground != null) { 4070fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); 40864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet backgroundView.setBackground(d); 4093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 411ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 4123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (PostInflateException e) { 413ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(e.getMessage(), e); 4143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 4153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 4163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 4173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 4183bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 4193bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 421ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_INFLATION.createResult(t.getMessage(), t); 4223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 4263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Renders the scene. 4273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * <p> 428ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 429ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 4304c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * @param freshRender whether the render is a new one and should erase the existing bitmap (in 4314c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * the case where bitmaps are reused). This is typically needed when not playing 4324c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * animations.) 4334c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet * 434ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 435ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 4361392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet * 4378d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * @see SessionParams#getRenderingMode() 438799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#render(long) 4393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 4404c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet public Result render(boolean freshRender) { 441ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 442ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 4430fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet SessionParams params = getParams(); 4440fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 4453bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet try { 4463bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (mViewRoot == null) { 447ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_NOT_INFLATED.createResult(); 4483bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 4493bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 4500fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet RenderingMode renderingMode = params.getRenderingMode(); 45164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 452e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet 4531392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // only do the screen measure when needed. 4541392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet boolean newRenderSize = false; 4551392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (mMeasuredScreenWidth == -1) { 4561392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet newRenderSize = true; 45764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mMeasuredScreenWidth = hardwareConfig.getScreenWidth(); 45864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); 4591392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 4601392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode != RenderingMode.NORMAL) { 4618ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int widthMeasureSpecMode = renderingMode.isHorizExpand() ? 4628ae691c1148038995d1185716f629b82c582897fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4638ae691c1148038995d1185716f629b82c582897fXavier Ducrohet : MeasureSpec.EXACTLY; 4648ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int heightMeasureSpecMode = renderingMode.isVertExpand() ? 4658ae691c1148038995d1185716f629b82c582897fXavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 4668ae691c1148038995d1185716f629b82c582897fXavier Ducrohet : MeasureSpec.EXACTLY; 4678ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4688ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // We used to compare the measured size of the content to the screen size but 4698ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // this does not work anymore due to the 2 following issues: 4708ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // - If the content is in a decor (system bar, title/action bar), the root view 4718ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // will not resize even with the UNSPECIFIED because of the embedded layout. 4728ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // - If there is no decor, but a dialog frame, then the dialog padding prevents 4738ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // comparing the size of the content to the screen frame (as it would not 4748ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // take into account the dialog padding). 4758ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4768ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // The solution is to first get the content size in a normal rendering, inside 4778ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // the decor or the dialog padding. 4788ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // Then measure only the content with UNSPECIFIED to see the size difference 4798ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // and apply this to the screen size. 4808ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4818ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // first measure the full layout, with EXACTLY to get the size of the 4828ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // content as it is inside the decor/dialog 483952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 4848ae691c1148038995d1185716f629b82c582897fXavier Ducrohet Pair<Integer, Integer> exactMeasure = measureView( 4858ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mViewRoot, mContentRoot.getChildAt(0), 4868ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 4878ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 4888ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4898ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // now measure the content only using UNSPECIFIED (where applicable, based on 4908ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // the rendering mode). This will give us the size the content needs. 491952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 4928ae691c1148038995d1185716f629b82c582897fXavier Ducrohet Pair<Integer, Integer> result = measureView( 4938ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mContentRoot, mContentRoot.getChildAt(0), 4948ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, widthMeasureSpecMode, 4958ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, heightMeasureSpecMode); 4968ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 4978ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // now look at the difference and add what is needed. 4981392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isHorizExpand()) { 4998ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int measuredWidth = exactMeasure.getFirst(); 5008ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int neededWidth = result.getFirst(); 5018ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (neededWidth > measuredWidth) { 5028ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth += neededWidth - measuredWidth; 5031392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 504e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 5053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5061392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet if (renderingMode.isVertExpand()) { 5078ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int measuredHeight = exactMeasure.getSecond(); 5088ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int neededHeight = result.getSecond(); 5098ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (neededHeight > measuredHeight) { 5108ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight += neededHeight - measuredHeight; 5111392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 512e489a969de010782fcc0ab048c7357d42ada9400Xavier Ducrohet } 5133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5168ae691c1148038995d1185716f629b82c582897fXavier Ducrohet // measure again with the size we need 5173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // This must always be done before the call to layout 5188ae691c1148038995d1185716f629b82c582897fXavier Ducrohet measureView(mViewRoot, null /*measuredView*/, 5198ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 5208ae691c1148038995d1185716f629b82c582897fXavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 5213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // now do the layout. 523a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 5243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 525f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.isLayoutOnly()) { 526f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // delete the canvas and image to reset them on the next full rendering 527f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = null; 528f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mCanvas = null; 529f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } else { 530994236e95e9809ec8c1d06a218f606f1af2083afXavier Ducrohet AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot); 531f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 532f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // draw the views 533f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create the BufferedImage into which the layout will be rendered. 534f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet boolean newImage = false; 535f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (newRenderSize || mCanvas == null) { 536f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.getImageFactory() != null) { 537f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = params.getImageFactory().getImage( 538f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, 539f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenHeight); 540f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } else { 541f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mImage = new BufferedImage( 542f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, 543f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenHeight, 544f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet BufferedImage.TYPE_INT_ARGB); 545f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet newImage = true; 546f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 547f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 548f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet if (params.isBgColorOverridden()) { 549f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // since we override the content, it's the same as if it was a new image. 550f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet newImage = true; 551f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet Graphics2D gc = mImage.createGraphics(); 552f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setColor(new Color(params.getOverrideBgColor(), true)); 553f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setComposite(AlphaComposite.Src); 554f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 555f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.dispose(); 556f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 557f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 558f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create an Android bitmap around the BufferedImage 559f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, 56064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet true /*isMutable*/, hardwareConfig.getDensity()); 561f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet 562f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // create a Canvas around the Android bitmap 563f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mCanvas = new Canvas(bitmap); 56464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue()); 5651392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 5663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 567952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (freshRender && !newImage) { 5681392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet Graphics2D gc = mImage.createGraphics(); 5694c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet gc.setComposite(AlphaComposite.Src); 5703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 571f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.setColor(new Color(0x00000000, true)); 572f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.fillRect(0, 0, 573f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mMeasuredScreenWidth, mMeasuredScreenHeight); 574a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 575f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet // done 576f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet gc.dispose(); 577f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet } 578a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 579f27575799aab2e552c0491a07b34389e1422fc27Xavier Ducrohet mViewRoot.draw(mCanvas); 5804c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet } 5814c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet 58241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), 58341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta false); 5843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // success! 586ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 5873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } catch (Throwable e) { 5883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the real cause of the exception. 5893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet Throwable t = e; 5903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet while (t.getCause() != null) { 5913bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet t = t.getCause(); 5923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 594ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 5953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 5973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 5983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 5998ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * Executes {@link View#measure(int, int)} on a given view with the given parameters (used 6008ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}. 6018ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * 6028ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height) 6038ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}). 6048ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * 6058ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param viewToMeasure the view on which to execute measure(). 6068ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param measuredView if non null, the view to query for its measured width/height. 6078ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param width the width to use in the MeasureSpec. 6088ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param widthMode the MeasureSpec mode to use for the width. 6098ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param height the height to use in the MeasureSpec. 6108ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @param heightMode the MeasureSpec mode to use for the height. 6118ae691c1148038995d1185716f629b82c582897fXavier Ducrohet * @return the measured width/height if measuredView is non-null, null otherwise. 6128ae691c1148038995d1185716f629b82c582897fXavier Ducrohet */ 613952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") // For the use of Pair 6148ae691c1148038995d1185716f629b82c582897fXavier Ducrohet private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, 6158ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int width, int widthMode, int height, int heightMode) { 6168ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode); 6178ae691c1148038995d1185716f629b82c582897fXavier Ducrohet int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode); 6188ae691c1148038995d1185716f629b82c582897fXavier Ducrohet viewToMeasure.measure(w_spec, h_spec); 6198ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6208ae691c1148038995d1185716f629b82c582897fXavier Ducrohet if (measuredView != null) { 6218ae691c1148038995d1185716f629b82c582897fXavier Ducrohet return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight()); 6228ae691c1148038995d1185716f629b82c582897fXavier Ducrohet } 6238ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6248ae691c1148038995d1185716f629b82c582897fXavier Ducrohet return null; 6258ae691c1148038995d1185716f629b82c582897fXavier Ducrohet } 6268ae691c1148038995d1185716f629b82c582897fXavier Ducrohet 6278ae691c1148038995d1185716f629b82c582897fXavier Ducrohet /** 628ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * Animate an object 629ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * <p> 630ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 631ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * 632ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 633ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 63433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 635799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#animate(Object, String, boolean, IAnimationListener) 636ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet */ 637ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result animate(Object targetObject, String animationName, 638ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet boolean isFrameworkAnimation, IAnimationListener listener) { 639ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet checkLock(); 640ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 6410fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 6420fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 643ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet // find the animation file. 644952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta ResourceValue animationResource; 645ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet int animationId = 0; 646ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (isFrameworkAnimation) { 6470fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationResource = context.getRenderResources().getFrameworkResource( 6481b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 649ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 650947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName); 651ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 652ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } else { 6530fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationResource = context.getRenderResources().getProjectResource( 6541b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 655ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 6560fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet animationId = context.getProjectCallback().getResourceId( 6571b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceType.ANIMATOR, animationName); 658ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 659ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 660ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 661ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (animationResource != null) { 662ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet try { 6630fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet Animator anim = AnimatorInflater.loadAnimator(context, animationId); 664ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet if (anim != null) { 665ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet anim.setTarget(targetObject); 666ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 66733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new PlayAnimationThread(anim, this, animationName, listener).start(); 668ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 669ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 670ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 671ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } catch (Exception e) { 672b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get the real cause of the exception. 673b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet Throwable t = e; 674b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet while (t.getCause() != null) { 675b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet t = t.getCause(); 676b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 677b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 678ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 679ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 680ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 681ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 682ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_ANIM_NOT_FOUND.createResult(); 683b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 684b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 68533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 68633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Insert a new child into an existing parent. 68733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 68833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 68933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 69033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 69133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 69233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 693799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener) 69433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 695ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml, 69633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final int index, IAnimationListener listener) { 697b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 698b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 6990fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet BridgeContext context = getContext(); 7000fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet 701b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // create a block parser for the XML 702a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( 703a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet childXml, context, false /* platformResourceFlag */); 704b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 705b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // inflate the child without adding it to the root since we want to control where it'll 706b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // get added. We do pass the parentView however to ensure that the layoutParams will 707b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet // be created correctly. 70833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); 709a732a0101ad07b28e828bbbc8fb81be0580d53b5Xavier Ducrohet blockParser.ensurePopped(); 710b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 71133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 71233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 71333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 71433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "insertChild", listener) { 71533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 71633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 717ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 71833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(new LayoutTransition()); 71933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return addView(parentView, child, index); 72033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 72133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 72233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 72333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 72433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parentView.setLayoutTransition(null); 72533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 72633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 72733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 72833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 729ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(child); 7301392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 7311392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 73233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // add it to the parentView in the correct location 733ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = addView(parentView, child, index); 734952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 73533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 73633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 737b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 7384c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 7391766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet if (result.isSuccess()) { 74033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(child); 7411766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet } 7421766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet 7431766c77e7e79afbb4fd2611837ac487f5610d71dXavier Ducrohet return result; 744b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 745b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 74633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 74733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Adds a given view to a given parent at a given index. 74833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 74933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param parent the parent to receive the view 75033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to add to the parent 75133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the index where to do the add. 75233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 753ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 754ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 75533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 75633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 757ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result addView(ViewGroup parent, View view, int index) { 75833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 75933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.addView(view, index); 760ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 76133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 76233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 763ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 76433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 76533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 76633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 76733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 76833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a view to a new parent at a given location 76933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 77033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 77133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 77233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 77333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 77433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 775799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener) 77633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 77762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public Result moveChild(final ViewGroup newParentView, final View childView, final int index, 77824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Map<String, String> layoutParamsMap, final IAnimationListener listener) { 779b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet checkLock(); 780b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 78133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet invalidateRenderingSize(); 78233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 783ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet LayoutParams layoutParams = null; 78433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (layoutParamsMap != null) { 78533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // need to create a new LayoutParams object for the new parent. 78662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet layoutParams = newParentView.generateLayoutParams( 78733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new BridgeLayoutParamsMapAttributes(layoutParamsMap)); 78833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 7891392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 79062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // get the current parent of the view that needs to be moved. 79162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet final ViewGroup previousParent = (ViewGroup) childView.getParent(); 79262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 79333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 79433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final LayoutParams params = layoutParams; 795ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 79624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // there is no support for animating views across layouts, so in case the new and old 79724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // parent views are different we fake the animation through a no animation thread. 79824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousParent != newParentView) { 79924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new Thread("not animated moveChild") { 80024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 80124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void run() { 80224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, 80324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet params); 804952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 80524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 80624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 80724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 80824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // ready to do the work, acquire the scene. 80924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet result = acquire(250); 810952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 81124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 81224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return; 81324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 81424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 81524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet try { 8164c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 81724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (result.isSuccess()) { 81824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.onNewFrame(RenderSessionImpl.this.getSession()); 81924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 82024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } finally { 82124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet release(); 82224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 82324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 82424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet listener.done(result); 82562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 82624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 82724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } else { 82824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 82962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 83024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 83124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public Result preAnimation() { 83224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // set up the transition for the parent. 83324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition transition = new LayoutTransition(); 83424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(transition); 8355562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet 83624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // tweak the animation durations and start delays (to match the duration of 83724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // animation playing just before). 83824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // Note: Cannot user Animation.setDuration() directly. Have to set it 83924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // on the LayoutTransition. 84024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.DISAPPEARING, 100); 84124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_DISAPPEARING plays after DISAPPEARING 84224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100); 843ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 84424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100); 84524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 84624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100); 84724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet // CHANGE_APPEARING plays after CHANGE_APPEARING 84824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setStartDelay(LayoutTransition.APPEARING, 100); 84924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 85024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet transition.setDuration(LayoutTransition.APPEARING, 100); 85124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 85224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet return moveView(previousParent, newParentView, childView, index, params); 85324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 85424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 85524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet @Override 85624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet public void postAnimation() { 85724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.setLayoutTransition(null); 85824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParentView.setLayoutTransition(null); 85924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 86024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet }.start(); 86124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 86233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 86333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 864ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(layoutParams); 865b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 866b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 86762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, layoutParams); 868952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 86933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 87033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 871b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 8724c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet result = render(false /*freshRender*/); 873ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet if (layoutParams != null && result.isSuccess()) { 87433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet result = result.getCopyWithData(layoutParams); 875ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet } 876ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet 877ce63b05275ddd2acd9d2f39e9ab3cb3039f26677Xavier Ducrohet return result; 878b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 879b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 88033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 88133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Moves a View from its current parent to a new given parent at a new given location, with 88233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * an optional new {@link LayoutParams} instance 88333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 88462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param previousParent the previous parent, still owning the child at the time of the call. 88562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet * @param newParent the new parent 88624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet * @param movedView the view to move 88733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param index the new location in the new parent 88833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param params an option (can be null) {@link LayoutParams} instance. 88933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 890ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 891ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 89233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 89333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 89424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private Result moveView(ViewGroup previousParent, final ViewGroup newParent, 89524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet final View movedView, final int index, final LayoutParams params) { 8961392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet try { 89762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // check if there is a transition on the previousParent. 89824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet LayoutTransition previousTransition = previousParent.getLayoutTransition(); 89924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (previousTransition != null) { 9005562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // in this case there is an animation. This means we have to wait for the child's 9015562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent reference to be null'ed out so that we can add it to the new parent. 9025562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // It is technically removed right before the DISAPPEARING animation is done (if 9035562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // the animation of this type is not null, otherwise it's after which is impossible 9045562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // to handle). 9055562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // Because there is no move animation, if the new parent is the same as the old 9065562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before 9075562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // adding the child or the child will appear in its new location before the 9085562208aafcaccf366dd8cd906700f48c6c342a8Xavier Ducrohet // other children have made room for it. 90962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 91062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add a listener to the transition to be notified of the actual removal. 91124cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousTransition.addTransitionListener(new TransitionListener() { 91224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet private int mChangeDisappearingCount = 0; 91362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 914d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 91562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void startTransition(LayoutTransition transition, ViewGroup container, 91662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 91724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 91824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount++; 91924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 92062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 92133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 922d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 92362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet public void endTransition(LayoutTransition transition, ViewGroup container, 92462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet View view, int transitionType) { 92524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 92624cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount--; 92724cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet } 92824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet 92924cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING && 93024cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet mChangeDisappearingCount == 0) { 93162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 93262039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 93324cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 93462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 93524cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 93662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 93762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 93862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 93962039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet }); 94062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 94162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // remove the view from the current parent. 94224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 94362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 94462039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // and return since adding the view to the new parent is done in the listener. 94562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 94633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } else { 94762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // standard code with no animation. pretty simple. 94824cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet previousParent.removeView(movedView); 94933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 95062039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet // add it to the parentView in the correct location 95162039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet if (params != null) { 95224cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index, params); 95362039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } else { 95424cdf6c407351a157880a0a1bbf65c95af753418Xavier Ducrohet newParent.addView(movedView, index); 95562039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 95662039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet 95762039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet return SUCCESS.createResult(); 95862039873060d26a7be141573b0f468c5ba0414dcXavier Ducrohet } 9591392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } catch (UnsupportedOperationException e) { 9601392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 961ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 962b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 96333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 96433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 96533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet /** 96633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a child from its current parent. 96733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * <p> 96833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 96933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 97033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 97133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 97233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 973799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet * @see RenderSession#removeChild(Object, IAnimationListener) 97433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 975ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result removeChild(final View childView, IAnimationListener listener) { 97633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet checkLock(); 977b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 9781392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet invalidateRenderingSize(); 9791392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 98033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet final ViewGroup parent = (ViewGroup) childView.getParent(); 98133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 98233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet if (listener != null) { 98333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 98433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 98533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 986ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Result preAnimation() { 98733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(new LayoutTransition()); 98833840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return removeView(parent, childView); 98933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 99033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 99133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet @Override 99233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet public void postAnimation() { 99333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.setLayoutTransition(null); 99433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 99533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet }.start(); 99633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 99733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // always return success since the real status will come through the listener. 998ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 99933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 100033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 1001ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet Result result = removeView(parent, childView); 1002952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!result.isSuccess()) { 100333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet return result; 100433840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 100533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 10064c6c050f68c67097b92eb38e9f01dae9885907caXavier Ducrohet return render(false /*freshRender*/); 1007ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet } 1008ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1009ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet /** 101033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * Removes a given view from its current parent. 101133840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 101233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * @param view the view to remove from its parent 101333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * 1014ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 1015ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 101633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet * adding views. 101733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet */ 1018ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet private Result removeView(ViewGroup parent, View view) { 101933840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet try { 102033840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet parent.removeView(view); 1021ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return SUCCESS.createResult(); 102233840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } catch (UnsupportedOperationException e) { 102333840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 1024ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 102533840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 102633840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet } 102733840c00b3b56db9613dcd33abd69601b711ce69Xavier Ducrohet 1028ddea50d03cdda807bbaea54beffd7a341c51f770Xavier Ducrohet 1029a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findBackground(RenderResources resources) { 1030952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!getParams().isBgColorOverridden()) { 103141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet mWindowBackground = resources.findItemInTheme("windowBackground", 103241fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 1033a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (mWindowBackground != null) { 1034a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet mWindowBackground = resources.resolveResValue(mWindowBackground); 1035a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1036a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1037a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 103964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private boolean hasSoftwareButtons() { 104064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet return getParams().getHardwareConfig().hasSoftwareButtons(); 1041a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 10423bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1043a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { 104464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet boolean windowFullscreen = getBooleanThemeValue(resources, 104564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet "windowFullscreen", false /*defaultValue*/); 1046a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1047952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!windowFullscreen && !mWindowIsFloating) { 104864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // default value 104964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; 1050a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 105164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // get the real value 105264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 105364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet "status_bar_height"); 1054a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 105564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (value != null) { 105664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("status_bar_height", 105764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet value.getValue(), true /*requireUnit*/); 105864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (typedValue != null) { 105964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute the pixel value based on the display metrics 106064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mStatusBarSize = (int)typedValue.getDimension(metrics); 1061a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1062a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1063a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1064a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1065a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1066799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet private void findActionBar(RenderResources resources, DisplayMetrics metrics) { 1067799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (mWindowIsFloating) { 1068799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet return; 1069a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1070a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1071a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet boolean windowActionBar = getBooleanThemeValue(resources, 1072a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet "windowActionBar", true /*defaultValue*/); 1073a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1074a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's a value and it's false (default is true) 1075a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (windowActionBar) { 10763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10773bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default size of the window title bar 1078799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT; 10793bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10803bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get value from the theme. 108141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme("actionBarSize", 108241fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 10833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // resolve it 1085a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 10863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 10873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 10883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // get the numerical value, if available 1089d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(), 1090d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet true /*requireUnit*/); 10913bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 10923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 1093799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mActionBarSize = (int)typedValue.getDimension(metrics); 10943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 10953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1096799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } else { 1097799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // action bar overrides title bar so only look for this one if action bar is hidden 1098799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet boolean windowNoTitle = getBooleanThemeValue(resources, 1099799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet "windowNoTitle", false /*defaultValue*/); 11003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1101952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!windowNoTitle) { 1102a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1103799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // default size of the window title bar 1104799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT; 1105a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1106799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // get value from the theme. 110741fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme("windowTitleSize", 110841fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet true /*isFrameworkAttr*/); 1109a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1110799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // resolve it 1111799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet value = resources.resolveResValue(value); 11123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1113799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (value != null) { 1114799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // get the numerical value, if available 1115d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("windowTitleSize", 1116d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet value.getValue(), true /*requireUnit*/); 1117799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet if (typedValue != null) { 1118799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet // compute the pixel value based on the display metrics 1119799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet mTitleBarSize = (int)typedValue.getDimension(metrics); 1120799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 1121a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1122a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1123799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 1124a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1125a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1126a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 112764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { 1128952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (hasSoftwareButtons() && !mWindowIsFloating) { 11293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // default value 113164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize = 48; // ?? 113264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 113364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet HardwareConfig hardwareConfig = getParams().getHardwareConfig(); 113464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 113564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet boolean barOnBottom = true; 113664f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 113764f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { 113864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute the dp of the screen. 113964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet int shortSize = hardwareConfig.getScreenHeight(); 114064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 114164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet // compute in dp 1142952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / 1143952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta hardwareConfig.getDensity().getDpiValue(); 114464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 1145952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // 0-599dp: "phone" UI with bar on the side 1146952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // 600+dp: "tablet" UI with bar on the bottom 1147952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta barOnBottom = shortSizeDp >= 600; 114864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 114964f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet 115064f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet if (barOnBottom) { 115164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarOrientation = LinearLayout.HORIZONTAL; 115264f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } else { 115364f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarOrientation = LinearLayout.VERTICAL; 115464f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet } 11553bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1156089143ffed72bb47fd8d870f29caffb646138781Xavier Ducrohet // get the real value 11571b5ef2d19e1d7cb491c1c79f867e38ec0bde2770Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 115864f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); 1159a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 11603bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (value != null) { 116164f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", 1162d7e9eda58981700df39f08ee8465de236eeed2d4Xavier Ducrohet value.getValue(), true /*requireUnit*/); 11633bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (typedValue != null) { 11643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // compute the pixel value based on the display metrics 116564f5dc0e6437e95695ed4048f047c3cbef447e0fXavier Ducrohet mNavigationBarSize = (int)typedValue.getDimension(metrics); 11663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 1168a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1169a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1170a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 117141fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet /** 117241fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * Looks for a attribute in the current theme. The attribute is in the android 117341fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * namespace. 117441fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * 117541fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param resources the render resources 117641fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param name the name of the attribute 117741fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @param defaultValue the default value. 117841fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet * @return the value of the attribute or the default one if not found. 117941fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet */ 1180a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet private boolean getBooleanThemeValue(RenderResources resources, 1181a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet String name, boolean defaultValue) { 1182a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1183a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // get the title bar flag from the current theme. 118441fb2853aa6de48c3b657bd6be32797dfac2103bXavier Ducrohet ResourceValue value = resources.findItemInTheme(name, true /*isFrameworkAttr*/); 1185a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1186a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // because it may reference something else, we resolve it. 1187a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet value = resources.resolveResValue(value); 11883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1189a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet // if there's no value, return the default. 1190a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet if (value == null || value.getValue() == null) { 1191a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return defaultValue; 11923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1194a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); 11953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 11963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 11973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 1198952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * Post process on a view hierarchy that was just inflated. 1199952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * <p/> 1200952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the 12013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically 12023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * based on the content of the {@link FrameLayout}. 12033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param view the root view to process. 12043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param projectCallback callback to the project. 12053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 1206952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") // For the use of Pair 12073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private void postInflateProcess(View view, IProjectCallback projectCallback) 12083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 12093bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view instanceof TabHost) { 12103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet setupTabHost((TabHost)view, projectCallback); 121162c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet } else if (view instanceof QuickContactBadge) { 121262c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet QuickContactBadge badge = (QuickContactBadge) view; 121362c9c3463a9b4a4bc899f5db353f2856876e6590Xavier Ducrohet badge.setImageToDefault(); 12147062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else if (view instanceof AdapterView<?>) { 12157062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // get the view ID. 12167062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet int id = view.getId(); 12177062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12187062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet BridgeContext context = getContext(); 12197062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12207062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // get a ResourceReference from the integer ID. 12217062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ResourceReference listRef = context.resolveId(id); 12227062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12237062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (listRef != null) { 12247062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet SessionParams params = getParams(); 12257062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet AdapterBinding binding = params.getAdapterBindings().get(listRef); 12267062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12277062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet // if there was no adapter binding, trying to get it from the call back. 12287062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (binding == null) { 12297062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding = params.getProjectCallback().getAdapterBinding(listRef, 12307062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet context.getViewKey(view), view); 12317062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12327062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12337062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (binding != null) { 12347062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12357062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (view instanceof AbsListView) { 12367062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) && 12377062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet view instanceof ListView) { 12387062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ListView list = (ListView) view; 12397062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12407062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet boolean skipCallbackParser = false; 12417062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12427062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet int count = binding.getHeaderCount(); 12437062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet for (int i = 0 ; i < count ; i++) { 12447062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 12457062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding.getHeaderAt(i), 12467062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list, false /*attachToRoot*/, skipCallbackParser); 12477062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (pair.getFirst() != null) { 12487062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list.addHeaderView(pair.getFirst()); 12497062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12507062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12517062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet skipCallbackParser |= pair.getSecond(); 12527062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12537062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12547062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet count = binding.getFooterCount(); 12557062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet for (int i = 0 ; i < count ; i++) { 12567062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 12577062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet binding.getFooterAt(i), 12587062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list, false /*attachToRoot*/, skipCallbackParser); 12597062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (pair.getFirst() != null) { 12607062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet list.addFooterView(pair.getFirst()); 12617062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12627062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12637062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet skipCallbackParser |= pair.getSecond(); 12647062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12657062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12667062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet 12677062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet if (view instanceof ExpandableListView) { 12687062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((ExpandableListView) view).setAdapter( 12697062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet new FakeExpandableAdapter( 12707062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet listRef, binding, params.getProjectCallback())); 12717062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else { 12727062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((AbsListView) view).setAdapter( 12737062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet new FakeAdapter( 12747062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet listRef, binding, params.getProjectCallback())); 12757062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12767062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } else if (view instanceof AbsSpinner) { 12777062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet ((AbsSpinner) view).setAdapter( 12787062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet new FakeAdapter( 12797062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet listRef, binding, params.getProjectCallback())); 12807062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12817062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12827062c1ad9adcb216ac49100ca1044e9d89e8f8c1Xavier Ducrohet } 12833bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } else if (view instanceof ViewGroup) { 12843bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet ViewGroup group = (ViewGroup)view; 12853bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = group.getChildCount(); 12863bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet for (int c = 0 ; c < count ; c++) { 12873bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View child = group.getChildAt(c); 12883bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet postInflateProcess(child, projectCallback); 12893bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12903bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12913bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 12923bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 12933bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 12943bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * Sets up a {@link TabHost} object. 12953bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param tabHost the TabHost to setup. 12963bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @param projectCallback The project callback object to access the project R class. 12973bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet * @throws PostInflateException 12983bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 12993bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback) 13003bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throws PostInflateException { 13013bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // look for the TabWidget, and the FrameLayout. They have their own specific names 13023bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet View v = tabHost.findViewById(android.R.id.tabs); 13033bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13043bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 13053bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 13063bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n"); 13073bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13083bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1309952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!(v instanceof TabWidget)) { 13103bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 13113bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n" + 13123bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName())); 13133bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13143bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13153bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet v = tabHost.findViewById(android.R.id.tabcontent); 13163bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13173bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (v == null) { 1318952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty) 1319952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection SpellCheckingInspection 13203bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException( 13213bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\"."); 13223bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1324952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta if (!(v instanceof FrameLayout)) { 1325952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta //noinspection SpellCheckingInspection 13263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet throw new PostInflateException(String.format( 13273bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" + 13283bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName())); 13293bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13303bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13313bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet FrameLayout content = (FrameLayout)v; 13323bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1333952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // now process the content of the frameLayout and dynamically create tabs for it. 13343bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet final int count = content.getChildCount(); 13353bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 13363bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // this must be called before addTab() so that the TabHost searches its TabWidget 13373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet // and FrameLayout. 13383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet tabHost.setup(); 13393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1340f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (count == 0) { 1341f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye // Create a dummy child to get a single tab 1342f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label", 1343f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details)) 1344f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye .setContent(new TabHost.TabContentFactory() { 1345d98e133b3911b8db3430ce9d85efd5a6adcf70bfXavier Ducrohet @Override 1346f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye public View createTabContent(String tag) { 13470fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet return new LinearLayout(getContext()); 1348f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1349f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye }); 1350f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(spec); 1351f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1352952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta // for each child of the frameLayout, add a new TabSpec 1353f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye for (int i = 0 ; i < count ; i++) { 1354f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye View child = content.getChildAt(i); 1355f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String tabSpec = String.format("tab_spec%d", i+1); 1356f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye int id = child.getId(); 1357952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta @SuppressWarnings("deprecation") 1358947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id); 1359f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye String name; 1360f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye if (resource != null) { 1361947b979a91ac1cd556244d875d8b8d4fec8fd474Xavier Ducrohet name = resource.getSecond(); 1362f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } else { 1363f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye name = String.format("Tab %d", i+1); // default name if id is unresolved. 1364f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye } 1365f14c342b8a0024e5ca8c2c3ffce8b79abe03e941Tor Norbye tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id)); 13663bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13673bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13683bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 13693bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 137085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 137185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the 137285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * bounds of all the views. 137385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 137485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param view the root View 137585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset for the view bounds. 137685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 137785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 137885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * content frame. 137985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 138085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @return {@code ViewInfo} containing the bounds of the view and it children otherwise. 138185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 138285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo visit(View view, int offset, boolean setExtendedInfo, 138385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isContentFrame) { 138485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo result = createViewInfo(view, offset, setExtendedInfo, isContentFrame); 1385799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 138685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view instanceof ViewGroup) { 138785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewGroup group = ((ViewGroup) view); 138885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result.setChildren(visitAllChildren(group, isContentFrame ? 0 : offset, 138985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta setExtendedInfo, isContentFrame)); 139085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 139185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 139285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1393799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 139485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 139585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo} 13968d43509cc2c0f95bd07d6585dadfac296bc5d24dDeepanshu Gupta * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with 139785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * the children of the {@code mContentRoot}. 139885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 139985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param viewGroup the root View 140085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset from the top for the content view frame. 140185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 140285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 140385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * content frame. {@code false} if the {@code ViewInfo} to be created is 140485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * part of the system decor. 140585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 140685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset, 140785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean setExtendedInfo, boolean isContentFrame) { 140885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (viewGroup == null) { 140985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return null; 1410799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 1411799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 141285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (!isContentFrame) { 141385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta offset += viewGroup.getTop(); 141485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1415799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 141685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta int childCount = viewGroup.getChildCount(); 141785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (viewGroup == mContentRoot) { 141885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> childrenWithoutOffset = new ArrayList<ViewInfo>(childCount); 141985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> childrenWithOffset = new ArrayList<ViewInfo>(childCount); 142085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta for (int i = 0; i < childCount; i++) { 142185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo[] childViewInfo = visitContentRoot(viewGroup.getChildAt(i), offset, 14226208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet setExtendedInfo); 142385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta childrenWithoutOffset.add(childViewInfo[0]); 142485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta childrenWithOffset.add(childViewInfo[1]); 1425799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 142685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mViewInfoList = childrenWithOffset; 142785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return childrenWithoutOffset; 142885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 142985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> children = new ArrayList<ViewInfo>(childCount); 143085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta for (int i = 0; i < childCount; i++) { 143185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo, 143285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta isContentFrame)); 143385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 143485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return children; 1435799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 143685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1437799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet 143885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 143985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the 144085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * bounds of all the views. It returns two {@code ViewInfo} objects with the same children, 144185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * one with the {@code offset} and other without the {@code offset}. The offset is needed to 144285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * get the right bounds if the {@code ViewInfo} hierarchy is accessed from 144385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the 144485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * offset is not needed. 144585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 144685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at 144785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * index 1 is with the offset. 144885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 144985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo[] visitContentRoot(View view, int offset, boolean setExtendedInfo) { 145085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo[] result = new ViewInfo[2]; 145185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view == null) { 145285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 145385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 145485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 145585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[0] = createViewInfo(view, 0, setExtendedInfo, true); 145685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[1] = createViewInfo(view, offset, setExtendedInfo, true); 145785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (view instanceof ViewGroup) { 145885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta List<ViewInfo> children = visitAllChildren((ViewGroup) view, 0, setExtendedInfo, true); 145985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[0].setChildren(children); 146085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result[1].setChildren(children); 146185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 146285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return result; 1463799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet } 14643bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 14653bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet /** 146685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children 146785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not 146885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * set. 146985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param offset an offset for the view bounds. Used only if view is part of the content frame. 14703bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet */ 147185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private ViewInfo createViewInfo(View view, int offset, boolean setExtendedInfo, 147285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isContentFrame) { 14733bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet if (view == null) { 14743bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return null; 14753bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 14763bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 147785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ViewInfo result; 147885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (isContentFrame) { 147970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // The view is part of the layout added by the user. Hence, 148070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // the ViewCookie may be obtained only through the Context. 148185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta result = new ViewInfo(view.getClass().getName(), 148270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta getContext().getViewKey(view), 148385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getLeft(), view.getTop() + offset, view.getRight(), 148485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getBottom() + offset, view, view.getLayoutParams()); 148585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 148670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // We are part of the system decor. 148770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta SystemViewInfo r = new SystemViewInfo(view.getClass().getName(), 148841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta getViewKey(view), 148985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getLeft(), view.getTop(), view.getRight(), 149085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta view.getBottom(), view, view.getLayoutParams()); 149170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta result = r; 149270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // We currently mark three kinds of views: 149370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 1. Menus in the Action Bar 149470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 2. Menus in the Overflow popup. 149570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // 3. The overflow popup button. 149670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (view instanceof ListMenuItemView) { 149770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 2. 149870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // All menus in the popup are of type ListMenuItemView. 149970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU); 150070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } else { 150170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 3. 150270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ViewGroup.LayoutParams lp = view.getLayoutParams(); 150370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (lp instanceof ActionMenuView.LayoutParams && 150470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ((ActionMenuView.LayoutParams) lp).isOverflowButton) { 150570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_OVERFLOW); 150670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } else { 150770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // Mark 1. 150870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // A view is a menu in the Action Bar is it is not the overflow button and of 150970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // its parent is of type ActionMenuView. We can also check if the view is 151070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // instanceof ActionMenuItemView but that will fail for menus using 151170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta // actionProviderClass. 151270114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta ViewParent parent = view.getParent(); 151370114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta while (parent != mViewRoot && parent instanceof ViewGroup) { 151470114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta if (parent instanceof ActionMenuView) { 151570114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta r.setViewType(ViewType.ACTION_BAR_MENU); 151670114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta break; 151770114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 151870114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta parent = parent.getParent(); 151970114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 152070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 152170114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta } 152285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 15233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 15246208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet if (setExtendedInfo) { 15256208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet MarginLayoutParams marginParams = null; 15266208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet LayoutParams params = view.getLayoutParams(); 15276208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet if (params instanceof MarginLayoutParams) { 15286208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams = (MarginLayoutParams) params; 15296208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet } 15306208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet result.setExtendedInfo(view.getBaseline(), 15316208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.leftMargin : 0, 15326208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.topMargin : 0, 15336208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.rightMargin : 0, 15346208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet marginParams != null ? marginParams.bottomMargin : 0); 15356208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet } 15366208081afd488af51d4f7cbf858e2de59d47e4e5Xavier Ducrohet 15373bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return result; 15383bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 15393bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 154070114b33f8054cc38090a2bbd213ebf15abee63dDeepanshu Gupta /* (non-Javadoc) 154141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta * The cookie for menu items are stored in menu item and not in the map from View stored in 154241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta * BridgeContext. 154341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta */ 154441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta private Object getViewKey(View view) { 154541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta BridgeContext context = getContext(); 154641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (!(view instanceof MenuView.ItemView)) { 154741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return context.getViewKey(view); 154841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 154941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta MenuItemImpl menuItem; 155041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (view instanceof ActionMenuItemView) { 155141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((ActionMenuItemView) view).getItemData(); 155241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else if (view instanceof ListMenuItemView) { 155341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((ListMenuItemView) view).getItemData(); 155441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else if (view instanceof IconMenuItemView) { 155541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = ((IconMenuItemView) view).getItemData(); 155641670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } else { 155741670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta menuItem = null; 155841670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 155941670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta if (menuItem instanceof BridgeMenuItemImpl) { 156041670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return ((BridgeMenuItemImpl) menuItem).getViewCookie(); 156141670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 156241670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta 156341670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta return null; 156441670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta } 156541670df819e35f5822cc166db775ed2e9e3dfb7dDeepanshu Gupta 156685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private void invalidateRenderingSize() { 156785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mMeasuredScreenWidth = mMeasuredScreenHeight = -1; 156885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 156985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 1570799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet /** 157185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the status bar with wifi and battery icons. 1572799fe3b371c812a0e94872f896b54afa44e94868Xavier Ducrohet */ 157385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private StatusBar createStatusBar(BridgeContext context, Density density, int direction, 157485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isRtlSupported) throws XmlPullParserException { 157585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta StatusBar statusBar = new StatusBar(context, density, 157685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta direction, isRtlSupported); 157785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta statusBar.setLayoutParams( 157885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta new LinearLayout.LayoutParams( 157985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, mStatusBarSize)); 158085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return statusBar; 158185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1582e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 158385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 158485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the navigation bar with back, home and recent buttons. 158585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * 158685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isRtl true if the current locale is right-to-left 158785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * @param isRtlSupported true is the project manifest declares that the application 158885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * is RTL aware. 158985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 159085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private NavigationBar createNavigationBar(BridgeContext context, Density density, 159185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta boolean isRtl, boolean isRtlSupported) throws XmlPullParserException { 159285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta NavigationBar navigationBar = new NavigationBar(context, 159385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta density, mNavigationBarOrientation, isRtl, 159485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta isRtlSupported); 159585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta if (mNavigationBarOrientation == LinearLayout.VERTICAL) { 159685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, 159785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT)); 159885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } else { 159985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 160085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta mNavigationBarSize)); 1601e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 160285c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return navigationBar; 1603e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet } 1604e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 160585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta private TitleBar createTitleBar(BridgeContext context, Density density, String title) 160685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta throws XmlPullParserException { 160785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta TitleBar titleBar = new TitleBar(context, density, title); 160885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta titleBar.setLayoutParams( 160985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize)); 161085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return titleBar; 161185c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 1612e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet 161385c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta /** 161485c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta * Creates the action bar. Also queries the project callback for missing information. 161585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta */ 1616952c989b307d4b710ee1adba064f663808af9eb3Deepanshu Gupta private ActionBarLayout createActionBar(BridgeContext context, SessionParams params) { 161785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta ActionBarLayout actionBar = new ActionBarLayout(context, params); 161885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta actionBar.setLayoutParams(new LinearLayout.LayoutParams( 161985c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 162085c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return actionBar; 16211392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet } 16221392615c49943383baf51262e2df6975266b4c2fXavier Ducrohet 16233bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet public BufferedImage getImage() { 16243bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet return mImage; 16253bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 16263bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet 1627a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet public boolean isAlphaChannelImage() { 1628a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet return mIsAlphaChannelImage; 1629a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet } 1630a6a38c02bfd3f6a678ac1671f5744b8e439e075aXavier Ducrohet 1631e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet public List<ViewInfo> getViewInfos() { 1632e9a2ea4ac32589b372ec195d8be59391c686a8c6Xavier Ducrohet return mViewInfoList; 16333bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet } 16342d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet 163585c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta public List<ViewInfo> getSystemViewInfos() { 163685c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta return mSystemViewInfoList; 163785c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta } 163885c5ae75ab4b9041bb143f146ef5fc4547686210Deepanshu Gupta 1639ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public Map<String, String> getDefaultProperties(Object viewObject) { 16400fde9af6be75b32a401eafc8904426424e00e70cXavier Ducrohet return getContext().getDefaultPropMap(viewObject); 16412d240967c9bc38cbf69967457b33f953f8826e96Xavier Ducrohet } 1642b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1643ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public void setScene(RenderSession session) { 1644ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet mScene = session; 1645b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 1646b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet 1647ecb67b629266bd616da571c1e391164a4f8c8e93Xavier Ducrohet public RenderSession getSession() { 1648b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet return mScene; 1649b12b63f973ebf8fdc4f36f77dd29bd1bed436609Xavier Ducrohet } 16503bd98986a97e4e1921616a0a86983307e68ceb6cXavier Ducrohet} 1651