1 /*
2  * Copyright (C) 2022 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.qs.tiles;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.when;
23 
24 import android.os.Handler;
25 import android.service.quicksettings.Tile;
26 import android.testing.TestableLooper;
27 
28 import androidx.test.ext.junit.runners.AndroidJUnit4;
29 import androidx.test.filters.SmallTest;
30 
31 import com.android.dx.mockito.inline.extended.ExtendedMockito;
32 import com.android.internal.logging.MetricsLogger;
33 import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
34 import com.android.systemui.SysuiTestCase;
35 import com.android.systemui.classifier.FalsingManagerFake;
36 import com.android.systemui.plugins.ActivityStarter;
37 import com.android.systemui.plugins.qs.QSTile;
38 import com.android.systemui.plugins.statusbar.StatusBarStateController;
39 import com.android.systemui.qs.QSHost;
40 import com.android.systemui.qs.QsEventLogger;
41 import com.android.systemui.qs.logging.QSLogger;
42 import com.android.systemui.qs.tileimpl.QSTileImpl;
43 import com.android.systemui.res.R;
44 import com.android.systemui.statusbar.policy.DataSaverController;
45 import com.android.systemui.statusbar.policy.HotspotController;
46 
47 import org.junit.After;
48 import org.junit.Before;
49 import org.junit.Rule;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.mockito.Mock;
53 import org.mockito.MockitoSession;
54 import org.mockito.junit.MockitoJUnit;
55 import org.mockito.junit.MockitoRule;
56 
57 @RunWith(AndroidJUnit4.class)
58 @TestableLooper.RunWithLooper(setAsMainLooper = true)
59 @SmallTest
60 public class HotspotTileTest extends SysuiTestCase {
61 
62     @Rule
63     public MockitoRule mRule = MockitoJUnit.rule();
64     @Mock
65     private QSHost mHost;
66     @Mock
67     private HotspotController mHotspotController;
68     @Mock
69     private DataSaverController mDataSaverController;
70     @Mock
71     private QsEventLogger mUiEventLogger;
72 
73     private TestableLooper mTestableLooper;
74     private HotspotTile mTile;
75     private QSTile.BooleanState mState = new QSTile.BooleanState();
76 
77     @Before
setUp()78     public void setUp() throws Exception {
79         mTestableLooper = TestableLooper.get(this);
80         when(mHost.getContext()).thenReturn(mContext);
81         when(mHost.getUserContext()).thenReturn(mContext);
82         when(mDataSaverController.isDataSaverEnabled()).thenReturn(false);
83 
84         mTile = new HotspotTile(
85                 mHost,
86                 mUiEventLogger,
87                 mTestableLooper.getLooper(),
88                 new Handler(mTestableLooper.getLooper()),
89                 new FalsingManagerFake(),
90                 mock(MetricsLogger.class),
91                 mock(StatusBarStateController.class),
92                 mock(ActivityStarter.class),
93                 mock(QSLogger.class),
94                 mHotspotController,
95                 mDataSaverController
96         );
97 
98         mTile.initialize();
99         mTestableLooper.processAllMessages();
100     }
101 
102     @After
tearDown()103     public void tearDown() {
104         mTile.destroy();
105         mTestableLooper.processAllMessages();
106     }
107 
108     @Test
handleUpdateState_wifiTetheringIsAllowed_stateIsNotUnavailable()109     public void handleUpdateState_wifiTetheringIsAllowed_stateIsNotUnavailable() {
110         MockitoSession mockitoSession = ExtendedMockito.mockitoSession()
111                 .spyStatic(WifiEnterpriseRestrictionUtils.class)
112                 .startMocking();
113         when(WifiEnterpriseRestrictionUtils.isWifiTetheringAllowed(mContext)).thenReturn(true);
114 
115         mTile.handleUpdateState(mState, null);
116 
117         assertThat(mState.state).isNotEqualTo(Tile.STATE_UNAVAILABLE);
118         assertThat(String.valueOf(mState.secondaryLabel))
119                 .isNotEqualTo(mContext.getString(com.android.wifitrackerlib.R.string.wifitrackerlib_admin_restricted_network));
120         mockitoSession.finishMocking();
121     }
122 
123     @Test
handleUpdateState_wifiTetheringIsDisallowed_stateIsUnavailable()124     public void handleUpdateState_wifiTetheringIsDisallowed_stateIsUnavailable() {
125         MockitoSession mockitoSession = ExtendedMockito.mockitoSession()
126                 .spyStatic(WifiEnterpriseRestrictionUtils.class)
127                 .startMocking();
128         when(WifiEnterpriseRestrictionUtils.isWifiTetheringAllowed(mContext)).thenReturn(false);
129 
130         mTile.handleUpdateState(mState, null);
131 
132         assertThat(mState.state).isEqualTo(Tile.STATE_UNAVAILABLE);
133         assertThat(String.valueOf(mState.secondaryLabel))
134                 .isEqualTo(mContext.getString(com.android.wifitrackerlib.R.string.wifitrackerlib_admin_restricted_network));
135         mockitoSession.finishMocking();
136     }
137 
138     @Test
testIcon_whenDisabled_isOffState()139     public void testIcon_whenDisabled_isOffState() {
140         QSTile.BooleanState state = new QSTile.BooleanState();
141         when(mHotspotController.isHotspotTransient()).thenReturn(false);
142         when(mHotspotController.isHotspotEnabled()).thenReturn(false);
143 
144         mTile.handleUpdateState(state, /* arg= */ null);
145 
146         assertThat(state.icon)
147                 .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_off));
148     }
149 
150     @Test
testIcon_whenTransient_isSearchState()151     public void testIcon_whenTransient_isSearchState() {
152         QSTile.BooleanState state = new QSTile.BooleanState();
153         when(mHotspotController.isHotspotTransient()).thenReturn(true);
154         when(mHotspotController.isHotspotEnabled()).thenReturn(true);
155 
156         mTile.handleUpdateState(state, /* arg= */ null);
157 
158         assertThat(state.icon)
159                 .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_search));
160     }
161 
162     @Test
testIcon_whenEnabled_isOnState()163     public void testIcon_whenEnabled_isOnState() {
164         QSTile.BooleanState state = new QSTile.BooleanState();
165         when(mHotspotController.isHotspotTransient()).thenReturn(false);
166         when(mHotspotController.isHotspotEnabled()).thenReturn(true);
167 
168         mTile.handleUpdateState(state, /* arg= */ null);
169 
170         assertThat(state.icon)
171                 .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_on));
172     }
173 }
174