RenderSessionImpl.java revision 1b87390c9426c4bc9119829e9375d712dfde11c3
1c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet/* 2c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Copyright (C) 2010 The Android Open Source Project 3c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * 4c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 5c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * you may not use this file except in compliance with the License. 6c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * You may obtain a copy of the License at 7c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * 8c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 9c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * 10c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Unless required by applicable law or agreed to in writing, software 11c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 12c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * See the License for the specific language governing permissions and 14c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * limitations under the License. 15c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 16c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 17c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetpackage com.android.layoutlib.bridge.impl; 18c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND; 2019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION; 2119a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED; 2219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; 2319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN; 2419a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 2519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet 262fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.AdapterBinding; 27891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport com.android.ide.common.rendering.api.HardwareConfig; 2819a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.IAnimationListener; 2919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.ILayoutPullParser; 3019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback; 31bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderParams; 3270552fb92dbc5cb5b1d53b20f92f2a64969a50c4Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 3319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderSession; 342fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.ResourceReference; 3519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceValue; 3619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 3719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status; 3846d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams; 391126422ee1f532d8582a4e3b56dbfe505c15e775Xavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams.RenderingMode; 4046d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohetimport com.android.ide.common.rendering.api.ViewInfo; 41c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport com.android.internal.util.XmlUtils; 422eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 43c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 4401811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; 45c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser; 46891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport com.android.layoutlib.bridge.bars.NavigationBar; 47891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport com.android.layoutlib.bridge.bars.StatusBar; 48bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohetimport com.android.layoutlib.bridge.bars.TitleBar; 491b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Guptaimport com.android.layoutlib.bridge.bars.ActionBarLayout; 502fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeAdapter; 512fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; 524ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Guptaimport com.android.resources.Density; 5335ea7cd4c0c89122fda0b57af20061645082ffb9Xavier Ducrohetimport com.android.resources.ResourceType; 54891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport com.android.resources.ScreenOrientation; 55b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohetimport com.android.util.Pair; 56c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 57bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohetimport org.xmlpull.v1.XmlPullParserException; 58bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 597f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.animation.AnimationThread; 60e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohetimport android.animation.Animator; 612eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.animation.AnimatorInflater; 62e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohetimport android.animation.LayoutTransition; 632b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohetimport android.animation.LayoutTransition.TransitionListener; 64c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.app.Fragment_Delegate; 65c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.graphics.Bitmap; 66c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.graphics.Bitmap_Delegate; 67c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.graphics.Canvas; 68c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.graphics.drawable.Drawable; 69c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.util.DisplayMetrics; 70c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.util.TypedValue; 717f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.view.AttachInfo_Accessor; 727f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.view.BridgeInflater; 736dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohetimport android.view.IWindowManager; 74891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport android.view.IWindowManagerImpl; 756dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohetimport android.view.Surface; 76c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.view.View; 77c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.view.View.MeasureSpec; 7846d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohetimport android.view.ViewGroup; 7901811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohetimport android.view.ViewGroup.LayoutParams; 8005b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohetimport android.view.ViewGroup.MarginLayoutParams; 816dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohetimport android.view.WindowManagerGlobal_Delegate; 822fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.AbsListView; 832fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.AbsSpinner; 842fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.AdapterView; 852fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.ExpandableListView; 86c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.widget.FrameLayout; 87796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbyeimport android.widget.LinearLayout; 882fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.ListView; 8931fd1cf7697ef777b41c7a6a20e37ff5d573d732Xavier Ducrohetimport android.widget.QuickContactBadge; 90c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport android.widget.TabHost; 91796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbyeimport android.widget.TabHost.TabSpec; 9246d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohetimport android.widget.TabWidget; 93c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 945a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohetimport java.awt.AlphaComposite; 95c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport java.awt.Color; 96c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport java.awt.Graphics2D; 97c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport java.awt.image.BufferedImage; 98c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport java.util.ArrayList; 99c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport java.util.List; 100c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport java.util.Map; 101c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 102c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet/** 10319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * Class implementing the render session. 104c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * 10519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * A session is a stateful representation of a layout file. It is initialized with data coming 10619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then 107c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * be done on the layout. 108c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * 109c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 110b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetpublic class RenderSessionImpl extends RenderAction<SessionParams> { 111c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 112c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; 113c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; 114c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 115c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // scene state 11619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet private RenderSession mScene; 117c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private BridgeXmlBlockParser mBlockParser; 118c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private BridgeInflater mInflater; 119ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet private ResourceValue mWindowBackground; 120bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private ViewGroup mViewRoot; 121bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private FrameLayout mContentRoot; 1229eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet private Canvas mCanvas; 1239eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet private int mMeasuredScreenWidth = -1; 1249eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet private int mMeasuredScreenHeight = -1; 125bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private boolean mIsAlphaChannelImage; 126bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private boolean mWindowIsFloating; 12716584225125acba18b74920b902c798dfead0328Xavier Ducrohet 12816584225125acba18b74920b902c798dfead0328Xavier Ducrohet private int mStatusBarSize; 129891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet private int mNavigationBarSize; 130891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; 131bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private int mTitleBarSize; 132bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private int mActionBarSize; 13316584225125acba18b74920b902c798dfead0328Xavier Ducrohet 134c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 135c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // information being returned through the API 136c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private BufferedImage mImage; 1377d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet private List<ViewInfo> mViewInfoList; 1384ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private List<ViewInfo> mSystemViewInfoList; 139c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 140c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private static final class PostInflateException extends Exception { 141c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private static final long serialVersionUID = 1L; 142c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 143c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet public PostInflateException(String message) { 144c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet super(message); 145c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 146c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 147c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 148c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 149c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Creates a layout scene with all the information coming from the layout bridge API. 150c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * <p> 1511b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)}, 1521b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta * which act as a 15319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * call to {@link RenderSessionImpl#acquire(long)} 154c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * 1551b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta * @see Bridge#createSession(SessionParams) 156c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 1571126422ee1f532d8582a4e3b56dbfe505c15e775Xavier Ducrohet public RenderSessionImpl(SessionParams params) { 158b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet super(new SessionParams(params)); 1592eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 1602eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 1612eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet /** 1622eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 1632eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * inflater, and parser. 1642eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * 1652eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 1662eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * 1672eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @return whether the scene was prepared 1682eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * 1692eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @see #acquire(long) 1702eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @see #release() 1712eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet */ 172b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet @Override 17319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result init(long timeout) { 174b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = super.init(timeout); 175b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result.isSuccess() == false) { 1762eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet return result; 1772eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 178c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 179b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet SessionParams params = getParams(); 180b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet BridgeContext context = getContext(); 181c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 182b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet RenderResources resources = getParams().getResources(); 183b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet DisplayMetrics metrics = getContext().getMetrics(); 184c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 18516584225125acba18b74920b902c798dfead0328Xavier Ducrohet // use default of true in case it's not found to use alpha by default 18616584225125acba18b74920b902c798dfead0328Xavier Ducrohet mIsAlphaChannelImage = getBooleanThemeValue(resources, 18716584225125acba18b74920b902c798dfead0328Xavier Ducrohet "windowIsFloating", true /*defaultValue*/); 18816584225125acba18b74920b902c798dfead0328Xavier Ducrohet 189bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", 190bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet true /*defaultValue*/); 1912eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 19216584225125acba18b74920b902c798dfead0328Xavier Ducrohet findBackground(resources); 19316584225125acba18b74920b902c798dfead0328Xavier Ducrohet findStatusBar(resources, metrics); 194bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet findActionBar(resources, metrics); 195891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet findNavigationBar(resources, metrics); 196c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1976dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohet // FIXME: find those out, and possibly add them to the render params 1986dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohet boolean hasNavigationBar = true; 1996dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohet IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(), 2006dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohet metrics, Surface.ROTATION_0, 20180f00c1f2375796dab09bc4ed5b7631c62f7e158John Spurlock hasNavigationBar); 2026dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohet WindowManagerGlobal_Delegate.setWindowManagerService(iwm); 2036dfd0b39a63559999a769f93d5cdb48abe675344Xavier Ducrohet 204c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // build the inflater and parser. 205b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mInflater = new BridgeInflater(context, params.getProjectCallback()); 206b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet context.setBridgeInflater(mInflater); 2072eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 20802d2b5a4031c80bfe1012ce2f4f7b3695762abd9Xavier Ducrohet mBlockParser = new BridgeXmlBlockParser( 20902d2b5a4031c80bfe1012ce2f4f7b3695762abd9Xavier Ducrohet params.getLayoutDescription(), context, false /* platformResourceFlag */); 2102eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 211168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet return SUCCESS.createResult(); 212c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 213c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 214c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 215c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Inflates the layout. 216c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * <p> 2172eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 2182eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * 2192eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 2202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * the scene, or if {@link #init(long)} was not called. 221c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 22219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result inflate() { 2232eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet checkLock(); 2242eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 225c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet try { 226c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 227b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet SessionParams params = getParams(); 228891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 229b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet BridgeContext context = getContext(); 23088db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta boolean isRtl = Bridge.isLocaleRtl(params.getLocale()); 2314ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; 2321b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta ActionBarLayout actionBar = null; 233891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 234abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet // the view group that receives the window background. 235abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet ViewGroup backgroundView = null; 236abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet 237b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mWindowIsFloating || params.isForceNoDecor()) { 238abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); 2394ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mViewRoot.setLayoutDirection(layoutDirection); 240bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } else { 241891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { 242891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet /* 243891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet * This is a special case where the navigation bar is on the right. 244891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet +-------------------------------------------------+---+ 245891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | Status bar (always) | | 246891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet +-------------------------------------------------+ | 247891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | (Layout with background drawable) | | 248891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | +---------------------------------------------+ | | 249891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | | Title/Action bar (optional) | | | 250891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | +---------------------------------------------+ | | 251891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | | Content, vertical extending | | | 252891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | | | | | 253891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | +---------------------------------------------+ | | 254891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet +-------------------------------------------------+---+ 255891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 256891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet So we create a horizontal layout, with the nav bar on the right, 257891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet and the left part is the normal layout below without the nav bar at 258891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet the bottom 259891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet */ 260891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 2614ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 262891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mViewRoot = topLayout; 263891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet topLayout.setOrientation(LinearLayout.HORIZONTAL); 264891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 265891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet try { 2664ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 2674ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported()); 268891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet topLayout.addView(navigationBar); 269891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } catch (XmlPullParserException e) { 270891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 271891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } 272891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } 273891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 274bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet /* 275bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * we're creating the following layout 276bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * 277bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet +-------------------------------------------------+ 278891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | Status bar (always) | 279bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet +-------------------------------------------------+ 280abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | (Layout with background drawable) | 281abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | +---------------------------------------------+ | 282abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | | Title/Action bar (optional) | | 283abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | +---------------------------------------------+ | 284abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | | Content, vertical extending | | 285abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | | | | 286abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet | +---------------------------------------------+ | 287bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet +-------------------------------------------------+ 288891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet | Navigation bar for soft buttons, maybe see above| 289bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet +-------------------------------------------------+ 290bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 291bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet */ 292bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 293b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet LinearLayout topLayout = new LinearLayout(context); 294bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet topLayout.setOrientation(LinearLayout.VERTICAL); 2954ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta topLayout.setLayoutDirection(layoutDirection); 296891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // if we don't already have a view root this is it 297891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (mViewRoot == null) { 298891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mViewRoot = topLayout; 299891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } else { 3004ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta int topLayoutWidth = 3014ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta params.getHardwareConfig().getScreenWidth() - mNavigationBarSize; 302891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 3034ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta topLayoutWidth, LayoutParams.MATCH_PARENT); 304891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet topLayout.setLayoutParams(layoutParams); 305891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 306891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // this is the case of soft buttons + vertical bar. 307891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // this top layout is the first layout in the horizontal layout. see above) 30888db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta if (isRtl && params.isRtlSupported()) { 30988db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta // If RTL is enabled, layoutlib will mirror the layouts. So, add the 31088db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta // topLayout to the right of Navigation Bar and layoutlib will draw it 31188db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta // to the left. 31288db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta mViewRoot.addView(topLayout); 31388db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta } else { 31488db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta // Add the top layout to the left of the Navigation Bar. 31588db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta mViewRoot.addView(topLayout, 0); 31688db0ee2afbae38b53a0527506f0890914a7f115Deepanshu Gupta } 317891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } 318bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 319bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet if (mStatusBarSize > 0) { 320bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // system bar 321bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet try { 3224ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(), 3234ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta layoutDirection, params.isRtlSupported()); 3244ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta topLayout.addView(statusBar); 325bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } catch (XmlPullParserException e) { 326bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 327bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 328bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 329bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 330abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet LinearLayout backgroundLayout = new LinearLayout(context); 331abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet backgroundView = backgroundLayout; 332abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet backgroundLayout.setOrientation(LinearLayout.VERTICAL); 333abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 33435d56c0d67537e56fafebd8edf790026644fe8deDeepanshu Gupta LayoutParams.MATCH_PARENT, 0); 335abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet layoutParams.weight = 1; 336abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet backgroundLayout.setLayoutParams(layoutParams); 337abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet topLayout.addView(backgroundLayout); 338abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet 339abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet 340bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // if the theme says no title/action bar, then the size will be 0 341bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet if (mActionBarSize > 0) { 342bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet try { 3431b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta actionBar = createActionBar(context, params); 344abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet backgroundLayout.addView(actionBar); 3451b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta actionBar.createMenuPopup(); 3461b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta mContentRoot = actionBar.getContentRoot(); 347bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } catch (XmlPullParserException e) { 348bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 349bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 350bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } else if (mTitleBarSize > 0) { 351bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet try { 3524ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta TitleBar titleBar = createTitleBar(context, 353891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet hardwareConfig.getDensity(), params.getAppLabel()); 354abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet backgroundLayout.addView(titleBar); 355bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } catch (XmlPullParserException e) { 356bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 357bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 358bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 359bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 360bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // content frame 3614ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (mContentRoot == null) { 3624ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mContentRoot = new FrameLayout(context); 3634ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta layoutParams = new LinearLayout.LayoutParams( 3644ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta LayoutParams.MATCH_PARENT, 0); 3654ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta layoutParams.weight = 1; 3664ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mContentRoot.setLayoutParams(layoutParams); 3674ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta backgroundLayout.addView(mContentRoot); 3684ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 369bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 370891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (mNavigationBarOrientation == LinearLayout.HORIZONTAL && 371891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mNavigationBarSize > 0) { 372bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // system bar 373bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet try { 3744ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta NavigationBar navigationBar = createNavigationBar(context, 3754ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta hardwareConfig.getDensity(), isRtl, params.isRtlSupported()); 376891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet topLayout.addView(navigationBar); 377bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } catch (XmlPullParserException e) { 378bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 379bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 380bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 381bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 382bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 383c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 384c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // Sets the project callback (custom view loader) to the fragment delegate so that 385c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // it can instantiate the custom Fragment. 386b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Fragment_Delegate.setProjectCallback(params.getProjectCallback()); 387c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 388bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet View view = mInflater.inflate(mBlockParser, mContentRoot); 389c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 3902fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // done with the parser, pop it. 3912fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet context.popParser(); 3922fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 393c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet Fragment_Delegate.setProjectCallback(null); 394c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 395c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // set the AttachInfo on the root view. 3967f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet AttachInfo_Accessor.setAttachInfo(mViewRoot); 397c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 39833758ef8c98efb669c65eb9404b99ee5df09c6b5Xavier Ducrohet // post-inflate process. For now this supports TabHost/TabWidget 399b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet postInflateProcess(view, params.getProjectCallback()); 40033758ef8c98efb669c65eb9404b99ee5df09c6b5Xavier Ducrohet 401c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // get the background drawable 402abc33e014d4490dc993d1453e2589f538dbd7bbeXavier Ducrohet if (mWindowBackground != null && backgroundView != null) { 403b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); 404891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet backgroundView.setBackground(d); 405c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 406c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 40719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(); 408c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } catch (PostInflateException e) { 40919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_INFLATION.createResult(e.getMessage(), e); 410c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } catch (Throwable e) { 411c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // get the real cause of the exception. 412c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet Throwable t = e; 413c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet while (t.getCause() != null) { 414c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet t = t.getCause(); 415c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 416c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 41719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_INFLATION.createResult(t.getMessage(), t); 418c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 419c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 420c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 421c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 422c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Renders the scene. 423c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * <p> 4242eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 4252eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * 4265a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet * @param freshRender whether the render is a new one and should erase the existing bitmap (in 4275a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet * the case where bitmaps are reused). This is typically needed when not playing 4285a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet * animations.) 4295a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet * 4302eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 4312eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 4329eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet * 4331b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta * @see SessionParams#getRenderingMode() 434bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * @see RenderSession#render(long) 435c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 4365a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet public Result render(boolean freshRender) { 4372eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet checkLock(); 4382eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 439b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet SessionParams params = getParams(); 440b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 441c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet try { 442c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (mViewRoot == null) { 44319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_NOT_INFLATED.createResult(); 444c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 445c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 446b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet RenderingMode renderingMode = params.getRenderingMode(); 447891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet HardwareConfig hardwareConfig = params.getHardwareConfig(); 448fb25cae1916da1caf206ede879f07a4f8b61cfecXavier Ducrohet 4499eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet // only do the screen measure when needed. 4509eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet boolean newRenderSize = false; 4519eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet if (mMeasuredScreenWidth == -1) { 4529eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet newRenderSize = true; 453891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mMeasuredScreenWidth = hardwareConfig.getScreenWidth(); 454891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); 4559eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet 4569eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet if (renderingMode != RenderingMode.NORMAL) { 457c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int widthMeasureSpecMode = renderingMode.isHorizExpand() ? 458c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 459c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet : MeasureSpec.EXACTLY; 460c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int heightMeasureSpecMode = renderingMode.isVertExpand() ? 461c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet MeasureSpec.UNSPECIFIED // this lets us know the actual needed size 462c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet : MeasureSpec.EXACTLY; 463c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 464c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // We used to compare the measured size of the content to the screen size but 465c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // this does not work anymore due to the 2 following issues: 466c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // - If the content is in a decor (system bar, title/action bar), the root view 467c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // will not resize even with the UNSPECIFIED because of the embedded layout. 468c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // - If there is no decor, but a dialog frame, then the dialog padding prevents 469c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // comparing the size of the content to the screen frame (as it would not 470c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // take into account the dialog padding). 471c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 472c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // The solution is to first get the content size in a normal rendering, inside 473c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // the decor or the dialog padding. 474c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // Then measure only the content with UNSPECIFIED to see the size difference 475c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // and apply this to the screen size. 476c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 477c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // first measure the full layout, with EXACTLY to get the size of the 478c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // content as it is inside the decor/dialog 479c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet Pair<Integer, Integer> exactMeasure = measureView( 480c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mViewRoot, mContentRoot.getChildAt(0), 481c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 482c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 483c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 484c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // now measure the content only using UNSPECIFIED (where applicable, based on 485c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // the rendering mode). This will give us the size the content needs. 486c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet Pair<Integer, Integer> result = measureView( 487c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mContentRoot, mContentRoot.getChildAt(0), 488c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenWidth, widthMeasureSpecMode, 489c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenHeight, heightMeasureSpecMode); 490c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 491c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // now look at the difference and add what is needed. 4929eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet if (renderingMode.isHorizExpand()) { 493c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int measuredWidth = exactMeasure.getFirst(); 494c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int neededWidth = result.getFirst(); 495c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet if (neededWidth > measuredWidth) { 496c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenWidth += neededWidth - measuredWidth; 4979eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet } 498fb25cae1916da1caf206ede879f07a4f8b61cfecXavier Ducrohet } 499c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 5009eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet if (renderingMode.isVertExpand()) { 501c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int measuredHeight = exactMeasure.getSecond(); 502c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int neededHeight = result.getSecond(); 503c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet if (neededHeight > measuredHeight) { 504c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenHeight += neededHeight - measuredHeight; 5059eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet } 506fb25cae1916da1caf206ede879f07a4f8b61cfecXavier Ducrohet } 507c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 508c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 509c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 510c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet // measure again with the size we need 511c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // This must always be done before the call to layout 512c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet measureView(mViewRoot, null /*measuredView*/, 513c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenWidth, MeasureSpec.EXACTLY, 514c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet mMeasuredScreenHeight, MeasureSpec.EXACTLY); 515c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 516c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // now do the layout. 51716584225125acba18b74920b902c798dfead0328Xavier Ducrohet mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 518c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 51910df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet if (params.isLayoutOnly()) { 52010df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // delete the canvas and image to reset them on the next full rendering 52110df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mImage = null; 52210df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mCanvas = null; 52310df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet } else { 5247f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot); 52510df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet 52610df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // draw the views 52710df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // create the BufferedImage into which the layout will be rendered. 52810df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet boolean newImage = false; 52910df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet if (newRenderSize || mCanvas == null) { 53010df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet if (params.getImageFactory() != null) { 53110df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mImage = params.getImageFactory().getImage( 53210df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mMeasuredScreenWidth, 53310df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mMeasuredScreenHeight); 53410df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet } else { 53510df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mImage = new BufferedImage( 53610df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mMeasuredScreenWidth, 53710df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mMeasuredScreenHeight, 53810df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet BufferedImage.TYPE_INT_ARGB); 53910df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet newImage = true; 54010df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet } 54110df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet 54210df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet if (params.isBgColorOverridden()) { 54310df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // since we override the content, it's the same as if it was a new image. 54410df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet newImage = true; 54510df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet Graphics2D gc = mImage.createGraphics(); 54610df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.setColor(new Color(params.getOverrideBgColor(), true)); 54710df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.setComposite(AlphaComposite.Src); 54810df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); 54910df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.dispose(); 55010df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet } 55110df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet 55210df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // create an Android bitmap around the BufferedImage 55310df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, 554891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet true /*isMutable*/, hardwareConfig.getDensity()); 55510df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet 55610df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // create a Canvas around the Android bitmap 55710df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mCanvas = new Canvas(bitmap); 558891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue()); 5599eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet } 560c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 56110df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet if (freshRender && newImage == false) { 5629eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet Graphics2D gc = mImage.createGraphics(); 5635a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet gc.setComposite(AlphaComposite.Src); 564c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 56510df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.setColor(new Color(0x00000000, true)); 56610df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.fillRect(0, 0, 56710df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mMeasuredScreenWidth, mMeasuredScreenHeight); 56816584225125acba18b74920b902c798dfead0328Xavier Ducrohet 56910df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet // done 57010df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet gc.dispose(); 57110df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet } 57216584225125acba18b74920b902c798dfead0328Xavier Ducrohet 57310df650f0d4bdf086dae9ac29fafd8a1ded06c23Xavier Ducrohet mViewRoot.draw(mCanvas); 5745a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet } 5755a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet 5764ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), false); 577c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 578c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // success! 57919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(); 580c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } catch (Throwable e) { 581c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // get the real cause of the exception. 582c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet Throwable t = e; 583c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet while (t.getCause() != null) { 584c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet t = t.getCause(); 585c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 586c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 58719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 588c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 589c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 590c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 591c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 592c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * Executes {@link View#measure(int, int)} on a given view with the given parameters (used 593c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}. 594c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * 595c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height) 596c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}). 597c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * 598c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @param viewToMeasure the view on which to execute measure(). 599c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @param measuredView if non null, the view to query for its measured width/height. 600c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @param width the width to use in the MeasureSpec. 601c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @param widthMode the MeasureSpec mode to use for the width. 602c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @param height the height to use in the MeasureSpec. 603c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @param heightMode the MeasureSpec mode to use for the height. 604c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet * @return the measured width/height if measuredView is non-null, null otherwise. 605c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet */ 606c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, 607c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int width, int widthMode, int height, int heightMode) { 608c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode); 609c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode); 610c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet viewToMeasure.measure(w_spec, h_spec); 611c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 612c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet if (measuredView != null) { 613c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight()); 614c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet } 615c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 616c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet return null; 617c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet } 618c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet 619c5aeac7f157e3cb9e29ab8c126f74e26493501f5Xavier Ducrohet /** 6202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * Animate an object 6212eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * <p> 6222eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 6232eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * 6242eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 6252eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 626e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 627bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * @see RenderSession#animate(Object, String, boolean, IAnimationListener) 6282eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet */ 62919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result animate(Object targetObject, String animationName, 6302eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet boolean isFrameworkAnimation, IAnimationListener listener) { 6312eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet checkLock(); 6322eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 633b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet BridgeContext context = getContext(); 634b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 6352eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet // find the animation file. 636ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet ResourceValue animationResource = null; 6372eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet int animationId = 0; 6382eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet if (isFrameworkAnimation) { 639b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet animationResource = context.getRenderResources().getFrameworkResource( 64035ea7cd4c0c89122fda0b57af20061645082ffb9Xavier Ducrohet ResourceType.ANIMATOR, animationName); 6412eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet if (animationResource != null) { 642b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName); 6432eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 6442eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } else { 645b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet animationResource = context.getRenderResources().getProjectResource( 64635ea7cd4c0c89122fda0b57af20061645082ffb9Xavier Ducrohet ResourceType.ANIMATOR, animationName); 6472eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet if (animationResource != null) { 648b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet animationId = context.getProjectCallback().getResourceId( 64935ea7cd4c0c89122fda0b57af20061645082ffb9Xavier Ducrohet ResourceType.ANIMATOR, animationName); 6502eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 6512eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 6522eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 6532eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet if (animationResource != null) { 6542eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet try { 655b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Animator anim = AnimatorInflater.loadAnimator(context, animationId); 6562eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet if (anim != null) { 6572eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet anim.setTarget(targetObject); 6582eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 659e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet new PlayAnimationThread(anim, this, animationName, listener).start(); 6602eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 66119a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(); 6622eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 6632eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } catch (Exception e) { 664c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet // get the real cause of the exception. 665c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet Throwable t = e; 666c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet while (t.getCause() != null) { 667c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet t = t.getCause(); 668c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 669c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 67019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_UNKNOWN.createResult(t.getMessage(), t); 6712eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 6722eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 6732eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 67419a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_ANIM_NOT_FOUND.createResult(); 675c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 676c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 677e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet /** 678e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * Insert a new child into an existing parent. 679e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * <p> 680e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 681e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 682e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 683e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 684e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 685bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener) 686e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet */ 68719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml, 688e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet final int index, IAnimationListener listener) { 689c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet checkLock(); 690c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 691b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet BridgeContext context = getContext(); 692b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 693c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet // create a block parser for the XML 69402d2b5a4031c80bfe1012ce2f4f7b3695762abd9Xavier Ducrohet BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( 69502d2b5a4031c80bfe1012ce2f4f7b3695762abd9Xavier Ducrohet childXml, context, false /* platformResourceFlag */); 696c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 697c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet // inflate the child without adding it to the root since we want to control where it'll 698c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet // get added. We do pass the parentView however to ensure that the layoutParams will 699c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet // be created correctly. 700e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); 70102d2b5a4031c80bfe1012ce2f4f7b3695762abd9Xavier Ducrohet blockParser.ensurePopped(); 702c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 703e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet invalidateRenderingSize(); 704e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 705e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (listener != null) { 706e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet new AnimationThread(this, "insertChild", listener) { 707e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 708e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet @Override 70919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result preAnimation() { 710e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet parentView.setLayoutTransition(new LayoutTransition()); 711e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet return addView(parentView, child, index); 712e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 713e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 714e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet @Override 715e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet public void postAnimation() { 716e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet parentView.setLayoutTransition(null); 717e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 718e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet }.start(); 719e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 720e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // always return success since the real status will come through the listener. 72119a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(child); 7229eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet } 7239eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet 724e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // add it to the parentView in the correct location 72519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet Result result = addView(parentView, child, index); 726e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (result.isSuccess() == false) { 727e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet return result; 728e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 729c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 7305a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet result = render(false /*freshRender*/); 731c8aec064f9f304c88f61c8c1aa3d60521b92177aXavier Ducrohet if (result.isSuccess()) { 732e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet result = result.getCopyWithData(child); 733c8aec064f9f304c88f61c8c1aa3d60521b92177aXavier Ducrohet } 734c8aec064f9f304c88f61c8c1aa3d60521b92177aXavier Ducrohet 735c8aec064f9f304c88f61c8c1aa3d60521b92177aXavier Ducrohet return result; 736c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 737c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 738e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet /** 739e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * Adds a given view to a given parent at a given index. 740e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 741e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @param parent the parent to receive the view 742e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @param view the view to add to the parent 743e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @param index the index where to do the add. 744e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 74519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 74619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 747e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * adding views. 748e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet */ 74919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet private Result addView(ViewGroup parent, View view, int index) { 750e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet try { 751e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet parent.addView(view, index); 75219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(); 753e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } catch (UnsupportedOperationException e) { 754e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 75519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 756e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 757e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 758e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 759e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet /** 760e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * Moves a view to a new parent at a given location 761e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * <p> 762e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 763e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 764e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 765e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 766e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 767bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener) 768e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet */ 7692b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet public Result moveChild(final ViewGroup newParentView, final View childView, final int index, 770479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet Map<String, String> layoutParamsMap, final IAnimationListener listener) { 771c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet checkLock(); 772c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 773e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet invalidateRenderingSize(); 774e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 77501811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet LayoutParams layoutParams = null; 776e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (layoutParamsMap != null) { 777e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // need to create a new LayoutParams object for the new parent. 7782b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet layoutParams = newParentView.generateLayoutParams( 779e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet new BridgeLayoutParamsMapAttributes(layoutParamsMap)); 780e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 7819eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet 7822b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // get the current parent of the view that needs to be moved. 7832b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet final ViewGroup previousParent = (ViewGroup) childView.getParent(); 7842b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 785e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (listener != null) { 786e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet final LayoutParams params = layoutParams; 78701811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet 788479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // there is no support for animating views across layouts, so in case the new and old 789479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // parent views are different we fake the animation through a no animation thread. 790479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (previousParent != newParentView) { 791479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet new Thread("not animated moveChild") { 792479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet @Override 793479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet public void run() { 794479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, 795479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet params); 796479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (result.isSuccess() == false) { 797479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet listener.done(result); 798479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 799479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 800479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // ready to do the work, acquire the scene. 801479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet result = acquire(250); 802479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (result.isSuccess() == false) { 803479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet listener.done(result); 804479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet return; 805479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 806479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 807479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet try { 8085a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet result = render(false /*freshRender*/); 809479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (result.isSuccess()) { 810479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet listener.onNewFrame(RenderSessionImpl.this.getSession()); 811479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 812479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } finally { 813479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet release(); 814479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 815479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 816479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet listener.done(result); 8172b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 818479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet }.start(); 819479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } else { 820479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet new AnimationThread(this, "moveChild", listener) { 8212b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 822479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet @Override 823479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet public Result preAnimation() { 824479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // set up the transition for the parent. 825479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet LayoutTransition transition = new LayoutTransition(); 826479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet previousParent.setLayoutTransition(transition); 8277550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet 828479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // tweak the animation durations and start delays (to match the duration of 829479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // animation playing just before). 830479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // Note: Cannot user Animation.setDuration() directly. Have to set it 831479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // on the LayoutTransition. 832479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet transition.setDuration(LayoutTransition.DISAPPEARING, 100); 833479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // CHANGE_DISAPPEARING plays after DISAPPEARING 834479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100); 83501811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet 836479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100); 837479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 838479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100); 839479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet // CHANGE_APPEARING plays after CHANGE_APPEARING 840479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet transition.setStartDelay(LayoutTransition.APPEARING, 100); 841479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 842479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet transition.setDuration(LayoutTransition.APPEARING, 100); 843479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 844479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet return moveView(previousParent, newParentView, childView, index, params); 845479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 846479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 847479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet @Override 848479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet public void postAnimation() { 849479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet previousParent.setLayoutTransition(null); 850479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet newParentView.setLayoutTransition(null); 851479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 852479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet }.start(); 853479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 854e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 855e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // always return success since the real status will come through the listener. 85619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(layoutParams); 857c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 858c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 8592b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet Result result = moveView(previousParent, newParentView, childView, index, layoutParams); 860e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (result.isSuccess() == false) { 861e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet return result; 862e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 863c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 8645a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet result = render(false /*freshRender*/); 86501811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet if (layoutParams != null && result.isSuccess()) { 866e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet result = result.getCopyWithData(layoutParams); 86701811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet } 86801811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet 86901811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet return result; 870c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 871c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 872e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet /** 873e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * Moves a View from its current parent to a new given parent at a new given location, with 874e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * an optional new {@link LayoutParams} instance 875e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 8762b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet * @param previousParent the previous parent, still owning the child at the time of the call. 8772b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet * @param newParent the new parent 878479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet * @param movedView the view to move 879e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @param index the new location in the new parent 880e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @param params an option (can be null) {@link LayoutParams} instance. 881e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 88219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 88319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 884e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * adding views. 885e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet */ 886479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet private Result moveView(ViewGroup previousParent, final ViewGroup newParent, 887479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet final View movedView, final int index, final LayoutParams params) { 8889eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet try { 8892b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // check if there is a transition on the previousParent. 890479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet LayoutTransition previousTransition = previousParent.getLayoutTransition(); 891479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (previousTransition != null) { 8927550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // in this case there is an animation. This means we have to wait for the child's 8937550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // parent reference to be null'ed out so that we can add it to the new parent. 8947550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // It is technically removed right before the DISAPPEARING animation is done (if 8957550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // the animation of this type is not null, otherwise it's after which is impossible 8967550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // to handle). 8977550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // Because there is no move animation, if the new parent is the same as the old 8987550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before 8997550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // adding the child or the child will appear in its new location before the 9007550ec1d8e526c4ae8c0bb08b06e1b6e799eacecXavier Ducrohet // other children have made room for it. 9012b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 9022b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // add a listener to the transition to be notified of the actual removal. 903479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet previousTransition.addTransitionListener(new TransitionListener() { 904479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet private int mChangeDisappearingCount = 0; 9052b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 90646d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 9072b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet public void startTransition(LayoutTransition transition, ViewGroup container, 9082b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet View view, int transitionType) { 909479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 910479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet mChangeDisappearingCount++; 911479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 9122b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 913e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 91446d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 9152b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet public void endTransition(LayoutTransition transition, ViewGroup container, 9162b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet View view, int transitionType) { 917479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) { 918479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet mChangeDisappearingCount--; 919479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet } 920479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet 921479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet if (transitionType == LayoutTransition.CHANGE_DISAPPEARING && 922479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet mChangeDisappearingCount == 0) { 9232b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // add it to the parentView in the correct location 9242b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet if (params != null) { 925479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet newParent.addView(movedView, index, params); 9262b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } else { 927479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet newParent.addView(movedView, index); 9282b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 9292b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 9302b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 9312b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet }); 9322b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 9332b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // remove the view from the current parent. 934479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet previousParent.removeView(movedView); 9352b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 9362b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // and return since adding the view to the new parent is done in the listener. 9372b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet return SUCCESS.createResult(); 938e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } else { 9392b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // standard code with no animation. pretty simple. 940479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet previousParent.removeView(movedView); 941e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 9422b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet // add it to the parentView in the correct location 9432b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet if (params != null) { 944479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet newParent.addView(movedView, index, params); 9452b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } else { 946479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet newParent.addView(movedView, index); 9472b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 9482b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet 9492b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet return SUCCESS.createResult(); 9502b9c38ab62abc8d5b2f956e961087f259caf25ffXavier Ducrohet } 9519eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet } catch (UnsupportedOperationException e) { 9529eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 95319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 954c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 955e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 956e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 957e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet /** 958e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * Removes a child from its current parent. 959e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * <p> 960e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * {@link #acquire(long)} must have been called before this. 961e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 962e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 963e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 964e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 965bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet * @see RenderSession#removeChild(Object, IAnimationListener) 966e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet */ 96719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result removeChild(final View childView, IAnimationListener listener) { 968e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet checkLock(); 969c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 9709eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet invalidateRenderingSize(); 9719eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet 972e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet final ViewGroup parent = (ViewGroup) childView.getParent(); 973e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 974e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (listener != null) { 975e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet new AnimationThread(this, "moveChild", listener) { 976e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 977e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet @Override 97819a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Result preAnimation() { 979e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet parent.setLayoutTransition(new LayoutTransition()); 980e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet return removeView(parent, childView); 981e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 982e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 983e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet @Override 984e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet public void postAnimation() { 985e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet parent.setLayoutTransition(null); 986e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 987e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet }.start(); 988e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 989e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // always return success since the real status will come through the listener. 99019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(); 991e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 992e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 99319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet Result result = removeView(parent, childView); 994e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet if (result.isSuccess() == false) { 995e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet return result; 996e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 997e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 9985a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet return render(false /*freshRender*/); 9992eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet } 10002eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 10012eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet /** 1002e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * Removes a given view from its current parent. 1003e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 1004e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * @param view the view to remove from its parent 1005e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * 100619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * @return a Result with {@link Status#SUCCESS} or 100719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet * {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support 1008e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet * adding views. 1009e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet */ 101019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet private Result removeView(ViewGroup parent, View view) { 1011e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet try { 1012e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet parent.removeView(view); 101319a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return SUCCESS.createResult(); 1014e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } catch (UnsupportedOperationException e) { 1015e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet // looks like this is a view class that doesn't support children manipulation! 101619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet return ERROR_VIEWGROUP_NO_CHILDREN.createResult(); 1017e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 1018e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet } 1019e1179ea065392485a6e3bf1e28a1242179cd48b0Xavier Ducrohet 10202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet 102116584225125acba18b74920b902c798dfead0328Xavier Ducrohet private void findBackground(RenderResources resources) { 1022b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (getParams().isBgColorOverridden() == false) { 102301b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet mWindowBackground = resources.findItemInTheme("windowBackground", 102401b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet true /*isFrameworkAttr*/); 102516584225125acba18b74920b902c798dfead0328Xavier Ducrohet if (mWindowBackground != null) { 102616584225125acba18b74920b902c798dfead0328Xavier Ducrohet mWindowBackground = resources.resolveResValue(mWindowBackground); 102716584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 102816584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 102916584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 1030c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1031891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet private boolean hasSoftwareButtons() { 1032891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet return getParams().getHardwareConfig().hasSoftwareButtons(); 103316584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 1034c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 103516584225125acba18b74920b902c798dfead0328Xavier Ducrohet private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { 1036891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet boolean windowFullscreen = getBooleanThemeValue(resources, 1037891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet "windowFullscreen", false /*defaultValue*/); 103816584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1039891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (windowFullscreen == false && mWindowIsFloating == false) { 1040891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // default value 1041891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; 104216584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1043891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // get the real value 1044891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 1045891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet "status_bar_height"); 104616584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1047891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (value != null) { 1048891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("status_bar_height", 1049891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet value.getValue(), true /*requireUnit*/); 1050891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (typedValue != null) { 1051891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // compute the pixel value based on the display metrics 1052891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mStatusBarSize = (int)typedValue.getDimension(metrics); 105316584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 105416584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 105516584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 105616584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 105716584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1058bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet private void findActionBar(RenderResources resources, DisplayMetrics metrics) { 1059bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet if (mWindowIsFloating) { 1060bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet return; 106116584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 106216584225125acba18b74920b902c798dfead0328Xavier Ducrohet 106316584225125acba18b74920b902c798dfead0328Xavier Ducrohet boolean windowActionBar = getBooleanThemeValue(resources, 106416584225125acba18b74920b902c798dfead0328Xavier Ducrohet "windowActionBar", true /*defaultValue*/); 106516584225125acba18b74920b902c798dfead0328Xavier Ducrohet 106616584225125acba18b74920b902c798dfead0328Xavier Ducrohet // if there's a value and it's false (default is true) 106716584225125acba18b74920b902c798dfead0328Xavier Ducrohet if (windowActionBar) { 1068c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1069c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // default size of the window title bar 1070bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT; 1071c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1072c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // get value from the theme. 107301b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet ResourceValue value = resources.findItemInTheme("actionBarSize", 107401b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet true /*isFrameworkAttr*/); 1075c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1076c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // resolve it 107716584225125acba18b74920b902c798dfead0328Xavier Ducrohet value = resources.resolveResValue(value); 1078c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1079c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (value != null) { 1080c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // get the numerical value, if available 108104ce81113107d2bfa0b8248b13145b4cf24cb943Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(), 108204ce81113107d2bfa0b8248b13145b4cf24cb943Xavier Ducrohet true /*requireUnit*/); 1083c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (typedValue != null) { 1084c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // compute the pixel value based on the display metrics 1085bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet mActionBarSize = (int)typedValue.getDimension(metrics); 1086c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1087c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1088bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } else { 1089bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // action bar overrides title bar so only look for this one if action bar is hidden 1090bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet boolean windowNoTitle = getBooleanThemeValue(resources, 1091bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet "windowNoTitle", false /*defaultValue*/); 1092c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1093bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet if (windowNoTitle == false) { 109416584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1095bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // default size of the window title bar 1096bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT; 109716584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1098bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // get value from the theme. 109901b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet ResourceValue value = resources.findItemInTheme("windowTitleSize", 110001b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet true /*isFrameworkAttr*/); 110116584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1102bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // resolve it 1103bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet value = resources.resolveResValue(value); 1104c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1105bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet if (value != null) { 1106bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // get the numerical value, if available 110704ce81113107d2bfa0b8248b13145b4cf24cb943Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("windowTitleSize", 110804ce81113107d2bfa0b8248b13145b4cf24cb943Xavier Ducrohet value.getValue(), true /*requireUnit*/); 1109bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet if (typedValue != null) { 1110bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet // compute the pixel value based on the display metrics 1111bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet mTitleBarSize = (int)typedValue.getDimension(metrics); 1112bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 111316584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 111416584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 1115bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 111616584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 111716584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 111816584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1119891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { 1120891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (hasSoftwareButtons() && mWindowIsFloating == false) { 1121c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1122c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // default value 1123891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mNavigationBarSize = 48; // ?? 1124891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 1125891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet HardwareConfig hardwareConfig = getParams().getHardwareConfig(); 1126891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 1127891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet boolean barOnBottom = true; 1128891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 1129891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { 1130891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // compute the dp of the screen. 1131891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet int shortSize = hardwareConfig.getScreenHeight(); 1132891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 1133891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // compute in dp 1134891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue(); 1135891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 1136891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (shortSizeDp < 600) { 1137891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // 0-599dp: "phone" UI with bar on the side 1138891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet barOnBottom = false; 1139891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } else { 1140891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet // 600+dp: "tablet" UI with bar on the bottom 1141891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet barOnBottom = true; 1142891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } 1143891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } 1144891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 1145891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet if (barOnBottom) { 1146891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mNavigationBarOrientation = LinearLayout.HORIZONTAL; 1147891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } else { 1148891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mNavigationBarOrientation = LinearLayout.VERTICAL; 1149891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet } 1150c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1151d1d6fafc7fc63543b10552dadf202dd6fa40fe6bXavier Ducrohet // get the real value 115235ea7cd4c0c89122fda0b57af20061645082ffb9Xavier Ducrohet ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, 1153891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); 115416584225125acba18b74920b902c798dfead0328Xavier Ducrohet 1155c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (value != null) { 1156891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", 115704ce81113107d2bfa0b8248b13145b4cf24cb943Xavier Ducrohet value.getValue(), true /*requireUnit*/); 1158c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (typedValue != null) { 1159c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // compute the pixel value based on the display metrics 1160891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet mNavigationBarSize = (int)typedValue.getDimension(metrics); 1161c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1162c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 116316584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 116416584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 116516584225125acba18b74920b902c798dfead0328Xavier Ducrohet 116601b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet /** 116701b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * Looks for a attribute in the current theme. The attribute is in the android 116801b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * namespace. 116901b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * 117001b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * @param resources the render resources 117101b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * @param name the name of the attribute 117201b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * @param defaultValue the default value. 117301b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet * @return the value of the attribute or the default one if not found. 117401b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet */ 117516584225125acba18b74920b902c798dfead0328Xavier Ducrohet private boolean getBooleanThemeValue(RenderResources resources, 117616584225125acba18b74920b902c798dfead0328Xavier Ducrohet String name, boolean defaultValue) { 117716584225125acba18b74920b902c798dfead0328Xavier Ducrohet 117816584225125acba18b74920b902c798dfead0328Xavier Ducrohet // get the title bar flag from the current theme. 117901b6c755dbcf24e71192dc44757e2eea2a426091Xavier Ducrohet ResourceValue value = resources.findItemInTheme(name, true /*isFrameworkAttr*/); 118016584225125acba18b74920b902c798dfead0328Xavier Ducrohet 118116584225125acba18b74920b902c798dfead0328Xavier Ducrohet // because it may reference something else, we resolve it. 118216584225125acba18b74920b902c798dfead0328Xavier Ducrohet value = resources.resolveResValue(value); 1183c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 118416584225125acba18b74920b902c798dfead0328Xavier Ducrohet // if there's no value, return the default. 118516584225125acba18b74920b902c798dfead0328Xavier Ducrohet if (value == null || value.getValue() == null) { 118616584225125acba18b74920b902c798dfead0328Xavier Ducrohet return defaultValue; 1187c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1188c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 118916584225125acba18b74920b902c798dfead0328Xavier Ducrohet return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); 1190c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1191c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1192c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 1193c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Post process on a view hierachy that was just inflated. 1194c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the 1195c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically 1196c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * based on the content of the {@link FrameLayout}. 1197c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * @param view the root view to process. 1198c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * @param projectCallback callback to the project. 1199c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 1200c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private void postInflateProcess(View view, IProjectCallback projectCallback) 1201c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet throws PostInflateException { 1202c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (view instanceof TabHost) { 1203c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet setupTabHost((TabHost)view, projectCallback); 120431fd1cf7697ef777b41c7a6a20e37ff5d573d732Xavier Ducrohet } else if (view instanceof QuickContactBadge) { 120531fd1cf7697ef777b41c7a6a20e37ff5d573d732Xavier Ducrohet QuickContactBadge badge = (QuickContactBadge) view; 120631fd1cf7697ef777b41c7a6a20e37ff5d573d732Xavier Ducrohet badge.setImageToDefault(); 12072fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else if (view instanceof AdapterView<?>) { 12082fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // get the view ID. 12092fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int id = view.getId(); 12102fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12112fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet BridgeContext context = getContext(); 12122fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12132fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // get a ResourceReference from the integer ID. 12142fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ResourceReference listRef = context.resolveId(id); 12152fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12162fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (listRef != null) { 12172fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet SessionParams params = getParams(); 12182fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet AdapterBinding binding = params.getAdapterBindings().get(listRef); 12192fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12202fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // if there was no adapter binding, trying to get it from the call back. 12212fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (binding == null) { 12222fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet binding = params.getProjectCallback().getAdapterBinding(listRef, 12232fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet context.getViewKey(view), view); 12242fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12252fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12262fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (binding != null) { 12272fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12282fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view instanceof AbsListView) { 12292fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) && 12302fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet view instanceof ListView) { 12312fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ListView list = (ListView) view; 12322fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12332fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet boolean skipCallbackParser = false; 12342fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12352fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int count = binding.getHeaderCount(); 12362fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet for (int i = 0 ; i < count ; i++) { 12372fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 12382fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet binding.getHeaderAt(i), 12392fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet list, false /*attachToRoot*/, skipCallbackParser); 12402fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (pair.getFirst() != null) { 12412fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet list.addHeaderView(pair.getFirst()); 12422fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12432fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12442fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet skipCallbackParser |= pair.getSecond(); 12452fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12462fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12472fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet count = binding.getFooterCount(); 12482fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet for (int i = 0 ; i < count ; i++) { 12492fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Pair<View, Boolean> pair = context.inflateView( 12502fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet binding.getFooterAt(i), 12512fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet list, false /*attachToRoot*/, skipCallbackParser); 12522fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (pair.getFirst() != null) { 12532fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet list.addFooterView(pair.getFirst()); 12542fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12552fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12562fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet skipCallbackParser |= pair.getSecond(); 12572fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12582fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12592fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12602fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view instanceof ExpandableListView) { 12612fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ((ExpandableListView) view).setAdapter( 12622fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet new FakeExpandableAdapter( 12632fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet listRef, binding, params.getProjectCallback())); 12642fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else { 12652fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ((AbsListView) view).setAdapter( 12662fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet new FakeAdapter( 12672fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet listRef, binding, params.getProjectCallback())); 12682fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12692fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else if (view instanceof AbsSpinner) { 12702fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ((AbsSpinner) view).setAdapter( 12712fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet new FakeAdapter( 12722fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet listRef, binding, params.getProjectCallback())); 12732fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12742fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 12752fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1276c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } else if (view instanceof ViewGroup) { 1277c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet ViewGroup group = (ViewGroup)view; 1278c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet final int count = group.getChildCount(); 1279c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet for (int c = 0 ; c < count ; c++) { 1280c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet View child = group.getChildAt(c); 1281c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet postInflateProcess(child, projectCallback); 1282c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1283c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1284c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1285c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1286c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 1287c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * Sets up a {@link TabHost} object. 1288c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * @param tabHost the TabHost to setup. 1289c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * @param projectCallback The project callback object to access the project R class. 1290c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet * @throws PostInflateException 1291c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 1292c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback) 1293c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet throws PostInflateException { 1294c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // look for the TabWidget, and the FrameLayout. They have their own specific names 1295c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet View v = tabHost.findViewById(android.R.id.tabs); 1296c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1297c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (v == null) { 1298c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet throw new PostInflateException( 1299c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n"); 1300c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1301c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1302c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if ((v instanceof TabWidget) == false) { 1303c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet throw new PostInflateException(String.format( 1304c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet "TabHost requires a TabWidget with id \"android:id/tabs\".\n" + 1305c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName())); 1306c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1307c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1308c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet v = tabHost.findViewById(android.R.id.tabcontent); 1309c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1310c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (v == null) { 1311c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty) 1312c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet throw new PostInflateException( 1313c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\"."); 1314c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1315c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1316c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if ((v instanceof FrameLayout) == false) { 1317c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet throw new PostInflateException(String.format( 1318c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" + 1319c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName())); 1320c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1321c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1322c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet FrameLayout content = (FrameLayout)v; 1323c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1324c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // now process the content of the framelayout and dynamically create tabs for it. 1325c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet final int count = content.getChildCount(); 1326c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1327c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // this must be called before addTab() so that the TabHost searches its TabWidget 1328c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet // and FrameLayout. 1329c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet tabHost.setup(); 1330c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1331796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye if (count == 0) { 1332796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye // Create a dummy child to get a single tab 1333796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label", 1334796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details)) 1335796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye .setContent(new TabHost.TabContentFactory() { 133646d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 1337796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye public View createTabContent(String tag) { 1338b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return new LinearLayout(getContext()); 1339796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye } 1340796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye }); 1341796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye tabHost.addTab(spec); 1342796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye return; 1343796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye } else { 1344796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye // for each child of the framelayout, add a new TabSpec 1345796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye for (int i = 0 ; i < count ; i++) { 1346796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye View child = content.getChildAt(i); 1347796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye String tabSpec = String.format("tab_spec%d", i+1); 1348796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye int id = child.getId(); 1349b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id); 1350796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye String name; 1351796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye if (resource != null) { 1352b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet name = resource.getSecond(); 1353796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye } else { 1354796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye name = String.format("Tab %d", i+1); // default name if id is unresolved. 1355796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye } 1356796992a942f3508a15ee62d34d6c7ec5de045d83Tor Norbye tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id)); 1357c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1358c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1359c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1360c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 13614ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta /** 13624ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the 13634ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * bounds of all the views. 13644ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * 13654ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param view the root View 13664ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param offset an offset for the view bounds. 13674ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 13684ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 13694ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * content frame. 13704ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * 13714ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @return {@code ViewInfo} containing the bounds of the view and it children otherwise. 13724ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta */ 13734ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private ViewInfo visit(View view, int offset, boolean setExtendedInfo, 13744ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta boolean isContentFrame) { 13754ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta ViewInfo result = createViewInfo(view, offset, setExtendedInfo, isContentFrame); 1376bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 13774ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (view instanceof ViewGroup) { 13784ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta ViewGroup group = ((ViewGroup) view); 13794ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result.setChildren(visitAllChildren(group, isContentFrame ? 0 : offset, 13804ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta setExtendedInfo, isContentFrame)); 13814ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 13824ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return result; 13834ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 1384bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 13854ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta /** 13864ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo} 13871b87390c9426c4bc9119829e9375d712dfde11c3Deepanshu Gupta * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with 13884ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * the children of the {@code mContentRoot}. 13894ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * 13904ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param viewGroup the root View 13914ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param offset an offset from the top for the content view frame. 13924ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object. 13934ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the 13944ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * content frame. {@code false} if the {@code ViewInfo} to be created is 13954ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * part of the system decor. 13964ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta */ 13974ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset, 13984ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta boolean setExtendedInfo, boolean isContentFrame) { 13994ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (viewGroup == null) { 14004ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return null; 1401bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 1402bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 14034ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (!isContentFrame) { 14044ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta offset += viewGroup.getTop(); 14054ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 1406bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 14074ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta int childCount = viewGroup.getChildCount(); 14084ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (viewGroup == mContentRoot) { 14094ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta List<ViewInfo> childrenWithoutOffset = new ArrayList<ViewInfo>(childCount); 14104ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta List<ViewInfo> childrenWithOffset = new ArrayList<ViewInfo>(childCount); 14114ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta for (int i = 0; i < childCount; i++) { 14124ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta ViewInfo[] childViewInfo = visitContentRoot(viewGroup.getChildAt(i), offset, 141305b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet setExtendedInfo); 14144ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta childrenWithoutOffset.add(childViewInfo[0]); 14154ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta childrenWithOffset.add(childViewInfo[1]); 1416bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 14174ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mViewInfoList = childrenWithOffset; 14184ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return childrenWithoutOffset; 14194ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } else { 14204ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta List<ViewInfo> children = new ArrayList<ViewInfo>(childCount); 14214ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta for (int i = 0; i < childCount; i++) { 14224ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo, 14234ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta isContentFrame)); 14244ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 14254ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return children; 1426bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 14274ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 1428bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet 14294ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta /** 14304ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the 14314ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * bounds of all the views. It returns two {@code ViewInfo} objects with the same children, 14324ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * one with the {@code offset} and other without the {@code offset}. The offset is needed to 14334ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * get the right bounds if the {@code ViewInfo} hierarchy is accessed from 14344ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the 14354ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * offset is not needed. 14364ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * 14374ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at 14384ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * index 1 is with the offset. 14394ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta */ 14404ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private ViewInfo[] visitContentRoot(View view, int offset, boolean setExtendedInfo) { 14414ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta ViewInfo[] result = new ViewInfo[2]; 14424ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (view == null) { 14434ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return result; 14444ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 14454ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta 14464ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result[0] = createViewInfo(view, 0, setExtendedInfo, true); 14474ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result[1] = createViewInfo(view, offset, setExtendedInfo, true); 14484ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (view instanceof ViewGroup) { 14494ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta List<ViewInfo> children = visitAllChildren((ViewGroup) view, 0, setExtendedInfo, true); 14504ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result[0].setChildren(children); 14514ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result[1].setChildren(children); 14524ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 14534ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return result; 1454bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet } 1455c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 1456c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet /** 14574ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children 14584ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not 14594ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * set. 14604ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param offset an offset for the view bounds. Used only if view is part of the content frame. 1461c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet */ 14624ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private ViewInfo createViewInfo(View view, int offset, boolean setExtendedInfo, 14634ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta boolean isContentFrame) { 1464c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet if (view == null) { 1465c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet return null; 1466c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1467c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 14684ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta ViewInfo result; 14694ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (isContentFrame) { 14704ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result = new ViewInfo(view.getClass().getName(), 14714ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta getContext().getViewKey(view), 14724ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta view.getLeft(), view.getTop() + offset, view.getRight(), 14734ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta view.getBottom() + offset, view, view.getLayoutParams()); 14744ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta 14754ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } else { 14764ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta result = new SystemViewInfo(view.getClass().getName(), 14774ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta getContext().getViewKey(view), 14784ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta view.getLeft(), view.getTop(), view.getRight(), 14794ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta view.getBottom(), view, view.getLayoutParams()); 14804ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 1481c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 148205b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet if (setExtendedInfo) { 148305b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet MarginLayoutParams marginParams = null; 148405b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet LayoutParams params = view.getLayoutParams(); 148505b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet if (params instanceof MarginLayoutParams) { 148605b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet marginParams = (MarginLayoutParams) params; 148705b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet } 148805b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet result.setExtendedInfo(view.getBaseline(), 148905b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet marginParams != null ? marginParams.leftMargin : 0, 149005b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet marginParams != null ? marginParams.topMargin : 0, 149105b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet marginParams != null ? marginParams.rightMargin : 0, 149205b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet marginParams != null ? marginParams.bottomMargin : 0); 149305b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet } 149405b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet 1495c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet return result; 1496c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1497c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 14984ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private void invalidateRenderingSize() { 14994ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mMeasuredScreenWidth = mMeasuredScreenHeight = -1; 15004ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 15014ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta 1502bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet /** 15034ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Creates the status bar with wifi and battery icons. 1504bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet */ 15054ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private StatusBar createStatusBar(BridgeContext context, Density density, int direction, 15064ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta boolean isRtlSupported) throws XmlPullParserException { 15074ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta StatusBar statusBar = new StatusBar(context, density, 15084ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta direction, isRtlSupported); 15094ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta statusBar.setLayoutParams( 15104ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta new LinearLayout.LayoutParams( 15114ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta LayoutParams.MATCH_PARENT, mStatusBarSize)); 15124ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return statusBar; 15134ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 15147d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet 15154ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta /** 15164ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Creates the navigation bar with back, home and recent buttons. 15174ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * 15184ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param isRtl true if the current locale is right-to-left 15194ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * @param isRtlSupported true is the project manifest declares that the application 15204ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * is RTL aware. 15214ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta */ 15224ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private NavigationBar createNavigationBar(BridgeContext context, Density density, 15234ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta boolean isRtl, boolean isRtlSupported) throws XmlPullParserException { 15244ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta NavigationBar navigationBar = new NavigationBar(context, 15254ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta density, mNavigationBarOrientation, isRtl, 15264ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta isRtlSupported); 15274ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta if (mNavigationBarOrientation == LinearLayout.VERTICAL) { 15284ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, 15294ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta LayoutParams.MATCH_PARENT)); 15304ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } else { 15314ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 15324ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta mNavigationBarSize)); 15337d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet } 15344ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return navigationBar; 15357d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet } 15367d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet 15374ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private TitleBar createTitleBar(BridgeContext context, Density density, String title) 15384ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta throws XmlPullParserException { 15394ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta TitleBar titleBar = new TitleBar(context, density, title); 15404ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta titleBar.setLayoutParams( 15414ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize)); 15424ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return titleBar; 15434ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 15447d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet 15454ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta /** 15464ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta * Creates the action bar. Also queries the project callback for missing information. 15474ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta */ 15484ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta private ActionBarLayout createActionBar(BridgeContext context, SessionParams params) 15494ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta throws XmlPullParserException { 15504ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta ActionBarLayout actionBar = new ActionBarLayout(context, params); 15514ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta actionBar.setLayoutParams(new LinearLayout.LayoutParams( 15524ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 15534ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return actionBar; 15549eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet } 15559eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet 1556c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet public BufferedImage getImage() { 1557c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet return mImage; 1558c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1559c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet 156016584225125acba18b74920b902c798dfead0328Xavier Ducrohet public boolean isAlphaChannelImage() { 156116584225125acba18b74920b902c798dfead0328Xavier Ducrohet return mIsAlphaChannelImage; 156216584225125acba18b74920b902c798dfead0328Xavier Ducrohet } 156316584225125acba18b74920b902c798dfead0328Xavier Ducrohet 15647d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet public List<ViewInfo> getViewInfos() { 15657d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet return mViewInfoList; 1566c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet } 1567cf52390eee4c9ae792ef63af1528b2e71b33a04fXavier Ducrohet 15684ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta public List<ViewInfo> getSystemViewInfos() { 15694ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta return mSystemViewInfoList; 15704ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta } 15714ccc4bd54f85d86818f61d728c6361d2003ddd8eDeepanshu Gupta 157219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public Map<String, String> getDefaultProperties(Object viewObject) { 1573b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return getContext().getDefaultPropMap(viewObject); 1574cf52390eee4c9ae792ef63af1528b2e71b33a04fXavier Ducrohet } 1575c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 157619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public void setScene(RenderSession session) { 157719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet mScene = session; 1578c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 1579c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet 158019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet public RenderSession getSession() { 1581c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet return mScene; 1582c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet } 1583c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet} 1584