RenderAction.java revision fb93ce9684120a36862b5b5e67b1865a652907e9
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; 30b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.resources.ResourceType; 31b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 32fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohetimport android.os.HandlerThread_Delegate; 33b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport android.util.DisplayMetrics; 34b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 35b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport java.util.concurrent.TimeUnit; 36b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport java.util.concurrent.locks.ReentrantLock; 37b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 38b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet/** 39fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Base class for rendering action. 40fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 41fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * It provides life-cycle methods to init and stop the rendering. 42fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * The most important methods are: 43fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()} 44fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * after the rendering. 45b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 46b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 47b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param <T> the {@link RenderParams} implementation 48b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 49b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 50fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetpublic abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { 51b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 52b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 53b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The current context being rendered. This is set through {@link #acquire(long)} and 54b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link #init(long)}, and unset in {@link #release()}. 55b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 56b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private static BridgeContext sCurrentContext = null; 57b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 58b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private final T mParams; 59b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 60b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private BridgeContext mContext; 61b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 62b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 63b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Creates a renderAction. 64b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 65b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This <b>must</b> be followed by a call to {@link RenderAction#init()}, which act as a 66b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * call to {@link RenderAction#acquire(long)} 67b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 68b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param params the RenderParams. This must be a copy that the action can keep 69b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 70b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 71fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet protected RenderAction(T params) { 72b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mParams = params; 73b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 74b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 75b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 76b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 77b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * inflater, and parser. 78b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 79b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 80b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 81b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return whether the scene was prepared 82b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 83b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #acquire(long) 84b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #release() 85b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 86b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Result init(long timeout) { 87b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 88b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // the result. 89b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = acquireLock(timeout); 90b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result != null) { 91b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return result; 92b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 93b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 94b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // setup the display Metrics. 95b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet DisplayMetrics metrics = new DisplayMetrics(); 96b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.densityDpi = mParams.getDensity().getDpiValue(); 97b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.density = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT; 98b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.scaledDensity = metrics.density; 99b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.widthPixels = mParams.getScreenWidth(); 100b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.heightPixels = mParams.getScreenHeight(); 101b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.xdpi = mParams.getXdpi(); 102b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet metrics.ydpi = mParams.getYdpi(); 103b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 104b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet RenderResources resources = mParams.getResources(); 105b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 106b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // build the context 107b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, 108b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mParams.getProjectCallback(), mParams.getTargetSdkVersion()); 109b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 110b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet setUp(); 111b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 112b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 113b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 114b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 115b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 116b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Prepares the scene for action. 117b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 118b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This call is blocking if another rendering/inflating is currently happening, and will return 119b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * whether the preparation worked. 120b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 121b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The preparation can fail if another rendering took too long and the timeout was elapsed. 122b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 123b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * More than one call to this from the same thread will have no effect and will return 124b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link Result#SUCCESS}. 125b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 126b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * After scene actions have taken place, only one call to {@link #release()} must be 127b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * done. 128b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 129b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 130b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 131b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return whether the scene was prepared 132b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 133b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #release() 134b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 135b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if {@link #init(long)} was never called. 136b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 137b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Result acquire(long timeout) { 138b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mContext == null) { 139b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("After scene creation, #init() must be called"); 140b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 141b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 142b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 143b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // the result. 144b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = acquireLock(timeout); 145b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result != null) { 146b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return result; 147b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 148b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 149b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet setUp(); 150b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 151b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 152b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 153b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 154b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 155b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Acquire the lock so that the scene can be acted upon. 156b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 157b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This returns null if the lock was just acquired, otherwise it returns 158b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link Result#SUCCESS} if the lock already belonged to that thread, or another 159b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * instance (see {@link Result#getStatus()}) if an error occurred. 160b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 161b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 162b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return null if the lock was just acquire or another result depending on the state. 163b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 164b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 165b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * the scene. 166b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 167b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private Result acquireLock(long timeout) { 168b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 169b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 170b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet try { 171b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS); 172b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 173b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (acquired == false) { 174b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return ERROR_TIMEOUT.createResult(); 175b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 176b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } catch (InterruptedException e) { 177b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return ERROR_LOCK_INTERRUPTED.createResult(); 178b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 179b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } else { 180b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // This thread holds the lock already. Checks that this wasn't for a different context. 181b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // If this is called by init, mContext will be null and so should sCurrentContext 182b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // anyway 183b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mContext != sCurrentContext) { 184b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("Acquiring different scenes from same thread without releases"); 185b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 186b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 187b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 188b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 189b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return null; 190b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 191b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 192b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 193b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Cleans up the scene after an action. 194b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 195b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public void release() { 196b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 197b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 198b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // with the use of finally blocks, it is possible to find ourself calling this 199b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // without a successful call to prepareScene. This test makes sure that unlock() will 200b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // not throw IllegalMonitorStateException. 201b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread()) { 202b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet tearDown(); 203b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet lock.unlock(); 204b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 205b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 206b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 207b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 208b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Sets up the session for rendering. 209b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p/> 210b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The counterpart is {@link #tearDown()}. 211b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 212b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private void setUp() { 213b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // make sure the Resources object references the context (and other objects) for this 214b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // scene 215b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.initResources(); 216b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet sCurrentContext = mContext; 217b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 218b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet LayoutLog currentLog = mParams.getLog(); 219b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Bridge.setLog(currentLog); 220b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(this); 221b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setLogger(currentLog); 222b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 223b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 224b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 225b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Tear down the session after rendering. 226b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p/> 227b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The counterpart is {@link #setUp()}. 228b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 229b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private void tearDown() { 230b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // Make sure to remove static references, otherwise we could not unload the lib 231b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.disposeResources(); 232fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet 233fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet // quit HandlerThread created during this session. 234fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet HandlerThread_Delegate.cleanUp(sCurrentContext); 235fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet 236b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet sCurrentContext = null; 237b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 238b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Bridge.setLog(null); 239b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(null); 240b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setLogger(null); 241b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 242b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 243b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public static BridgeContext getCurrentContext() { 244b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return sCurrentContext; 245b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 246b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 247b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected T getParams() { 248b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mParams; 249b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 250b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 251b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected BridgeContext getContext() { 252b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mContext; 253b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 254b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 255b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 256b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Returns the log associated with the session. 257b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return the log or null if there are none. 258b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 259b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public LayoutLog getLog() { 260b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mParams != null) { 261b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mParams.getLog(); 262b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 263b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 264b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return null; 265b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 266b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 267b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 268b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Checks that the lock is owned by the current thread and that the current context is the one 269b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * from this scene. 270b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 271b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 272b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 273b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 274b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected void checkLock() { 275b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 276b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 277b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); 278b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 279b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (sCurrentContext != mContext) { 280b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("Thread acquired a scene but is rendering a different one"); 281b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 282b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 283b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 284b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // --- FrameworkResourceIdProvider methods 285b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 286b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet @Override 287b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Integer getId(ResourceType resType, String resName) { 288b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return Bridge.getResourceId(resType, resName); 289b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 290b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet} 291