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
17package com.android.server.net;
18
19import static org.junit.Assert.assertEquals;
20import static org.mockito.Mockito.when;
21
22import android.Manifest;
23import android.Manifest.permission;
24import android.app.AppOpsManager;
25import android.app.admin.DeviceAdminInfo;
26import android.app.admin.DevicePolicyManagerInternal;
27import android.content.Context;
28import android.content.pm.PackageManager;
29import android.support.test.filters.SmallTest;
30import android.support.test.runner.AndroidJUnit4;
31import android.telephony.TelephonyManager;
32
33import com.android.server.LocalServices;
34
35import org.junit.After;
36import org.junit.Before;
37import org.junit.Test;
38import org.junit.runner.RunWith;
39import org.mockito.Mock;
40import org.mockito.MockitoAnnotations;
41
42@RunWith(AndroidJUnit4.class)
43@SmallTest
44public class NetworkStatsAccessTest {
45    private static final String TEST_PKG = "com.example.test";
46    private static final int TEST_UID = 12345;
47
48    @Mock private Context mContext;
49    @Mock private DevicePolicyManagerInternal mDpmi;
50    @Mock private TelephonyManager mTm;
51    @Mock private AppOpsManager mAppOps;
52
53    // Hold the real service so we can restore it when tearing down the test.
54    private DevicePolicyManagerInternal mSystemDpmi;
55
56    @Before
57    public void setUp() throws Exception {
58        MockitoAnnotations.initMocks(this);
59
60        mSystemDpmi = LocalServices.getService(DevicePolicyManagerInternal.class);
61        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
62        LocalServices.addService(DevicePolicyManagerInternal.class, mDpmi);
63
64        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTm);
65        when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOps);
66    }
67
68    @After
69    public void tearDown() throws Exception {
70        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
71        LocalServices.addService(DevicePolicyManagerInternal.class, mSystemDpmi);
72    }
73
74    @Test
75    public void testCheckAccessLevel_hasCarrierPrivileges() throws Exception {
76        setHasCarrierPrivileges(true);
77        setIsDeviceOwner(false);
78        setIsProfileOwner(false);
79        setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
80        setHasReadHistoryPermission(false);
81        assertEquals(NetworkStatsAccess.Level.DEVICE,
82                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
83    }
84
85    @Test
86    public void testCheckAccessLevel_isDeviceOwner() throws Exception {
87        setHasCarrierPrivileges(false);
88        setIsDeviceOwner(true);
89        setIsProfileOwner(false);
90        setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
91        setHasReadHistoryPermission(false);
92        assertEquals(NetworkStatsAccess.Level.DEVICE,
93                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
94    }
95
96    @Test
97    public void testCheckAccessLevel_isProfileOwner() throws Exception {
98        setHasCarrierPrivileges(false);
99        setIsDeviceOwner(false);
100        setIsProfileOwner(true);
101        setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
102        setHasReadHistoryPermission(false);
103        assertEquals(NetworkStatsAccess.Level.USER,
104                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
105    }
106
107    @Test
108    public void testCheckAccessLevel_hasAppOpsBitAllowed() throws Exception {
109        setHasCarrierPrivileges(false);
110        setIsDeviceOwner(false);
111        setIsProfileOwner(true);
112        setHasAppOpsPermission(AppOpsManager.MODE_ALLOWED, false);
113        setHasReadHistoryPermission(false);
114        assertEquals(NetworkStatsAccess.Level.DEVICESUMMARY,
115                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
116    }
117
118    @Test
119    public void testCheckAccessLevel_hasAppOpsBitDefault_grantedPermission() throws Exception {
120        setHasCarrierPrivileges(false);
121        setIsDeviceOwner(false);
122        setIsProfileOwner(true);
123        setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, true);
124        setHasReadHistoryPermission(false);
125        assertEquals(NetworkStatsAccess.Level.DEVICESUMMARY,
126                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
127    }
128
129    @Test
130    public void testCheckAccessLevel_hasReadHistoryPermission() throws Exception {
131        setHasCarrierPrivileges(false);
132        setIsDeviceOwner(false);
133        setIsProfileOwner(true);
134        setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
135        setHasReadHistoryPermission(true);
136        assertEquals(NetworkStatsAccess.Level.DEVICESUMMARY,
137                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
138    }
139
140    @Test
141    public void testCheckAccessLevel_deniedAppOpsBit() throws Exception {
142        setHasCarrierPrivileges(false);
143        setIsDeviceOwner(false);
144        setIsProfileOwner(false);
145        setHasAppOpsPermission(AppOpsManager.MODE_ERRORED, true);
146        setHasReadHistoryPermission(false);
147        assertEquals(NetworkStatsAccess.Level.DEFAULT,
148                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
149    }
150
151    @Test
152    public void testCheckAccessLevel_deniedAppOpsBit_deniedPermission() throws Exception {
153        setHasCarrierPrivileges(false);
154        setIsDeviceOwner(false);
155        setIsProfileOwner(false);
156        setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
157        setHasReadHistoryPermission(false);
158        assertEquals(NetworkStatsAccess.Level.DEFAULT,
159                NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
160    }
161
162    private void setHasCarrierPrivileges(boolean hasPrivileges) {
163        when(mTm.checkCarrierPrivilegesForPackage(TEST_PKG)).thenReturn(
164                hasPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
165                        : TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
166    }
167
168    private void setIsDeviceOwner(boolean isOwner) {
169        when(mDpmi.isActiveAdminWithPolicy(TEST_UID, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER))
170                .thenReturn(isOwner);
171    }
172
173    private void setIsProfileOwner(boolean isOwner) {
174        when(mDpmi.isActiveAdminWithPolicy(TEST_UID, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))
175                .thenReturn(isOwner);
176    }
177
178    private void setHasAppOpsPermission(int appOpsMode, boolean hasPermission) {
179        when(mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, TEST_UID, TEST_PKG))
180                .thenReturn(appOpsMode);
181        when(mContext.checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)).thenReturn(
182                hasPermission ? PackageManager.PERMISSION_GRANTED
183                        : PackageManager.PERMISSION_DENIED);
184    }
185
186    private void setHasReadHistoryPermission(boolean hasPermission) {
187        when(mContext.checkCallingOrSelfPermission(permission.READ_NETWORK_USAGE_HISTORY))
188                .thenReturn(hasPermission ? PackageManager.PERMISSION_GRANTED
189                        : PackageManager.PERMISSION_DENIED);
190    }
191}
192