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