ViewRoot.java revision ba87e3e6c985e7175152993b5efcc7dd2f0e1c93
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodCallback; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodSession; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Point; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PorterDuff; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Region; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.*; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AndroidRuntimeException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.DisplayMetrics; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View.MeasureSpec; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputConnection; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.Scroller; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.Manifest; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.AudioManager; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.egl.*; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.microedition.khronos.opengles.*; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static javax.microedition.khronos.opengles.GL10.*; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The top of a view hierarchy, implementing the needed protocol between View 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the WindowManager. This is for the most part an internal implementation 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * detail of {@link WindowManagerImpl}. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@SuppressWarnings({"EmptyCatchBlock"}) 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class ViewRoot extends Handler implements ViewParent, 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View.AttachInfo.Callbacks { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ViewRoot"; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DBG = false; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings({"ConstantConditionalExpression"}) 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean LOCAL_LOGV = false ? Config.LOGD : Config.LOGV; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @noinspection PointlessBooleanExpression*/ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG_DRAW = false || LOCAL_LOGV; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG_LAYOUT = false || LOCAL_LOGV; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG_INPUT_RESIZE = false || LOCAL_LOGV; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG_ORIENTATION = false || LOCAL_LOGV; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG_TRACKBALL = false || LOCAL_LOGV; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG_IMF = false || LOCAL_LOGV; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean WATCH_POINTER = false; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean PROFILE_DRAWING = false; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean PROFILE_LAYOUT = false; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // profiles real fps (times between draws) and displays the result 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean SHOW_FPS = false; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // used by SHOW_FPS 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int sDrawTime; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Maximum time we allow the user to roll the trackball enough to generate 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a key event, before resetting the counters. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MAX_TRACKBALL_DELAY = 250; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static long sInstanceCount = 0; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static IWindowSession sWindowSession; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final Object mStaticInit = new Object(); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static boolean mInitialized = false; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>(); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mLastTrackballTime = 0; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TrackballAxis mTrackballAxisX = new TrackballAxis(); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TrackballAxis mTrackballAxisY = new TrackballAxis(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] mTmpLocation = new int[2]; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputMethodCallback mInputMethodCallback; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SparseArray<Object> mPendingEvents = new SparseArray<Object>(); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mPendingEventSeq = 0; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Thread mThread; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowLeaked mLocation; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowManager.LayoutParams mWindowAttributes = new WindowManager.LayoutParams(); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final W mWindow; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mView; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mFocusedView; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mRealFocusedView; // this is not set to null in touch mode 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mViewVisibility; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAppVisible = true; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Region mTransparentRegion; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Region mPreviousTransparentRegion; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mWidth; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mHeight; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect mDirty; // will be a graphics.Region soon 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View.AttachInfo mAttachInfo; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mTempRect; // used in the transaction to not thrash the heap. 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mVisRect; // used to retrieve visible rect of focused view. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Point mVisPoint; // used to retrieve global offset of focused view. 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mTraversalScheduled; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWillDrawSoon; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mLayoutRequested; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mFirst; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mReportNextDraw; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mFullRedrawNeeded; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mNewSurfaceNeeded; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mHasHadWindowFocus; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mLastWasImTarget; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWindowAttributesChanged = false; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These can be accessed by any thread, must be protected with a lock. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Surface mSurface; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAdded; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAddedTouchMode; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*package*/ int mAddNesting; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These are accessed by multiple threads. 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mWinFrame; // frame given by window manager. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mPendingVisibleInsets = new Rect(); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mPendingContentInsets = new Rect(); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new ViewTreeObserver.InternalInsetsInfo(); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mScrollMayChange; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSoftInputMode; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mLastScrolledFocus; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mScrollY; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCurScrollY; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Scroller mScroller; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10 mEgl; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLDisplay mEglDisplay; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLContext mEglContext; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGLSurface mEglSurface; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GL11 mGL; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Canvas mGlCanvas; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mUseGL; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mGlWanted; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewConfiguration mViewConfiguration; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link #playSoundEffect(int)} 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AudioManager mAudioManager; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final float mDensity; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ViewRoot(Context context) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ++sInstanceCount; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Initialize the statics when this class is first instantiated. This is 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // done here instead of in the static block because Zygote does not 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allow the spawning of threads. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStaticInit) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mInitialized) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.getInstance(context); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession = IWindowManager.Stub.asInterface( 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("window")) 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .openSession(imm.getClient(), imm.getInputContext()); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInitialized = true; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = Thread.currentThread(); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation = new WindowLeaked(null); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.fillInStackTrace(); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = -1; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = -1; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDirty = new Rect(); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempRect = new Rect(); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVisRect = new Rect(); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVisPoint = new Point(); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWinFrame = new Rect(); 222ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mWindow = new W(this, context); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodCallback = new InputMethodCallback(this); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViewVisibility = View.GONE; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTransparentRegion = new Region(); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreviousTransparentRegion = new Region(); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirst = true; // true for the first time the view is added 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSurface = new Surface(); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdded = false; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, this); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViewConfiguration = ViewConfiguration.get(context); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDensity = context.getResources().getDisplayMetrics().density; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project --sInstanceCount; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static long getInstanceCount() { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sInstanceCount; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // FIXME for perf testing only 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mProfile = false; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call this to profile the next traversal call. 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * FIXME for perf testing only. Remove eventually 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void profile() { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProfile = true; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether we are in touch mode. Calling this method triggers an IPC 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call and should be avoided whenever possible. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True, if the device is in touch mode, false otherwise. 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static boolean isInTouchMode() { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInitialized) { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sWindowSession.getInTouchMode(); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initializeGL() { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initializeGLInner(); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err = mEgl.eglGetError(); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != EGL10.EGL_SUCCESS) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // give-up on using GL 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project destroyGL(); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlWanted = false; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initializeGLInner() { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final EGL10 egl = (EGL10) EGLContext.getEGL(); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl = egl; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get to the default display. 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglDisplay = eglDisplay; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We can now initialize EGL for that display 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] version = new int[2]; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project egl.eglInitialize(eglDisplay, version); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Specify a configuration for our opengl session 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and grab the first configuration that matches is 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] configSpec = { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_RED_SIZE, 5, 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_GREEN_SIZE, 6, 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_BLUE_SIZE, 5, 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_DEPTH_SIZE, 0, 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NONE 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final EGLConfig[] configs = new EGLConfig[1]; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] num_config = new int[1]; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project egl.eglChooseConfig(eglDisplay, configSpec, configs, 1, num_config); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final EGLConfig config = configs[0]; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create an OpenGL ES context. This must be done only once, an 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OpenGL context is a somewhat heavy object. 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final EGLContext context = egl.eglCreateContext(eglDisplay, config, 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NO_CONTEXT, null); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglContext = context; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create an EGL surface we can render into. 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final EGLSurface surface = egl.eglCreateWindowSurface(eglDisplay, config, mHolder, null); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglSurface = surface; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Before we can issue GL commands, we need to make sure 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the context is current and bound to a surface. 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project egl.eglMakeCurrent(eglDisplay, surface, surface, context); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get to the appropriate GL interface. 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is simply done by casting the GL context to either 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * GL10 or GL11. 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GL11 gl = (GL11) context.getGL(); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGL = gl; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlCanvas = new Canvas(gl); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseGL = true; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void destroyGL() { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inform skia that the context is gone 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeAbandonGlCaches(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglDestroyContext(mEglDisplay, mEglContext); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglTerminate(mEglDisplay); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglContext = null; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglSurface = null; 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEglDisplay = null; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl = null; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlCanvas = null; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGL = null; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseGL = false; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkEglErrors() { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseGL) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err = mEgl.eglGetError(); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != EGL10.EGL_SUCCESS) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // something bad has happened revert to 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // normal rendering. 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project destroyGL(); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != EGL11.EGL_CONTEXT_LOST) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we'll try again if it was context lost 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlWanted = false; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We have one child 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setView(View view, WindowManager.LayoutParams attrs, 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View panelParentView) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView == null) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributes.copyFrom(attrs); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSoftInputMode = attrs.softInputMode; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributesChanged = true; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView = view; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mRootView = view; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (panelParentView != null) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mPanelParentWindowToken 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = panelParentView.getApplicationWindowToken(); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdded = true; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; /* = WindowManagerImpl.ADD_OKAY; */ 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Schedule the first layout -before- adding to the window 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // manager, to make sure we do the relayout before receiving 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // any other events from the system. 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res = sWindowSession.add(mWindow, attrs, 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getHostVisibility(), mAttachInfo.mContentInsets); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdded = false; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView = null; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mRootView = null; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unscheduleTraversals(); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Adding window failed", e); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingContentInsets.set(mAttachInfo.mContentInsets); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingVisibleInsets.set(0, 0, 0, 0); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v("ViewRoot", "Added window " + mWindow); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res < WindowManagerImpl.ADD_OKAY) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView = null; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mRootView = null; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdded = false; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unscheduleTraversals(); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (res) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_BAD_APP_TOKEN: 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN: 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new WindowManagerImpl.BadTokenException( 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window -- token " + attrs.token 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " is not valid; is your activity running?"); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_NOT_APP_TOKEN: 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new WindowManagerImpl.BadTokenException( 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window -- token " + attrs.token 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " is not for an application"); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_APP_EXITING: 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new WindowManagerImpl.BadTokenException( 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window -- app for token " + attrs.token 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " is exiting"); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_DUPLICATE_ADD: 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new WindowManagerImpl.BadTokenException( 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window -- window " + mWindow 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " has already been added"); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_STARTING_NOT_NEEDED: 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Silently ignore -- we would have just removed it 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // right away, anyway. 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_MULTIPLE_SINGLETON: 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new WindowManagerImpl.BadTokenException( 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window " + mWindow + 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " -- another window of this type already exists"); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManagerImpl.ADD_PERMISSION_DENIED: 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new WindowManagerImpl.BadTokenException( 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window " + mWindow + 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " -- permission denied for this window type"); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unable to add window -- unknown error code " + res); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.assignParent(this); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAddedTouchMode = (res&WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE) != 0; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAppVisible = (res&WindowManagerImpl.ADD_FLAG_APP_VISIBLE) != 0; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getView() { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mView; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowLeaked getLocation() { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLocation; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributes.copyFrom(attrs); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newView) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSoftInputMode = attrs.softInputMode; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributesChanged = true; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void handleAppVisibility(boolean visible) { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAppVisible != visible) { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAppVisible = visible; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void handleGetNewSurface() { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNewSurfaceNeeded = true; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFullRedrawNeeded = true; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLayout() { 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutRequested = true; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isLayoutRequested() { 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLayoutRequested; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void invalidateChild(View child, Rect dirty) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "Invalidate child: " + dirty); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurScrollY != 0) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempRect.set(dirty); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempRect.offset(0, -mCurScrollY); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirty = mTempRect; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDirty.union(dirty); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mWillDrawSoon) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ViewParent getParent() { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateChild(null, dirty); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child != mView) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("child is not mine, honest!"); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: don't apply scroll offset, because we want to know its 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // visibility in the virtual canvas being given to the view hierarchy. 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.intersect(0, 0, mWidth, mHeight); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void bringChildToFront(View child) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleTraversals() { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTraversalScheduled) { 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTraversalScheduled = true; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEmptyMessage(DO_TRAVERSAL); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unscheduleTraversals() { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTraversalScheduled) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTraversalScheduled = false; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeMessages(DO_TRAVERSAL); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getHostVisibility() { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAppVisible ? mView.getVisibility() : View.GONE; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void performTraversals() { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache mView since it is used so much below... 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View host = mView; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("======================================"); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("performTraversals"); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.debug(); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (host == null || !mAdded) 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTraversalScheduled = false; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWillDrawSoon = true; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean windowResizesToFitContent = false; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean fullRedrawNeeded = mFullRedrawNeeded; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean newSurface = false; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = mWindowAttributes; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int desiredWindowWidth; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int desiredWindowHeight; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidthMeasureSpec; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeightMeasureSpec; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View.AttachInfo attachInfo = mAttachInfo; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int viewVisibility = getHostVisibility(); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean viewVisibilityChanged = mViewVisibility != viewVisibility 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mNewSurfaceNeeded; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams params = null; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWindowAttributesChanged) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributesChanged = false; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params = lp; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirst) { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullRedrawNeeded = true; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutRequested = true; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Display d = new Display(0); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project desiredWindowWidth = d.getWidth(); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project desiredWindowHeight = d.getHeight(); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For the very first time, tell the view hierarchy that it 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is attached to the window. Note that at this point the surface 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // object is not initialized to its backing store, but soon it 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // will be (assuming the window is visible). 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mSurface = mSurface; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mHasWindowFocus = false; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mWindowVisibility = viewVisibility; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mRecomputeGlobalAttributes = false; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mKeepScreenOn = false; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewVisibilityChanged = false; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.dispatchAttachedToWindow(attachInfo, 0); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getRunQueue().executeActions(attachInfo.mHandler); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project desiredWindowWidth = mWinFrame.width(); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project desiredWindowHeight = mWinFrame.height(); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_ORIENTATION) Log.v("ViewRoot", 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "View " + host + " resized to: " + mWinFrame); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullRedrawNeeded = true; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutRequested = true; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project windowResizesToFitContent = true; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewVisibilityChanged) { 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mWindowVisibility = viewVisibility; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.dispatchWindowVisibilityChanged(viewVisibility); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseGL) { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project destroyGL(); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewVisibility == View.GONE) { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // After making a window gone, we will count it as being 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // shown for the first time the next time it gets focus. 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasHadWindowFocus = false; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean insetsChanged = false; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLayoutRequested) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirst) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.fitSystemWindows(mAttachInfo.mContentInsets); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure touch mode code executes by setting cached value 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to opposite of the added touch mode. 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mInTouchMode = !mAddedTouchMode; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ensureTouchModeLocally(mAddedTouchMode); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAttachInfo.mContentInsets.equals(mPendingContentInsets)) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mContentInsets.set(mPendingContentInsets); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.fitSystemWindows(mAttachInfo.mContentInsets); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project insetsChanged = true; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: " 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mAttachInfo.mContentInsets); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAttachInfo.mVisibleInsets.equals(mPendingVisibleInsets)) { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "Visible insets changing to: " 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mAttachInfo.mVisibleInsets); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project windowResizesToFitContent = true; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Display d = new Display(0); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project desiredWindowWidth = d.getWidth(); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project desiredWindowHeight = d.getHeight(); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height); 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Ask host how big it wants to be 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v("ViewRoot", 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Measuring " + host + " in display " + desiredWindowWidth 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "x" + desiredWindowHeight + "..."); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.measure(childWidthMeasureSpec, childHeightMeasureSpec); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("======================================"); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("performTraversals -- after measure"); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.debug(); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attachInfo.mRecomputeGlobalAttributes) { 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i(TAG, "Computing screen on!"); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mRecomputeGlobalAttributes = false; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean oldVal = attachInfo.mKeepScreenOn; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mKeepScreenOn = false; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.dispatchCollectViewAttributes(0); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attachInfo.mKeepScreenOn != oldVal) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params = lp; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i(TAG, "Keep screen on changed: " + attachInfo.mKeepScreenOn); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirst || attachInfo.mViewVisibilityChanged) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mViewVisibilityChanged = false; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int resizeMode = mSoftInputMode & 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we are in auto resize mode, then we need to determine 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // what mode to use now. 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = attachInfo.mScrollContainers.size(); 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attachInfo.mScrollContainers.get(i).isShown()) { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resizeMode == 0) { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((lp.softInputMode & 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) != resizeMode) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.softInputMode = (lp.softInputMode & 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) | 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resizeMode; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params = lp; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (params != null && (host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!PixelFormat.formatHasAlpha(params.format)) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params.format = PixelFormat.TRANSLUCENT; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean windowShouldResize = mLayoutRequested && windowResizesToFitContent 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (mWidth != host.mMeasuredWidth || mHeight != host.mMeasuredHeight); 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean computesInternalInsets = 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mTreeObserver.hasComputeInternalInsetsListeners(); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean insetsPending = false; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int relayoutResult = 0; 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirst || windowShouldResize || insetsChanged 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || viewVisibilityChanged || params != null) { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewVisibility == View.VISIBLE) { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this window is giving internal insets to the window 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // manager, and it is being added or changing its visibility, 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // then we want to first give the window manager "fake" 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // insets to cause it to effectively ignore the content of 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the window during layout. This avoids it briefly causing 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // other windows to resize/move based on the raw frame of the 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // window, waiting until we can finish laying out this window 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and get back to the window manager with the ultimately 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // computed insets. 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project insetsPending = computesInternalInsets 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (mFirst || viewVisibilityChanged); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWindowAttributes.memoryType == WindowManager.LayoutParams.MEMORY_TYPE_GPU) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (params == null) { 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params = mWindowAttributes; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlWanted = true; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect frame = mWinFrame; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean initialized = false; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean contentInsetsChanged = false; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean visibleInsetsChanged = false; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hadSurface = mSurface.isValid(); 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fl = 0; 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (params != null) { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fl = params.flags; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attachInfo.mKeepScreenOn) { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project relayoutResult = sWindowSession.relayout( 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow, params, host.mMeasuredWidth, host.mMeasuredHeight, 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewVisibility, insetsPending, frame, 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingContentInsets, mPendingVisibleInsets, mSurface); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (params != null) { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params.flags = fl; 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "relayout: frame=" + frame.toShortString() 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " content=" + mPendingContentInsets.toShortString() 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " visible=" + mPendingVisibleInsets.toShortString() 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " surface=" + mSurface); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentInsetsChanged = !mPendingContentInsets.equals( 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mContentInsets); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project visibleInsetsChanged = !mPendingVisibleInsets.equals( 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mVisibleInsets); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentInsetsChanged) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mContentInsets.set(mPendingContentInsets); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.fitSystemWindows(mAttachInfo.mContentInsets); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: " 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mAttachInfo.mContentInsets); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visibleInsetsChanged) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "Visible insets changing to: " 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mAttachInfo.mVisibleInsets); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!hadSurface) { 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSurface.isValid()) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we are creating a new surface, then we need to 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // completely redraw it. Also, when we get to the 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // point of drawing it we will hold off and schedule 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a new traversal instead. This is so we can tell the 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // window manager about all of the windows being displayed 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // before actually drawing them, so it can display then 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // all at once. 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newSurface = true; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullRedrawNeeded = true; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGlWanted && !mUseGL) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initializeGL(); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initialized = mGlCanvas != null; 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!mSurface.isValid()) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the surface has been removed, then reset the scroll 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // positions. 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastScrolledFocus = null; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScrollY = mCurScrollY = 0; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mScroller != null) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScroller.abortAnimation(); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_ORIENTATION) Log.v( 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Relayout returned: frame=" + mWinFrame + ", surface=" + mSurface); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mWindowLeft = frame.left; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mWindowTop = frame.top; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // !!FIXME!! This next section handles the case where we did not get the 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // window size we asked for. We should avoid this by getting a maximum size from 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the window session beforehand. 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = frame.width(); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = frame.height(); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (initialized) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlCanvas.setViewport(mWidth, mHeight); 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean focusChangedDueToTouchMode = ensureTouchModeLocally( 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focusChangedDueToTouchMode || mWidth != host.mMeasuredWidth 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mHeight != host.mMeasuredHeight || contentInsetsChanged) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth=" 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mWidth + " measuredWidth=" + host.mMeasuredWidth 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mHeight=" + mHeight 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " measuredHeight" + host.mMeasuredHeight 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " coveredInsetsChanged=" + contentInsetsChanged); 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Ask host how big it wants to be 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.measure(childWidthMeasureSpec, childHeightMeasureSpec); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Implementation of weights from WindowManager.LayoutParams 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We just grow the dimensions as needed and re-measure if 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // needs be 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int width = host.mMeasuredWidth; 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = host.mMeasuredHeight; 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean measureAgain = false; 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lp.horizontalWeight > 0.0f) { 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project width += (int) ((mWidth - width) * lp.horizontalWeight); 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.EXACTLY); 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureAgain = true; 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lp.verticalWeight > 0.0f) { 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project height += (int) ((mHeight - height) * lp.verticalWeight); 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.EXACTLY); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureAgain = true; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (measureAgain) { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "And hey let's measure once more: width=" + width 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " height=" + height); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.measure(childWidthMeasureSpec, childHeightMeasureSpec); 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutRequested = true; 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean didLayout = mLayoutRequested; 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean triggerGlobalLayoutListener = didLayout 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || attachInfo.mRecomputeGlobalAttributes; 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (didLayout) { 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutRequested = false; 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScrollMayChange = true; 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v( 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Laying out " + host + " to (" + 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.mMeasuredWidth + ", " + host.mMeasuredHeight + ")"); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long startTime; 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (PROFILE_LAYOUT) { 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startTime = SystemClock.elapsedRealtime(); 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (PROFILE_LAYOUT) { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EventLog.writeEvent(60001, SystemClock.elapsedRealtime() - startTime); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // By this point all views have been sized and positionned 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can compute the transparent area 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) { 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // start out transparent 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: AVOID THAT CALL BY CACHING THE RESULT? 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.getLocationInWindow(mTmpLocation); 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTransparentRegion.set(mTmpLocation[0], mTmpLocation[1], 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTmpLocation[0] + host.mRight - host.mLeft, 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTmpLocation[1] + host.mBottom - host.mTop); 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.gatherTransparentRegion(mTransparentRegion); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTransparentRegion.equals(mPreviousTransparentRegion)) { 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreviousTransparentRegion.set(mTransparentRegion); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reconfigure window manager 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.setTransparentRegion(mWindow, mTransparentRegion); 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) { 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("======================================"); 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("performTraversals -- after setFrame"); 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project host.debug(); 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (triggerGlobalLayoutListener) { 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mRecomputeGlobalAttributes = false; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mTreeObserver.dispatchOnGlobalLayout(); 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (computesInternalInsets) { 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewTreeObserver.InternalInsetsInfo insets = attachInfo.mGivenInternalInsets; 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect givenContent = attachInfo.mGivenInternalInsets.contentInsets; 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect givenVisible = attachInfo.mGivenInternalInsets.visibleInsets; 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project givenContent.left = givenContent.top = givenContent.right 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = givenContent.bottom = givenVisible.left = givenVisible.top 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = givenVisible.right = givenVisible.bottom = 0; 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets); 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (insetsPending || !mLastGivenInsets.equals(insets)) { 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastGivenInsets.set(insets); 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.setInsets(mWindow, insets.mTouchableInsets, 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project insets.contentInsets, insets.visibleInsets); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirst) { 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handle first focus request 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: mView.hasFocus()=" 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mView.hasFocus()); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null) { 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mView.hasFocus()) { 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.requestFocus(View.FOCUS_FORWARD); 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = mRealFocusedView = mView.findFocus(); 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: requested focused view=" 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mFocusedView); 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRealFocusedView = mView.findFocus(); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: existing focused view=" 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mRealFocusedView); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirst = false; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWillDrawSoon = false; 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNewSurfaceNeeded = false; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViewVisibility = viewVisibility; 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAttachInfo.mHasWindowFocus) { 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean imTarget = WindowManager.LayoutParams 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .mayUseInputMethod(mWindowAttributes.flags); 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imTarget != mLastWasImTarget) { 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWasImTarget = imTarget; 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null && imTarget) { 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.startGettingWindowFocus(mView); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.onWindowFocus(mView, mView.findFocus(), 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributes.softInputMode, 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !mHasHadWindowFocus, mWindowAttributes.flags); 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean cancelDraw = attachInfo.mTreeObserver.dispatchOnPreDraw(); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!cancelDraw && !newSurface) { 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFullRedrawNeeded = false; 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project draw(fullRedrawNeeded); 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mReportNextDraw) { 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) { 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ViewRoot", "FINISHED DRAWING: " + mWindowAttributes.getTitle()); 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReportNextDraw = false; 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishDrawing(mWindow); 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We were supposed to report when we are done drawing. Since we canceled the 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // draw, remember it here. 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) { 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReportNextDraw = true; 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fullRedrawNeeded) { 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFullRedrawNeeded = true; 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try again 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestTransparentRegion(View child) { 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the test below should not fail unless someone is messing with us 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView == child) { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.mPrivateFlags |= View.REQUEST_TRANSPARENT_REGIONS; 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Need to make sure we re-evaluate the window attributes next 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time around, to ensure the window has the correct format. 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributesChanged = true; 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Figures out the measure spec for the root view in a window based on it's 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * layout params. 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param windowSize 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The available width or height of the window 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rootDimension 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The layout params for one dimension (width or height) of the 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window. 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The measure spec to use to measure the root view. 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getRootMeasureSpec(int windowSize, int rootDimension) { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int measureSpec; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (rootDimension) { 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ViewGroup.LayoutParams.FILL_PARENT: 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Window can't resize. Force root view to be windowSize. 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY); 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ViewGroup.LayoutParams.WRAP_CONTENT: 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Window can resize. Set max size for root view. 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST); 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Window wants to be an exact size. Force root view to be that size. 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY); 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return measureSpec; 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void draw(boolean fullRedrawNeeded) { 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Surface surface = mSurface; 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (surface == null || !surface.isValid()) { 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollToRectOrFocus(null, false); 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAttachInfo.mViewScrollChanged) { 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mViewScrollChanged = false; 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mTreeObserver.dispatchOnScrollChanged(); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int yoff; 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean scrolling = mScroller != null 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mScroller.computeScrollOffset(); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrolling) { 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yoff = mScroller.getCurrY(); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yoff = mScrollY; 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurScrollY != yoff) { 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurScrollY = yoff; 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullRedrawNeeded = true; 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect dirty = mDirty; 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseGL) { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirty.isEmpty()) { 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Canvas canvas = mGlCanvas; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGL!=null && canvas != null) { 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGL.glDisable(GL_SCISSOR_TEST); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGL.glClearColor(0, 0, 0, 0); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGL.glClear(GL_COLOR_BUFFER_BIT); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGL.glEnable(GL_SCISSOR_TEST); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.translate(0, -yoff); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.mPrivateFlags |= View.DRAWN; 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.draw(canvas); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.translate(0, yoff); 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkEglErrors(); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SHOW_FPS) { 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int now = (int)SystemClock.elapsedRealtime(); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sDrawTime != 0) { 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeShowFPS(canvas, now - sDrawTime); 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sDrawTime = now; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrolling) { 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFullRedrawNeeded = true; 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fullRedrawNeeded) 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirty.union(0, 0, mWidth, mHeight); 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_ORIENTATION || DEBUG_DRAW) { 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ViewRoot", "Draw " + mView + "/" 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mWindowAttributes.getTitle() 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": dirty={" + dirty.left + "," + dirty.top 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "," + dirty.right + "," + dirty.bottom + "} surface=" 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + surface + " surface.isValid()=" + surface.isValid()); 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Canvas canvas; 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas = surface.lockCanvas(dirty); 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Do this in native 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.setDensityScale(mDensity); 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Surface.OutOfResourcesException e) { 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e("ViewRoot", "OutOfResourcesException locking surface", e); 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: we should ask the window manager to do something! 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for now we just do nothing 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!dirty.isEmpty()) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long startTime; 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_ORIENTATION || DEBUG_DRAW) { 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w=" 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + canvas.getWidth() + ", h=" + canvas.getHeight()); 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //canvas.drawARGB(255, 255, 0, 0); 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (PROFILE_DRAWING) { 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startTime = SystemClock.elapsedRealtime(); 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this bitmap's format includes an alpha channel, we 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // need to clear it before drawing so that the child will 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properly re-composite its drawing on a transparent 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // background. This automatically respects the clip/dirty region 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canvas.isOpaque()) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (yoff != 0) { 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we are applying an offset, we need to clear the area 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // where the offset doesn't appear to avoid having garbage 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // left in the blank areas. 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawColor(0, PorterDuff.Mode.CLEAR); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dirty.setEmpty(); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.translate(0, -yoff); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.mPrivateFlags |= View.DRAWN; 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.draw(canvas); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.translate(0, yoff); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SHOW_FPS) { 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int now = (int)SystemClock.elapsedRealtime(); 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sDrawTime != 0) { 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeShowFPS(canvas, now - sDrawTime); 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sDrawTime = now; 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (PROFILE_DRAWING) { 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime); 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project surface.unlockCanvasAndPost(canvas); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) { 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost"); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrolling) { 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFullRedrawNeeded = true; 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean scrollToRectOrFocus(Rect rectangle, boolean immediate) { 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View.AttachInfo attachInfo = mAttachInfo; 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect ci = attachInfo.mContentInsets; 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect vi = attachInfo.mVisibleInsets; 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int scrollY = 0; 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = false; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vi.left > ci.left || vi.top > ci.top 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || vi.right > ci.right || vi.bottom > ci.bottom) { 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We'll assume that we aren't going to change the scroll 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // offset, since we want to avoid that unless it is actually 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // going to make the focus visible... otherwise we scroll 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // all over the place. 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollY = mScrollY; 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can be called for two different situations: during a draw, 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to update the scroll position if the focus has changed (in which 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // case 'rectangle' is null), or in response to a 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requestChildRectangleOnScreen() call (in which case 'rectangle' 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is non-null and we just want to scroll to whatever that 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // rectangle is). 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View focus = mRealFocusedView; 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focus != mLastScrolledFocus) { 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the focus has changed, then ignore any requests to scroll 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to a rectangle; first we want to make sure the entire focus 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // view is visible. 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rectangle = null; 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Eval scroll: focus=" + focus 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " rectangle=" + rectangle + " ci=" + ci 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " vi=" + vi); 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focus == mLastScrolledFocus && !mScrollMayChange 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && rectangle == null) { 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Optimization: if the focus hasn't changed since last 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time, and no layout has happened, then just leave things 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // as they are. 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Keeping scroll y=" 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mScrollY + " vi=" + vi.toShortString()); 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (focus != null) { 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to determine if the currently focused view is 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // within the visible part of the window and, if not, apply 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a pan so it can be seen. 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastScrolledFocus = focus; 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScrollMayChange = false; 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Need to scroll?"); 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try to find the rectangle from the focus view. 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focus.getGlobalVisibleRect(mVisRect, null)) { 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Root w=" 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mView.getWidth() + " h=" + mView.getHeight() 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " ci=" + ci.toShortString() 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " vi=" + vi.toShortString()); 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rectangle == null) { 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project focus.getFocusedRect(mTempRect); 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Focus " + focus 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": focusRect=" + mTempRect.toShortString()); 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((ViewGroup) mView).offsetDescendantRectToMyCoords( 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project focus, mTempRect); 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Focus in window: focusRect=" 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mTempRect.toShortString() 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " visRect=" + mVisRect.toShortString()); 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempRect.set(rectangle); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Request scroll to rect: " 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mTempRect.toShortString() 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " visRect=" + mVisRect.toShortString()); 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTempRect.intersect(mVisRect)) { 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Focus window visible rect: " 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mTempRect.toShortString()); 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTempRect.height() > 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mView.getHeight()-vi.top-vi.bottom)) { 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the focus simply is not going to fit, then 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // best is probably just to leave things as-is. 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Too tall; leaving scrollY=" + scrollY); 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((mTempRect.top-scrollY) < vi.top) { 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollY -= vi.top - (mTempRect.top-scrollY); 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Top covered; scrollY=" + scrollY); 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((mTempRect.bottom-scrollY) 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > (mView.getHeight()-vi.bottom)) { 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollY += (mTempRect.bottom-scrollY) 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project - (mView.getHeight()-vi.bottom); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Bottom covered; scrollY=" + scrollY); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = true; 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrollY != mScrollY) { 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Pan scroll changed: old=" 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mScrollY + " , new=" + scrollY); 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!immediate) { 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mScroller == null) { 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScroller = new Scroller(mView.getContext()); 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScroller.startScroll(0, mScrollY, 0, scrollY-mScrollY); 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mScroller != null) { 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScroller.abortAnimation(); 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScrollY = scrollY; 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return handled; 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestChildFocus(View child, View focused) { 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFocusedView != focused) { 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mFocusedView, focused); 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = mRealFocusedView = focused; 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Request child focus: focus now " 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mFocusedView); 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearChildFocus(View child) { 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View oldFocus = mFocusedView; 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Clearing child focus"); 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = mRealFocusedView = null; 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null && !mView.hasFocus()) { 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If a view gets the focus, the listener will be invoked from requestChildFocus() 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mView.requestFocus(View.FOCUS_FORWARD)) { 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null); 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (oldFocus != null) { 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null); 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void focusableViewAvailable(View v) { 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null && !mView.hasFocus()) { 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v.requestFocus(); 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the one case where will transfer focus away from the current one 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is if the current view is a view group that prefers to give focus 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to its children first AND the view is a descendant of it. 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = mView.findFocus(); 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean descendantsHaveDibsOnFocus = 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mFocusedView instanceof ViewGroup) && 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((ViewGroup) mFocusedView).getDescendantFocusability() == 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.FOCUS_AFTER_DESCENDANTS); 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (descendantsHaveDibsOnFocus && isViewDescendantOf(v, mFocusedView)) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If a view gets the focus, the listener will be invoked from requestChildFocus() 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v.requestFocus(); 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void recomputeViewAttributes(View child) { 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView == child) { 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mRecomputeGlobalAttributes = true; 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mWillDrawSoon) { 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTraversals(); 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dispatchDetachedFromWindow() { 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v("ViewRoot", "Detaching in " + this + " of " + mSurface); 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null) { 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.dispatchDetachedFromWindow(); 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView = null; 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mRootView = null; 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseGL) { 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project destroyGL(); 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.remove(mWindow); 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return true if child is an ancestor of parent, (or equal to the parent). 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean isViewDescendantOf(View child, View parent) { 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child == parent) { 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewParent theParent = child.getParent(); 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent); 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DO_TRAVERSAL = 1000; 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DIE = 1001; 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int RESIZED = 1002; 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int RESIZED_REPORT = 1003; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int WINDOW_FOCUS_CHANGED = 1004; 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DISPATCH_KEY = 1005; 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DISPATCH_POINTER = 1006; 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DISPATCH_TRACKBALL = 1007; 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DISPATCH_APP_VISIBILITY = 1008; 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DISPATCH_GET_NEW_SURFACE = 1009; 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int FINISHED_EVENT = 1010; 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int DISPATCH_KEY_FROM_IME = 1011; 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int FINISH_INPUT_CONNECTION = 1012; 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static int CHECK_FOCUS = 1013; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.AttachInfo.INVALIDATE_MSG: 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((View) msg.obj).invalidate(); 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.AttachInfo.INVALIDATE_RECT_MSG: 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj; 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.target.invalidate(info.left, info.top, info.right, info.bottom); 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.release(); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DO_TRAVERSAL: 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProfile) { 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Debug.startMethodTracing("ViewRoot"); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performTraversals(); 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProfile) { 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Debug.stopMethodTracing(); 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProfile = false; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FINISHED_EVENT: 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleFinishedEvent(msg.arg1, msg.arg2 != 0); 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DISPATCH_KEY: 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v( 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Dispatching key " 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + msg.obj + " to " + mView); 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEvent((KeyEvent)msg.obj, true); 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DISPATCH_POINTER: 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MotionEvent event = (MotionEvent)msg.obj; 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean didFinish; 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event == null) { 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event = sWindowSession.getPendingPointerMove(mWindow); 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project didFinish = true; 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE; 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled; 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null && mAdded && event != null) { 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // enter touch mode on the down 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN; 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isDown) { 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ensureTouchMode(true); 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(Config.LOGV) { 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project captureMotionLog("captureDispatchPointer", event); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event.offsetLocation(0, mCurScrollY); 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = mView.dispatchTouchEvent(event); 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!handled && isDown) { 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int edgeSlop = mViewConfiguration.getScaledEdgeSlop(); 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int edgeFlags = event.getEdgeFlags(); 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int direction = View.FOCUS_UP; 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x = (int)event.getX(); 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = (int)event.getY(); 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] deltas = new int[2]; 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) { 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_DOWN; 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) { 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltas[0] = edgeSlop; 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x += edgeSlop; 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) { 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltas[0] = -edgeSlop; 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x -= edgeSlop; 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) { 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_UP; 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) { 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltas[0] = edgeSlop; 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x += edgeSlop; 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) { 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltas[0] = -edgeSlop; 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x -= edgeSlop; 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) { 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_RIGHT; 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) { 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_LEFT; 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (edgeFlags != 0 && mView instanceof ViewGroup) { 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View nearest = FocusFinder.getInstance().findNearestTouchable( 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((ViewGroup) mView), x, y, direction, deltas); 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nearest != null) { 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event.offsetLocation(deltas[0], deltas[1]); 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event.setEdgeFlags(0); 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.dispatchTouchEvent(event); 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!didFinish) { 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishKey(mWindow); 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event != null) { 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event.recycle(); 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!"); 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Let the exception fall through -- the looper will catch 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it and take care of the bad app for us. 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DISPATCH_TRACKBALL: 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverTrackballEvent((MotionEvent)msg.obj); 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DISPATCH_APP_VISIBILITY: 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleAppVisibility(msg.arg1 != 0); 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DISPATCH_GET_NEW_SURFACE: 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleGetNewSurface(); 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RESIZED: 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect coveredInsets = ((Rect[])msg.obj)[0]; 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect visibleInsets = ((Rect[])msg.obj)[1]; 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mPendingContentInsets.equals(coveredInsets) 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mPendingVisibleInsets.equals(visibleInsets)) { 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through... 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RESIZED_REPORT: 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdded) { 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWinFrame.left = 0; 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWinFrame.right = msg.arg1; 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWinFrame.top = 0; 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWinFrame.bottom = msg.arg2; 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingContentInsets.set(((Rect[])msg.obj)[0]); 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingVisibleInsets.set(((Rect[])msg.obj)[1]); 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.what == RESIZED_REPORT) { 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReportNextDraw = true; 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WINDOW_FOCUS_CHANGED: { 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdded) { 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasWindowFocus = msg.arg1 != 0; 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mHasWindowFocus = hasWindowFocus; 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasWindowFocus) { 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean inTouchMode = msg.arg2 != 0; 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ensureTouchModeLocally(inTouchMode); 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGlWanted) { 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkEglErrors(); 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we lost the gl context, so recreate it. 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGlWanted && !mUseGL) { 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initializeGL(); 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGlCanvas != null) { 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGlCanvas.setViewport(mWidth, mHeight); 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWasImTarget = WindowManager.LayoutParams 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .mayUseInputMethod(mWindowAttributes.flags); 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null) { 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasWindowFocus && imm != null && mLastWasImTarget) { 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.startGettingWindowFocus(mView); 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.dispatchWindowFocusChanged(hasWindowFocus); 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: must be done after the focus change callbacks, 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so all of the view state is set up correctly. 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasWindowFocus) { 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null && mLastWasImTarget) { 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.onWindowFocus(mView, mView.findFocus(), 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributes.softInputMode, 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !mHasHadWindowFocus, mWindowAttributes.flags); 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Clear the forward bit. We can just do this directly, since 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the window manager doesn't care about it. 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAttributes.softInputMode &= 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((WindowManager.LayoutParams)mView.getLayoutParams()) 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .softInputMode &= 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasHadWindowFocus = true; 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DIE: 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchDetachedFromWindow(); 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DISPATCH_KEY_FROM_IME: 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v( 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Dispatching key " 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + msg.obj + " from IME to " + mView); 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEventToViewHierarchy((KeyEvent)msg.obj, false); 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FINISH_INPUT_CONNECTION: { 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null) { 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.reportFinishInputConnection((InputConnection)msg.obj); 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case CHECK_FOCUS: { 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null) { 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.checkFocus(); 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Something in the current window tells us we need to change the touch mode. For 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * example, we are not in touch mode, and the user touches the screen. 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the touch mode has changed, tell the window manager, and handle it locally. 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inTouchMode Whether we want to be in touch mode. 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the touch mode changed and focus changed was changed as a result 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean ensureTouchMode(boolean inTouchMode) { 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) Log.d("touchmode", "ensureTouchMode(" + inTouchMode + "), current " 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "touch mode is " + mAttachInfo.mInTouchMode); 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAttachInfo.mInTouchMode == inTouchMode) return false; 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // tell the window manager 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.setInTouchMode(inTouchMode); 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handle the change 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ensureTouchModeLocally(inTouchMode); 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Ensure that the touch mode for this window is set, and if it is changing, 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * take the appropriate action. 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inTouchMode Whether we want to be in touch mode. 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the touch mode changed and focus changed was changed as a result 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean ensureTouchModeLocally(boolean inTouchMode) { 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) Log.d("touchmode", "ensureTouchModeLocally(" + inTouchMode + "), current " 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "touch mode is " + mAttachInfo.mInTouchMode); 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAttachInfo.mInTouchMode == inTouchMode) return false; 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mInTouchMode = inTouchMode; 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mTreeObserver.dispatchOnTouchModeChanged(inTouchMode); 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (inTouchMode) ? enterTouchMode() : leaveTouchMode(); 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean enterTouchMode() { 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null) { 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView.hasFocus()) { 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // note: not relying on mFocusedView here because this could 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be when the window is first being added, and mFocused isn't 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // set yet. 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View focused = mView.findFocus(); 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focused != null && !focused.isFocusableInTouchMode()) { 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup ancestorToTakeFocus = 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project findAncestorToTakeFocusInTouchMode(focused); 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ancestorToTakeFocus != null) { 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // there is an ancestor that wants focus after its descendants that 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is focusable in touch mode.. give it focus 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ancestorToTakeFocus.requestFocus(); 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing appropriate to have focus in touch mode, clear it out 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.unFocus(); 17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(focused, null); 17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = null; 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Find an ancestor of focused that wants focus after its descendants and is 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * focusable in touch mode. 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focused The currently focused view. 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return An appropriate view, or null if no such view exists. 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ViewGroup findAncestorToTakeFocusInTouchMode(View focused) { 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewParent parent = focused.getParent(); 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (parent instanceof ViewGroup) { 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup vgParent = (ViewGroup) parent; 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vgParent.getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && vgParent.isFocusableInTouchMode()) { 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return vgParent; 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vgParent.isRootNamespace()) { 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent = vgParent.getParent(); 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean leaveTouchMode() { 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null) { 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView.hasFocus()) { 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // i learned the hard way to not trust mFocusedView :) 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = mView.findFocus(); 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(mFocusedView instanceof ViewGroup)) { 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // some view has focus, let it keep it 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (((ViewGroup)mFocusedView).getDescendantFocusability() != 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.FOCUS_AFTER_DESCENDANTS) { 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // some view group has focus, and doesn't prefer its children 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // over itself for focus, so let them keep it. 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find the best view to give focus to in this brave new non-touch-mode 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // world 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View focused = focusSearch(null, View.FOCUS_DOWN); 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focused != null) { 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return focused.requestFocus(View.FOCUS_DOWN); 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void deliverTrackballEvent(MotionEvent event) { 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean didFinish; 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event == null) { 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event = sWindowSession.getPendingTrackballMove(mWindow); 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project didFinish = true; 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project didFinish = false; 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event); 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = false; 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event == null) { 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = true; 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mView != null && mAdded) { 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = mView.dispatchTrackballEvent(event); 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!handled) { 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we could do something here, like changing the focus 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // or something? 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handled) { 18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!didFinish) { 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishKey(mWindow); 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event != null) { 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event.recycle(); 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we reach this, we delivered a trackball event to mView and 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mView consumed it. Because we will not translate the trackball 18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // event into a key event, touch mode will not exit, so we exit 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // touch mode here. 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ensureTouchMode(false); 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //noinspection ReturnInsideFinallyBlock 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Let the exception fall through -- the looper will catch 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it and take care of the bad app for us. 18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TrackballAxis x = mTrackballAxisX; 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TrackballAxis y = mTrackballAxisY; 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long curTime = SystemClock.uptimeMillis(); 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mLastTrackballTime+MAX_TRACKBALL_DELAY) < curTime) { 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It has been too long since the last movement, 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so restart at the beginning. 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x.reset(0); 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y.reset(0); 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastTrackballTime = curTime; 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int action = event.getAction(); 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int metastate = event.getMetaState(); 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (action) { 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_DOWN: 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x.reset(2); 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y.reset(2); 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEvent(new KeyEvent(curTime, curTime, 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, metastate), false); 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_UP: 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x.reset(2); 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y.reset(2); 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEvent(new KeyEvent(curTime, curTime, 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, metastate), false); 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step=" 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + x.step + " dir=" + x.dir + " acc=" + x.acceleration 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " move=" + event.getX() 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " / Y=" + y.position + " step=" 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + y.step + " dir=" + y.dir + " acc=" + y.acceleration 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " move=" + event.getY()); 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float xOff = x.collect(event.getX(), event.getEventTime(), "X"); 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float yOff = y.collect(event.getY(), event.getEventTime(), "Y"); 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Generate DPAD events based on the trackball movement. 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We pick the axis that has moved the most as the direction of 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the DPAD. When we generate DPAD events for one axis, then the 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // other axis is reset -- we don't want to perform DPAD jumps due 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to slight movements in the trackball when making major movements 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // along the other axis. 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int keycode = 0; 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int movement = 0; 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float accel = 1; 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xOff > yOff) { 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement = x.generate((2/event.getXPrecision())); 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (movement != 0) { 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : KeyEvent.KEYCODE_DPAD_LEFT; 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accel = x.acceleration; 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y.reset(2); 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (yOff > 0) { 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement = y.generate((2/event.getYPrecision())); 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (movement != 0) { 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_DOWN 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : KeyEvent.KEYCODE_DPAD_UP; 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accel = y.acceleration; 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x.reset(2); 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (keycode != 0) { 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (movement < 0) movement = -movement; 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int accelMovement = (int)(movement * accel); 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " accelMovement=" + accelMovement 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " accel=" + accel); 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accelMovement > movement) { 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: " 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + keycode); 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement--; 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEvent(new KeyEvent(curTime, curTime, 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent.ACTION_MULTIPLE, keycode, 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accelMovement-movement, metastate), false); 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (movement > 0) { 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: " 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + keycode); 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement--; 19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curTime = SystemClock.uptimeMillis(); 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEvent(new KeyEvent(curTime, curTime, 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false); 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEvent(new KeyEvent(curTime, curTime, 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent.ACTION_UP, keycode, 0, metastate), false); 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastTrackballTime = curTime; 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!didFinish) { 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishKey(mWindow); 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event != null) { 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event.recycle(); 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Let the exception fall through -- the looper will catch 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it and take care of the bad app for us. 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param keyCode The key code 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the key is directional. 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static boolean isDirectional(int keyCode) { 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (keyCode) { 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if this key is a keyboard key. 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param keyEvent The key event. 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether this key is a keyboard key. 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean isKeyboardKey(KeyEvent keyEvent) { 19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int convertedKey = keyEvent.getUnicodeChar(); 19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return convertedKey > 0; 19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See if the key event means we should leave touch mode (and leave touch 19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mode if so). 19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param event The key event. 19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether this key event should be consumed (meaning the act of 19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * leaving touch mode alone is considered the event). 19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean checkForLeavingTouchModeAndConsume(KeyEvent event) { 19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getAction() != KeyEvent.ACTION_DOWN) { 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getFlags()&KeyEvent.FLAG_KEEP_TOUCH_MODE) != 0) { 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only relevant if we are in touch mode 20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAttachInfo.mInTouchMode) { 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if something like an edit text has focus and the user is typing, 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // leave touch mode 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // note: the condition of not being a keyboard key is kind of a hacky 20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // approximation of whether we think the focused view will want the 20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // key; if we knew for sure whether the focused view would consume 20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the event, that would be better. 20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isKeyboardKey(event) && mView != null && mView.hasFocus()) { 20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusedView = mView.findFocus(); 20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mFocusedView instanceof ViewGroup) 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((ViewGroup) mFocusedView).getDescendantFocusability() == 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.FOCUS_AFTER_DESCENDANTS) { 20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // something has focus, but is holding it weakly as a container 20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ensureTouchMode(false)) { 20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("should not have changed focus " 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "when leaving touch mode while a view has focus."); 20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isDirectional(event.getKeyCode())) { 20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no view has focus, so we leave touch mode (and find something 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to give focus to). the event is consumed if we were able to 20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find something to give focus to. 20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ensureTouchMode(false); 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * log motion events 20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void captureMotionLog(String subTag, MotionEvent ev) { 20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //check dynamic switch 20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ev == null || 20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SystemProperties.getInt(ViewDebug.SYSTEM_PROPERTY_CAPTURE_EVENT, 0) == 0) { 20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder sb = new StringBuilder(subTag + ": "); 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getDownTime()).append(','); 20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getEventTime()).append(','); 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getAction()).append(','); 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getX()).append(','); 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getY()).append(','); 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getPressure()).append(','); 20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getSize()).append(','); 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getMetaState()).append(','); 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getXPrecision()).append(','); 20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getYPrecision()).append(','); 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getDeviceId()).append(','); 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getEdgeFlags()); 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, sb.toString()); 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * log motion events 20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void captureKeyLog(String subTag, KeyEvent ev) { 20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //check dynamic switch 20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ev == null || 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SystemProperties.getInt(ViewDebug.SYSTEM_PROPERTY_CAPTURE_EVENT, 0) == 0) { 20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder sb = new StringBuilder(subTag + ": "); 20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getDownTime()).append(','); 20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getEventTime()).append(','); 20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getAction()).append(','); 20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getKeyCode()).append(','); 20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getRepeatCount()).append(','); 20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getMetaState()).append(','); 20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getDeviceId()).append(','); 20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(ev.getScanCode()); 20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, sb.toString()); 20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int enqueuePendingEvent(Object event, boolean sendDone) { 20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int seq = mPendingEventSeq+1; 20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (seq < 0) seq = 0; 20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingEventSeq = seq; 20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingEvents.put(seq, event); 20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sendDone ? seq : -seq; 20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object retrievePendingEvent(int seq) { 20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (seq < 0) seq = -seq; 20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object event = mPendingEvents.get(seq); 20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event != null) { 20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingEvents.remove(seq); 20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return event; 20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void deliverKeyEvent(KeyEvent event, boolean sendDone) { 21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If mView is null, we just consume the key event because it doesn't 21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sense to do anything else with it. 21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = mView != null 21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? mView.dispatchKeyEventPreIme(event) : true; 21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handled) { 21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sendDone) { 21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v( 21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Telling window manager key is finished"); 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishKey(mWindow); 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it is possible for this window to interact with the input 21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // method window, then we want to first dispatch our key events 21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to the input method. 21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLastWasImTarget) { 21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null && mView != null) { 21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int seq = enqueuePendingEvent(event, sendDone); 21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq=" 21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + seq + " event=" + event); 21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.dispatchKeyEvent(mView.getContext(), seq, event, 21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodCallback); 21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEventToViewHierarchy(event, sendDone); 21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void handleFinishedEvent(int seq, boolean handled) { 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final KeyEvent event = (KeyEvent)retrievePendingEvent(seq); 21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_IMF) Log.v(TAG, "IME finished event: seq=" + seq 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " handled=" + handled + " event=" + event); 21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event != null) { 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sendDone = seq >= 0; 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!handled) { 21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deliverKeyEventToViewHierarchy(event, sendDone); 21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sendDone) { 21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v( 21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Telling window manager key is finished"); 21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishKey(mWindow); 21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("ViewRoot", "handleFinishedEvent(seq=" + seq 21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " handled=" + handled + " ev=" + event 21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ") neither delivering nor finishing key"); 21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) { 21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView != null && mAdded) { 21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int action = event.getAction(); 21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isDown = (action == KeyEvent.ACTION_DOWN); 21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checkForLeavingTouchModeAndConsume(event)) { 21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) { 21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project captureKeyLog("captureDispatchKeyEvent", event); 21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean keyHandled = mView.dispatchKeyEvent(event); 21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!keyHandled && isDown) { 21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int direction = 0; 21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (event.getKeyCode()) { 21769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_LEFT; 21789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_RIGHT; 21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_UP; 21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project direction = View.FOCUS_DOWN; 21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (direction != 0) { 21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View focused = mView != null ? mView.findFocus() : null; 21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (focused != null) { 21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View v = focused.focusSearch(direction); 21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean focusPassed = false; 21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v != null && v != focused) { 21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do the math the get the interesting rect 21989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of previous focused into the coord system of 21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // newly focused view 22009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project focused.getFocusedRect(mTempRect); 22019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((ViewGroup) mView).offsetDescendantRectToMyCoords(focused, mTempRect); 22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((ViewGroup) mView).offsetRectIntoDescendantCoords(v, mTempRect); 22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project focusPassed = v.requestFocus(direction, mTempRect); 22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!focusPassed) { 22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.dispatchUnhandledMove(focused, direction); 22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); 22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sendDone) { 22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v( 22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "Telling window manager key is finished"); 22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishKey(mWindow); 22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Let the exception fall through -- the looper will catch 22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it and take care of the bad app for us. 22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AudioManager getAudioManager() { 22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mView == null) { 22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("getAudioManager called when there is no mView"); 22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAudioManager == null) { 22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioManager = (AudioManager) mView.getContext().getSystemService(Context.AUDIO_SERVICE); 22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAudioManager; 22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void playSoundEffect(int effectId) { 22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final AudioManager audioManager = getAudioManager(); 22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (effectId) { 22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SoundEffectConstants.CLICK: 22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); 22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SoundEffectConstants.NAVIGATION_DOWN: 22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); 22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SoundEffectConstants.NAVIGATION_LEFT: 22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); 22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SoundEffectConstants.NAVIGATION_RIGHT: 22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); 22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SoundEffectConstants.NAVIGATION_UP: 22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); 22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unknown effect id " + effectId + 22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " not defined in " + SoundEffectConstants.class.getCanonicalName()); 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performHapticFeedback(int effectId, boolean always) { 22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sWindowSession.performHapticFeedback(mWindow, effectId, always); 22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 22779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View focusSearch(View focused, int direction) { 22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(mView instanceof ViewGroup)) { 22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FocusFinder.getInstance().findNextFocus((ViewGroup) mView, focused, direction); 22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void debug() { 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.debug(); 22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void die(boolean immediate) { 22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkThread(); 22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v("ViewRoot", "DIE in " + this + " of " + mSurface); 22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdded && !mFirst) { 23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int viewVisibility = mView.getVisibility(); 23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean viewVisibilityChanged = mViewVisibility != viewVisibility; 23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWindowAttributesChanged || viewVisibilityChanged) { 23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If layout params have been changed, first give them 23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to the window manager to make sure it has the correct 23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // animation info. 23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sWindowSession.relayout( 23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow, mWindowAttributes, 23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mView.mMeasuredWidth, mView.mMeasuredHeight, 23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewVisibility, false, mWinFrame, mPendingContentInsets, 23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingVisibleInsets, mSurface) 23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) { 23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowSession.finishDrawing(mWindow); 23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSurface = null; 23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdded) { 23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdded = false; 23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (immediate) { 23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchDetachedFromWindow(); 23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mView != null) { 23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEmptyMessage(DIE); 23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchFinishedEvent(int seq, boolean handled) { 23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(FINISHED_EVENT); 23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg1 = seq; 23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg2 = handled ? 1 : 0; 23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessage(msg); 23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchResized(int w, int h, Rect coveredInsets, 23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect visibleInsets, boolean reportDraw) { 23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": w=" + w 23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " h=" + h + " coveredInsets=" + coveredInsets.toShortString() 23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " visibleInsets=" + visibleInsets.toShortString() 23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " reportDraw=" + reportDraw); 23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED); 23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg1 = w; 23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg2 = h; 23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) }; 23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessage(msg); 23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchKey(KeyEvent event) { 23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getAction() == KeyEvent.ACTION_DOWN) { 23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //noinspection ConstantConditions 23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (false && event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) { 23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d("keydisp", 23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "==================================================="); 23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d("keydisp", "Focused view Hierarchy is:"); 23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project debug(); 23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d("keydisp", 23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "==================================================="); 23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(DISPATCH_KEY); 23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = event; 23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v( 23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ViewRoot", "sending key " + event + " to " + mView); 23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessageAtTime(msg, event.getEventTime()); 23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchPointer(MotionEvent event, long eventTime) { 23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(DISPATCH_POINTER); 23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = event; 23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessageAtTime(msg, eventTime); 23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchTrackball(MotionEvent event, long eventTime) { 23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(DISPATCH_TRACKBALL); 23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = event; 23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessageAtTime(msg, eventTime); 23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchAppVisibility(boolean visible) { 23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(DISPATCH_APP_VISIBILITY); 23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg1 = visible ? 1 : 0; 23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessage(msg); 23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchGetNewSurface() { 23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = obtainMessage(DISPATCH_GET_NEW_SURFACE); 23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessage(msg); 23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { 24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = WINDOW_FOCUS_CHANGED; 24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg1 = hasFocus ? 1 : 0; 24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.arg2 = inTouchMode ? 1 : 0; 24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessage(msg); 24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean showContextMenuForChild(View originalView) { 24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void createContextMenu(ContextMenu menu) { 24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void childDrawableStateChanged(View child) { 24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Rect getWindowFrame() { 24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWinFrame; 24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void checkThread() { 24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThread != Thread.currentThread()) { 24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new CalledFromWrongThreadException( 24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Only the original thread that created a view hierarchy can touch its views."); 24259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ViewRoot never intercepts touch event, so this can be a no-op 24309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requestChildRectangleOnScreen(View child, Rect rectangle, 24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean immediate) { 24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return scrollToRectOrFocus(rectangle, immediate); 24359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class InputMethodCallback extends IInputMethodCallback.Stub { 24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WeakReference<ViewRoot> mViewRoot; 24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public InputMethodCallback(ViewRoot viewRoot) { 24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViewRoot = new WeakReference<ViewRoot>(viewRoot); 24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void finishedEvent(int seq, boolean handled) { 24459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 24479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchFinishedEvent(seq, handled); 24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void sessionCreated(IInputMethodSession session) throws RemoteException { 24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stub -- not for use in the client. 24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2456ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project static class EventCompletion extends Handler { 2457ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project final IWindow mWindow; 2458ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project final KeyEvent mKeyEvent; 2459ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project final boolean mIsPointer; 2460ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project final MotionEvent mMotionEvent; 2461ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 2462ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project EventCompletion(Looper looper, IWindow window, KeyEvent key, 2463ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project boolean isPointer, MotionEvent motion) { 2464ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project super(looper); 2465ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mWindow = window; 2466ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mKeyEvent = key; 2467ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mIsPointer = isPointer; 2468ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mMotionEvent = motion; 2469ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project sendEmptyMessage(0); 2470ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2471ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 2472ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project @Override 2473ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project public void handleMessage(Message msg) { 2474ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project if (mKeyEvent != null) { 2475ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project try { 2476ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project sWindowSession.finishKey(mWindow); 2477ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } catch (RemoteException e) { 2478ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2479ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else if (mIsPointer) { 2480ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project boolean didFinish; 2481ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project MotionEvent event = mMotionEvent; 2482ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project if (event == null) { 2483ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project try { 2484ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project event = sWindowSession.getPendingPointerMove(mWindow); 2485ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } catch (RemoteException e) { 2486ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2487ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project didFinish = true; 2488ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else { 2489ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE; 2490ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2491ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project if (!didFinish) { 2492ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project try { 2493ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project sWindowSession.finishKey(mWindow); 2494ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } catch (RemoteException e) { 2495ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2496ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2497ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else { 2498ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project MotionEvent event = mMotionEvent; 2499ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project if (event == null) { 2500ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project try { 2501ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project event = sWindowSession.getPendingTrackballMove(mWindow); 2502ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } catch (RemoteException e) { 2503ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2504ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else { 2505ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project try { 2506ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project sWindowSession.finishKey(mWindow); 2507ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } catch (RemoteException e) { 2508ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2509ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2510ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2511ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2512ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } 2513ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class W extends IWindow.Stub { 2515ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project private final WeakReference<ViewRoot> mViewRoot; 2516ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project private final Looper mMainLooper; 25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2518ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project public W(ViewRoot viewRoot, Context context) { 25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViewRoot = new WeakReference<ViewRoot>(viewRoot); 2520ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project mMainLooper = context.getMainLooper(); 25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void resized(int w, int h, Rect coveredInsets, 25249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect visibleInsets, boolean reportDraw) { 25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchResized(w, h, coveredInsets, 25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project visibleInsets, reportDraw); 25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchKey(KeyEvent event) { 25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchKey(event); 25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("ViewRoot.W", "Key event " + event + " but no ViewRoot available!"); 2538ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project new EventCompletion(mMainLooper, this, event, false, null); 25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchPointer(MotionEvent event, long eventTime) { 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchPointer(event, eventTime); 2546ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else { 2547ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project new EventCompletion(mMainLooper, this, null, true, event); 25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchTrackball(MotionEvent event, long eventTime) { 25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchTrackball(event, eventTime); 2555ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project } else { 2556ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project new EventCompletion(mMainLooper, this, null, false, event); 25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchAppVisibility(boolean visible) { 25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchAppVisibility(visible); 25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dispatchGetNewSurface() { 25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.dispatchGetNewSurface(); 25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { 25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewRoot.windowFocusChanged(hasFocus, inTouchMode); 25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int checkCallingPermission(String permission) { 25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!Process.supportsProcesses()) { 25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PackageManager.PERMISSION_GRANTED; 25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ActivityManagerNative.getDefault().checkPermission( 25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project permission, Binder.getCallingPid(), Binder.getCallingUid()); 25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PackageManager.PERMISSION_DENIED; 25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { 25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewRoot viewRoot = mViewRoot.get(); 25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewRoot != null) { 25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view = viewRoot.mView; 25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view != null) { 25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checkCallingPermission(Manifest.permission.DUMP) != 26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Insufficient permissions to invoke" 26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " executeCommand() from pid=" + Binder.getCallingPid() 26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OutputStream clientStream = null; 26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clientStream = new ParcelFileDescriptor.AutoCloseOutputStream(out); 26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewDebug.dispatchCommand(view, command, parameters, clientStream); 26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.printStackTrace(); 26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clientStream != null) { 26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 26159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clientStream.close(); 26169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.printStackTrace(); 26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Maintains state information for a single trackball axis, generating 26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * discrete (DPAD) movements based on raw trackball motion. 26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final class TrackballAxis { 26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The maximum amount of acceleration we will apply. 26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final float MAX_ACCELERATION = 20; 26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The maximum amount of time (in milliseconds) between events in order 26389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for us to consider the user to be doing fast trackball movements, 26399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and thus apply an acceleration. 26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final long FAST_MOVE_TIME = 150; 26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scaling factor to the time (in milliseconds) between events to how 26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * much to multiple/divide the current acceleration. When movement 26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is < FAST_MOVE_TIME this multiplies the acceleration; when > 26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * FAST_MOVE_TIME it divides it. 26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/40); 26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float position; 26529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float absPosition; 26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float acceleration = 1; 26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long lastMoveTime = 0; 26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int step; 26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int dir; 26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nonAccelMovement; 26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void reset(int _step) { 26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = 0; 26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acceleration = 1; 26629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastMoveTime = 0; 26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project step = _step; 26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dir = 0; 26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add trackball movement into the state. If the direction of movement 26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been reversed, the state is reset before adding the 26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * movement (so that you don't have to compensate for any previously 26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * collected movement before see the result of the movement in the 26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * new direction). 26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns the absolute value of the amount of movement 26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * collected so far. 26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float collect(float off, long time, String axis) { 26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long normTime; 26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off > 0) { 26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normTime = (long)(off * FAST_MOVE_TIME); 26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dir < 0) { 26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to positive!"); 26839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = 0; 26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project step = 0; 26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acceleration = 1; 26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastMoveTime = 0; 26879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dir = 1; 26899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (off < 0) { 26909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normTime = (long)((-off) * FAST_MOVE_TIME); 26919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dir > 0) { 26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to negative!"); 26939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = 0; 26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project step = 0; 26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acceleration = 1; 26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastMoveTime = 0; 26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dir = -1; 26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normTime = 0; 27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The number of milliseconds between each movement that is 27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // considered "normal" and will not result in any acceleration 27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // or deceleration, scaled by the offset we have here. 27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (normTime > 0) { 27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long delta = time - lastMoveTime; 27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastMoveTime = time; 27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float acc = acceleration; 27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta < normTime) { 27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The user is scrolling rapidly, so increase acceleration. 27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float scale = (normTime-delta) * ACCEL_MOVE_SCALING_FACTOR; 27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scale > 1) acc *= scale; 27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, axis + " accelerate: off=" 27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + off + " normTime=" + normTime + " delta=" + delta 27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " scale=" + scale + " acc=" + acc); 27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acceleration = acc < MAX_ACCELERATION ? acc : MAX_ACCELERATION; 27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The user is scrolling slowly, so decrease acceleration. 27209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float scale = (delta-normTime) * ACCEL_MOVE_SCALING_FACTOR; 27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scale > 1) acc /= scale; 27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_TRACKBALL) Log.v(TAG, axis + " deccelerate: off=" 27239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + off + " normTime=" + normTime + " delta=" + delta 27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " scale=" + scale + " acc=" + acc); 27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acceleration = acc > 1 ? acc : 1; 27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += off; 27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (absPosition = Math.abs(position)); 27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Generate the number of discrete movement events appropriate for 27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the currently collected trackball movement. 27359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 27369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param precision The minimum movement required to generate the 27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * first discrete movement. 27389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns the number of discrete movements, either positive 27409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or negative, or 0 if there is not enough trackball movement yet 27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a discrete movement. 27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int generate(float precision) { 27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int movement = 0; 27459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nonAccelMovement = 0; 27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int dir = position >= 0 ? 1 : -1; 27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (step) { 27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we are going to execute the first step, then we want 27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to do this as soon as possible instead of waiting for 27519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a full movement, in order to make things look responsive. 27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (absPosition < precision) { 27549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return movement; 27559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement += dir; 27579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nonAccelMovement += dir; 27589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project step = 1; 27599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 27609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we have generated the first movement, then we need 27619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to wait for the second complete trackball motion before 27629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // generating the second discrete movement. 27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 1: 27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (absPosition < 2) { 27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return movement; 27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement += dir; 27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nonAccelMovement += dir; 27699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += dir > 0 ? -2 : 2; 27709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project absPosition = Math.abs(position); 27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project step = 2; 27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 27739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // After the first two, we generate discrete movements 27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // consistently with the trackball, applying an acceleration 27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the trackball is moving quickly. This is a simple 27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // acceleration on top of what we already compute based 27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on how quickly the wheel is being turned, to apply 27789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a longer increasing acceleration to continuous movement 27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in one direction. 27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 27819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (absPosition < 1) { 27829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return movement; 27839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project movement += dir; 27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += dir >= 0 ? -1 : 1; 27869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project absPosition = Math.abs(position); 27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float acc = acceleration; 27889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acc *= 1.1f; 27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project acceleration = acc < MAX_ACCELERATION ? acc : acceleration; 27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (true); 27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final class CalledFromWrongThreadException extends AndroidRuntimeException { 27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CalledFromWrongThreadException(String msg) { 27989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(msg); 27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SurfaceHolder mHolder = new SurfaceHolder() { 28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we only need a SurfaceHolder for opengl. it would be nice 28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to implement everything else though, especially the callback 28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // support (opengl doesn't make use of it right now, but eventually 28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // will). 28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Surface getSurface() { 28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSurface; 28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isCreating() { 28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 28139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addCallback(Callback callback) { 28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeCallback(Callback callback) { 28199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFixedSize(int width, int height) { 28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSizeFromLayout() { 28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFormat(int format) { 28289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setType(int type) { 28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setKeepScreenOn(boolean screenOn) { 28349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Canvas lockCanvas() { 28379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 28389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Canvas lockCanvas(Rect dirty) { 28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unlockCanvasAndPost(Canvas canvas) { 28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Rect getSurfaceFrame() { 28479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static RunQueue getRunQueue() { 28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RunQueue rq = sRunQueues.get(); 28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rq != null) { 28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rq; 28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rq = new RunQueue(); 28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sRunQueues.set(rq); 28589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rq; 28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 28629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 28649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final class RunQueue { 28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<HandlerAction> mActions = new ArrayList<HandlerAction>(); 28669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void post(Runnable action) { 28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project postDelayed(action, 0); 28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void postDelayed(Runnable action, long delayMillis) { 28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HandlerAction handlerAction = new HandlerAction(); 28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlerAction.action = action; 28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlerAction.delay = delayMillis; 28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mActions) { 28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActions.add(handlerAction); 28789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeCallbacks(Runnable action) { 28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final HandlerAction handlerAction = new HandlerAction(); 28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handlerAction.action = action; 28849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mActions) { 28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<HandlerAction> actions = mActions; 28879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (actions.remove(handlerAction)) { 28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Keep going 28909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void executeActions(Handler handler) { 28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mActions) { 28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<HandlerAction> actions = mActions; 28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = actions.size(); 28989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final HandlerAction handlerAction = actions.get(i); 29019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handler.postDelayed(handlerAction.action, handlerAction.delay); 29029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActions.clear(); 29059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class HandlerAction { 29099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Runnable action; 29109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long delay; 29119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 29139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object o) { 29149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (this == o) return true; 29159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (o == null || getClass() != o.getClass()) return false; 29169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HandlerAction that = (HandlerAction) o; 29189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return !(action != null ? !action.equals(that.action) : that.action != null); 29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 29249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = action != null ? action.hashCode() : 0; 29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = 31 * result + (int) (delay ^ (delay >>> 32)); 29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeShowFPS(Canvas canvas, int durationMillis); 29339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inform skia to just abandon its texture cache IDs 29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // doesn't call glDeleteTextures 29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeAbandonGlCaches(); 29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2938