1 /*
2  * Copyright (C) 2015 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 package com.android.car;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import android.car.Car;
21 import android.car.content.pm.AppBlockingPackageInfo;
22 import android.car.content.pm.CarAppBlockingPolicy;
23 import android.car.content.pm.CarPackageManager;
24 import android.util.Log;
25 
26 import androidx.test.ext.junit.runners.AndroidJUnit4;
27 import androidx.test.filters.FlakyTest;
28 import androidx.test.filters.SmallTest;
29 import androidx.test.filters.Suppress;
30 
31 import com.android.car.pm.CarPackageManagerService;
32 
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 @RunWith(AndroidJUnit4.class)
37 @SmallTest
38 public class CarPackageManagerTest extends MockedCarTestBase {
39     private static final String TAG = CarPackageManagerTest.class.getSimpleName();
40 
41     private static final int POLLING_MAX_RETRY = 10;
42     private static final long POLLING_SLEEP = 100;
43 
44     private CarPackageManager mCarPm;
45     private CarPackageManagerService mCarPmService;
46 
init(boolean policyFromService)47     private void init(boolean policyFromService) throws Exception {
48         Log.i(TAG, "init started");
49         TestAppBlockingPolicyService.controlPolicySettingFromService(policyFromService);
50         mCarPm = (CarPackageManager) getCar().getCarManager(Car.PACKAGE_SERVICE);
51         assertThat(mCarPm).isNotNull();
52         mCarPmService = CarLocalServices.getService(CarPackageManagerService.class);
53         assertThat(mCarPmService).isNotNull();
54         mCarPmService.startAppBlockingPolicies();
55     }
56 
57     @Test
testServiceLaunched()58     public void testServiceLaunched() throws Exception {
59         init(true);
60         Log.i(TAG, "testServiceLaunched, init called");
61         assertThat(pollingCheck(new PollingChecker() {
62             @Override
63             public boolean check() {
64                 Log.i(TAG, "checking instance ...");
65                 return TestAppBlockingPolicyService.getInstance() != null;
66             }
67         }, POLLING_MAX_RETRY, POLLING_SLEEP)).isTrue();
68         final String thisPackage = getContext().getPackageName();
69         final String serviceClassName = "DOES_NOT_MATTER";
70         assertThat(pollingCheck(
71                 () -> mCarPm.isServiceDistractionOptimized(thisPackage, serviceClassName),
72                 POLLING_MAX_RETRY,
73                 POLLING_SLEEP)).isTrue();
74         assertThat(mCarPm.isServiceDistractionOptimized(thisPackage, null)).isTrue();
75         assertThat(mCarPm.isServiceDistractionOptimized(serviceClassName,
76                 serviceClassName)).isFalse();
77         assertThat(mCarPm.isServiceDistractionOptimized(serviceClassName, null)).isFalse();
78     }
79 
80     // TODO(b/113531788): Suppress this temporarily. Need to find the cause of issue and re-evaluate
81     // if the test is necessary.
82     @Suppress
83     @Test
84     @FlakyTest
testSettingAllowlist()85     public void testSettingAllowlist() throws Exception {
86         init(false);
87         final String carServicePackageName = "com.android.car";
88         final String activityAllowed = "NO_SUCH_ACTIVITY_BUT_ALLOWED";
89         final String activityNotAllowed = "NO_SUCH_ACTIVITY_AND_NOT_ALLOWED";
90         final String acticityAllowed2 = "NO_SUCH_ACTIVITY_BUT_ALLOWED2";
91         final String thisPackage = getContext().getPackageName();
92 
93         AppBlockingPackageInfo info = new AppBlockingPackageInfo(carServicePackageName, 0, 0,
94                 AppBlockingPackageInfo.FLAG_SYSTEM_APP, null, new String[] { activityAllowed });
95         CarAppBlockingPolicy policy = new CarAppBlockingPolicy(new AppBlockingPackageInfo[] { info }
96                 , null);
97         Log.i(TAG, "setting policy");
98         mCarPm.setAppBlockingPolicy(thisPackage, policy,
99                 CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE);
100         Log.i(TAG, "setting policy done");
101         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
102                 activityAllowed)).isTrue();
103         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
104                 activityNotAllowed)).isFalse();
105 
106         // replace policy
107         info = new AppBlockingPackageInfo(carServicePackageName, 0, 0,
108                 AppBlockingPackageInfo.FLAG_SYSTEM_APP, null, new String[] { acticityAllowed2 });
109         policy = new CarAppBlockingPolicy(new AppBlockingPackageInfo[] { info }
110                 , null);
111         mCarPm.setAppBlockingPolicy(thisPackage, policy,
112                 CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE);
113         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
114                 activityAllowed)).isFalse();
115         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
116                 acticityAllowed2)).isTrue();
117         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
118                 activityNotAllowed)).isFalse();
119 
120         //add, it replace the whole package policy. So activities are not added.
121         info = new AppBlockingPackageInfo(carServicePackageName, 0, 0,
122                 AppBlockingPackageInfo.FLAG_SYSTEM_APP, null, new String[] { activityAllowed });
123         policy = new CarAppBlockingPolicy(new AppBlockingPackageInfo[] { info }
124                 , null);
125         mCarPm.setAppBlockingPolicy(thisPackage, policy,
126                 CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE |
127                 CarPackageManager.FLAG_SET_POLICY_ADD);
128         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
129                 activityAllowed)).isTrue();
130         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
131                 acticityAllowed2)).isFalse();
132         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
133                 activityNotAllowed)).isFalse();
134 
135         //remove
136         info = new AppBlockingPackageInfo(carServicePackageName, 0, 0,
137                 AppBlockingPackageInfo.FLAG_SYSTEM_APP, null, new String[] { activityAllowed });
138         policy = new CarAppBlockingPolicy(new AppBlockingPackageInfo[] { info }
139                 , null);
140         mCarPm.setAppBlockingPolicy(thisPackage, policy,
141                 CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE |
142                 CarPackageManager.FLAG_SET_POLICY_REMOVE);
143         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
144                 activityAllowed)).isFalse();
145         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
146                 acticityAllowed2)).isFalse();
147         assertThat(mCarPm.isActivityDistractionOptimized(carServicePackageName,
148                 activityNotAllowed)).isFalse();
149     }
150 
151     interface PollingChecker {
check()152         boolean check();
153     }
154 
pollingCheck(PollingChecker checker, int maxRetry, long sleepMs)155     static boolean pollingCheck(PollingChecker checker, int maxRetry, long sleepMs)
156             throws Exception {
157         int retry = 0;
158         boolean checked = checker.check();
159         while (!checked && (retry < maxRetry)) {
160             Thread.sleep(sleepMs);
161             retry++;
162             checked = checker.check();
163         }
164         return checked;
165     }
166 }
167