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