157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang/*
257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * Copyright (C) 2012 The Android Open Source Project
357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang *
457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * Licensed under the Apache License, Version 2.0 (the "License");
557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * you may not use this file except in compliance with the License.
657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * You may obtain a copy of the License at
757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang *
857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang *      http://www.apache.org/licenses/LICENSE-2.0
957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang *
1057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * Unless required by applicable law or agreed to in writing, software
1157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * distributed under the License is distributed on an "AS IS" BASIS,
1257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * See the License for the specific language governing permissions and
1457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * limitations under the License.
1557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang */
1657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangpackage com.example.android.supportv7.media;
1857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1961636870e0a12db5909955eca58e0070357dde42Donghyun Choimport android.annotation.TargetApi;
2057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.Context;
21cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.graphics.Bitmap;
2257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.graphics.SurfaceTexture;
2357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.hardware.display.DisplayManager;
248e006e629800b4a2643416f97bca2711af728837Jeff Brownimport android.os.Build;
2561636870e0a12db5909955eca58e0070357dde42Donghyun Choimport android.util.DisplayMetrics;
2657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.util.Log;
2757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.Display;
2857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.GestureDetector;
2957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.Gravity;
3057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.LayoutInflater;
3157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.MotionEvent;
3257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ScaleGestureDetector;
3361636870e0a12db5909955eca58e0070357dde42Donghyun Choimport android.view.Surface;
348e006e629800b4a2643416f97bca2711af728837Jeff Brownimport android.view.SurfaceHolder;
358e006e629800b4a2643416f97bca2711af728837Jeff Brownimport android.view.SurfaceView;
3657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.TextureView;
3761636870e0a12db5909955eca58e0070357dde42Donghyun Choimport android.view.TextureView.SurfaceTextureListener;
3857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.View;
3957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.WindowManager;
4057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.TextView;
4157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
4261636870e0a12db5909955eca58e0070357dde42Donghyun Choimport com.example.android.supportv7.R;
4361636870e0a12db5909955eca58e0070357dde42Donghyun Cho
4457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang/**
4557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * Manages an overlay display window, used for simulating remote playback.
4657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang */
478e006e629800b4a2643416f97bca2711af728837Jeff Brownpublic abstract class OverlayDisplayWindow {
4857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private static final String TAG = "OverlayDisplayWindow";
4957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private static final boolean DEBUG = false;
5057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
518e006e629800b4a2643416f97bca2711af728837Jeff Brown    private static final float WINDOW_ALPHA = 0.8f;
528e006e629800b4a2643416f97bca2711af728837Jeff Brown    private static final float INITIAL_SCALE = 0.5f;
538e006e629800b4a2643416f97bca2711af728837Jeff Brown    private static final float MIN_SCALE = 0.3f;
548e006e629800b4a2643416f97bca2711af728837Jeff Brown    private static final float MAX_SCALE = 1.0f;
5557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
568e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected final Context mContext;
578e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected final String mName;
588e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected final int mWidth;
598e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected final int mHeight;
608e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected final int mGravity;
618e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected OverlayWindowListener mListener;
6257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
638e006e629800b4a2643416f97bca2711af728837Jeff Brown    protected OverlayDisplayWindow(Context context, String name,
6457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            int width, int height, int gravity) {
6557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mContext = context;
668e006e629800b4a2643416f97bca2711af728837Jeff Brown        mName = name;
6757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mWidth = width;
6857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mHeight = height;
6957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mGravity = gravity;
708e006e629800b4a2643416f97bca2711af728837Jeff Brown    }
7157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
728e006e629800b4a2643416f97bca2711af728837Jeff Brown    public static OverlayDisplayWindow create(Context context, String name,
738e006e629800b4a2643416f97bca2711af728837Jeff Brown            int width, int height, int gravity) {
748e006e629800b4a2643416f97bca2711af728837Jeff Brown        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
758e006e629800b4a2643416f97bca2711af728837Jeff Brown            return new JellybeanMr1Impl(context, name, width, height, gravity);
768e006e629800b4a2643416f97bca2711af728837Jeff Brown        } else {
778e006e629800b4a2643416f97bca2711af728837Jeff Brown            return new LegacyImpl(context, name, width, height, gravity);
788e006e629800b4a2643416f97bca2711af728837Jeff Brown        }
7957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
8057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
8157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void setOverlayWindowListener(OverlayWindowListener listener) {
8257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mListener = listener;
8357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
8457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
8557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public Context getContext() {
8657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        return mContext;
8757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
8857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
898e006e629800b4a2643416f97bca2711af728837Jeff Brown    public abstract void show();
9057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
918e006e629800b4a2643416f97bca2711af728837Jeff Brown    public abstract void dismiss();
9257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
938e006e629800b4a2643416f97bca2711af728837Jeff Brown    public abstract void updateAspectRatio(int width, int height);
948e006e629800b4a2643416f97bca2711af728837Jeff Brown
95cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang    public abstract Bitmap getSnapshot();
96cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang
978e006e629800b4a2643416f97bca2711af728837Jeff Brown    // Watches for significant changes in the overlay display window lifecycle.
988e006e629800b4a2643416f97bca2711af728837Jeff Brown    public interface OverlayWindowListener {
9976d965dc41863b33f887db33d283cb7f1523f60dJae Seo        void onWindowCreated(Surface surface);
10076d965dc41863b33f887db33d283cb7f1523f60dJae Seo        void onWindowCreated(SurfaceHolder surfaceHolder);
10176d965dc41863b33f887db33d283cb7f1523f60dJae Seo        void onWindowDestroyed();
10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1048e006e629800b4a2643416f97bca2711af728837Jeff Brown    /**
1058e006e629800b4a2643416f97bca2711af728837Jeff Brown     * Implementation for older versions.
1068e006e629800b4a2643416f97bca2711af728837Jeff Brown     */
107e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas    @SuppressWarnings("deprecation") // Intentionally using deprecated APIs for pre JB MR1 devices.
1088e006e629800b4a2643416f97bca2711af728837Jeff Brown    private static final class LegacyImpl extends OverlayDisplayWindow {
1098e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final WindowManager mWindowManager;
1108e006e629800b4a2643416f97bca2711af728837Jeff Brown
1118e006e629800b4a2643416f97bca2711af728837Jeff Brown        private boolean mWindowVisible;
1128e006e629800b4a2643416f97bca2711af728837Jeff Brown        private SurfaceView mSurfaceView;
1138e006e629800b4a2643416f97bca2711af728837Jeff Brown
1148e006e629800b4a2643416f97bca2711af728837Jeff Brown        public LegacyImpl(Context context, String name,
1158e006e629800b4a2643416f97bca2711af728837Jeff Brown                int width, int height, int gravity) {
1168e006e629800b4a2643416f97bca2711af728837Jeff Brown            super(context, name, width, height, gravity);
1178e006e629800b4a2643416f97bca2711af728837Jeff Brown
1188e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowManager = (WindowManager)context.getSystemService(
1198e006e629800b4a2643416f97bca2711af728837Jeff Brown                    Context.WINDOW_SERVICE);
12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1228e006e629800b4a2643416f97bca2711af728837Jeff Brown        @Override
1238e006e629800b4a2643416f97bca2711af728837Jeff Brown        public void show() {
1248e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (!mWindowVisible) {
1258e006e629800b4a2643416f97bca2711af728837Jeff Brown                mSurfaceView = new SurfaceView(mContext);
1268e006e629800b4a2643416f97bca2711af728837Jeff Brown
1278e006e629800b4a2643416f97bca2711af728837Jeff Brown                Display display = mWindowManager.getDefaultDisplay();
1288e006e629800b4a2643416f97bca2711af728837Jeff Brown
1298e006e629800b4a2643416f97bca2711af728837Jeff Brown                WindowManager.LayoutParams params = new WindowManager.LayoutParams(
1308e006e629800b4a2643416f97bca2711af728837Jeff Brown                        WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
1318e006e629800b4a2643416f97bca2711af728837Jeff Brown                params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1328e006e629800b4a2643416f97bca2711af728837Jeff Brown                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1338e006e629800b4a2643416f97bca2711af728837Jeff Brown                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
1348e006e629800b4a2643416f97bca2711af728837Jeff Brown                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1358e006e629800b4a2643416f97bca2711af728837Jeff Brown                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
1368e006e629800b4a2643416f97bca2711af728837Jeff Brown                params.alpha = WINDOW_ALPHA;
1378e006e629800b4a2643416f97bca2711af728837Jeff Brown                params.gravity = Gravity.LEFT | Gravity.BOTTOM;
1388e006e629800b4a2643416f97bca2711af728837Jeff Brown                params.setTitle(mName);
1398e006e629800b4a2643416f97bca2711af728837Jeff Brown
1408e006e629800b4a2643416f97bca2711af728837Jeff Brown                int width = (int)(display.getWidth() * INITIAL_SCALE);
1418e006e629800b4a2643416f97bca2711af728837Jeff Brown                int height = (int)(display.getHeight() * INITIAL_SCALE);
1428e006e629800b4a2643416f97bca2711af728837Jeff Brown                if (mWidth > mHeight) {
1438e006e629800b4a2643416f97bca2711af728837Jeff Brown                    height = mHeight * width / mWidth;
1448e006e629800b4a2643416f97bca2711af728837Jeff Brown                } else {
1458e006e629800b4a2643416f97bca2711af728837Jeff Brown                    width = mWidth * height / mHeight;
1468e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
1478e006e629800b4a2643416f97bca2711af728837Jeff Brown                params.width = width;
1488e006e629800b4a2643416f97bca2711af728837Jeff Brown                params.height = height;
1498e006e629800b4a2643416f97bca2711af728837Jeff Brown
1508e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowManager.addView(mSurfaceView, params);
1518e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowVisible = true;
1528e006e629800b4a2643416f97bca2711af728837Jeff Brown
1534523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang                SurfaceHolder holder = mSurfaceView.getHolder();
1544523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang                holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
1554523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang                mListener.onWindowCreated(holder);
1568e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
15757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
15857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1598e006e629800b4a2643416f97bca2711af728837Jeff Brown        @Override
1608e006e629800b4a2643416f97bca2711af728837Jeff Brown        public void dismiss() {
1618e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (mWindowVisible) {
1628e006e629800b4a2643416f97bca2711af728837Jeff Brown                mListener.onWindowDestroyed();
16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1648e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowManager.removeView(mSurfaceView);
1658e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowVisible = false;
1668e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1698e006e629800b4a2643416f97bca2711af728837Jeff Brown        @Override
1708e006e629800b4a2643416f97bca2711af728837Jeff Brown        public void updateAspectRatio(int width, int height) {
17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
172cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang
173cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        @Override
174cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        public Bitmap getSnapshot() {
175cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            return null;
176cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        }
1778e006e629800b4a2643416f97bca2711af728837Jeff Brown    }
17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1798e006e629800b4a2643416f97bca2711af728837Jeff Brown    /**
1808e006e629800b4a2643416f97bca2711af728837Jeff Brown     * Implementation for API version 17+.
1818e006e629800b4a2643416f97bca2711af728837Jeff Brown     */
18261636870e0a12db5909955eca58e0070357dde42Donghyun Cho    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
1838e006e629800b4a2643416f97bca2711af728837Jeff Brown    private static final class JellybeanMr1Impl extends OverlayDisplayWindow {
1848e006e629800b4a2643416f97bca2711af728837Jeff Brown        // When true, disables support for moving and resizing the overlay.
1858e006e629800b4a2643416f97bca2711af728837Jeff Brown        // The window is made non-touchable, which makes it possible to
1868e006e629800b4a2643416f97bca2711af728837Jeff Brown        // directly interact with the content underneath.
1878e006e629800b4a2643416f97bca2711af728837Jeff Brown        private static final boolean DISABLE_MOVE_AND_RESIZE = false;
18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1898e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final DisplayManager mDisplayManager;
1908e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final WindowManager mWindowManager;
19157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1928e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final Display mDefaultDisplay;
1938e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final DisplayMetrics mDefaultDisplayMetrics = new DisplayMetrics();
19457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1958e006e629800b4a2643416f97bca2711af728837Jeff Brown        private View mWindowContent;
1968e006e629800b4a2643416f97bca2711af728837Jeff Brown        private WindowManager.LayoutParams mWindowParams;
1978e006e629800b4a2643416f97bca2711af728837Jeff Brown        private TextureView mTextureView;
1988e006e629800b4a2643416f97bca2711af728837Jeff Brown        private TextView mNameTextView;
19957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
2008e006e629800b4a2643416f97bca2711af728837Jeff Brown        private GestureDetector mGestureDetector;
2018e006e629800b4a2643416f97bca2711af728837Jeff Brown        private ScaleGestureDetector mScaleGestureDetector;
20257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
2038e006e629800b4a2643416f97bca2711af728837Jeff Brown        private boolean mWindowVisible;
2048e006e629800b4a2643416f97bca2711af728837Jeff Brown        private int mWindowX;
2058e006e629800b4a2643416f97bca2711af728837Jeff Brown        private int mWindowY;
2068e006e629800b4a2643416f97bca2711af728837Jeff Brown        private float mWindowScale;
2078e006e629800b4a2643416f97bca2711af728837Jeff Brown
2088e006e629800b4a2643416f97bca2711af728837Jeff Brown        private float mLiveTranslationX;
2098e006e629800b4a2643416f97bca2711af728837Jeff Brown        private float mLiveTranslationY;
2108e006e629800b4a2643416f97bca2711af728837Jeff Brown        private float mLiveScale = 1.0f;
2118e006e629800b4a2643416f97bca2711af728837Jeff Brown
2128e006e629800b4a2643416f97bca2711af728837Jeff Brown        public JellybeanMr1Impl(Context context, String name,
2138e006e629800b4a2643416f97bca2711af728837Jeff Brown                int width, int height, int gravity) {
2148e006e629800b4a2643416f97bca2711af728837Jeff Brown            super(context, name, width, height, gravity);
2158e006e629800b4a2643416f97bca2711af728837Jeff Brown
2168e006e629800b4a2643416f97bca2711af728837Jeff Brown            mDisplayManager = (DisplayManager)context.getSystemService(
2178e006e629800b4a2643416f97bca2711af728837Jeff Brown                    Context.DISPLAY_SERVICE);
2188e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowManager = (WindowManager)context.getSystemService(
2198e006e629800b4a2643416f97bca2711af728837Jeff Brown                    Context.WINDOW_SERVICE);
2208e006e629800b4a2643416f97bca2711af728837Jeff Brown
2218e006e629800b4a2643416f97bca2711af728837Jeff Brown            mDefaultDisplay = mWindowManager.getDefaultDisplay();
2228e006e629800b4a2643416f97bca2711af728837Jeff Brown            updateDefaultDisplayInfo();
2238e006e629800b4a2643416f97bca2711af728837Jeff Brown
2248e006e629800b4a2643416f97bca2711af728837Jeff Brown            createWindow();
22557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
22657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
22757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
2288e006e629800b4a2643416f97bca2711af728837Jeff Brown        public void show() {
2298e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (!mWindowVisible) {
2308e006e629800b4a2643416f97bca2711af728837Jeff Brown                mDisplayManager.registerDisplayListener(mDisplayListener, null);
2318e006e629800b4a2643416f97bca2711af728837Jeff Brown                if (!updateDefaultDisplayInfo()) {
2328e006e629800b4a2643416f97bca2711af728837Jeff Brown                    mDisplayManager.unregisterDisplayListener(mDisplayListener);
2338e006e629800b4a2643416f97bca2711af728837Jeff Brown                    return;
23457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
2358e006e629800b4a2643416f97bca2711af728837Jeff Brown
2368e006e629800b4a2643416f97bca2711af728837Jeff Brown                clearLiveState();
2378e006e629800b4a2643416f97bca2711af728837Jeff Brown                updateWindowParams();
2388e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowManager.addView(mWindowContent, mWindowParams);
2398e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowVisible = true;
24057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
24157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
24257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
24357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
2448e006e629800b4a2643416f97bca2711af728837Jeff Brown        public void dismiss() {
2458e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (mWindowVisible) {
2468e006e629800b4a2643416f97bca2711af728837Jeff Brown                mDisplayManager.unregisterDisplayListener(mDisplayListener);
2478e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowManager.removeView(mWindowContent);
2488e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowVisible = false;
24957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
25057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
25157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
25257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
2538e006e629800b4a2643416f97bca2711af728837Jeff Brown        public void updateAspectRatio(int width, int height) {
2548e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (mWidth * height < mHeight * width) {
2558e006e629800b4a2643416f97bca2711af728837Jeff Brown                mTextureView.getLayoutParams().width = mWidth;
2568e006e629800b4a2643416f97bca2711af728837Jeff Brown                mTextureView.getLayoutParams().height = mWidth * height / width;
2578e006e629800b4a2643416f97bca2711af728837Jeff Brown            } else {
2588e006e629800b4a2643416f97bca2711af728837Jeff Brown                mTextureView.getLayoutParams().width = mHeight * width / height;
2598e006e629800b4a2643416f97bca2711af728837Jeff Brown                mTextureView.getLayoutParams().height = mHeight;
26057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
2618e006e629800b4a2643416f97bca2711af728837Jeff Brown            relayout();
26257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
26357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
264cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        @Override
265cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        public Bitmap getSnapshot() {
266cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            return mTextureView.getBitmap();
267cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        }
268cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang
2698e006e629800b4a2643416f97bca2711af728837Jeff Brown        private void relayout() {
2708e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (mWindowVisible) {
2718e006e629800b4a2643416f97bca2711af728837Jeff Brown                updateWindowParams();
2728e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowManager.updateViewLayout(mWindowContent, mWindowParams);
27357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
2768e006e629800b4a2643416f97bca2711af728837Jeff Brown        private boolean updateDefaultDisplayInfo() {
2778e006e629800b4a2643416f97bca2711af728837Jeff Brown            mDefaultDisplay.getMetrics(mDefaultDisplayMetrics);
2788e006e629800b4a2643416f97bca2711af728837Jeff Brown            return true;
27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
28057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
2818e006e629800b4a2643416f97bca2711af728837Jeff Brown        private void createWindow() {
2828e006e629800b4a2643416f97bca2711af728837Jeff Brown            LayoutInflater inflater = LayoutInflater.from(mContext);
2838e006e629800b4a2643416f97bca2711af728837Jeff Brown
2848e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowContent = inflater.inflate(
2858e006e629800b4a2643416f97bca2711af728837Jeff Brown                    R.layout.overlay_display_window, null);
2868e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowContent.setOnTouchListener(mOnTouchListener);
2878e006e629800b4a2643416f97bca2711af728837Jeff Brown
2888e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView = (TextureView)mWindowContent.findViewById(
2898e006e629800b4a2643416f97bca2711af728837Jeff Brown                    R.id.overlay_display_window_texture);
2908e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setPivotX(0);
2918e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setPivotY(0);
2928e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.getLayoutParams().width = mWidth;
2938e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.getLayoutParams().height = mHeight;
2948e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setOpaque(false);
2958e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
2968e006e629800b4a2643416f97bca2711af728837Jeff Brown
2978e006e629800b4a2643416f97bca2711af728837Jeff Brown            mNameTextView = (TextView)mWindowContent.findViewById(
2988e006e629800b4a2643416f97bca2711af728837Jeff Brown                    R.id.overlay_display_window_title);
2998e006e629800b4a2643416f97bca2711af728837Jeff Brown            mNameTextView.setText(mName);
3008e006e629800b4a2643416f97bca2711af728837Jeff Brown
3018e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams = new WindowManager.LayoutParams(
3028e006e629800b4a2643416f97bca2711af728837Jeff Brown                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
3038e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
3048e006e629800b4a2643416f97bca2711af728837Jeff Brown                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
3058e006e629800b4a2643416f97bca2711af728837Jeff Brown                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
3068e006e629800b4a2643416f97bca2711af728837Jeff Brown                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
3078e006e629800b4a2643416f97bca2711af728837Jeff Brown                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
3088e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (DISABLE_MOVE_AND_RESIZE) {
3098e006e629800b4a2643416f97bca2711af728837Jeff Brown                mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
3108e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
3118e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.alpha = WINDOW_ALPHA;
3128e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
3138e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.setTitle(mName);
3148e006e629800b4a2643416f97bca2711af728837Jeff Brown
3158e006e629800b4a2643416f97bca2711af728837Jeff Brown            mGestureDetector = new GestureDetector(mContext, mOnGestureListener);
3168e006e629800b4a2643416f97bca2711af728837Jeff Brown            mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener);
3178e006e629800b4a2643416f97bca2711af728837Jeff Brown
3188e006e629800b4a2643416f97bca2711af728837Jeff Brown            // Set the initial position and scale.
3198e006e629800b4a2643416f97bca2711af728837Jeff Brown            // The position and scale will be clamped when the display is first shown.
3208e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ?
3218e006e629800b4a2643416f97bca2711af728837Jeff Brown                    0 : mDefaultDisplayMetrics.widthPixels;
3228e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ?
3238e006e629800b4a2643416f97bca2711af728837Jeff Brown                    0 : mDefaultDisplayMetrics.heightPixels;
3248e006e629800b4a2643416f97bca2711af728837Jeff Brown            Log.d(TAG, mDefaultDisplayMetrics.toString());
3258e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowScale = INITIAL_SCALE;
3268e006e629800b4a2643416f97bca2711af728837Jeff Brown
3278e006e629800b4a2643416f97bca2711af728837Jeff Brown            // calculate and save initial settings
3288e006e629800b4a2643416f97bca2711af728837Jeff Brown            updateWindowParams();
3298e006e629800b4a2643416f97bca2711af728837Jeff Brown            saveWindowParams();
33057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
33157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3328e006e629800b4a2643416f97bca2711af728837Jeff Brown        private void updateWindowParams() {
3338e006e629800b4a2643416f97bca2711af728837Jeff Brown            float scale = mWindowScale * mLiveScale;
3348e006e629800b4a2643416f97bca2711af728837Jeff Brown            scale = Math.min(scale, (float)mDefaultDisplayMetrics.widthPixels / mWidth);
3358e006e629800b4a2643416f97bca2711af728837Jeff Brown            scale = Math.min(scale, (float)mDefaultDisplayMetrics.heightPixels / mHeight);
3368e006e629800b4a2643416f97bca2711af728837Jeff Brown            scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
3378e006e629800b4a2643416f97bca2711af728837Jeff Brown
3388e006e629800b4a2643416f97bca2711af728837Jeff Brown            float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f;
3398e006e629800b4a2643416f97bca2711af728837Jeff Brown            int width = (int)(mWidth * scale);
3408e006e629800b4a2643416f97bca2711af728837Jeff Brown            int height = (int)(mHeight * scale);
3418e006e629800b4a2643416f97bca2711af728837Jeff Brown            int x = (int)(mWindowX + mLiveTranslationX - width * offsetScale);
3428e006e629800b4a2643416f97bca2711af728837Jeff Brown            int y = (int)(mWindowY + mLiveTranslationY - height * offsetScale);
3438e006e629800b4a2643416f97bca2711af728837Jeff Brown            x = Math.max(0, Math.min(x, mDefaultDisplayMetrics.widthPixels - width));
3448e006e629800b4a2643416f97bca2711af728837Jeff Brown            y = Math.max(0, Math.min(y, mDefaultDisplayMetrics.heightPixels - height));
3458e006e629800b4a2643416f97bca2711af728837Jeff Brown
3468e006e629800b4a2643416f97bca2711af728837Jeff Brown            if (DEBUG) {
3478e006e629800b4a2643416f97bca2711af728837Jeff Brown                Log.d(TAG, "updateWindowParams: scale=" + scale
3488e006e629800b4a2643416f97bca2711af728837Jeff Brown                        + ", offsetScale=" + offsetScale
3498e006e629800b4a2643416f97bca2711af728837Jeff Brown                        + ", x=" + x + ", y=" + y
3508e006e629800b4a2643416f97bca2711af728837Jeff Brown                        + ", width=" + width + ", height=" + height);
35157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
35257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3538e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setScaleX(scale);
3548e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setScaleY(scale);
3558e006e629800b4a2643416f97bca2711af728837Jeff Brown
3568e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setTranslationX(
3578e006e629800b4a2643416f97bca2711af728837Jeff Brown                    (mWidth - mTextureView.getLayoutParams().width) * scale / 2);
3588e006e629800b4a2643416f97bca2711af728837Jeff Brown            mTextureView.setTranslationY(
3598e006e629800b4a2643416f97bca2711af728837Jeff Brown                    (mHeight - mTextureView.getLayoutParams().height) * scale / 2);
3608e006e629800b4a2643416f97bca2711af728837Jeff Brown
3618e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.x = x;
3628e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.y = y;
3638e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.width = width;
3648e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowParams.height = height;
36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3678e006e629800b4a2643416f97bca2711af728837Jeff Brown        private void saveWindowParams() {
3688e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowX = mWindowParams.x;
3698e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowY = mWindowParams.y;
3708e006e629800b4a2643416f97bca2711af728837Jeff Brown            mWindowScale = mTextureView.getScaleX();
3718e006e629800b4a2643416f97bca2711af728837Jeff Brown            clearLiveState();
37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3748e006e629800b4a2643416f97bca2711af728837Jeff Brown        private void clearLiveState() {
3758e006e629800b4a2643416f97bca2711af728837Jeff Brown            mLiveTranslationX = 0f;
3768e006e629800b4a2643416f97bca2711af728837Jeff Brown            mLiveTranslationY = 0f;
3778e006e629800b4a2643416f97bca2711af728837Jeff Brown            mLiveScale = 1.0f;
37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3808e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final DisplayManager.DisplayListener mDisplayListener =
3818e006e629800b4a2643416f97bca2711af728837Jeff Brown                new DisplayManager.DisplayListener() {
3828e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
3838e006e629800b4a2643416f97bca2711af728837Jeff Brown            public void onDisplayAdded(int displayId) {
3848e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
3858e006e629800b4a2643416f97bca2711af728837Jeff Brown
3868e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
3878e006e629800b4a2643416f97bca2711af728837Jeff Brown            public void onDisplayChanged(int displayId) {
3888e006e629800b4a2643416f97bca2711af728837Jeff Brown                if (displayId == mDefaultDisplay.getDisplayId()) {
3898e006e629800b4a2643416f97bca2711af728837Jeff Brown                    if (updateDefaultDisplayInfo()) {
3908e006e629800b4a2643416f97bca2711af728837Jeff Brown                        relayout();
3918e006e629800b4a2643416f97bca2711af728837Jeff Brown                    } else {
3928e006e629800b4a2643416f97bca2711af728837Jeff Brown                        dismiss();
3938e006e629800b4a2643416f97bca2711af728837Jeff Brown                    }
3948e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
3958e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
3968e006e629800b4a2643416f97bca2711af728837Jeff Brown
3978e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
3988e006e629800b4a2643416f97bca2711af728837Jeff Brown            public void onDisplayRemoved(int displayId) {
3998e006e629800b4a2643416f97bca2711af728837Jeff Brown                if (displayId == mDefaultDisplay.getDisplayId()) {
4008e006e629800b4a2643416f97bca2711af728837Jeff Brown                    dismiss();
4018e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
4028e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4038e006e629800b4a2643416f97bca2711af728837Jeff Brown        };
4048e006e629800b4a2643416f97bca2711af728837Jeff Brown
4058e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final SurfaceTextureListener mSurfaceTextureListener =
4068e006e629800b4a2643416f97bca2711af728837Jeff Brown                new SurfaceTextureListener() {
4078e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4088e006e629800b4a2643416f97bca2711af728837Jeff Brown            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
4098e006e629800b4a2643416f97bca2711af728837Jeff Brown                    int width, int height) {
4108e006e629800b4a2643416f97bca2711af728837Jeff Brown                if (mListener != null) {
4118e006e629800b4a2643416f97bca2711af728837Jeff Brown                    mListener.onWindowCreated(new Surface(surfaceTexture));
4128e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
4138e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4148e006e629800b4a2643416f97bca2711af728837Jeff Brown
4158e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4168e006e629800b4a2643416f97bca2711af728837Jeff Brown            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
4178e006e629800b4a2643416f97bca2711af728837Jeff Brown                if (mListener != null) {
4188e006e629800b4a2643416f97bca2711af728837Jeff Brown                    mListener.onWindowDestroyed();
4198e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
4208e006e629800b4a2643416f97bca2711af728837Jeff Brown                return true;
4218e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4228e006e629800b4a2643416f97bca2711af728837Jeff Brown
4238e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4248e006e629800b4a2643416f97bca2711af728837Jeff Brown            public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
4258e006e629800b4a2643416f97bca2711af728837Jeff Brown                    int width, int height) {
4268e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4278e006e629800b4a2643416f97bca2711af728837Jeff Brown
4288e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4298e006e629800b4a2643416f97bca2711af728837Jeff Brown            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
4308e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4318e006e629800b4a2643416f97bca2711af728837Jeff Brown        };
4328e006e629800b4a2643416f97bca2711af728837Jeff Brown
4338e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
4348e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4358e006e629800b4a2643416f97bca2711af728837Jeff Brown            public boolean onTouch(View view, MotionEvent event) {
4368e006e629800b4a2643416f97bca2711af728837Jeff Brown                // Work in screen coordinates.
4378e006e629800b4a2643416f97bca2711af728837Jeff Brown                final float oldX = event.getX();
4388e006e629800b4a2643416f97bca2711af728837Jeff Brown                final float oldY = event.getY();
4398e006e629800b4a2643416f97bca2711af728837Jeff Brown                event.setLocation(event.getRawX(), event.getRawY());
4408e006e629800b4a2643416f97bca2711af728837Jeff Brown
4418e006e629800b4a2643416f97bca2711af728837Jeff Brown                mGestureDetector.onTouchEvent(event);
4428e006e629800b4a2643416f97bca2711af728837Jeff Brown                mScaleGestureDetector.onTouchEvent(event);
4438e006e629800b4a2643416f97bca2711af728837Jeff Brown
4448e006e629800b4a2643416f97bca2711af728837Jeff Brown                switch (event.getActionMasked()) {
4458e006e629800b4a2643416f97bca2711af728837Jeff Brown                    case MotionEvent.ACTION_UP:
4468e006e629800b4a2643416f97bca2711af728837Jeff Brown                    case MotionEvent.ACTION_CANCEL:
4478e006e629800b4a2643416f97bca2711af728837Jeff Brown                        saveWindowParams();
4488e006e629800b4a2643416f97bca2711af728837Jeff Brown                        break;
4498e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
4508e006e629800b4a2643416f97bca2711af728837Jeff Brown
4518e006e629800b4a2643416f97bca2711af728837Jeff Brown                // Revert to window coordinates.
4528e006e629800b4a2643416f97bca2711af728837Jeff Brown                event.setLocation(oldX, oldY);
4538e006e629800b4a2643416f97bca2711af728837Jeff Brown                return true;
4548e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4558e006e629800b4a2643416f97bca2711af728837Jeff Brown        };
4568e006e629800b4a2643416f97bca2711af728837Jeff Brown
4578e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final GestureDetector.OnGestureListener mOnGestureListener =
4588e006e629800b4a2643416f97bca2711af728837Jeff Brown                new GestureDetector.SimpleOnGestureListener() {
4598e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4608e006e629800b4a2643416f97bca2711af728837Jeff Brown            public boolean onScroll(MotionEvent e1, MotionEvent e2,
4618e006e629800b4a2643416f97bca2711af728837Jeff Brown                    float distanceX, float distanceY) {
4628e006e629800b4a2643416f97bca2711af728837Jeff Brown                mLiveTranslationX -= distanceX;
4638e006e629800b4a2643416f97bca2711af728837Jeff Brown                mLiveTranslationY -= distanceY;
4648e006e629800b4a2643416f97bca2711af728837Jeff Brown                relayout();
4658e006e629800b4a2643416f97bca2711af728837Jeff Brown                return true;
4668e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4678e006e629800b4a2643416f97bca2711af728837Jeff Brown        };
4688e006e629800b4a2643416f97bca2711af728837Jeff Brown
4698e006e629800b4a2643416f97bca2711af728837Jeff Brown        private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener =
4708e006e629800b4a2643416f97bca2711af728837Jeff Brown                new ScaleGestureDetector.SimpleOnScaleGestureListener() {
4718e006e629800b4a2643416f97bca2711af728837Jeff Brown            @Override
4728e006e629800b4a2643416f97bca2711af728837Jeff Brown            public boolean onScale(ScaleGestureDetector detector) {
4738e006e629800b4a2643416f97bca2711af728837Jeff Brown                mLiveScale *= detector.getScaleFactor();
4748e006e629800b4a2643416f97bca2711af728837Jeff Brown                relayout();
4758e006e629800b4a2643416f97bca2711af728837Jeff Brown                return true;
4768e006e629800b4a2643416f97bca2711af728837Jeff Brown            }
4778e006e629800b4a2643416f97bca2711af728837Jeff Brown        };
47857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
4794523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang}
480