1 /*
2  * Copyright (C) 2018 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.settings.enterprise;
18 
19 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.never;
28 import static org.mockito.Mockito.verify;
29 
30 import android.app.Activity;
31 import android.app.admin.DevicePolicyManager;
32 import android.content.ComponentName;
33 import android.content.pm.UserInfo;
34 import android.os.Process;
35 import android.os.UserHandle;
36 import android.os.UserManager;
37 import android.view.ViewGroup;
38 import android.widget.FrameLayout;
39 import android.widget.TextView;
40 
41 import androidx.appcompat.app.AlertDialog;
42 
43 import com.android.settings.R;
44 import com.android.settings.testutils.CustomActivity;
45 import com.android.settings.testutils.shadow.ShadowActivity;
46 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
47 import com.android.settings.testutils.shadow.ShadowUserManager;
48 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
49 
50 import org.junit.Before;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.robolectric.Robolectric;
54 import org.robolectric.RobolectricTestRunner;
55 import org.robolectric.RuntimeEnvironment;
56 import org.robolectric.Shadows;
57 import org.robolectric.annotation.Config;
58 import org.robolectric.shadow.api.Shadow;
59 import org.robolectric.shadows.ShadowProcess;
60 
61 @RunWith(RobolectricTestRunner.class)
62 @Config(shadows = {
63         ShadowDevicePolicyManager.class,
64         ShadowUserManager.class,
65         ShadowActivity.class
66 })
67 public class ActionDisabledByAdminDialogHelperTest {
68     private static final ComponentName ADMIN_COMPONENT =
69             new ComponentName("some.package.name", "some.package.name.SomeClass");
70     private static final int USER_ID = 123;
71     private static final EnforcedAdmin ENFORCED_ADMIN =
72             new EnforcedAdmin(ADMIN_COMPONENT, UserHandle.of(USER_ID));
73     private ActionDisabledByAdminDialogHelper mHelper;
74     private Activity mActivity;
75     private org.robolectric.shadows.ShadowActivity mActivityShadow;
76 
77     @Before
setUp()78     public void setUp() {
79         mActivity = Robolectric.setupActivity(CustomActivity.class);
80         mActivityShadow = Shadow.extract(mActivity);
81         mHelper = new ActionDisabledByAdminDialogHelper(mActivity);
82     }
83 
84     @Test
testSetAdminSupportTitle()85     public void testSetAdminSupportTitle() {
86         final ViewGroup view = new FrameLayout(mActivity);
87         final TextView textView = createAdminSupportDialogTitleTextView(view, mActivity);
88 
89         mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_ADJUST_VOLUME);
90         assertEquals(Shadows.shadowOf(textView).innerText(),
91                 mActivity.getString(R.string.disabled_by_policy_title_adjust_volume));
92 
93         mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_OUTGOING_CALLS);
94         assertEquals(Shadows.shadowOf(textView).innerText(),
95                 mActivity.getString(R.string.disabled_by_policy_title_outgoing_calls));
96 
97         mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_SMS);
98         assertEquals(Shadows.shadowOf(textView).innerText(),
99                 mActivity.getString(R.string.disabled_by_policy_title_sms));
100 
101         mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_DISABLE_CAMERA);
102         assertEquals(Shadows.shadowOf(textView).innerText(),
103                 mActivity.getString(R.string.disabled_by_policy_title_camera));
104 
105         mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
106         assertEquals(Shadows.shadowOf(textView).innerText(),
107                 mActivity.getString(R.string.disabled_by_policy_title_screen_capture));
108 
109         mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_SUSPEND_PACKAGES);
110         assertEquals(Shadows.shadowOf(textView).innerText(),
111                 mActivity.getString(R.string.disabled_by_policy_title_suspend_packages));
112 
113         mHelper.setAdminSupportTitle(view, "another restriction");
114         assertEquals(Shadows.shadowOf(textView).innerText(),
115                 mActivity.getString(R.string.disabled_by_policy_title));
116 
117         mHelper.setAdminSupportTitle(view, null);
118         assertEquals(Shadows.shadowOf(textView).innerText(),
119                 mActivity.getString(R.string.disabled_by_policy_title));
120     }
121 
122     @Test
testSetAdminSupportTitleForFinancedDevice()123     public void testSetAdminSupportTitleForFinancedDevice() {
124         final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow();
125         final ViewGroup view = new FrameLayout(mActivity);
126         final TextView textView = createAdminSupportDialogTitleTextView(view, mActivity);
127         setupFinancedDevice(dpmShadow);
128         mHelper = new ActionDisabledByAdminDialogHelper(mActivity);
129 
130         mHelper.setAdminSupportTitle(view, null);
131 
132         assertEquals(Shadows.shadowOf(textView).innerText(),
133                 mActivity.getString(R.string.disabled_by_policy_title_financed_device));
134     }
135 
136     @Test
testSetAdminSupportDetails()137     public void testSetAdminSupportDetails() {
138         final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow();
139         final UserManager userManager = RuntimeEnvironment.application.getSystemService(
140                 UserManager.class);
141         final ShadowUserManager userManagerShadow = Shadow.extract(userManager);
142         final ViewGroup view = new FrameLayout(mActivity);
143         final ComponentName component = new ComponentName("some.package.name",
144                 "some.package.name.SomeClass");
145         final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123));
146         final TextView textView = createAdminSupportTextView(view, mActivity);
147         dpmShadow.setShortSupportMessageForUser(component, 123, "some message");
148         dpmShadow.setIsAdminActiveAsUser(true);
149         createShadowWorkProfile(userManagerShadow);
150 
151         mHelper.setAdminSupportDetails(mActivity, view, admin);
152 
153         assertNotNull(admin.component);
154         assertEquals("some message", Shadows.shadowOf(textView).innerText());
155     }
156 
157     @Test
testSetAdminSupportDetails_shortSupportMessageIsNull()158     public void testSetAdminSupportDetails_shortSupportMessageIsNull() {
159         final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow();
160         final UserManager userManager = RuntimeEnvironment.application.getSystemService(
161                 UserManager.class);
162         final ShadowUserManager userManagerShadow = Shadow.extract(userManager);
163         final ViewGroup view = new FrameLayout(mActivity);
164         final ComponentName component = new ComponentName("some.package.name",
165                 "some.package.name.SomeClass");
166         final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123));
167         final TextView textView = createAdminSupportTextView(view, mActivity);
168         dpmShadow.setShortSupportMessageForUser(component, 123, null);
169         dpmShadow.setIsAdminActiveAsUser(true);
170         createShadowWorkProfile(userManagerShadow);
171 
172         mHelper.setAdminSupportDetails(mActivity, view, admin);
173 
174         assertNotNull(admin.component);
175         assertEquals(mActivity.getString(R.string.default_admin_support_msg),
176                 Shadows.shadowOf(textView).innerText());
177     }
178 
179     @Test
testSetAdminSupportDetailsNotAdmin()180     public void testSetAdminSupportDetailsNotAdmin() {
181         final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow();
182         final UserManager userManager = RuntimeEnvironment.application.getSystemService(
183                 UserManager.class);
184         final ShadowUserManager userManagerShadow = Shadow.extract(userManager);
185         final ViewGroup view = new FrameLayout(mActivity);
186         final ComponentName component = new ComponentName("some.package.name",
187                 "some.package.name.SomeClass");
188         final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123));
189         final TextView textView = createAdminSupportTextView(view, mActivity);
190         dpmShadow.setShortSupportMessageForUser(component, 123, "some message");
191         dpmShadow.setIsAdminActiveAsUser(false);
192         userManagerShadow.addProfile(new UserInfo(123, null, 0));
193 
194         mHelper.setAdminSupportDetails(mActivity, textView, admin);
195 
196         assertNull(admin.component);
197         assertEquals(mActivity.getString(R.string.default_admin_support_msg),
198                 Shadows.shadowOf(textView).innerText());
199     }
200 
201     @Test
testMaybeSetLearnMoreButton()202     public void testMaybeSetLearnMoreButton() {
203         UserManager userManager = RuntimeEnvironment.application
204                 .getSystemService(UserManager.class);
205         ShadowUserManager userManagerShadow = Shadow.extract(userManager);
206         // Set up for shadow call.
207         userManagerShadow.getSameProfileGroupIds().put(USER_ID, 0);
208 
209         // Test that the button is shown when user IDs are in the same profile group
210         AlertDialog.Builder builder = mock(AlertDialog.Builder.class);
211         mHelper.prepareDialogBuilder(builder, /* restriction= */ null, ENFORCED_ADMIN);
212         verify(builder).setNeutralButton(anyInt(), any());
213 
214         // Test that the button is not shown when user IDs are not in the same profile group
215         userManagerShadow.getSameProfileGroupIds().clear();
216         builder = mock(AlertDialog.Builder.class);
217         mHelper.prepareDialogBuilder(builder, /* restriction= */ null, ENFORCED_ADMIN);
218         verify(builder, never()).setNeutralButton(anyInt(), any());
219     }
220 
createAdminSupportDialogTitleTextView(final ViewGroup view, final Activity activity)221     private static TextView createAdminSupportDialogTitleTextView(final ViewGroup view,
222             final Activity activity) {
223         final TextView textView = new TextView(activity);
224         textView.setId(R.id.admin_support_dialog_title);
225         view.addView(textView);
226         return textView;
227     }
228 
createAdminSupportTextView(final ViewGroup view, final Activity activity)229     private static TextView createAdminSupportTextView(final ViewGroup view,
230             final Activity activity) {
231         final TextView textView = new TextView(activity);
232         textView.setId(R.id.admin_support_msg);
233         view.addView(textView);
234         return textView;
235     }
236 
createShadowWorkProfile(final ShadowUserManager userManagerShadow)237     private static void createShadowWorkProfile(final ShadowUserManager userManagerShadow) {
238         userManagerShadow.addProfile(new UserInfo(123, null, 0));
239         userManagerShadow.addUserProfile(new UserHandle(123));
240         ShadowProcess.setUid(Process.SYSTEM_UID);
241     }
242 
setupFinancedDevice(final ShadowDevicePolicyManager dpmShadow)243     private static void setupFinancedDevice(final ShadowDevicePolicyManager dpmShadow) {
244         final ComponentName component = new ComponentName("some.package.name",
245                 "some.package.name.SomeClass");
246         dpmShadow.setDeviceOwner(component);
247         dpmShadow.setDeviceOwnerComponentOnAnyUser(component);
248         dpmShadow.setDeviceOwnerType(component, DEVICE_OWNER_TYPE_FINANCED);
249         dpmShadow.setShortSupportMessageForUser(component, 123, null);
250         dpmShadow.setIsAdminActiveAsUser(true);
251     }
252 }
253