RenderAction.java revision 0a49635b171f3ba366b1a7ebf28791c4661829bd
1b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet/* 2b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Copyright (C) 2010 The Android Open Source Project 3b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 4b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 5b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * you may not use this file except in compliance with the License. 6b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * You may obtain a copy of the License at 7b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 8b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 9b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 10b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Unless required by applicable law or agreed to in writing, software 11b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 12b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * See the License for the specific language governing permissions and 14b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * limitations under the License. 15b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 16b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 17b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetpackage com.android.layoutlib.bridge.impl; 18b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 19b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED; 20b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT; 21b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 22b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 23b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog; 24b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderParams; 25b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 26b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 27b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider; 28b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 29b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 300a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport com.android.resources.Density; 31b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.resources.ResourceType; 320a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport com.android.resources.ScreenSize; 33b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 340a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport android.content.res.Configuration; 35fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohetimport android.os.HandlerThread_Delegate; 36b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport android.util.DisplayMetrics; 370a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport android.view.ViewConfiguration; 38b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 39b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport java.util.concurrent.TimeUnit; 40b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport java.util.concurrent.locks.ReentrantLock; 41b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 42b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet/** 43fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Base class for rendering action. 44fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 45fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * It provides life-cycle methods to init and stop the rendering. 46fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * The most important methods are: 47fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()} 48fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * after the rendering. 49b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 50b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 51b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param <T> the {@link RenderParams} implementation 52b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 53b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 54fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetpublic abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { 55b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 56b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 57b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The current context being rendered. This is set through {@link #acquire(long)} and 58b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link #init(long)}, and unset in {@link #release()}. 59b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 60b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private static BridgeContext sCurrentContext = null; 61b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 62b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private final T mParams; 63b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 64b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private BridgeContext mContext; 65b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 66b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 67b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Creates a renderAction. 68b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 69b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This <b>must</b> be followed by a call to {@link RenderAction#init()}, which act as a 70b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * call to {@link RenderAction#acquire(long)} 71b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 72b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param params the RenderParams. This must be a copy that the action can keep 73b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 74b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 75fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet protected RenderAction(T params) { 76b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mParams = params; 77b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 78b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 79b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 80b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 81b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * inflater, and parser. 82b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 83b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 84b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 85b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return whether the scene was prepared 86b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 87b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #acquire(long) 88b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #release() 89b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 90b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Result init(long timeout) { 91b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 92b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // the result. 93b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = acquireLock(timeout); 94b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result != null) { 95b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return result; 96b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 97b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 98b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // setup the display Metrics. 99b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet DisplayMetrics metrics = new DisplayMetrics(); 100b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.densityDpi = mParams.getDensity().getDpiValue(); 1010a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 1020a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.density = metrics.noncompatDensity = 1030a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT; 1040a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 1050a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density; 1060a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 1070a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.widthPixels = metrics.noncompatWidthPixels = mParams.getScreenWidth(); 1080a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.heightPixels = metrics.noncompatHeightPixels = mParams.getScreenHeight(); 1090a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.xdpi = metrics.noncompatXdpi = mParams.getXdpi(); 1100a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.ydpi = metrics.noncompatYdpi = mParams.getYdpi(); 111b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 112b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet RenderResources resources = mParams.getResources(); 113b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 114b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // build the context 115b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, 1160a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion()); 117b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 118b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet setUp(); 119b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 120b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 121b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 122b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 1230a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 124b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 125b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Prepares the scene for action. 126b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 127b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This call is blocking if another rendering/inflating is currently happening, and will return 128b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * whether the preparation worked. 129b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 130b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The preparation can fail if another rendering took too long and the timeout was elapsed. 131b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 132b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * More than one call to this from the same thread will have no effect and will return 133b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link Result#SUCCESS}. 134b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 135b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * After scene actions have taken place, only one call to {@link #release()} must be 136b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * done. 137b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 138b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 139b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 140b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return whether the scene was prepared 141b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 142b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #release() 143b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 144b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if {@link #init(long)} was never called. 145b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 146b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Result acquire(long timeout) { 147b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mContext == null) { 148b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("After scene creation, #init() must be called"); 149b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 150b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 151b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 152b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // the result. 153b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = acquireLock(timeout); 154b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result != null) { 155b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return result; 156b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 157b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 158b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet setUp(); 159b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 160b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 161b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 162b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 163b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 164b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Acquire the lock so that the scene can be acted upon. 165b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 166b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This returns null if the lock was just acquired, otherwise it returns 167b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link Result#SUCCESS} if the lock already belonged to that thread, or another 168b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * instance (see {@link Result#getStatus()}) if an error occurred. 169b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 170b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 171b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return null if the lock was just acquire or another result depending on the state. 172b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 173b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 174b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * the scene. 175b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 176b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private Result acquireLock(long timeout) { 177b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 178b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 179b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet try { 180b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS); 181b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 182b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (acquired == false) { 183b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return ERROR_TIMEOUT.createResult(); 184b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 185b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } catch (InterruptedException e) { 186b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return ERROR_LOCK_INTERRUPTED.createResult(); 187b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 188b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } else { 189b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // This thread holds the lock already. Checks that this wasn't for a different context. 190b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // If this is called by init, mContext will be null and so should sCurrentContext 191b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // anyway 192b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mContext != sCurrentContext) { 193b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("Acquiring different scenes from same thread without releases"); 194b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 195b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 196b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 197b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 198b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return null; 199b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 200b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 201b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 202b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Cleans up the scene after an action. 203b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 204b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public void release() { 205b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 206b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 207b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // with the use of finally blocks, it is possible to find ourself calling this 208b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // without a successful call to prepareScene. This test makes sure that unlock() will 209b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // not throw IllegalMonitorStateException. 210b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread()) { 211b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet tearDown(); 212b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet lock.unlock(); 213b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 214b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 215b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 216b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 217b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Sets up the session for rendering. 218b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p/> 219b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The counterpart is {@link #tearDown()}. 220b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 221b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private void setUp() { 222b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // make sure the Resources object references the context (and other objects) for this 223b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // scene 224b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.initResources(); 225b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet sCurrentContext = mContext; 226b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 227b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet LayoutLog currentLog = mParams.getLog(); 228b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Bridge.setLog(currentLog); 229b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(this); 230b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setLogger(currentLog); 231b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 232b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 233b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 234b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Tear down the session after rendering. 235b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p/> 236b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The counterpart is {@link #setUp()}. 237b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 238b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private void tearDown() { 239b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // Make sure to remove static references, otherwise we could not unload the lib 240b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.disposeResources(); 241fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet 242fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet // quit HandlerThread created during this session. 243fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet HandlerThread_Delegate.cleanUp(sCurrentContext); 244fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet 2450a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet // clear the stored ViewConfiguration since the map is per density and not per context. 2460a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet ViewConfiguration.sConfigurations.clear(); 2470a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 248b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet sCurrentContext = null; 249b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 250b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Bridge.setLog(null); 251b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(null); 252b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setLogger(null); 253b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 254b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 255b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public static BridgeContext getCurrentContext() { 256b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return sCurrentContext; 257b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 258b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 259b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected T getParams() { 260b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mParams; 261b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 262b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 263b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected BridgeContext getContext() { 264b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mContext; 265b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 266b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 267b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 268b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Returns the log associated with the session. 269b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return the log or null if there are none. 270b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 271b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public LayoutLog getLog() { 272b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mParams != null) { 273b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mParams.getLog(); 274b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 275b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 276b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return null; 277b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 278b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 279b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 280b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Checks that the lock is owned by the current thread and that the current context is the one 281b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * from this scene. 282b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 283b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 284b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 285b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 286b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected void checkLock() { 287b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 288b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 289b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); 290b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 291b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (sCurrentContext != mContext) { 292b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("Thread acquired a scene but is rendering a different one"); 293b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 294b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 295b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 2960a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet private Configuration getConfiguration() { 2970a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet Configuration config = new Configuration(); 2980a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 2990a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet ScreenSize screenSize = mParams.getConfigScreenSize(); 3000a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet if (screenSize != null) { 3010a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet switch (screenSize) { 3020a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case SMALL: 3030a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL; 3040a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3050a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case NORMAL: 3060a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL; 3070a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3080a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case LARGE: 3090a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE; 3100a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3110a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case XLARGE: 3120a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE; 3130a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3140a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3150a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3160a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3170a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet Density density = mParams.getDensity(); 3180a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet if (density == null) { 3190a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet density = Density.MEDIUM; 3200a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3210a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3220a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenWidthDp = mParams.getScreenWidth() / density.getDpiValue(); 3230a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenHeightDp = mParams.getScreenHeight() / density.getDpiValue(); 3240a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet if (config.screenHeightDp < config.screenWidthDp) { 3250a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.smallestScreenWidthDp = config.screenHeightDp; 3260a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } else { 3270a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.smallestScreenWidthDp = config.screenWidthDp; 3280a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3290a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3300a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet // never run in compat mode: 3310a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.compatScreenWidthDp = config.screenWidthDp; 3320a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.compatScreenHeightDp = config.screenHeightDp; 3330a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3340a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet // TODO: fill in more config info. 3350a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3360a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet return config; 3370a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3380a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3390a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 340b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // --- FrameworkResourceIdProvider methods 341b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 342b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet @Override 343b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Integer getId(ResourceType resType, String resName) { 344b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return Bridge.getResourceId(resType, resName); 345b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 346b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet} 347