1/*
2 * Copyright (C) 2017 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
17package com.android.settings.applications;
18
19import static com.google.common.truth.Truth.assertThat;
20import static org.mockito.Matchers.anyInt;
21import static org.mockito.Matchers.anyString;
22import static org.mockito.Matchers.eq;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.spy;
25import static org.mockito.Mockito.verify;
26import static org.mockito.Mockito.when;
27
28import android.content.Context;
29import android.content.pm.PackageInfo;
30import android.content.pm.PackageManager;
31import android.content.pm.PackageManager.NameNotFoundException;
32import android.content.pm.PermissionGroupInfo;
33import android.content.pm.PermissionInfo;
34import android.support.v7.preference.Preference;
35
36import com.android.settings.testutils.SettingsRobolectricTestRunner;
37import com.android.settings.TestConfig;
38import java.util.ArrayList;
39import java.util.List;
40import org.junit.Before;
41import org.junit.Test;
42import org.junit.runner.RunWith;
43import org.mockito.Mock;
44import org.mockito.MockitoAnnotations;
45import org.robolectric.RuntimeEnvironment;
46import org.robolectric.annotation.Config;
47
48@RunWith(SettingsRobolectricTestRunner.class)
49@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
50public class AppPermissionsPreferenceControllerTest {
51
52    private static final String PERM_LOCATION = "android.permission-group.LOCATION";
53    private static final String PERM_MICROPHONE = "android.permission-group.MICROPHONE";
54    private static final String PERM_CAMERA = "android.permission-group.CAMERA";
55    private static final String PERM_SMS = "android.permission-group.SMS";
56    private static final String PERM_CONTACTS = "android.permission-group.CONTACTS";
57    private static final String PERM_PHONE = "android.permission-group.PHONE";
58    private static final String LABEL_LOCATION = "Location";
59    private static final String LABEL_MICROPHONE = "Microphone";
60    private static final String LABEL_CAMERA = "Camera";
61    private static final String LABEL_SMS = "Sms";
62    private static final String LABEL_CONTACTS = "Contacts";
63    private static final String LABEL_PHONE = "Phone";
64
65    @Mock
66    private Preference mPreference;
67    @Mock
68    private PackageManager mPackageManager;
69    @Mock
70    private PermissionGroupInfo mGroupLocation;
71    @Mock
72    private PermissionGroupInfo mGroupMic;
73    @Mock
74    private PermissionGroupInfo mGroupCamera;
75    @Mock
76    private PermissionGroupInfo mGroupSms;
77    @Mock
78    private PermissionGroupInfo mGroupContacts;
79    @Mock
80    private PermissionGroupInfo mGroupPhone;
81
82    private Context mContext;
83    private AppPermissionsPreferenceController mController;
84    private PermissionInfo mPermLocation;
85    private PermissionInfo mPermMic;
86    private PermissionInfo mPermCamera;
87    private PermissionInfo mPermSms;
88    private PermissionInfo mPermContacts;
89    private PermissionInfo mPermPhone;
90
91    @Before
92    public void setUp() throws NameNotFoundException {
93        MockitoAnnotations.initMocks(this);
94        mContext = spy(RuntimeEnvironment.application);
95        when(mContext.getPackageManager()).thenReturn(mPackageManager);
96
97        // create permission groups
98        when(mPackageManager.getPermissionGroupInfo(eq(PERM_LOCATION), anyInt()))
99            .thenReturn(mGroupLocation);
100        when(mGroupLocation.loadLabel(mPackageManager)).thenReturn(LABEL_LOCATION);
101        when(mPackageManager.getPermissionGroupInfo(eq(PERM_MICROPHONE), anyInt()))
102            .thenReturn(mGroupMic);
103        when(mGroupMic.loadLabel(mPackageManager)).thenReturn(LABEL_MICROPHONE);
104        when(mPackageManager.getPermissionGroupInfo(eq(PERM_CAMERA), anyInt()))
105            .thenReturn(mGroupCamera);
106        when(mGroupCamera.loadLabel(mPackageManager)).thenReturn(LABEL_CAMERA);
107        when(mPackageManager.getPermissionGroupInfo(eq(PERM_SMS), anyInt())).thenReturn(mGroupSms);
108        when(mGroupSms.loadLabel(mPackageManager)).thenReturn(LABEL_SMS);
109        when(mPackageManager.getPermissionGroupInfo(eq(PERM_CONTACTS), anyInt()))
110            .thenReturn(mGroupContacts);
111        when(mGroupContacts.loadLabel(mPackageManager)).thenReturn(LABEL_CONTACTS);
112        when(mPackageManager.getPermissionGroupInfo(eq(PERM_PHONE), anyInt()))
113            .thenReturn(mGroupPhone);
114        when(mGroupPhone.loadLabel(mPackageManager)).thenReturn(LABEL_PHONE);
115
116        // create permissions
117        mPermLocation = new PermissionInfo();
118        mPermLocation.name = "Permission1";
119        mPermLocation.group = PERM_LOCATION;
120        mPermMic = new PermissionInfo();
121        mPermMic.name = "Permission2";
122        mPermMic.group = PERM_MICROPHONE;
123        mPermCamera = new PermissionInfo();
124        mPermCamera.name = "Permission3";
125        mPermCamera.group = PERM_CAMERA;
126        mPermSms = new PermissionInfo();
127        mPermSms.name = "Permission4";
128        mPermSms.group = PERM_SMS;
129        mPermContacts = new PermissionInfo();
130        mPermContacts.name = "Permission4";
131        mPermContacts.group = PERM_CONTACTS;
132        mPermPhone = new PermissionInfo();
133        mPermPhone.name = "Permission4";
134        mPermPhone.group = PERM_PHONE;
135        final List<PermissionInfo> permissions = new ArrayList<>();
136        permissions.add(mPermLocation);
137        permissions.add(mPermMic);
138        permissions.add(mPermCamera);
139        permissions.add(mPermSms);
140        permissions.add(mPermContacts);
141        permissions.add(mPermPhone);
142        when(mPackageManager.queryPermissionsByGroup(anyString(), anyInt()))
143            .thenReturn(permissions);
144
145        mController = spy(new AppPermissionsPreferenceController(mContext));
146    }
147
148    @Test
149    public void isAvailable_shouldAlwaysReturnTrue() {
150        assertThat(mController.isAvailable()).isTrue();
151    }
152
153    @Test
154    public void updateState_noGrantedPermissions_shouldNotSetSummary() {
155        final List<PackageInfo> installedPackages = new ArrayList<>();
156        final PackageInfo info = new PackageInfo();
157        installedPackages.add(info);
158        when(mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS))
159            .thenReturn(installedPackages);
160
161        mController.updateState(mPreference);
162
163        verify(mPreference, never()).setSummary(anyString());
164    }
165
166    @Test
167    public void updateState_hasPermissions_shouldSetSummary() {
168        final List<PackageInfo> installedPackages = new ArrayList<>();
169        final PackageInfo info = new PackageInfo();
170        installedPackages.add(info);
171        when(mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS))
172            .thenReturn(installedPackages);
173        PermissionInfo[] permissions = new PermissionInfo[4];
174        info.permissions = permissions;
175
176        permissions[0] = mPermLocation;
177        permissions[1] = mPermMic;
178        permissions[2] = mPermCamera;
179        permissions[3] = mPermSms;
180        mController.updateState(mPreference);
181        verify(mPreference).setSummary("Apps using Location, Microphone, Camera");
182
183        permissions[0] = mPermPhone;
184        permissions[1] = mPermMic;
185        permissions[2] = mPermCamera;
186        permissions[3] = mPermSms;
187        mController.updateState(mPreference);
188        verify(mPreference).setSummary("Apps using Microphone, Camera, Sms");
189
190        permissions[0] = mPermPhone;
191        permissions[1] = mPermMic;
192        permissions[2] = mPermContacts;
193        permissions[3] = mPermSms;
194        mController.updateState(mPreference);
195        verify(mPreference).setSummary("Apps using Microphone, Sms, Contacts");
196
197        permissions = new PermissionInfo[2];
198        info.permissions = permissions;
199        permissions[0] = mPermLocation;
200        permissions[1] = mPermCamera;
201        mController.updateState(mPreference);
202        verify(mPreference).setSummary("Apps using Location, Camera");
203
204        permissions = new PermissionInfo[1];
205        info.permissions = permissions;
206        permissions[0] = mPermCamera;
207        mController.updateState(mPreference);
208        verify(mPreference).setSummary("Apps using Camera");
209    }
210}
211