• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
17 package com.android.quickstep.views;
18 
19 import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
20 import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_SHARE;
21 import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
22 
23 import android.content.Context;
24 import android.content.res.Configuration;
25 import android.graphics.Rect;
26 import android.util.AttributeSet;
27 import android.view.View;
28 import android.view.View.OnClickListener;
29 import android.widget.FrameLayout;
30 
31 import androidx.annotation.IntDef;
32 import androidx.annotation.Nullable;
33 
34 import com.android.launcher3.Insettable;
35 import com.android.launcher3.R;
36 import com.android.launcher3.util.MultiValueAlpha;
37 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
38 import com.android.quickstep.SysUINavigationMode;
39 import com.android.quickstep.SysUINavigationMode.Mode;
40 import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
41 import com.android.quickstep.util.LayoutUtils;
42 
43 import java.lang.annotation.Retention;
44 import java.lang.annotation.RetentionPolicy;
45 
46 /**
47  * View for showing action buttons in Overview
48  */
49 public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayout
50         implements OnClickListener, Insettable {
51 
52     private final Rect mInsets = new Rect();
53 
54     @IntDef(flag = true, value = {
55             HIDDEN_UNSUPPORTED_NAVIGATION,
56             HIDDEN_DISABLED_FEATURE,
57             HIDDEN_NON_ZERO_ROTATION,
58             HIDDEN_NO_TASKS,
59             HIDDEN_GESTURE_RUNNING,
60             HIDDEN_NO_RECENTS})
61     @Retention(RetentionPolicy.SOURCE)
62     public @interface ActionsHiddenFlags { }
63 
64     public static final int HIDDEN_UNSUPPORTED_NAVIGATION = 1 << 0;
65     public static final int HIDDEN_DISABLED_FEATURE = 1 << 1;
66     public static final int HIDDEN_NON_ZERO_ROTATION = 1 << 2;
67     public static final int HIDDEN_NO_TASKS = 1 << 3;
68     public static final int HIDDEN_GESTURE_RUNNING = 1 << 4;
69     public static final int HIDDEN_NO_RECENTS = 1 << 5;
70 
71     @IntDef(flag = true, value = {
72             DISABLED_SCROLLING,
73             DISABLED_ROTATED,
74             DISABLED_NO_THUMBNAIL})
75     @Retention(RetentionPolicy.SOURCE)
76     public @interface ActionsDisabledFlags { }
77 
78     public static final int DISABLED_SCROLLING = 1 << 0;
79     public static final int DISABLED_ROTATED = 1 << 1;
80     public static final int DISABLED_NO_THUMBNAIL = 1 << 2;
81 
82     private static final int INDEX_CONTENT_ALPHA = 0;
83     private static final int INDEX_VISIBILITY_ALPHA = 1;
84     private static final int INDEX_FULLSCREEN_ALPHA = 2;
85     private static final int INDEX_HIDDEN_FLAGS_ALPHA = 3;
86 
87     private final MultiValueAlpha mMultiValueAlpha;
88 
89     @ActionsHiddenFlags
90     private int mHiddenFlags;
91 
92     @ActionsDisabledFlags
93     protected int mDisabledFlags;
94 
95     protected T mCallbacks;
96 
OverviewActionsView(Context context)97     public OverviewActionsView(Context context) {
98         this(context, null);
99     }
100 
OverviewActionsView(Context context, @Nullable AttributeSet attrs)101     public OverviewActionsView(Context context, @Nullable AttributeSet attrs) {
102         this(context, attrs, 0);
103     }
104 
OverviewActionsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)105     public OverviewActionsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
106         super(context, attrs, defStyleAttr, 0);
107         mMultiValueAlpha = new MultiValueAlpha(this, 4);
108         mMultiValueAlpha.setUpdateVisibility(true);
109     }
110 
111     @Override
onFinishInflate()112     protected void onFinishInflate() {
113         super.onFinishInflate();
114         View share = findViewById(R.id.action_share);
115         share.setOnClickListener(this);
116         findViewById(R.id.action_screenshot).setOnClickListener(this);
117         if (ENABLE_OVERVIEW_SHARE.get()) {
118             share.setVisibility(VISIBLE);
119             findViewById(R.id.share_space).setVisibility(VISIBLE);
120         }
121     }
122 
123     /**
124      * Set listener for callbacks on action button taps.
125      *
126      * @param callbacks for callbacks, or {@code null} to clear the listener.
127      */
setCallbacks(T callbacks)128     public void setCallbacks(T callbacks) {
129         mCallbacks = callbacks;
130     }
131 
132     @Override
onClick(View view)133     public void onClick(View view) {
134         if (mCallbacks == null) {
135             return;
136         }
137         int id = view.getId();
138         if (id == R.id.action_share) {
139             mCallbacks.onShare();
140         } else if (id == R.id.action_screenshot) {
141             mCallbacks.onScreenshot();
142         }
143     }
144 
145     @Override
onAttachedToWindow()146     protected void onAttachedToWindow() {
147         super.onAttachedToWindow();
148         updateHiddenFlags(HIDDEN_DISABLED_FEATURE, !ENABLE_OVERVIEW_ACTIONS.get());
149         updateHiddenFlags(HIDDEN_UNSUPPORTED_NAVIGATION, !removeShelfFromOverview(getContext()));
150     }
151 
152     @Override
onConfigurationChanged(Configuration newConfig)153     protected void onConfigurationChanged(Configuration newConfig) {
154         super.onConfigurationChanged(newConfig);
155         updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
156     }
157 
158     @Override
setInsets(Rect insets)159     public void setInsets(Rect insets) {
160         mInsets.set(insets);
161         updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
162     }
163 
updateHiddenFlags(@ctionsHiddenFlags int visibilityFlags, boolean enable)164     public void updateHiddenFlags(@ActionsHiddenFlags int visibilityFlags, boolean enable) {
165         if (enable) {
166             mHiddenFlags |= visibilityFlags;
167         } else {
168             mHiddenFlags &= ~visibilityFlags;
169         }
170         boolean isHidden = mHiddenFlags != 0;
171         mMultiValueAlpha.getProperty(INDEX_HIDDEN_FLAGS_ALPHA).setValue(isHidden ? 0 : 1);
172     }
173 
174     /**
175      * Updates the proper disabled flag to indicate whether OverviewActionsView should be enabled.
176      * Ignores DISABLED_ROTATED flag for determining enabled. Flag is used to enable/disable
177      * buttons individually, currently done for select button in subclass.
178      *
179      * @param disabledFlags The flag to update.
180      * @param enable        Whether to enable the disable flag: True will cause view to be disabled.
181      */
updateDisabledFlags(@ctionsDisabledFlags int disabledFlags, boolean enable)182     public void updateDisabledFlags(@ActionsDisabledFlags int disabledFlags, boolean enable) {
183         if (enable) {
184             mDisabledFlags |= disabledFlags;
185         } else {
186             mDisabledFlags &= ~disabledFlags;
187         }
188         //
189         boolean isEnabled = (mDisabledFlags & ~DISABLED_ROTATED) == 0;
190         LayoutUtils.setViewEnabled(this, isEnabled);
191     }
192 
getContentAlpha()193     public AlphaProperty getContentAlpha() {
194         return mMultiValueAlpha.getProperty(INDEX_CONTENT_ALPHA);
195     }
196 
getVisibilityAlpha()197     public AlphaProperty getVisibilityAlpha() {
198         return mMultiValueAlpha.getProperty(INDEX_VISIBILITY_ALPHA);
199     }
200 
getFullscreenAlpha()201     public AlphaProperty getFullscreenAlpha() {
202         return mMultiValueAlpha.getProperty(INDEX_FULLSCREEN_ALPHA);
203     }
204 
205     /** Updates vertical margins for different navigation mode or configuration changes. */
updateVerticalMargin(Mode mode)206     public void updateVerticalMargin(Mode mode) {
207         int bottomMargin;
208         int orientation = getResources().getConfiguration().orientation;
209         if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
210             bottomMargin = 0;
211         } else if (mode == Mode.THREE_BUTTONS) {
212             bottomMargin = getResources()
213                     .getDimensionPixelSize(R.dimen.overview_actions_bottom_margin_three_button);
214         } else {
215             bottomMargin = getResources()
216                     .getDimensionPixelSize(R.dimen.overview_actions_bottom_margin_gesture);
217         }
218         bottomMargin += mInsets.bottom;
219         LayoutParams params = (LayoutParams) getLayoutParams();
220         params.setMargins(
221                 params.leftMargin, params.topMargin, params.rightMargin, bottomMargin);
222     }
223 }
224