DecorCaptionView.java revision 3dec081967db3c0e906ff272d632618e260b6413
161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne/* 261b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * Copyright (C) 2015 The Android Open Source Project 361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * 461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * Licensed under the Apache License, Version 2.0 (the "License"); 561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * you may not use this file except in compliance with the License. 661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * You may obtain a copy of the License at 761b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * 861b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * http://www.apache.org/licenses/LICENSE-2.0 961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * 1061b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * Unless required by applicable law or agreed to in writing, software 1161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * distributed under the License is distributed on an "AS IS" BASIS, 1261b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * See the License for the specific language governing permissions and 1461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * limitations under the License. 1561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne */ 1661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 1761b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhnepackage com.android.internal.widget; 1861b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 193797c22ea16e932329ebffdc7e7ce09f9ecd9545Wale Ogunwaleimport static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 203797c22ea16e932329ebffdc7e7ce09f9ecd9545Wale Ogunwale 2161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport android.content.Context; 22a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskiimport android.graphics.Color; 23a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskiimport android.graphics.Rect; 2461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport android.os.RemoteException; 2561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport android.util.AttributeSet; 26a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskiimport android.util.Log; 27a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskiimport android.view.GestureDetector; 2881c524a66480d44b51600abee24c28d66603f15eSkuhneimport android.view.MotionEvent; 2961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport android.view.View; 30a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskiimport android.view.ViewConfiguration; 3161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport android.view.ViewGroup; 32f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhneimport android.view.ViewOutlineProvider; 33f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhneimport android.view.Window; 3461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 3561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport com.android.internal.R; 3661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhneimport com.android.internal.policy.PhoneWindow; 3761b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 38a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskiimport java.util.ArrayList; 39a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 4061b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne/** 4162a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale * This class represents the special screen elements to control a window on freeform 4262a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale * environment. 4361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * As such this class handles the following things: 4461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * <ul> 4561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * <li>The caption, containing the system buttons like maximize, close and such as well as 4661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * allowing the user to drag the window around.</li> 47a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * </ul> 48a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * After creating the view, the function {@link #setPhoneWindow} needs to be called to make 4961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * the connection to it's owning PhoneWindow. 5061b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * Note: At this time the application can change various attributes of the DecorView which 5161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * will break things (in settle/unexpected ways): 5261b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * <ul> 5361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * <li>setOutlineProvider</li> 5461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * <li>setSurfaceFormat</li> 5561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * <li>..</li> 5661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne * </ul> 57a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * 58a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * Although this ViewGroup has only two direct sub-Views, its behavior is more complex due to 59a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * overlaying caption on the content and drawing. 60a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * 61a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * First, no matter where the content View gets added, it will always be the first child and the 62a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * caption will be the second. This way the caption will always be drawn on top of the content when 63a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * overlaying is enabled. 64a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * 65a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * Second, the touch dispatch is customized to handle overlaying. This is what happens when touch 66a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * is dispatched on the caption area while overlaying it on content: 67a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * <ul> 68a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * <li>DecorCaptionView.onInterceptTouchEvent() will try intercepting the touch events if the 69a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * down action is performed on top close or maximize buttons; the reason for that is we want these 70a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * buttons to always work.</li> 71a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * <li>The content View will receive the touch event. Mind that content is actually underneath the 72a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * caption, so we need to introduce our own dispatch ordering. We achieve this by overriding 73a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * {@link #buildTouchDispatchChildList()}.</li> 74a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * <li>If the touch event is not consumed by the content View, it will go to the caption View 75a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * and the dragging logic will be executed.</li> 76a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski * </ul> 7761b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne */ 78a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynskipublic class DecorCaptionView extends ViewGroup implements View.OnTouchListener, 79a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski GestureDetector.OnGestureListener { 8062a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale private final static String TAG = "DecorCaptionView"; 8161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne private PhoneWindow mOwner = null; 8262a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale private boolean mShow = false; 8381c524a66480d44b51600abee24c28d66603f15eSkuhne 8481c524a66480d44b51600abee24c28d66603f15eSkuhne // True if the window is being dragged. 8581c524a66480d44b51600abee24c28d66603f15eSkuhne private boolean mDragging = false; 8681c524a66480d44b51600abee24c28d66603f15eSkuhne 8781c524a66480d44b51600abee24c28d66603f15eSkuhne // True when the left mouse button got released while dragging. 8881c524a66480d44b51600abee24c28d66603f15eSkuhne private boolean mLeftMouseButtonReleased; 8981c524a66480d44b51600abee24c28d66603f15eSkuhne 9063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski private boolean mOverlayWithAppContent = false; 9163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 9263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski private View mCaption; 9363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski private View mContent; 94a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private View mMaximize; 95a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private View mClose; 96a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 97a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // Fields for detecting drag events. 98a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private int mTouchDownX; 99a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private int mTouchDownY; 100a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private boolean mCheckForDragging; 101a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private int mDragSlop; 102a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 103a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // Fields for detecting and intercepting click events on close/maximize. 104a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private ArrayList<View> mTouchDispatchList = new ArrayList<>(2); 105a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // We use the gesture detector to detect clicks on close/maximize buttons and to be consistent 106a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // with existing click detection. 107a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private GestureDetector mGestureDetector; 108a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private final Rect mCloseRect = new Rect(); 109a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private final Rect mMaximizeRect = new Rect(); 110a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private View mClickTarget; 11163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 11262a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public DecorCaptionView(Context context) { 11361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne super(context); 114a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski init(context); 11561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 11661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 11762a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public DecorCaptionView(Context context, AttributeSet attrs) { 11861b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne super(context, attrs); 119a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski init(context); 12061b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 12161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 12262a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public DecorCaptionView(Context context, AttributeSet attrs, int defStyle) { 12361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne super(context, attrs, defStyle); 124a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski init(context); 125a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 126a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 127a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private void init(Context context) { 128a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mDragSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 129a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mGestureDetector = new GestureDetector(context, this); 13061b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 13161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 13263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 13363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski protected void onFinishInflate() { 13463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski super.onFinishInflate(); 13563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mCaption = getChildAt(0); 13663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 13763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 13862a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public void setPhoneWindow(PhoneWindow owner, boolean show) { 13961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne mOwner = owner; 14062a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale mShow = show; 14163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mOverlayWithAppContent = owner.getOverlayDecorCaption(); 142a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mOverlayWithAppContent) { 143a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // The caption is covering the content, so we make its background transparent to make 144a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // the content visible. 145a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mCaption.setBackgroundColor(Color.TRANSPARENT); 146a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 147f7b882c9c64418f1aacf4ffb73e8a3f92fed15deSkuhne updateCaptionVisibility(); 14861b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne // By changing the outline provider to BOUNDS, the window can remove its 14961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne // background without removing the shadow. 15061b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne mOwner.getDecorView().setOutlineProvider(ViewOutlineProvider.BOUNDS); 151a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mMaximize = findViewById(R.id.maximize_window); 152a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mClose = findViewById(R.id.close_window); 153a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 154b816087962aba0019b022303330f03b897b580edSkuhne 155a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 156a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public boolean onInterceptTouchEvent(MotionEvent ev) { 157a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // If the user starts touch on the maximize/close buttons, we immediately intercept, so 158a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // that these buttons are always clickable. 159a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (ev.getAction() == MotionEvent.ACTION_DOWN) { 160a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski final int x = (int) ev.getX(); 161a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski final int y = (int) ev.getY(); 162a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mMaximizeRect.contains(x, y)) { 163a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mClickTarget = mMaximize; 164a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 165a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mCloseRect.contains(x, y)) { 166a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mClickTarget = mClose; 167a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 168a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 169a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return mClickTarget != null; 170a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 171a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 172a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 173a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public boolean onTouchEvent(MotionEvent event) { 174a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mClickTarget != null) { 175a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mGestureDetector.onTouchEvent(event); 176a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski final int action = event.getAction(); 177a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 178a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mClickTarget = null; 179a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 180a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return true; 181a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 182a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return false; 18361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 18461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 18581c524a66480d44b51600abee24c28d66603f15eSkuhne @Override 186509ea6b28576c9dd7766bfa4878159c21a971cebChong Zhang public boolean onTouch(View v, MotionEvent e) { 18781c524a66480d44b51600abee24c28d66603f15eSkuhne // Note: There are no mixed events. When a new device gets used (e.g. 1. Mouse, 2. touch) 18881c524a66480d44b51600abee24c28d66603f15eSkuhne // the old input device events get cancelled first. So no need to remember the kind of 18981c524a66480d44b51600abee24c28d66603f15eSkuhne // input device we are listening to. 190a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski final int x = (int) e.getX(); 191a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski final int y = (int) e.getY(); 19281c524a66480d44b51600abee24c28d66603f15eSkuhne switch (e.getActionMasked()) { 19381c524a66480d44b51600abee24c28d66603f15eSkuhne case MotionEvent.ACTION_DOWN: 19462a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale if (!mShow) { 19562a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale // When there is no caption we should not react to anything. 196a635a26716d98af90e8f6fded34b28983cdb58eaSkuhne return false; 197a635a26716d98af90e8f6fded34b28983cdb58eaSkuhne } 198a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // Checking for a drag action is started if we aren't dragging already and the 199a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski // starting event is either a left mouse button or any other input device. 200a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (((e.getToolType(e.getActionIndex()) != MotionEvent.TOOL_TYPE_MOUSE || 201a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski (e.getButtonState() & MotionEvent.BUTTON_PRIMARY) != 0))) { 202a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mCheckForDragging = true; 203a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mTouchDownX = x; 204a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mTouchDownY = y; 20581c524a66480d44b51600abee24c28d66603f15eSkuhne } 20681c524a66480d44b51600abee24c28d66603f15eSkuhne break; 20781c524a66480d44b51600abee24c28d66603f15eSkuhne 20881c524a66480d44b51600abee24c28d66603f15eSkuhne case MotionEvent.ACTION_MOVE: 209a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (!mDragging && mCheckForDragging && passedSlop(x, y)) { 210a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mCheckForDragging = false; 211a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mDragging = true; 212a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mLeftMouseButtonReleased = false; 213a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski startMovingTask(e.getRawX(), e.getRawY()); 214a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } else if (mDragging && !mLeftMouseButtonReleased) { 21581c524a66480d44b51600abee24c28d66603f15eSkuhne if (e.getToolType(e.getActionIndex()) == MotionEvent.TOOL_TYPE_MOUSE && 21681c524a66480d44b51600abee24c28d66603f15eSkuhne (e.getButtonState() & MotionEvent.BUTTON_PRIMARY) == 0) { 21781c524a66480d44b51600abee24c28d66603f15eSkuhne // There is no separate mouse button up call and if the user mixes mouse 21881c524a66480d44b51600abee24c28d66603f15eSkuhne // button drag actions, we stop dragging once he releases the button. 21981c524a66480d44b51600abee24c28d66603f15eSkuhne mLeftMouseButtonReleased = true; 22081c524a66480d44b51600abee24c28d66603f15eSkuhne break; 22181c524a66480d44b51600abee24c28d66603f15eSkuhne } 22281c524a66480d44b51600abee24c28d66603f15eSkuhne } 22381c524a66480d44b51600abee24c28d66603f15eSkuhne break; 22481c524a66480d44b51600abee24c28d66603f15eSkuhne 22581c524a66480d44b51600abee24c28d66603f15eSkuhne case MotionEvent.ACTION_UP: 22681c524a66480d44b51600abee24c28d66603f15eSkuhne case MotionEvent.ACTION_CANCEL: 227a5a93eea9b696ad57c77b6855681a317865c565cSkuhne if (!mDragging) { 228a5a93eea9b696ad57c77b6855681a317865c565cSkuhne break; 22981c524a66480d44b51600abee24c28d66603f15eSkuhne } 230a5a93eea9b696ad57c77b6855681a317865c565cSkuhne // Abort the ongoing dragging. 231a5a93eea9b696ad57c77b6855681a317865c565cSkuhne mDragging = false; 232a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return !mCheckForDragging; 23381c524a66480d44b51600abee24c28d66603f15eSkuhne } 234a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return mDragging || mCheckForDragging; 235a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 236a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 237a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 238a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public ArrayList<View> buildTouchDispatchChildList() { 239a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mTouchDispatchList.ensureCapacity(3); 240a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mCaption != null) { 241a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mTouchDispatchList.add(mCaption); 242a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 243a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mContent != null) { 244a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mTouchDispatchList.add(mContent); 245a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 246a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return mTouchDispatchList; 247a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 248a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 249a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski private boolean passedSlop(int x, int y) { 250a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return Math.abs(x - mTouchDownX) > mDragSlop || Math.abs(y - mTouchDownY) > mDragSlop; 25181c524a66480d44b51600abee24c28d66603f15eSkuhne } 25281c524a66480d44b51600abee24c28d66603f15eSkuhne 253f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne /** 25462a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale * The phone window configuration has changed and the caption needs to be updated. 25562a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale * @param show True if the caption should be shown. 2562b547c3f30d3fdfd9b544972051a32b9aa4135cfWale Ogunwale */ 25762a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public void onConfigurationChanged(boolean show) { 25862a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale mShow = show; 259f7b882c9c64418f1aacf4ffb73e8a3f92fed15deSkuhne updateCaptionVisibility(); 260f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne } 261f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne 26261b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne @Override 263f7b882c9c64418f1aacf4ffb73e8a3f92fed15deSkuhne public void addView(View child, int index, ViewGroup.LayoutParams params) { 26463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (!(params instanceof MarginLayoutParams)) { 26563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski throw new IllegalArgumentException( 26663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski "params " + params + " must subclass MarginLayoutParams"); 26763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 268f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne // Make sure that we never get more then one client area in our view. 26961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne if (index >= 2 || getChildCount() >= 2) { 27062a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale throw new IllegalStateException("DecorCaptionView can only handle 1 client view"); 27161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 27263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski // To support the overlaying content in the caption, we need to put the content view as the 27363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski // first child to get the right Z-Ordering. 27463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski super.addView(child, 0, params); 27563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mContent = child; 27663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 27763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 27863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 27963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 28063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski final int captionHeight; 28163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mCaption.getVisibility() != View.GONE) { 28263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski measureChildWithMargins(mCaption, widthMeasureSpec, 0, heightMeasureSpec, 0); 28363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski captionHeight = mCaption.getMeasuredHeight(); 28463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } else { 28563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski captionHeight = 0; 28663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 28763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mContent != null) { 28863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mOverlayWithAppContent) { 28963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0); 29063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } else { 29163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 29263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski captionHeight); 29363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 29463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 29563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 29663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), 29763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski MeasureSpec.getSize(heightMeasureSpec)); 29861b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 29961b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 30063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 30163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 30263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski final int captionHeight; 30363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mCaption.getVisibility() != View.GONE) { 30463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mCaption.layout(0, 0, mCaption.getMeasuredWidth(), mCaption.getMeasuredHeight()); 30563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski captionHeight = mCaption.getBottom() - mCaption.getTop(); 306a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mMaximize.getHitRect(mMaximizeRect); 307a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mClose.getHitRect(mCloseRect); 30863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } else { 30963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski captionHeight = 0; 310a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mMaximizeRect.setEmpty(); 311a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mCloseRect.setEmpty(); 31263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 31363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 31463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mContent != null) { 31563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mOverlayWithAppContent) { 31663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mContent.layout(0, 0, mContent.getMeasuredWidth(), mContent.getMeasuredHeight()); 31763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } else { 31863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mContent.layout(0, captionHeight, mContent.getMeasuredWidth(), 31963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski captionHeight + mContent.getMeasuredHeight()); 32063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 32163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 3223dec081967db3c0e906ff272d632618e260b6413Filip Gruszczynski 3233dec081967db3c0e906ff272d632618e260b6413Filip Gruszczynski // This assumes that the caption bar is at the top. 3243dec081967db3c0e906ff272d632618e260b6413Filip Gruszczynski mOwner.notifyRestrictedCaptionAreaCallback(mMaximize.getLeft(), mMaximize.getTop(), 3253dec081967db3c0e906ff272d632618e260b6413Filip Gruszczynski mClose.getRight(), mClose.getBottom()); 32663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 327f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne /** 328f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne * Determine if the workspace is entirely covered by the window. 329f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne * @return Returns true when the window is filling the entire screen/workspace. 330f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne **/ 33161b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne private boolean isFillingScreen() { 33261b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne return (0 != ((getWindowSystemUiVisibility() | getSystemUiVisibility()) & 33361b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | 33461b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_LOW_PROFILE))); 33561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 33661b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne 337f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne /** 338f7b882c9c64418f1aacf4ffb73e8a3f92fed15deSkuhne * Updates the visibility of the caption. 339f7b882c9c64418f1aacf4ffb73e8a3f92fed15deSkuhne **/ 340f7b882c9c64418f1aacf4ffb73e8a3f92fed15deSkuhne private void updateCaptionVisibility() { 34162a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale // Don't show the caption if the window has e.g. entered full screen. 34262a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale boolean invisible = isFillingScreen() || !mShow; 34363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mCaption.setVisibility(invisible ? GONE : VISIBLE); 34463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mCaption.setOnTouchListener(this); 34561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne } 3461b42057707dce8039326492e89a766f397043aa8Stefan Kuhne 347f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne /** 348f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne * Maximize the window by moving it to the maximized workspace stack. 349f4dd71a2657d23d12d5fe6e5e1273aab65d80ca4Stefan Kuhne **/ 3501b42057707dce8039326492e89a766f397043aa8Stefan Kuhne private void maximizeWindow() { 351ce2faa5871e3bf5ec8407506df18bed209dd824cSkuhne Window.WindowControllerCallback callback = mOwner.getWindowControllerCallback(); 3521b42057707dce8039326492e89a766f397043aa8Stefan Kuhne if (callback != null) { 3531b42057707dce8039326492e89a766f397043aa8Stefan Kuhne try { 3543797c22ea16e932329ebffdc7e7ce09f9ecd9545Wale Ogunwale callback.changeWindowStack(FULLSCREEN_WORKSPACE_STACK_ID); 3551b42057707dce8039326492e89a766f397043aa8Stefan Kuhne } catch (RemoteException ex) { 3561b42057707dce8039326492e89a766f397043aa8Stefan Kuhne Log.e(TAG, "Cannot change task workspace."); 3571b42057707dce8039326492e89a766f397043aa8Stefan Kuhne } 3581b42057707dce8039326492e89a766f397043aa8Stefan Kuhne } 3591b42057707dce8039326492e89a766f397043aa8Stefan Kuhne } 3608cc5a74c9049423260a14e0ebb44a052ef8f4e2aWale Ogunwale 36162a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public boolean isCaptionShowing() { 36262a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale return mShow; 3638cc5a74c9049423260a14e0ebb44a052ef8f4e2aWale Ogunwale } 3648cc5a74c9049423260a14e0ebb44a052ef8f4e2aWale Ogunwale 36562a91d67cee99998c941c76ad1a61acf1bb40b77Wale Ogunwale public int getCaptionHeight() { 36663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski return (mCaption != null) ? mCaption.getHeight() : 0; 36763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 36863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 36963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski public void removeContentView() { 37063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski if (mContent != null) { 37163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski removeView(mContent); 37263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski mContent = null; 37363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 37463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 37563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 37663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski public View getCaption() { 37763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski return mCaption; 37863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 37963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 38063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 38163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski public LayoutParams generateLayoutParams(AttributeSet attrs) { 38263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski return new MarginLayoutParams(getContext(), attrs); 38363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 38463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 38563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 38663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski protected LayoutParams generateDefaultLayoutParams() { 38763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski return new MarginLayoutParams(MarginLayoutParams.MATCH_PARENT, 38863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski MarginLayoutParams.MATCH_PARENT); 38963250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 39063250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 39163250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 39263250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski protected LayoutParams generateLayoutParams(LayoutParams p) { 39363250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski return new MarginLayoutParams(p); 39463250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski } 39563250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski 39663250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski @Override 39763250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 39863250651ca4656fc1b9e9ffb9c48d481df80454dFilip Gruszczynski return p instanceof MarginLayoutParams; 3998cc5a74c9049423260a14e0ebb44a052ef8f4e2aWale Ogunwale } 400a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 401a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 402a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public boolean onDown(MotionEvent e) { 403a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return false; 404a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 405a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 406a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 407a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public void onShowPress(MotionEvent e) { 408a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 409a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 410a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 411a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 412a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public boolean onSingleTapUp(MotionEvent e) { 413a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski if (mClickTarget == mMaximize) { 414a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski maximizeWindow(); 415a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } else if (mClickTarget == mClose) { 416a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski mOwner.dispatchOnWindowDismissed(true /*finishTask*/); 417a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 418a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return true; 419a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 420a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 421a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 422a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 423a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return false; 424a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 425a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 426a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 427a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public void onLongPress(MotionEvent e) { 428a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 429a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 430a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski 431a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski @Override 432a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 433a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski return false; 434a33bdf372cf045aa55db841307c64d30a50ab60dFilip Gruszczynski } 43561b47bb267dec696e1bb11f7c5eb6b9d2f4bd096Stefan Kuhne} 436