blob: 824040a81ec7183aa6003125688e25622ce2fac5 [file] [log] [blame]
Sunny Goyal740ac7f2016-09-28 16:47:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.launcher3;
18
Tony Wickham50e51652017-03-20 17:12:24 -070019import android.annotation.SuppressLint;
Sunny Goyal740ac7f2016-09-28 16:47:32 -070020import android.content.Context;
21import android.support.annotation.IntDef;
22import android.util.AttributeSet;
Tony Wickham50e51652017-03-20 17:12:24 -070023import android.view.MotionEvent;
Sunny Goyal740ac7f2016-09-28 16:47:32 -070024import android.view.View;
25import android.widget.LinearLayout;
26
27import com.android.launcher3.dragndrop.DragLayer;
Sunny Goyal37920962017-09-28 13:43:24 -070028import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
29import com.android.launcher3.util.TouchController;
Sunny Goyal740ac7f2016-09-28 16:47:32 -070030
31import java.lang.annotation.Retention;
32import java.lang.annotation.RetentionPolicy;
33
34/**
35 * Base class for a View which shows a floating UI on top of the launcher UI.
36 */
Sunny Goyal37920962017-09-28 13:43:24 -070037public abstract class AbstractFloatingView extends LinearLayout implements TouchController {
Sunny Goyal740ac7f2016-09-28 16:47:32 -070038
Tony Wickham50e51652017-03-20 17:12:24 -070039 @IntDef(flag = true, value = {
40 TYPE_FOLDER,
Sunny Goyal10a1bd02017-10-09 14:56:21 -070041 TYPE_ACTION_POPUP,
Sunny Goyal37920962017-09-28 13:43:24 -070042 TYPE_WIDGETS_BOTTOM_SHEET,
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070043 TYPE_WIDGET_RESIZE_FRAME,
Sunny Goyalf8088ee2017-11-10 14:52:00 -080044 TYPE_WIDGETS_FULL_SHEET,
Tony Mak191b6882017-11-29 18:39:49 +000045 TYPE_QUICKSTEP_PREVIEW,
Tony Wickham2fae2a02017-12-14 18:38:25 -080046 TYPE_ON_BOARD_POPUP,
47 TYPE_TASK_MENU
Tony Wickham50e51652017-03-20 17:12:24 -070048 })
Sunny Goyal740ac7f2016-09-28 16:47:32 -070049 @Retention(RetentionPolicy.SOURCE)
50 public @interface FloatingViewType {}
51 public static final int TYPE_FOLDER = 1 << 0;
Sunny Goyal10a1bd02017-10-09 14:56:21 -070052 public static final int TYPE_ACTION_POPUP = 1 << 1;
Tony Wickham343a77e2017-04-12 18:31:09 -070053 public static final int TYPE_WIDGETS_BOTTOM_SHEET = 1 << 2;
Sunny Goyal37920962017-09-28 13:43:24 -070054 public static final int TYPE_WIDGET_RESIZE_FRAME = 1 << 3;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070055 public static final int TYPE_WIDGETS_FULL_SHEET = 1 << 4;
Sunny Goyalf8088ee2017-11-10 14:52:00 -080056 public static final int TYPE_QUICKSTEP_PREVIEW = 1 << 5;
Tony Mak191b6882017-11-29 18:39:49 +000057 public static final int TYPE_ON_BOARD_POPUP = 1 << 6;
Tony Wickham2fae2a02017-12-14 18:38:25 -080058 public static final int TYPE_TASK_MENU = 1 << 7;
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -070059
60 public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
Sunny Goyalf8088ee2017-11-10 14:52:00 -080061 | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
Tony Wickham2fae2a02017-12-14 18:38:25 -080062 | TYPE_QUICKSTEP_PREVIEW | TYPE_ON_BOARD_POPUP | TYPE_TASK_MENU;
Sunny Goyal740ac7f2016-09-28 16:47:32 -070063
Sunny Goyal7ede6112017-12-05 15:11:21 -080064 // Type of popups which should be kept open during launcher rebind
65 public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
66 | TYPE_QUICKSTEP_PREVIEW | TYPE_ON_BOARD_POPUP;
67
Sunny Goyal740ac7f2016-09-28 16:47:32 -070068 protected boolean mIsOpen;
69
70 public AbstractFloatingView(Context context, AttributeSet attrs) {
71 super(context, attrs);
72 }
73
74 public AbstractFloatingView(Context context, AttributeSet attrs, int defStyleAttr) {
75 super(context, attrs, defStyleAttr);
76 }
77
Tony Wickham50e51652017-03-20 17:12:24 -070078 /**
79 * We need to handle touch events to prevent them from falling through to the workspace below.
80 */
81 @SuppressLint("ClickableViewAccessibility")
82 @Override
83 public boolean onTouchEvent(MotionEvent ev) {
84 return true;
85 }
86
Sunny Goyal740ac7f2016-09-28 16:47:32 -070087 public final void close(boolean animate) {
88 animate &= !Utilities.isPowerSaverOn(getContext());
89 handleClose(animate);
90 Launcher.getLauncher(getContext()).getUserEventDispatcher().resetElapsedContainerMillis();
91 }
92
93 protected abstract void handleClose(boolean animate);
94
Sunny Goyal37920962017-09-28 13:43:24 -070095 public abstract void logActionCommand(int command);
Sunny Goyal740ac7f2016-09-28 16:47:32 -070096
97 public final boolean isOpen() {
98 return mIsOpen;
99 }
100
Tony Wickham26b17462017-03-20 17:12:24 -0700101 protected void onWidgetsBound() {
102 }
103
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700104 protected abstract boolean isOfType(@FloatingViewType int type);
105
Sunny Goyal37920962017-09-28 13:43:24 -0700106 public void onBackPressed() {
107 logActionCommand(Action.Command.BACK);
108 close(true);
109 }
110
111 @Override
112 public boolean onControllerTouchEvent(MotionEvent ev) {
113 return false;
114 }
115
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700116 protected static <T extends AbstractFloatingView> T getOpenView(
117 Launcher launcher, @FloatingViewType int type) {
118 DragLayer dragLayer = launcher.getDragLayer();
119 // Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
120 // and will be one of the last views.
121 for (int i = dragLayer.getChildCount() - 1; i >= 0; i--) {
122 View child = dragLayer.getChildAt(i);
123 if (child instanceof AbstractFloatingView) {
124 AbstractFloatingView view = (AbstractFloatingView) child;
125 if (view.isOfType(type) && view.isOpen()) {
126 return (T) view;
127 }
128 }
129 }
130 return null;
131 }
132
Tony Wickham51889b02017-02-27 16:30:47 -0800133 public static void closeOpenContainer(Launcher launcher, @FloatingViewType int type) {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700134 AbstractFloatingView view = getOpenView(launcher, type);
135 if (view != null) {
136 view.close(true);
137 }
138 }
139
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700140 public static void closeOpenViews(Launcher launcher, boolean animate,
141 @FloatingViewType int type) {
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700142 DragLayer dragLayer = launcher.getDragLayer();
143 // Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
144 // and will be one of the last views.
145 for (int i = dragLayer.getChildCount() - 1; i >= 0; i--) {
146 View child = dragLayer.getChildAt(i);
147 if (child instanceof AbstractFloatingView) {
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700148 AbstractFloatingView abs = (AbstractFloatingView) child;
149 if (abs.isOfType(type)) {
150 abs.close(animate);
151 }
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700152 }
153 }
154 }
155
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700156 public static void closeAllOpenViews(Launcher launcher, boolean animate) {
157 closeOpenViews(launcher, animate, TYPE_ALL);
Sunny Goyal7c8a65e2017-12-22 11:11:33 -0800158 launcher.finishAutoCancelActionMode();
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700159 }
160
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700161 public static void closeAllOpenViews(Launcher launcher) {
162 closeAllOpenViews(launcher, true);
163 }
164
165 public static AbstractFloatingView getTopOpenView(Launcher launcher) {
Sunny Goyalf1fbc3f2017-10-10 15:21:15 -0700166 return getOpenView(launcher, TYPE_ALL);
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700167 }
Sunny Goyal740ac7f2016-09-28 16:47:32 -0700168}