1 /*
2  * Copyright (C) 2021 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 android.car.apitest;
18 
19 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.junit.Assert.assertThrows;
24 import static org.junit.Assume.assumeTrue;
25 
26 import android.app.ActivityManager;
27 import android.car.Car;
28 import android.car.content.pm.CarPackageManager;
29 import android.content.pm.PackageManager;
30 import android.os.Build;
31 
32 import androidx.test.filters.SmallTest;
33 
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.Test;
37 
38 import java.util.List;
39 
40 @SmallTest
41 public class DrivingSafetyRegionTest extends CarApiTestBase {
42     private static final String REGION1 = "com.android.car.test.drivingsafetyregion.1";
43     private static final String REGION2 = "com.android.car.test.drivingsafetyregion.2";
44     private static final String REGION3 = "com.android.car.test.drivingsafetyregion.3";
45 
46     private static final String TEST_PACKAGE_NAME = "android.car.apitest";
47 
48     private CarPackageManager mCarPackageManager;
49     private String mOriginalDrivingSafetyRegion = null;
50 
51     private final int mCurrentUser = ActivityManager.getCurrentUser();
52 
53     @Before
setUp()54     public void setUp() {
55         mCarPackageManager = (CarPackageManager) getCar().getCarManager(Car.PACKAGE_SERVICE);
56 
57         assertThat(mCarPackageManager).isNotNull();
58 
59         mOriginalDrivingSafetyRegion = mCarPackageManager.getCurrentDrivingSafetyRegion();
60 
61         assertThat(mOriginalDrivingSafetyRegion).isNotNull();
62 
63         // cannot run this in user build as region change is not allowed in user build for shell.
64         assumeTrue(Build.IS_ENG || Build.IS_USERDEBUG);
65     }
66 
67     @After
tearDown()68     public void tearDown() {
69         if (mOriginalDrivingSafetyRegion != null) {
70             setDrivingSafetyRegion(mOriginalDrivingSafetyRegion);
71         }
72     }
73 
74     @Test
testImplicitAllRegions()75     public void testImplicitAllRegions() throws Exception {
76         doTestAllRegions(TestDrivingSafetyAllRegionActivity.class.getName());
77     }
78 
79     @Test
testExplicitAllRegions()80     public void testExplicitAllRegions() throws Exception {
81         doTestAllRegions(TestDrivingSafetyExplicitAllRegionsActivity.class.getName());
82     }
83 
doTestAllRegions(String activityClassName)84     private void doTestAllRegions(String activityClassName) throws Exception {
85         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
86                 activityClassName)).isTrue();
87 
88         List<String> regions = mCarPackageManager.getSupportedDrivingSafetyRegionsForActivityAsUser(
89                 TEST_PACKAGE_NAME, activityClassName, ActivityManager.getCurrentUser());
90 
91         assertThat(regions).containsExactly(CarPackageManager.DRIVING_SAFETY_REGION_ALL);
92 
93         // all region app should be safe always regardless of bypassing / region change
94         setDrivingSafetyRegion(REGION1);
95 
96         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
97                 activityClassName)).isTrue();
98 
99         mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(TEST_PACKAGE_NAME,
100                 activityClassName, true, mCurrentUser);
101 
102         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
103                 activityClassName)).isTrue();
104 
105         mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(TEST_PACKAGE_NAME,
106                 activityClassName, false, mCurrentUser);
107 
108         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
109                 activityClassName)).isTrue();
110     }
111 
112     @Test
testOneRegionOnly()113     public void testOneRegionOnly() throws Exception {
114         String activityClassName = TestDrivingSafetyOneRegionActivity.class.getName();
115 
116         List<String> regions = mCarPackageManager.getSupportedDrivingSafetyRegionsForActivityAsUser(
117                 TEST_PACKAGE_NAME, activityClassName, ActivityManager.getCurrentUser());
118 
119         assertThat(regions).containsExactly(REGION1);
120 
121         setDrivingSafetyRegion(REGION1);
122 
123         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
124                 activityClassName)).isTrue();
125 
126         setDrivingSafetyRegion(REGION2);
127 
128         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
129                 activityClassName)).isFalse();
130 
131         mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(TEST_PACKAGE_NAME,
132                 activityClassName, true, mCurrentUser);
133 
134         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
135                 activityClassName)).isTrue();
136 
137         mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(TEST_PACKAGE_NAME,
138                 activityClassName, false, mCurrentUser);
139 
140         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
141                 activityClassName)).isFalse();
142 
143         setDrivingSafetyRegion(CarPackageManager.DRIVING_SAFETY_REGION_ALL);
144 
145         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
146                 activityClassName)).isTrue();
147     }
148 
149     @Test
testTwoRegionsOnly()150     public void testTwoRegionsOnly() throws Exception {
151         String activityClassName = TestDrivingSafetyTwoRegionsActivity.class.getName();
152 
153         List<String> regions = mCarPackageManager.getSupportedDrivingSafetyRegionsForActivityAsUser(
154                 TEST_PACKAGE_NAME, activityClassName, ActivityManager.getCurrentUser());
155 
156         assertThat(regions).containsExactly(REGION1, REGION2);
157 
158         setDrivingSafetyRegion(REGION1);
159 
160         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
161                 activityClassName)).isTrue();
162 
163         setDrivingSafetyRegion(REGION2);
164 
165         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
166                 activityClassName)).isTrue();
167 
168         setDrivingSafetyRegion(REGION3);
169 
170         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
171                 activityClassName)).isFalse();
172 
173         setDrivingSafetyRegion(CarPackageManager.DRIVING_SAFETY_REGION_ALL);
174 
175         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
176                 activityClassName)).isTrue();
177     }
178 
179     @Test
testRegion1OnlyActivity()180     public void testRegion1OnlyActivity() throws Exception {
181         doTestRegionOnlyOrNoRegionCase(TestDrivingSafetyRegion1OnlyActivity.class.getName());
182     }
183 
184     @Test
testRegionAllOnlyActivity()185     public void testRegionAllOnlyActivity() throws Exception {
186         doTestRegionOnlyOrNoRegionCase(TestDrivingSafetyRegionAllOnlyActivity.class.getName());
187     }
188 
189     @Test
testRegionNoMetadataActivity()190     public void testRegionNoMetadataActivity() throws Exception {
191         doTestRegionOnlyOrNoRegionCase(TestDrivingSafetyRegionNoMetadataActivity.class.getName());
192     }
193 
doTestRegionOnlyOrNoRegionCase(String activityClassName)194     private void doTestRegionOnlyOrNoRegionCase(String activityClassName) throws Exception {
195         List<String> regions = mCarPackageManager.getSupportedDrivingSafetyRegionsForActivityAsUser(
196                 TEST_PACKAGE_NAME, activityClassName, ActivityManager.getCurrentUser());
197 
198         // not distraction optimized, so list should be empty.
199         assertThat(regions).isEmpty();
200 
201         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
202                 activityClassName)).isFalse();
203 
204         // should not be safe for any region.
205         setDrivingSafetyRegion(CarPackageManager.DRIVING_SAFETY_REGION_ALL);
206 
207         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
208                 activityClassName)).isFalse();
209 
210         setDrivingSafetyRegion(REGION1);
211 
212         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
213                 activityClassName)).isFalse();
214 
215         setDrivingSafetyRegion(REGION2);
216 
217         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
218                 activityClassName)).isFalse();
219 
220         mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(TEST_PACKAGE_NAME,
221                 activityClassName, true, mCurrentUser);
222 
223         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
224                 activityClassName)).isTrue();
225 
226         mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(TEST_PACKAGE_NAME,
227                 activityClassName, false, mCurrentUser);
228 
229         assertThat(mCarPackageManager.isActivityDistractionOptimized(TEST_PACKAGE_NAME,
230                 activityClassName)).isFalse();
231     }
232 
233     @Test
testNoPackage()234     public void testNoPackage() {
235         String noPkg = "NoSuchPackage";
236 
237         assertThrows(PackageManager.NameNotFoundException.class,
238                 () -> mCarPackageManager.getSupportedDrivingSafetyRegionsForActivityAsUser(
239                         noPkg, "", mCurrentUser));
240 
241         assertThrows(PackageManager.NameNotFoundException.class,
242                 () -> mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(
243                         noPkg, "", true, mCurrentUser));
244     }
245 
246     @Test
testNoActivity()247     public void testNoActivity() {
248         String noSuchActivity = "NoSuchActivity";
249 
250         assertThrows(PackageManager.NameNotFoundException.class,
251                 () -> mCarPackageManager.getSupportedDrivingSafetyRegionsForActivityAsUser(
252                         TEST_PACKAGE_NAME, noSuchActivity, mCurrentUser));
253 
254         assertThrows(PackageManager.NameNotFoundException.class,
255                 () -> mCarPackageManager.controlTemporaryActivityBlockingBypassingAsUser(
256                         TEST_PACKAGE_NAME, noSuchActivity, true, mCurrentUser));
257     }
258 
259     @Test
testResetEmptyRegion()260     public void testResetEmptyRegion() {
261         setDrivingSafetyRegion(REGION1);
262 
263         assertThat(mCarPackageManager.getCurrentDrivingSafetyRegion()).isEqualTo(REGION1);
264 
265         // no arg means all
266         runShellCommand("cmd car_service set-drivingsafety-region");
267 
268         assertThat(mCarPackageManager.getCurrentDrivingSafetyRegion()).isEqualTo(
269                 CarPackageManager.DRIVING_SAFETY_REGION_ALL);
270     }
271 
setDrivingSafetyRegion(String region)272     private void setDrivingSafetyRegion(String region) {
273         runShellCommand("cmd car_service set-drivingsafety-region  " + region);
274     }
275 }
276