1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2010 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage com.android.layoutlib.bridge.impl; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.HardwareConfig; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.RenderParams; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.RenderResources; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.Result; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge; 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.android.BridgeContext; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.Density; 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.ResourceType; 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.ScreenOrientation; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.ScreenSize; 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.res.Configuration; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.HandlerThread_Delegate; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.Looper; 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.DisplayMetrics; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.ViewConfiguration_Accessor; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.inputmethod.InputMethodManager; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.inputmethod.InputMethodManager_Accessor; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.concurrent.TimeUnit; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.concurrent.locks.ReentrantLock; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Base class for rendering action. 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * It provides life-cycle methods to init and stop the rendering. 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The most important methods are: 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()} 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * after the rendering. 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param <T> the {@link RenderParams} implementation 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The current context being rendered. This is set through {@link #acquire(long)} and 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link #init(long)}, and unset in {@link #release()}. 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static BridgeContext sCurrentContext = null; 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final T mParams; 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private BridgeContext mContext; 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates a renderAction. 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p> 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This <b>must</b> be followed by a call to {@link RenderAction#init()}, which act as a 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * call to {@link RenderAction#acquire(long)} 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param params the RenderParams. This must be a copy that the action can keep 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected RenderAction(T params) { 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams = params; 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Initializes and acquires the scene, creating various Android objects such as context, 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * inflater, and parser. 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param timeout the time to wait if another rendering is happening. 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return whether the scene was prepared 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #acquire(long) 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #release() 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public Result init(long timeout) { 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // acquire the lock. if the result is null, lock was just acquired, otherwise, return 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the result. 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Result result = acquireLock(timeout); 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != null) { 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski HardwareConfig hardwareConfig = mParams.getHardwareConfig(); 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // setup the display Metrics. 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DisplayMetrics metrics = new DisplayMetrics(); 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.densityDpi = metrics.noncompatDensityDpi = 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hardwareConfig.getDensity().getDpiValue(); 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.density = metrics.noncompatDensity = 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density; 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth(); 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight(); 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi(); 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi(); 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RenderResources resources = mParams.getResources(); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // build the context 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, 1248930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Gupta mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion(), 1258930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Gupta mParams.isRtlSupported()); 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setUp(); 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return SUCCESS.createResult(); 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Prepares the scene for action. 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p> 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This call is blocking if another rendering/inflating is currently happening, and will return 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * whether the preparation worked. 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The preparation can fail if another rendering took too long and the timeout was elapsed. 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * More than one call to this from the same thread will have no effect and will return 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link Result#SUCCESS}. 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * After scene actions have taken place, only one call to {@link #release()} must be 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * done. 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param timeout the time to wait if another rendering is happening. 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return whether the scene was prepared 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #release() 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @throws IllegalStateException if {@link #init(long)} was never called. 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public Result acquire(long timeout) { 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mContext == null) { 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new IllegalStateException("After scene creation, #init() must be called"); 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // acquire the lock. if the result is null, lock was just acquired, otherwise, return 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the result. 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Result result = acquireLock(timeout); 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != null) { 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setUp(); 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return SUCCESS.createResult(); 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Acquire the lock so that the scene can be acted upon. 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p> 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This returns null if the lock was just acquired, otherwise it returns 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link Result#SUCCESS} if the lock already belonged to that thread, or another 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * instance (see {@link Result#getStatus()}) if an error occurred. 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param timeout the time to wait if another rendering is happening. 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return null if the lock was just acquire or another result depending on the state. 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @throws IllegalStateException if the current context is different than the one owned by 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the scene. 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Result acquireLock(long timeout) { 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ReentrantLock lock = Bridge.getLock(); 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (lock.isHeldByCurrentThread() == false) { 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS); 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (acquired == false) { 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ERROR_TIMEOUT.createResult(); 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (InterruptedException e) { 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ERROR_LOCK_INTERRUPTED.createResult(); 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This thread holds the lock already. Checks that this wasn't for a different context. 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is called by init, mContext will be null and so should sCurrentContext 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // anyway 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mContext != sCurrentContext) { 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new IllegalStateException("Acquiring different scenes from same thread without releases"); 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return SUCCESS.createResult(); 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Cleans up the scene after an action. 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void release() { 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ReentrantLock lock = Bridge.getLock(); 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // with the use of finally blocks, it is possible to find ourself calling this 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // without a successful call to prepareScene. This test makes sure that unlock() will 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // not throw IllegalMonitorStateException. 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (lock.isHeldByCurrentThread()) { 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tearDown(); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lock.unlock(); 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sets up the session for rendering. 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The counterpart is {@link #tearDown()}. 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void setUp() { 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // make sure the Resources object references the context (and other objects) for this 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // scene 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mContext.initResources(); 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sCurrentContext = mContext; 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create an InputMethodManager 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski InputMethodManager.getInstance(); 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LayoutLog currentLog = mParams.getLog(); 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.setLog(currentLog); 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mContext.getRenderResources().setFrameworkResourceIdProvider(this); 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mContext.getRenderResources().setLogger(currentLog); 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Tear down the session after rendering. 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The counterpart is {@link #setUp()}. 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void tearDown() { 25103a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta // The context may be null, if there was an error during init(). 25203a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta if (mContext != null) { 25303a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta // Make sure to remove static references, otherwise we could not unload the lib 25403a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta mContext.disposeResources(); 25503a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta } 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25703a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta if (sCurrentContext != null) { 25803a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta // quit HandlerThread created during this session. 25903a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta HandlerThread_Delegate.cleanUp(sCurrentContext); 26003a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta } 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // clear the stored ViewConfiguration since the map is per density and not per context. 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ViewConfiguration_Accessor.clearConfigurations(); 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // remove the InputMethodManager 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski InputMethodManager_Accessor.resetInstance(); 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sCurrentContext = null; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.setLog(null); 27103a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta if (mContext != null) { 27203a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta mContext.getRenderResources().setFrameworkResourceIdProvider(null); 27303a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta mContext.getRenderResources().setLogger(null); 27403a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta } 27503a057c1af9ca3f125c7924bf0b78da52223d8d3Deepanshu Gupta 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static BridgeContext getCurrentContext() { 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sCurrentContext; 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected T getParams() { 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mParams; 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected BridgeContext getContext() { 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mContext; 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns the log associated with the session. 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return the log or null if there are none. 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public LayoutLog getLog() { 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParams != null) { 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mParams.getLog(); 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Checks that the lock is owned by the current thread and that the current context is the one 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * from this scene. 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @throws IllegalStateException if the current context is different than the one owned by 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the scene, or if {@link #acquire(long)} was not called. 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void checkLock() { 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ReentrantLock lock = Bridge.getLock(); 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (lock.isHeldByCurrentThread() == false) { 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sCurrentContext != mContext) { 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new IllegalStateException("Thread acquired a scene but is rendering a different one"); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Configuration getConfiguration() { 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Configuration config = new Configuration(); 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski HardwareConfig hardwareConfig = mParams.getHardwareConfig(); 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ScreenSize screenSize = hardwareConfig.getScreenSize(); 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (screenSize != null) { 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch (screenSize) { 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case SMALL: 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL; 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case NORMAL: 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL; 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case LARGE: 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE; 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case XLARGE: 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE; 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Density density = hardwareConfig.getDensity(); 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (density == null) { 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski density = Density.MEDIUM; 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue(); 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue(); 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config.screenHeightDp < config.screenWidthDp) { 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = config.screenHeightDp; 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp = config.screenWidthDp; 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.densityDpi = density.getDpiValue(); 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // never run in compat mode: 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.compatScreenWidthDp = config.screenWidthDp; 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.compatScreenHeightDp = config.screenHeightDp; 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ScreenOrientation orientation = hardwareConfig.getOrientation(); 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (orientation != null) { 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch (orientation) { 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case PORTRAIT: 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = Configuration.ORIENTATION_PORTRAIT; 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case LANDSCAPE: 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = Configuration.ORIENTATION_LANDSCAPE; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case SQUARE: 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = Configuration.ORIENTATION_SQUARE; 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation = Configuration.ORIENTATION_UNDEFINED; 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: fill in more config info. 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return config; 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- FrameworkResourceIdProvider methods 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public Integer getId(ResourceType resType, String resName) { 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Bridge.getResourceId(resType, resName); 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 390