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.managedprovisioning.task;
18 
19 import static android.app.AppOpsManager.MODE_ALLOWED;
20 import static android.app.AppOpsManager.MODE_DEFAULT;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static org.robolectric.Shadows.shadowOf;
25 
26 import android.Manifest;
27 import android.app.AppOpsManager;
28 import android.app.admin.DevicePolicyManager;
29 import android.content.Context;
30 import android.content.pm.CrossProfileApps;
31 import android.content.pm.PackageManager;
32 import android.os.UserManager;
33 
34 import com.android.managedprovisioning.analytics.MetricsWriterFactory;
35 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
36 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
37 import com.android.managedprovisioning.common.SettingsFacade;
38 import com.android.managedprovisioning.ota.ExtendsShadowCrossProfileApps;
39 import com.android.managedprovisioning.ota.ExtendsShadowDevicePolicyManager;
40 
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.robolectric.RobolectricTestRunner;
44 import org.robolectric.RuntimeEnvironment;
45 import org.robolectric.annotation.Config;
46 import org.robolectric.shadow.api.Shadow;
47 
48 import org.junit.runner.RunWith;
49 
50 import java.util.HashSet;
51 import java.util.Set;
52 
53 /**
54  * Unit-tests for {@link UpdateInteractAcrossProfilesAppOpTask}.
55  */
56 @RunWith(RobolectricTestRunner.class)
57 @Config(shadows={ExtendsShadowCrossProfileApps.class, ExtendsShadowDevicePolicyManager.class})
58 public class UpdateInteractAcrossProfilesAppOpTaskTest {
59     private static final String TEST_PACKAGE_NAME_1 = "com.test.packagea";
60     private static final String TEST_PACKAGE_NAME_2 = "com.test.packageb";
61     private static final int TEST_USER_ID = 123;
62 
63     private final Context mContext = RuntimeEnvironment.application;
64     private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
65     private final DevicePolicyManager mDevicePolicyManager =
66             mContext.getSystemService(DevicePolicyManager.class);
67     private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
68     private final PackageManager mPackageManager = mContext.getPackageManager();
69     private final TestTaskCallback mCallback = new TestTaskCallback();
70     private final CrossProfileApps mCrossProfileApps =
71             mContext.getSystemService(CrossProfileApps.class);
72     private final ManagedProvisioningSharedPreferences mManagedProvisioningSharedPreferences
73             = new ManagedProvisioningSharedPreferences(mContext);
74     private final ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker =
75             new ProvisioningAnalyticsTracker(
76                     MetricsWriterFactory.getMetricsWriter(mContext, new SettingsFacade()),
77                     mManagedProvisioningSharedPreferences);
78     private final UpdateInteractAcrossProfilesAppOpTask task =
79             new UpdateInteractAcrossProfilesAppOpTask(
80                     mContext, /* params= */ null, mCallback, mProvisioningAnalyticsTracker);
81 
myShadowOf(CrossProfileApps mCrossProfileApps)82     private static ExtendsShadowCrossProfileApps myShadowOf(CrossProfileApps mCrossProfileApps) {
83         return (ExtendsShadowCrossProfileApps) Shadow.extract(mCrossProfileApps);
84     }
85 
86     @Before
setUp()87     public void setUp() {
88         shadowOf(mUserManager).addUser(TEST_USER_ID, "Username", /* flags= */ 0);
89     }
90 
91     @Test
run_firstRun_appOpIsNotReset()92     public void run_firstRun_appOpIsNotReset() {
93         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_1, TEST_PACKAGE_NAME_2);
94         mCrossProfileApps.setInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2, MODE_ALLOWED);
95 
96         task.run(TEST_USER_ID);
97 
98         assertThat(myShadowOf(mCrossProfileApps).getInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2))
99                 .isEqualTo(MODE_ALLOWED);
100     }
101 
102     @Test
run_packageIsRemovedButStillConfigurable_appOpIsNotReset()103     public void run_packageIsRemovedButStillConfigurable_appOpIsNotReset() {
104         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_1, TEST_PACKAGE_NAME_2);
105         mCrossProfileApps.setInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2, MODE_ALLOWED);
106         myShadowOf(mCrossProfileApps).addCrossProfilePackage(TEST_PACKAGE_NAME_2);
107         task.run(TEST_USER_ID);
108 
109         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_1);
110         task.run(TEST_USER_ID);
111 
112         assertThat(myShadowOf(mCrossProfileApps).getInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2))
113                 .isEqualTo(MODE_ALLOWED);
114     }
115 
116     @Test
run_packageIsNoLongerConfigurable_appOpIsReset()117     public void run_packageIsNoLongerConfigurable_appOpIsReset() {
118         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_1, TEST_PACKAGE_NAME_2);
119         mCrossProfileApps.setInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2, MODE_ALLOWED);
120         // By default the configurable list is empty
121         task.run(TEST_USER_ID);
122 
123         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_1);
124         task.run(TEST_USER_ID);
125 
126         assertThat(myShadowOf(mCrossProfileApps).getInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2))
127                 .isEqualTo(MODE_DEFAULT);
128     }
129 
130     @Test
run_packageIsNotRemoved_appOpIsNotReset()131     public void run_packageIsNotRemoved_appOpIsNotReset() {
132         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_1, TEST_PACKAGE_NAME_2);
133         mCrossProfileApps.setInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2, MODE_ALLOWED);
134         task.run(TEST_USER_ID);
135 
136         setDefaultCrossProfilePackages(TEST_PACKAGE_NAME_2);
137         task.run(TEST_USER_ID);
138 
139         assertThat(myShadowOf(mCrossProfileApps).getInteractAcrossProfilesAppOp(TEST_PACKAGE_NAME_2))
140                 .isEqualTo(MODE_ALLOWED);
141     }
142 
setDefaultCrossProfilePackages(String... defaultCrossProfilePackages)143     private void setDefaultCrossProfilePackages(String... defaultCrossProfilePackages) {
144         Set<String> packages = new HashSet<>();
145         for (String packageName : defaultCrossProfilePackages) {
146             packages.add(packageName);
147         }
148 
149         ((ExtendsShadowDevicePolicyManager) Shadow.extract(mDevicePolicyManager)).setDefaultCrossProfilePackages(packages);
150     }
151 }
152