• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.quickstep;
2 
3 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
4 
5 import android.app.Activity;
6 import android.content.Context;
7 import android.content.res.Resources;
8 import android.graphics.Rect;
9 import android.os.Bundle;
10 
11 import androidx.annotation.Nullable;
12 
13 import com.android.launcher3.R;
14 import com.android.launcher3.taskbar.TaskbarActivityContext;
15 import com.android.launcher3.testing.TestInformationHandler;
16 import com.android.launcher3.testing.shared.TestProtocol;
17 import com.android.launcher3.touch.PagedOrientationHandler;
18 import com.android.launcher3.util.DisplayController;
19 import com.android.quickstep.util.LayoutUtils;
20 import com.android.quickstep.util.TISBindHelper;
21 
22 import java.util.concurrent.CountDownLatch;
23 import java.util.concurrent.ExecutionException;
24 import java.util.function.Consumer;
25 import java.util.function.Function;
26 
27 public class QuickstepTestInformationHandler extends TestInformationHandler {
28 
29     protected final Context mContext;
30 
QuickstepTestInformationHandler(Context context)31     public QuickstepTestInformationHandler(Context context) {
32         mContext = context;
33     }
34 
35     @Override
call(String method, String arg, @Nullable Bundle extras)36     public Bundle call(String method, String arg, @Nullable Bundle extras) {
37         final Bundle response = new Bundle();
38         switch (method) {
39             case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: {
40                 final float swipeHeight =
41                         LayoutUtils.getDefaultSwipeHeight(mContext, mDeviceProfile);
42                 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
43                 return response;
44             }
45 
46             case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: {
47                 final float swipeHeight =
48                         LayoutUtils.getShelfTrackingDistance(mContext, mDeviceProfile,
49                                 PagedOrientationHandler.PORTRAIT);
50                 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
51                 return response;
52             }
53 
54             case TestProtocol.REQUEST_GET_FOCUSED_TASK_HEIGHT_FOR_TABLET: {
55                 if (!mDeviceProfile.isTablet) {
56                     return null;
57                 }
58                 Rect focusedTaskRect = new Rect();
59                 LauncherActivityInterface.INSTANCE.calculateTaskSize(mContext, mDeviceProfile,
60                         focusedTaskRect, PagedOrientationHandler.PORTRAIT);
61                 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, focusedTaskRect.height());
62                 return response;
63             }
64 
65             case TestProtocol.REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET: {
66                 if (!mDeviceProfile.isTablet) {
67                     return null;
68                 }
69                 Rect gridTaskRect = new Rect();
70                 LauncherActivityInterface.INSTANCE.calculateGridTaskSize(mContext, mDeviceProfile,
71                         gridTaskRect, PagedOrientationHandler.PORTRAIT);
72                 response.putParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD, gridTaskRect);
73                 return response;
74             }
75 
76             case TestProtocol.REQUEST_GET_OVERVIEW_PAGE_SPACING: {
77                 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
78                         mDeviceProfile.overviewPageSpacing);
79                 return response;
80             }
81 
82             case TestProtocol.REQUEST_HAS_TIS: {
83                 response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, true);
84                 return response;
85             }
86 
87             case TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING:
88                 runOnTISBinder(tisBinder -> {
89                     enableManualTaskbarStashing(tisBinder, true);
90                 });
91                 return response;
92 
93             case TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING:
94                 runOnTISBinder(tisBinder -> {
95                     enableManualTaskbarStashing(tisBinder, false);
96                 });
97                 return response;
98 
99             case TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED:
100                 runOnTISBinder(tisBinder -> {
101                     enableManualTaskbarStashing(tisBinder, true);
102 
103                     // Allow null-pointer to catch illegal states.
104                     tisBinder.getTaskbarManager().getCurrentActivityContext()
105                             .unstashTaskbarIfStashed();
106 
107                     enableManualTaskbarStashing(tisBinder, false);
108                 });
109                 return response;
110 
111             case TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT: {
112                 final Resources resources = mContext.getResources();
113                 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
114                         resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size));
115                 return response;
116             }
117 
118             case TestProtocol.REQUEST_STASHED_TASKBAR_SCALE: {
119                 runOnTISBinder(tisBinder -> {
120                     response.putFloat(TestProtocol.TEST_INFO_RESPONSE_FIELD,
121                             tisBinder.getTaskbarManager()
122                                     .getCurrentActivityContext()
123                                     .getStashedTaskbarScale());
124                 });
125                 return response;
126             }
127 
128             case TestProtocol.REQUEST_TASKBAR_ALL_APPS_TOP_PADDING: {
129                 return getTISBinderUIProperty(Bundle::putInt, tisBinder ->
130                         tisBinder.getTaskbarManager()
131                                 .getCurrentActivityContext()
132                                 .getTaskbarAllAppsTopPadding());
133             }
134 
135             case TestProtocol.REQUEST_TASKBAR_APPS_LIST_SCROLL_Y: {
136                 return getTISBinderUIProperty(Bundle::putInt, tisBinder ->
137                         tisBinder.getTaskbarManager()
138                                 .getCurrentActivityContext()
139                                 .getTaskbarAllAppsScroll());
140             }
141 
142             case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT:
143                 runOnTISBinder(tisBinder -> {
144                     enableBlockingTimeout(tisBinder, true);
145                 });
146                 return response;
147 
148             case TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT:
149                 runOnTISBinder(tisBinder -> {
150                     enableBlockingTimeout(tisBinder, false);
151                 });
152                 return response;
153 
154             case TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR:
155                 enableTransientTaskbar(true);
156                 return response;
157 
158             case TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR:
159                 enableTransientTaskbar(false);
160                 return response;
161 
162             case TestProtocol.REQUEST_SHELL_DRAG_READY:
163                 response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
164                         SystemUiProxy.INSTANCE.get(mContext).isDragAndDropReady());
165                 return response;
166         }
167 
168         return super.call(method, arg, extras);
169     }
170 
171     @Override
getCurrentActivity()172     protected Activity getCurrentActivity() {
173         RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(mContext);
174         OverviewComponentObserver observer = new OverviewComponentObserver(mContext, rads);
175         try {
176             return observer.getActivityInterface().getCreatedActivity();
177         } finally {
178             observer.onDestroy();
179             rads.destroy();
180         }
181     }
182 
183     @Override
isLauncherInitialized()184     protected boolean isLauncherInitialized() {
185         return super.isLauncherInitialized() && TouchInteractionService.isInitialized();
186     }
187 
enableManualTaskbarStashing( TouchInteractionService.TISBinder tisBinder, boolean enable)188     private void enableManualTaskbarStashing(
189             TouchInteractionService.TISBinder tisBinder, boolean enable) {
190         // Allow null-pointer to catch illegal states.
191         tisBinder.getTaskbarManager().getCurrentActivityContext().enableManualStashingDuringTests(
192                 enable);
193     }
194 
enableBlockingTimeout( TouchInteractionService.TISBinder tisBinder, boolean enable)195     private void enableBlockingTimeout(
196             TouchInteractionService.TISBinder tisBinder, boolean enable) {
197         TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext();
198         if (context == null) {
199             return;
200         }
201         context.enableBlockingTimeoutDuringTests(enable);
202     }
203 
enableTransientTaskbar(boolean enable)204     private void enableTransientTaskbar(boolean enable) {
205         DisplayController.INSTANCE.get(mContext).enableTransientTaskbarForTests(enable);
206     }
207 
208     /**
209      * Runs the given command on the UI thread, after ensuring we are connected to
210      * TouchInteractionService.
211      */
runOnTISBinder(Consumer<TouchInteractionService.TISBinder> connectionCallback)212     protected void runOnTISBinder(Consumer<TouchInteractionService.TISBinder> connectionCallback) {
213         try {
214             CountDownLatch countDownLatch = new CountDownLatch(1);
215             TISBindHelper helper = MAIN_EXECUTOR.submit(() ->
216                     new TISBindHelper(mContext, tisBinder -> {
217                         connectionCallback.accept(tisBinder);
218                         countDownLatch.countDown();
219                     })).get();
220             countDownLatch.await();
221             MAIN_EXECUTOR.execute(helper::onDestroy);
222         } catch (ExecutionException | InterruptedException e) {
223             throw new RuntimeException(e);
224         }
225     }
226 
getTISBinderUIProperty( BundleSetter<T> bundleSetter, Function<TouchInteractionService.TISBinder, T> provider)227     private <T> Bundle getTISBinderUIProperty(
228             BundleSetter<T> bundleSetter, Function<TouchInteractionService.TISBinder, T> provider) {
229         Bundle response = new Bundle();
230 
231         runOnTISBinder(tisBinder -> bundleSetter.set(
232                 response,
233                 TestProtocol.TEST_INFO_RESPONSE_FIELD,
234                 provider.apply(tisBinder)));
235 
236         return response;
237     }
238 }
239