1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.settings.applications;
16 
17 import android.app.admin.DevicePolicyManager;
18 import android.content.Context;
19 import android.content.pm.ApplicationInfo;
20 import android.content.pm.IPackageManager;
21 import android.content.pm.PackageManager;
22 import android.os.Build;
23 import android.os.RemoteException;
24 import android.os.UserHandle;
25 
26 /**
27  * Counts installed apps across all users that have been granted one or more specific permissions by
28  * the admin.
29  */
30 public abstract class AppWithAdminGrantedPermissionsCounter extends AppCounter {
31 
32     private final String[] mPermissions;
33     private final IPackageManager mPackageManagerService;
34     private final DevicePolicyManager mDevicePolicyManager;
35 
AppWithAdminGrantedPermissionsCounter(Context context, String[] permissions, PackageManager packageManager, IPackageManager packageManagerService, DevicePolicyManager devicePolicyManager)36     public AppWithAdminGrantedPermissionsCounter(Context context, String[] permissions,
37             PackageManager packageManager, IPackageManager packageManagerService,
38             DevicePolicyManager devicePolicyManager) {
39         super(context, packageManager);
40         mPermissions = permissions;
41         mPackageManagerService = packageManagerService;
42         mDevicePolicyManager = devicePolicyManager;
43     }
44 
45     @Override
includeInCount(ApplicationInfo info)46     protected boolean includeInCount(ApplicationInfo info) {
47         return includeInCount(mPermissions, mDevicePolicyManager, mPm, mPackageManagerService,
48                 info);
49     }
50 
includeInCount(String[] permissions, DevicePolicyManager devicePolicyManager, PackageManager packageManager, IPackageManager packageManagerService, ApplicationInfo info)51     public static boolean includeInCount(String[] permissions,
52             DevicePolicyManager devicePolicyManager, PackageManager packageManager,
53             IPackageManager packageManagerService, ApplicationInfo info) {
54         if (info.targetSdkVersion >= Build.VERSION_CODES.M) {
55             // The app uses run-time permissions. Check whether one or more of the permissions were
56             // granted by enterprise policy.
57             for (final String permission : permissions) {
58                 if (devicePolicyManager.getPermissionGrantState(null /* admin */, info.packageName,
59                         permission) == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED) {
60                     return true;
61                 }
62             }
63             return false;
64         }
65 
66         // The app uses install-time permissions. Check whether the app requested one or more of the
67         // permissions and was installed by enterprise policy, implicitly granting permissions.
68         if (packageManager.getInstallReason(info.packageName,
69                 new UserHandle(UserHandle.getUserId(info.uid)))
70                 != PackageManager.INSTALL_REASON_POLICY) {
71             return false;
72         }
73         try {
74             for (final String permission : permissions) {
75                 if (packageManagerService.checkUidPermission(permission, info.uid)
76                         == PackageManager.PERMISSION_GRANTED) {
77                     return true;
78                 }
79             }
80         } catch (RemoteException exception) {
81         }
82         return false;
83     }
84 }
85