• 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.systemui.car.systembar;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
20 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.ArgumentMatchers.argThat;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.reset;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33 
34 import android.app.ActivityManager;
35 import android.app.ActivityTaskManager;
36 import android.content.Intent;
37 import android.graphics.drawable.Drawable;
38 import android.os.RemoteException;
39 import android.testing.AndroidTestingRunner;
40 import android.view.LayoutInflater;
41 import android.view.View;
42 import android.widget.ImageView;
43 import android.widget.LinearLayout;
44 
45 import androidx.test.filters.SmallTest;
46 
47 import com.android.systemui.SysuiTestCase;
48 import com.android.systemui.car.CarSystemUiTest;
49 import com.android.systemui.statusbar.AlphaOptimizedImageView;
50 import com.android.systemui.tests.R;
51 
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.mockito.ArgumentMatcher;
56 import org.mockito.MockitoAnnotations;
57 
58 @CarSystemUiTest
59 @RunWith(AndroidTestingRunner.class)
60 @SmallTest
61 public class CarSystemBarButtonTest extends SysuiTestCase {
62 
63     private static final String DIALER_BUTTON_ACTIVITY_NAME =
64             "com.android.car.dialer/.ui.TelecomActivity";
65     private static final String BROADCAST_ACTION_NAME =
66             "android.car.intent.action.TOGGLE_HVAC_CONTROLS";
67 
68     private ActivityManager mActivityManager;
69     // LinearLayout with CarSystemBarButtons with different configurations.
70     private LinearLayout mTestView;
71     // Does not have any selection state which is the default configuration.
72     private CarSystemBarButton mDefaultButton;
73 
74     @Before
setUp()75     public void setUp() {
76         MockitoAnnotations.initMocks(this);
77         mContext = spy(mContext);
78         ActivityManager am = mContext.getSystemService(ActivityManager.class);
79         mActivityManager = spy(am);
80         when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
81         mTestView = (LinearLayout) LayoutInflater.from(mContext).inflate(
82                 R.layout.car_system_bar_button_test, /* root= */ null);
83         mDefaultButton = mTestView.findViewById(R.id.default_no_selection_state);
84     }
85 
86     @Test
onCreate_iconIsVisible()87     public void onCreate_iconIsVisible() {
88         AlphaOptimizedImageView icon = mDefaultButton.findViewById(
89                 R.id.car_nav_button_icon_image);
90 
91         assertThat(icon.getDrawable()).isNotNull();
92     }
93 
94     @Test
onSelected_selectedIconDefined_togglesIcon()95     public void onSelected_selectedIconDefined_togglesIcon() {
96         mDefaultButton.setSelected(true);
97         waitForIdleSync();
98         Drawable selectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
99                 R.id.car_nav_button_icon_image)).getDrawable();
100 
101         mDefaultButton.setSelected(false);
102         waitForIdleSync();
103         Drawable unselectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
104                 R.id.car_nav_button_icon_image)).getDrawable();
105 
106         assertThat(selectedIconDrawable).isNotEqualTo(unselectedIconDrawable);
107     }
108 
109     @Test
onSelected_selectedIconUndefined_displaysSameIcon()110     public void onSelected_selectedIconUndefined_displaysSameIcon() {
111         CarSystemBarButton selectedIconUndefinedButton = mTestView.findViewById(
112                 R.id.selected_icon_undefined);
113 
114         selectedIconUndefinedButton.setSelected(true);
115         waitForIdleSync();
116         Drawable selectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
117                 R.id.car_nav_button_icon_image)).getDrawable();
118 
119 
120         selectedIconUndefinedButton.setSelected(false);
121         waitForIdleSync();
122         Drawable unselectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
123                 R.id.car_nav_button_icon_image)).getDrawable();
124 
125         assertThat(selectedIconDrawable).isEqualTo(unselectedIconDrawable);
126     }
127 
128     @Test
onUnselected_doesNotHighlightWhenSelected_applySelectedAlpha()129     public void onUnselected_doesNotHighlightWhenSelected_applySelectedAlpha() {
130         mDefaultButton.setSelected(false);
131         waitForIdleSync();
132 
133         assertThat(mDefaultButton.getAlpha()).isEqualTo(mDefaultButton.getSelectedAlpha());
134     }
135 
136     @Test
onSelected_doesNotHighlightWhenSelected_applyDefaultUnselectedAlpha()137     public void onSelected_doesNotHighlightWhenSelected_applyDefaultUnselectedAlpha() {
138         mDefaultButton.setSelected(true);
139         waitForIdleSync();
140 
141         assertThat(mDefaultButton.getIconAlpha()).isEqualTo(mDefaultButton.getUnselectedAlpha());
142     }
143 
144     @Test
onUnselected_highlightWhenSelected_applyDefaultUnselectedAlpha()145     public void onUnselected_highlightWhenSelected_applyDefaultUnselectedAlpha() {
146         CarSystemBarButton highlightWhenSelectedButton = mTestView.findViewById(
147                 R.id.highlightable_no_more_button);
148         highlightWhenSelectedButton.setSelected(false);
149         waitForIdleSync();
150 
151         assertThat(highlightWhenSelectedButton.getIconAlpha()).isEqualTo(
152                 highlightWhenSelectedButton.getUnselectedAlpha());
153     }
154 
155     @Test
onSelected_highlightWhenSelected_applyDefaultSelectedAlpha()156     public void onSelected_highlightWhenSelected_applyDefaultSelectedAlpha() {
157         CarSystemBarButton highlightWhenSelectedButton = mTestView.findViewById(
158                 R.id.highlightable_no_more_button);
159         highlightWhenSelectedButton.setSelected(true);
160         waitForIdleSync();
161 
162         assertThat(highlightWhenSelectedButton.getIconAlpha()).isEqualTo(
163                 highlightWhenSelectedButton.getSelectedAlpha());
164     }
165 
166     @Test
onSelected_doesNotShowMoreWhenSelected_doesNotShowMoreIcon()167     public void onSelected_doesNotShowMoreWhenSelected_doesNotShowMoreIcon() {
168         mDefaultButton.setSelected(true);
169         AlphaOptimizedImageView moreIcon = mDefaultButton.findViewById(
170                 R.id.car_nav_button_more_icon);
171         waitForIdleSync();
172 
173         assertThat(moreIcon.getVisibility()).isEqualTo(View.GONE);
174     }
175 
176     @Test
onSelected_showMoreWhenSelected_showsMoreIcon()177     public void onSelected_showMoreWhenSelected_showsMoreIcon() {
178         CarSystemBarButton showMoreWhenSelected = mTestView.findViewById(
179                 R.id.not_highlightable_more_button);
180         showMoreWhenSelected.setSelected(true);
181         AlphaOptimizedImageView moreIcon = showMoreWhenSelected.findViewById(
182                 R.id.car_nav_button_more_icon);
183         waitForIdleSync();
184 
185         assertThat(moreIcon.getVisibility()).isEqualTo(View.VISIBLE);
186     }
187 
188     @Test
onUnselected_showMoreWhenSelected_doesNotShowMoreIcon()189     public void onUnselected_showMoreWhenSelected_doesNotShowMoreIcon() {
190         CarSystemBarButton showMoreWhenSelected = mTestView.findViewById(
191                 R.id.highlightable_no_more_button);
192         showMoreWhenSelected.setSelected(true);
193         showMoreWhenSelected.setSelected(false);
194         AlphaOptimizedImageView moreIcon = showMoreWhenSelected.findViewById(
195                 R.id.car_nav_button_more_icon);
196         waitForIdleSync();
197 
198         assertThat(moreIcon.getVisibility()).isEqualTo(View.GONE);
199     }
200 
201     @Test
onUnselected_withAppIcon_showsAppIcon()202     public void onUnselected_withAppIcon_showsAppIcon() {
203         CarSystemBarButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
204         Drawable appIcon = getContext().getDrawable(R.drawable.ic_android);
205 
206         roleBasedButton.setAppIcon(appIcon);
207         roleBasedButton.setSelected(false);
208         waitForIdleSync();
209 
210         Drawable currentDrawable = ((AlphaOptimizedImageView) roleBasedButton.findViewById(
211                 R.id.car_nav_button_icon_image)).getDrawable();
212 
213         assertThat(currentDrawable).isEqualTo(appIcon);
214     }
215 
216     @Test
onUnselected_withAppIcon_applyUnselectedAlpha()217     public void onUnselected_withAppIcon_applyUnselectedAlpha() {
218         CarSystemBarButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
219 
220         roleBasedButton.setAppIcon(getContext().getDrawable(R.drawable.ic_android));
221         roleBasedButton.setSelected(false);
222         waitForIdleSync();
223 
224         assertThat(roleBasedButton.getIconAlpha()).isEqualTo(roleBasedButton.getUnselectedAlpha());
225     }
226 
227     @Test
onSelected_withAppIcon_showsAppIcon()228     public void onSelected_withAppIcon_showsAppIcon() {
229         CarSystemBarButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
230         Drawable appIcon = getContext().getDrawable(R.drawable.ic_android);
231 
232         roleBasedButton.setSelected(true);
233         roleBasedButton.setAppIcon(appIcon);
234         waitForIdleSync();
235 
236         Drawable currentDrawable = ((AlphaOptimizedImageView) roleBasedButton.findViewById(
237                 R.id.car_nav_button_icon_image)).getDrawable();
238 
239         assertThat(currentDrawable).isEqualTo(appIcon);
240     }
241 
242     @Test
onSelected_withAppIcon_applySelectedAlpha()243     public void onSelected_withAppIcon_applySelectedAlpha() {
244         CarSystemBarButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
245 
246         roleBasedButton.setSelected(true);
247         roleBasedButton.setAppIcon(getContext().getDrawable(R.drawable.ic_android));
248         waitForIdleSync();
249 
250         assertThat(roleBasedButton.getIconAlpha()).isEqualTo(roleBasedButton.getSelectedAlpha());
251     }
252 
253     @Test
onClick_launchesIntentActivity()254     public void onClick_launchesIntentActivity() {
255         mDefaultButton.performClick();
256 
257         CarSystemBarButton dialerButton = mTestView.findViewById(R.id.dialer_activity);
258         dialerButton.performClick();
259         waitForIdleSync();
260 
261         assertThat(getCurrentActivityName()).isEqualTo(DIALER_BUTTON_ACTIVITY_NAME);
262     }
263 
264     @Test
onLongClick_longIntentDefined_launchesLongIntentActivity()265     public void onLongClick_longIntentDefined_launchesLongIntentActivity() {
266         mDefaultButton.performClick();
267         waitForIdleSync();
268 
269         CarSystemBarButton dialerButton = mTestView.findViewById(
270                 R.id.long_click_dialer_activity);
271         dialerButton.performLongClick();
272 
273         assertThat(getCurrentActivityName()).isEqualTo(DIALER_BUTTON_ACTIVITY_NAME);
274     }
275 
276     @Test
onClick_useBroadcast_broadcastsIntent()277     public void onClick_useBroadcast_broadcastsIntent() {
278         CarSystemBarButton button = mTestView.findViewById(R.id.broadcast);
279         reset(mContext);
280 
281         button.performClick();
282         waitForIdleSync();
283 
284         verify(mContext).sendBroadcastAsUser(argThat(new ArgumentMatcher<Intent>() {
285             @Override
286             public boolean matches(Intent argument) {
287                 return argument.getAction().equals(BROADCAST_ACTION_NAME);
288             }
289         }), any());
290     }
291 
292     @Test
onClick_requestBackstackClear_clearBackStack()293     public void onClick_requestBackstackClear_clearBackStack() {
294         CarSystemBarButton dialerButton =
295                 mTestView.findViewById(R.id.dialer_activity_clear_backstack);
296 
297         dialerButton.performClick();
298 
299         verify(mActivityManager).moveTaskToFront(anyInt(), anyInt());
300     }
301 
302     @Test
onClick_useBroadcast_requestBackstackClear_doesNotClearingBackstack()303     public void onClick_useBroadcast_requestBackstackClear_doesNotClearingBackstack() {
304         CarSystemBarButton button =
305                 mTestView.findViewById(R.id.broadcast_try_clear_backstack);
306 
307         button.performClick();
308 
309         verify(mActivityManager, never()).moveTaskToFront(anyInt(), anyInt());
310     }
311 
312     @Test
onSetUnseen_hasUnseen_showsUnseenIndicator()313     public void onSetUnseen_hasUnseen_showsUnseenIndicator() {
314         mDefaultButton.setUnseen(true);
315         ImageView hasUnseenIndicator = mDefaultButton.findViewById(R.id.car_nav_button_unseen_icon);
316         waitForIdleSync();
317 
318         assertThat(hasUnseenIndicator.getVisibility()).isEqualTo(View.VISIBLE);
319     }
320 
321     @Test
onSetUnseen_doesNotHaveUnseen_hidesUnseenIndicator()322     public void onSetUnseen_doesNotHaveUnseen_hidesUnseenIndicator() {
323         mDefaultButton.setUnseen(false);
324         ImageView hasUnseenIndicator = mDefaultButton.findViewById(R.id.car_nav_button_unseen_icon);
325         waitForIdleSync();
326 
327         assertThat(hasUnseenIndicator.getVisibility()).isEqualTo(View.GONE);
328     }
329 
330     @Test
onSetDisabled_enabled_refreshIconAlpha()331     public void onSetDisabled_enabled_refreshIconAlpha() {
332         mDefaultButton.setDisabled(false, /* runnable= */ null);
333 
334         assertThat(mDefaultButton.getAlpha()).isEqualTo(mDefaultButton.getSelectedAlpha());
335     }
336 
337     @Test
onSetDisabled_disdabledAlpha()338     public void onSetDisabled_disdabledAlpha() {
339         mDefaultButton.setDisabled(true, /* runnable= */ null);
340 
341         assertThat(mDefaultButton.getIconAlpha()).isEqualTo(mDefaultButton.getDisabledAlpha());
342     }
343 
344     @Test
onSetDisabled_nullRunnable_doesNotSendBroadcast()345     public void onSetDisabled_nullRunnable_doesNotSendBroadcast() {
346         mDefaultButton.setDisabled(true, /* runnable= */ null);
347 
348         mDefaultButton.performClick();
349 
350         verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any());
351     }
352 
353     @Test
onSetDisabled_runnable()354     public void onSetDisabled_runnable() {
355         Runnable mockRunnable = mock(Runnable.class);
356         mDefaultButton.setDisabled(true, /* runnable= */ mockRunnable);
357 
358         mDefaultButton.performClick();
359 
360         verify(mockRunnable).run();
361     }
362 
363     /**
364      * Returns the name of the first activity running in fullscreen mode (i.e. excludes things
365      * like TaskViews).
366      */
getCurrentActivityName()367     private String getCurrentActivityName() {
368         try {
369             ActivityTaskManager.RootTaskInfo rootTaskInfo =
370                     ActivityTaskManager.getService().getRootTaskInfoOnDisplay(
371                             WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_UNDEFINED,
372                             mContext.getDisplayId());
373             if (rootTaskInfo == null || rootTaskInfo.topActivity == null) {
374                 return null;
375             }
376             return rootTaskInfo.topActivity.flattenToShortString();
377         } catch (RemoteException e) {
378             return null;
379         }
380     }
381 }
382