ViewRoot.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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();
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindow = new W(this);
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
24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class W extends IWindow.Stub {
24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private WeakReference<ViewRoot> mViewRoot;
24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public W(ViewRoot viewRoot) {
24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mViewRoot = new WeakReference<ViewRoot>(viewRoot);
24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void resized(int w, int h, Rect coveredInsets,
24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Rect visibleInsets, boolean reportDraw) {
24659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.dispatchResized(w, h, coveredInsets,
24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        visibleInsets, reportDraw);
24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchKey(KeyEvent event) {
24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.dispatchKey(event);
24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
24779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w("ViewRoot.W", "Key event " + event + " but no ViewRoot available!");
24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchPointer(MotionEvent event, long eventTime) {
24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
24839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.dispatchPointer(event, eventTime);
24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchTrackball(MotionEvent event, long eventTime) {
24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.dispatchTrackball(event, eventTime);
24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchAppVisibility(boolean visible) {
24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
24979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.dispatchAppVisibility(visible);
24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchGetNewSurface() {
25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
25049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.dispatchGetNewSurface();
25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
25129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                viewRoot.windowFocusChanged(hasFocus, inTouchMode);
25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static int checkCallingPermission(String permission) {
25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!Process.supportsProcesses()) {
25189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return PackageManager.PERMISSION_GRANTED;
25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return ActivityManagerNative.getDefault().checkPermission(
25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        permission, Binder.getCallingPid(), Binder.getCallingUid());
25249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return PackageManager.PERMISSION_DENIED;
25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewRoot viewRoot = mViewRoot.get();
25319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (viewRoot != null) {
25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View view = viewRoot.mView;
25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (view != null) {
25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (checkCallingPermission(Manifest.permission.DUMP) !=
25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            PackageManager.PERMISSION_GRANTED) {
25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        throw new SecurityException("Insufficient permissions to invoke"
25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                + " executeCommand() from pid=" + Binder.getCallingPid()
25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                + ", uid=" + Binder.getCallingUid());
25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    OutputStream clientStream = null;
25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        clientStream = new ParcelFileDescriptor.AutoCloseOutputStream(out);
25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ViewDebug.dispatchCommand(view, command, parameters, clientStream);
25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (IOException e) {
25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        e.printStackTrace();
25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } finally {
25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (clientStream != null) {
25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            try {
25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                clientStream.close();
25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } catch (IOException e) {
25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                e.printStackTrace();
25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
25559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Maintains state information for a single trackball axis, generating
25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * discrete (DPAD) movements based on raw trackball motion.
25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final class TrackballAxis {
25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
25679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The maximum amount of acceleration we will apply.
25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
25699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final float MAX_ACCELERATION = 20;
25709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The maximum amount of time (in milliseconds) between events in order
25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * for us to consider the user to be doing fast trackball movements,
25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * and thus apply an acceleration.
25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final long FAST_MOVE_TIME = 150;
25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Scaling factor to the time (in milliseconds) between events to how
25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * much to multiple/divide the current acceleration.  When movement
25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * is < FAST_MOVE_TIME this multiplies the acceleration; when >
25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * FAST_MOVE_TIME it divides it.
25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/40);
25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float position;
25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float absPosition;
25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float acceleration = 1;
25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long lastMoveTime = 0;
25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int step;
25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dir;
25929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nonAccelMovement;
25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void reset(int _step) {
25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            position = 0;
25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            acceleration = 1;
25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lastMoveTime = 0;
25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            step = _step;
25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dir = 0;
26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Add trackball movement into the state.  If the direction of movement
26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * has been reversed, the state is reset before adding the
26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * movement (so that you don't have to compensate for any previously
26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * collected movement before see the result of the movement in the
26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * new direction).
26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return Returns the absolute value of the amount of movement
26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * collected so far.
26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float collect(float off, long time, String axis) {
26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long normTime;
26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (off > 0) {
26159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                normTime = (long)(off * FAST_MOVE_TIME);
26169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dir < 0) {
26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to positive!");
26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    position = 0;
26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    step = 0;
26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    acceleration = 1;
26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    lastMoveTime = 0;
26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dir = 1;
26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (off < 0) {
26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                normTime = (long)((-off) * FAST_MOVE_TIME);
26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dir > 0) {
26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to negative!");
26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    position = 0;
26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    step = 0;
26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    acceleration = 1;
26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    lastMoveTime = 0;
26329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dir = -1;
26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                normTime = 0;
26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The number of milliseconds between each movement that is
26399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // considered "normal" and will not result in any acceleration
26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // or deceleration, scaled by the offset we have here.
26419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (normTime > 0) {
26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long delta = time - lastMoveTime;
26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                lastMoveTime = time;
26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                float acc = acceleration;
26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (delta < normTime) {
26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // The user is scrolling rapidly, so increase acceleration.
26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    float scale = (normTime-delta) * ACCEL_MOVE_SCALING_FACTOR;
26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (scale > 1) acc *= scale;
26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " accelerate: off="
26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + off + " normTime=" + normTime + " delta=" + delta
26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + " scale=" + scale + " acc=" + acc);
26529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    acceleration = acc < MAX_ACCELERATION ? acc : MAX_ACCELERATION;
26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // The user is scrolling slowly, so decrease acceleration.
26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    float scale = (delta-normTime) * ACCEL_MOVE_SCALING_FACTOR;
26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (scale > 1) acc /= scale;
26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " deccelerate: off="
26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + off + " normTime=" + normTime + " delta=" + delta
26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + " scale=" + scale + " acc=" + acc);
26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    acceleration = acc > 1 ? acc : 1;
26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            position += off;
26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (absPosition = Math.abs(position));
26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Generate the number of discrete movement events appropriate for
26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the currently collected trackball movement.
26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param precision The minimum movement required to generate the
26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * first discrete movement.
26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return Returns the number of discrete movements, either positive
26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * or negative, or 0 if there is not enough trackball movement yet
26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * for a discrete movement.
26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int generate(float precision) {
26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int movement = 0;
26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nonAccelMovement = 0;
26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            do {
26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int dir = position >= 0 ? 1 : -1;
26839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                switch (step) {
26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // If we are going to execute the first step, then we want
26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // to do this as soon as possible instead of waiting for
26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // a full movement, in order to make things look responsive.
26879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case 0:
26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (absPosition < precision) {
26899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return movement;
26909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
26919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        movement += dir;
26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        nonAccelMovement += dir;
26939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        step = 1;
26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // If we have generated the first movement, then we need
26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // to wait for the second complete trackball motion before
26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // generating the second discrete movement.
26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case 1:
26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (absPosition < 2) {
27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return movement;
27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        movement += dir;
27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        nonAccelMovement += dir;
27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        position += dir > 0 ? -2 : 2;
27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        absPosition = Math.abs(position);
27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        step = 2;
27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // After the first two, we generate discrete movements
27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // consistently with the trackball, applying an acceleration
27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // if the trackball is moving quickly.  This is a simple
27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // acceleration on top of what we already compute based
27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // on how quickly the wheel is being turned, to apply
27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // a longer increasing acceleration to continuous movement
27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // in one direction.
27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    default:
27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (absPosition < 1) {
27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return movement;
27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        movement += dir;
27209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        position += dir >= 0 ? -1 : 1;
27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        absPosition = Math.abs(position);
27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        float acc = acceleration;
27239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        acc *= 1.1f;
27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        acceleration = acc < MAX_ACCELERATION ? acc : acceleration;
27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } while (true);
27289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final class CalledFromWrongThreadException extends AndroidRuntimeException {
27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public CalledFromWrongThreadException(String msg) {
27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(msg);
27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private SurfaceHolder mHolder = new SurfaceHolder() {
27389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we only need a SurfaceHolder for opengl. it would be nice
27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // to implement everything else though, especially the callback
27409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // support (opengl doesn't make use of it right now, but eventually
27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // will).
27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Surface getSurface() {
27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mSurface;
27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isCreating() {
27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void addCallback(Callback callback) {
27519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void removeCallback(Callback callback) {
27549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setFixedSize(int width, int height) {
27579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setSizeFromLayout() {
27609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setFormat(int format) {
27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setType(int type) {
27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setKeepScreenOn(boolean screenOn) {
27699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Canvas lockCanvas() {
27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
27739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Canvas lockCanvas(Rect dirty) {
27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void unlockCanvasAndPost(Canvas canvas) {
27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Rect getSurfaceFrame() {
27829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
27839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static RunQueue getRunQueue() {
27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RunQueue rq = sRunQueues.get();
27889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (rq != null) {
27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return rq;
27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rq = new RunQueue();
27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sRunQueues.set(rq);
27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return rq;
27949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
27989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final class RunQueue {
28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final ArrayList<HandlerAction> mActions = new ArrayList<HandlerAction>();
28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void post(Runnable action) {
28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            postDelayed(action, 0);
28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void postDelayed(Runnable action, long delayMillis) {
28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            HandlerAction handlerAction = new HandlerAction();
28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            handlerAction.action = action;
28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            handlerAction.delay = delayMillis;
28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mActions) {
28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mActions.add(handlerAction);
28139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void removeCallbacks(Runnable action) {
28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final HandlerAction handlerAction = new HandlerAction();
28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            handlerAction.action = action;
28199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mActions) {
28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final ArrayList<HandlerAction> actions = mActions;
28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while (actions.remove(handlerAction)) {
28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Keep going
28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void executeActions(Handler handler) {
28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mActions) {
28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final ArrayList<HandlerAction> actions = mActions;
28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int count = actions.size();
28339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < count; i++) {
28359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    final HandlerAction handlerAction = actions.get(i);
28369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handler.postDelayed(handlerAction.action, handlerAction.delay);
28379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mActions.clear();
28409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static class HandlerAction {
28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Runnable action;
28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long delay;
28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override
28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public boolean equals(Object o) {
28499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (this == o) return true;
28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (o == null || getClass() != o.getClass()) return false;
28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                HandlerAction that = (HandlerAction) o;
28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return !(action != null ? !action.equals(that.action) : that.action != null);
28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override
28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public int hashCode() {
28609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int result = action != null ? action.hashCode() : 0;
28619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                result = 31 * result + (int) (delay ^ (delay >>> 32));
28629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return result;
28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeShowFPS(Canvas canvas, int durationMillis);
28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // inform skia to just abandon its texture cache IDs
28709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // doesn't call glDeleteTextures
28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeAbandonGlCaches();
28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2873