• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.permissioncontroller.permission.utils;
18 
19 import android.content.pm.PackageInfo;
20 import android.util.ArrayMap;
21 import android.util.ArraySet;
22 import android.util.EventLog;
23 
24 import com.android.permissioncontroller.permission.model.AppPermissionGroup;
25 import com.android.permissioncontroller.permission.model.Permission;
26 import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup;
27 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission;
28 
29 import java.util.ArrayList;
30 import java.util.List;
31 
32 public final class SafetyNetLogger {
33 
34     // The log tag used by SafetyNet to pick entries from the event log.
35     private static final int SNET_NET_EVENT_LOG_TAG = 0x534e4554;
36 
37     // Log tag for the result of permissions request.
38     private static final String PERMISSIONS_REQUESTED = "individual_permissions_requested";
39 
40     // Log tag for the result of permissions toggling.
41     private static final String PERMISSIONS_TOGGLED = "individual_permissions_toggled";
42 
SafetyNetLogger()43     private SafetyNetLogger() {
44         /* do nothing */
45     }
46 
logPermissionsRequested(PackageInfo packageInfo, List<AppPermissionGroup> groups)47     public static void logPermissionsRequested(PackageInfo packageInfo,
48             List<AppPermissionGroup> groups) {
49         EventLog.writeEvent(SNET_NET_EVENT_LOG_TAG, PERMISSIONS_REQUESTED,
50                 packageInfo.applicationInfo.uid, buildChangedPermissionForPackageMessage(
51                         packageInfo.packageName, groups));
52     }
53 
54     /**
55      * Log that permission groups have been toggled for the purpose of safety net.
56      *
57      * <p>The groups might refer to different permission groups and different apps.
58      *
59      * @param groups The groups toggled
60      */
logPermissionsToggled(ArraySet<AppPermissionGroup> groups)61     public static void logPermissionsToggled(ArraySet<AppPermissionGroup> groups) {
62         ArrayMap<String, ArrayList<AppPermissionGroup>> groupsByPackage = new ArrayMap<>();
63 
64         int numGroups = groups.size();
65         for (int i = 0; i < numGroups; i++) {
66             AppPermissionGroup group = groups.valueAt(i);
67 
68             ArrayList<AppPermissionGroup> groupsForThisPackage = groupsByPackage.get(
69                     group.getApp().packageName);
70             if (groupsForThisPackage == null) {
71                 groupsForThisPackage = new ArrayList<>();
72                 groupsByPackage.put(group.getApp().packageName, groupsForThisPackage);
73             }
74 
75             groupsForThisPackage.add(group);
76             if (group.getBackgroundPermissions() != null) {
77                 groupsForThisPackage.add(group.getBackgroundPermissions());
78             }
79         }
80 
81         int numPackages = groupsByPackage.size();
82         for (int i = 0; i < numPackages; i++) {
83             EventLog.writeEvent(SNET_NET_EVENT_LOG_TAG, PERMISSIONS_TOGGLED,
84                     android.os.Process.myUid(), buildChangedPermissionForPackageMessage(
85                             groupsByPackage.keyAt(i), groupsByPackage.valueAt(i)));
86         }
87     }
88 
89     /**
90      * Log that a permission group has been toggled for the purpose of safety net.
91      *
92      * @param group The group toggled.
93      */
logPermissionToggled(AppPermissionGroup group)94     public static void logPermissionToggled(AppPermissionGroup group) {
95         ArraySet groups = new ArraySet<AppPermissionGroup>(1);
96         groups.add(group);
97         logPermissionsToggled(groups);
98     }
99 
100     /**
101      * Log that a permission group has been toggled for the purpose of safety net.
102      *
103      * @param group The group which was toggled. This group must represent the current state, not
104      * the old state
105      * @param logOnlyBackground Whether to log only background permissions, or foreground and
106      * background
107      */
logPermissionToggled(LightAppPermGroup group, boolean logOnlyBackground)108     public static void logPermissionToggled(LightAppPermGroup group, boolean logOnlyBackground) {
109         EventLog.writeEvent(SNET_NET_EVENT_LOG_TAG, PERMISSIONS_TOGGLED,
110                 android.os.Process.myUid(), buildChangedPermissionForPackageMessage(group,
111                         logOnlyBackground));
112     }
113 
114     /**
115      * Log that a permission group has been toggled for the purpose of safety net. Logs both
116      * background and foreground permissions.
117      *
118      * @param group The group which was toggled. This group must represent the current state, not
119      * the old state
120      */
logPermissionToggled(LightAppPermGroup group)121     public static void logPermissionToggled(LightAppPermGroup group) {
122         logPermissionToggled(group, false);
123     }
124 
buildChangedPermissionForPackageMessage( LightAppPermGroup group, boolean logOnlyBackground)125     private static String buildChangedPermissionForPackageMessage(
126             LightAppPermGroup group, boolean logOnlyBackground) {
127         StringBuilder builder = new StringBuilder();
128 
129         builder.append(group.getPackageInfo().getPackageName()).append(':');
130 
131         for (LightPermission permission: group.getPermissions().values()) {
132             if (logOnlyBackground
133                     && !group.getBackgroundPermNames().contains(permission.getName())) {
134                 continue;
135             }
136 
137             if (builder.length() > 0) {
138                 builder.append(';');
139             }
140 
141             builder.append(permission.getName()).append('|');
142             builder.append(permission.isGrantedIncludingAppOp()).append('|');
143             builder.append(permission.getFlags());
144         }
145 
146         return builder.toString();
147     }
148 
buildChangedPermissionForGroup(AppPermissionGroup group, StringBuilder builder)149     private static void buildChangedPermissionForGroup(AppPermissionGroup group,
150             StringBuilder builder) {
151         int permissionCount = group.getPermissions().size();
152         for (int permissionNum = 0; permissionNum < permissionCount; permissionNum++) {
153             Permission permission = group.getPermissions().get(permissionNum);
154 
155             if (builder.length() > 0) {
156                 builder.append(';');
157             }
158 
159             builder.append(permission.getName()).append('|');
160             builder.append(permission.isGrantedIncludingAppOp()).append('|');
161             builder.append(permission.getFlags());
162         }
163     }
164 
buildChangedPermissionForPackageMessage(String packageName, List<AppPermissionGroup> groups)165     private static String buildChangedPermissionForPackageMessage(String packageName,
166             List<AppPermissionGroup> groups) {
167         StringBuilder builder = new StringBuilder();
168 
169         builder.append(packageName).append(':');
170 
171         int groupCount = groups.size();
172         for (int groupNum = 0; groupNum < groupCount; groupNum++) {
173             AppPermissionGroup group = groups.get(groupNum);
174 
175             buildChangedPermissionForGroup(group, builder);
176             if (group.getBackgroundPermissions() != null) {
177                 buildChangedPermissionForGroup(group.getBackgroundPermissions(), builder);
178             }
179         }
180 
181         return builder.toString();
182     }
183 }
184