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 23891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport com.android.ide.common.rendering.api.HardwareConfig; 24b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog; 25b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderParams; 26b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources; 27b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider; 28891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 29b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 30b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 310a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport com.android.resources.Density; 32b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport com.android.resources.ResourceType; 330a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport com.android.resources.ScreenSize; 34b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 350a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohetimport android.content.res.Configuration; 36fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohetimport android.os.HandlerThread_Delegate; 3796131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohetimport android.os.Looper; 38b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport android.util.DisplayMetrics; 397f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.view.ViewConfiguration_Accessor; 4096131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohetimport android.view.inputmethod.InputMethodManager; 417f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.view.inputmethod.InputMethodManager_Accessor; 42b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 43b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport java.util.concurrent.TimeUnit; 44b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohetimport java.util.concurrent.locks.ReentrantLock; 45b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 46b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet/** 47fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Base class for rendering action. 48fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 49fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * It provides life-cycle methods to init and stop the rendering. 50fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * The most important methods are: 51fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()} 52fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * after the rendering. 53b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 54b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 55b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param <T> the {@link RenderParams} implementation 56b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 57b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 58fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetpublic abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { 59b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 60b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 61b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The current context being rendered. This is set through {@link #acquire(long)} and 62b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link #init(long)}, and unset in {@link #release()}. 63b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 64b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private static BridgeContext sCurrentContext = null; 65b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 66b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private final T mParams; 67b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 68b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private BridgeContext mContext; 69b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 70b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 71b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Creates a renderAction. 72b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 73b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This <b>must</b> be followed by a call to {@link RenderAction#init()}, which act as a 74b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * call to {@link RenderAction#acquire(long)} 75b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 76b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param params the RenderParams. This must be a copy that the action can keep 77b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 78b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 79fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet protected RenderAction(T params) { 80b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mParams = params; 81b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 82b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 83b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 84b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Initializes and acquires the scene, creating various Android objects such as context, 85b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * inflater, and parser. 86b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 87b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 88b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 89b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return whether the scene was prepared 90b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 91b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #acquire(long) 92b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #release() 93b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 94b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Result init(long timeout) { 95b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 96b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // the result. 97b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = acquireLock(timeout); 98b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result != null) { 99b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return result; 100b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 101b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 102891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet HardwareConfig hardwareConfig = mParams.getHardwareConfig(); 103891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 104b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // setup the display Metrics. 105b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet DisplayMetrics metrics = new DisplayMetrics(); 106891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet metrics.densityDpi = metrics.noncompatDensityDpi = 107891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet hardwareConfig.getDensity().getDpiValue(); 1080a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 1090a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.density = metrics.noncompatDensity = 1100a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT; 1110a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 1120a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density; 1130a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 114891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth(); 115891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight(); 116891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi(); 117891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi(); 118b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 119b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet RenderResources resources = mParams.getResources(); 120b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 121b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // build the context 122b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, 1230a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion()); 124b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 125b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet setUp(); 126b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 127b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 128b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 129b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 1300a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 131b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 132b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Prepares the scene for action. 133b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 134b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This call is blocking if another rendering/inflating is currently happening, and will return 135b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * whether the preparation worked. 136b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 137b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The preparation can fail if another rendering took too long and the timeout was elapsed. 138b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 139b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * More than one call to this from the same thread will have no effect and will return 140b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link Result#SUCCESS}. 141b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 142b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * After scene actions have taken place, only one call to {@link #release()} must be 143b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * done. 144b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 145b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 146b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 147b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return whether the scene was prepared 148b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 149b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @see #release() 150b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 151b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if {@link #init(long)} was never called. 152b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 153b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Result acquire(long timeout) { 154b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mContext == null) { 155b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("After scene creation, #init() must be called"); 156b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 157b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 158b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // acquire the lock. if the result is null, lock was just acquired, otherwise, return 159b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // the result. 160b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Result result = acquireLock(timeout); 161b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (result != null) { 162b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return result; 163b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 164b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 165b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet setUp(); 166b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 167b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 168b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 169b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 170b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 171b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Acquire the lock so that the scene can be acted upon. 172b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p> 173b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * This returns null if the lock was just acquired, otherwise it returns 174b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * {@link Result#SUCCESS} if the lock already belonged to that thread, or another 175b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * instance (see {@link Result#getStatus()}) if an error occurred. 176b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 177b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @param timeout the time to wait if another rendering is happening. 178b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return null if the lock was just acquire or another result depending on the state. 179b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 180b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 181b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * the scene. 182b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 183b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private Result acquireLock(long timeout) { 184b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 185b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 186b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet try { 187b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS); 188b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 189b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (acquired == false) { 190b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return ERROR_TIMEOUT.createResult(); 191b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 192b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } catch (InterruptedException e) { 193b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return ERROR_LOCK_INTERRUPTED.createResult(); 194b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 195b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } else { 196b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // This thread holds the lock already. Checks that this wasn't for a different context. 197b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // If this is called by init, mContext will be null and so should sCurrentContext 198b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // anyway 199b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mContext != sCurrentContext) { 200b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("Acquiring different scenes from same thread without releases"); 201b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 202b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return SUCCESS.createResult(); 203b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 204b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 205b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return null; 206b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 207b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 208b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 209b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Cleans up the scene after an action. 210b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 211b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public void release() { 212b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 213b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 214b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // with the use of finally blocks, it is possible to find ourself calling this 215b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // without a successful call to prepareScene. This test makes sure that unlock() will 216b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // not throw IllegalMonitorStateException. 217b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread()) { 218b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet tearDown(); 219b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet lock.unlock(); 220b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 221b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 222b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 223b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 224b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Sets up the session for rendering. 225b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p/> 226b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The counterpart is {@link #tearDown()}. 227b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 228b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private void setUp() { 229b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // make sure the Resources object references the context (and other objects) for this 230b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // scene 231b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.initResources(); 232b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet sCurrentContext = mContext; 233b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 23496131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohet // create an InputMethodManager 23596131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohet InputMethodManager.getInstance(Looper.myLooper()); 23696131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohet 237b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet LayoutLog currentLog = mParams.getLog(); 238b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Bridge.setLog(currentLog); 239b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(this); 240b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setLogger(currentLog); 241b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 242b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 243b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 244b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Tear down the session after rendering. 245b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * <p/> 246b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * The counterpart is {@link #setUp()}. 247b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 248b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet private void tearDown() { 249b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // Make sure to remove static references, otherwise we could not unload the lib 250b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.disposeResources(); 251fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet 252fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet // quit HandlerThread created during this session. 253fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet HandlerThread_Delegate.cleanUp(sCurrentContext); 254fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet 2550a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet // clear the stored ViewConfiguration since the map is per density and not per context. 2567f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet ViewConfiguration_Accessor.clearConfigurations(); 2570a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 25896131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohet // remove the InputMethodManager 2597f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet InputMethodManager_Accessor.resetInstance(); 26096131eef3869f2be1300e1620f5c3874b41bb534Xavier Ducrohet 261b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet sCurrentContext = null; 262b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 263b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet Bridge.setLog(null); 264b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setFrameworkResourceIdProvider(null); 265b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet mContext.getRenderResources().setLogger(null); 266b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 267b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 268b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public static BridgeContext getCurrentContext() { 269b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return sCurrentContext; 270b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 271b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 272b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected T getParams() { 273b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mParams; 274b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 275b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 276b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected BridgeContext getContext() { 277b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mContext; 278b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 279b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 280b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 281b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Returns the log associated with the session. 282b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @return the log or null if there are none. 283b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 284b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public LayoutLog getLog() { 285b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (mParams != null) { 286b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return mParams.getLog(); 287b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 288b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 289b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return null; 290b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 291b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 292b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet /** 293b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * Checks that the lock is owned by the current thread and that the current context is the one 294b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * from this scene. 295b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * 296b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * @throws IllegalStateException if the current context is different than the one owned by 297b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet * the scene, or if {@link #acquire(long)} was not called. 298b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet */ 299b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet protected void checkLock() { 300b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet ReentrantLock lock = Bridge.getLock(); 301b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (lock.isHeldByCurrentThread() == false) { 302b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); 303b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 304b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet if (sCurrentContext != mContext) { 305b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet throw new IllegalStateException("Thread acquired a scene but is rendering a different one"); 306b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 307b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 308b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 3090a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet private Configuration getConfiguration() { 3100a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet Configuration config = new Configuration(); 3110a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 312891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet HardwareConfig hardwareConfig = mParams.getHardwareConfig(); 313891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet 314891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet ScreenSize screenSize = hardwareConfig.getScreenSize(); 3150a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet if (screenSize != null) { 3160a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet switch (screenSize) { 3170a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case SMALL: 3180a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL; 3190a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3200a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case NORMAL: 3210a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL; 3220a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3230a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case LARGE: 3240a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE; 3250a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3260a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet case XLARGE: 3270a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE; 3280a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet break; 3290a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3300a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3310a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 332891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet Density density = hardwareConfig.getDensity(); 3330a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet if (density == null) { 3340a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet density = Density.MEDIUM; 3350a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3360a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 337891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue(); 338891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue(); 3390a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet if (config.screenHeightDp < config.screenWidthDp) { 3400a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.smallestScreenWidthDp = config.screenHeightDp; 3410a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } else { 3420a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.smallestScreenWidthDp = config.screenWidthDp; 3430a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 344908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn config.densityDpi = density.getDpiValue(); 3450a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3460a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet // never run in compat mode: 3470a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.compatScreenWidthDp = config.screenWidthDp; 3480a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet config.compatScreenHeightDp = config.screenHeightDp; 3490a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3500a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet // TODO: fill in more config info. 3510a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3520a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet return config; 3530a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet } 3540a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 3550a49635b171f3ba366b1a7ebf28791c4661829bdXavier Ducrohet 356b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet // --- FrameworkResourceIdProvider methods 357b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet 358b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet @Override 359b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet public Integer getId(ResourceType resType, String resName) { 360b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet return Bridge.getResourceId(resType, resName); 361b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet } 362b0d34f9c99cbd43e8238c5952b19d032f02dd168Xavier Ducrohet} 363