1 /*
2  * Copyright (C) 2023 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.legacy;
18 
19 import android.util.ArrayMap;
20 import android.util.ArraySet;
21 import android.util.EventLog;
22 
23 import com.android.permissioncontroller.permission.model.AppPermissionGroup;
24 import com.android.permissioncontroller.permission.model.Permission;
25 
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 /**
30  * Legacy SafetyNetLogger that interacts with AppPermissionGroup for TV and wear.
31  */
32 public class LegacySafetyNetLogger {
33     // The log tag used by SafetyNet to pick entries from the event log.
34     private static final int SNET_NET_EVENT_LOG_TAG = 0x534e4554;
35 
36     // Log tag for the result of permissions toggling.
37     private static final String PERMISSIONS_TOGGLED = "individual_permissions_toggled";
38 
LegacySafetyNetLogger()39     private LegacySafetyNetLogger() {
40         /* do nothing */
41     }
42 
43     /**
44      * Log that permission groups have been toggled for the purpose of safety net.
45      *
46      * <p>The groups might refer to different permission groups and different apps.
47      *
48      * @param groups The groups toggled
49      */
logPermissionsToggled(ArraySet<AppPermissionGroup> groups)50     public static void logPermissionsToggled(ArraySet<AppPermissionGroup> groups) {
51         ArrayMap<String, ArrayList<AppPermissionGroup>> groupsByPackage = new ArrayMap<>();
52 
53         int numGroups = groups.size();
54         for (int i = 0; i < numGroups; i++) {
55             AppPermissionGroup group = groups.valueAt(i);
56 
57             ArrayList<AppPermissionGroup> groupsForThisPackage = groupsByPackage.get(
58                     group.getApp().packageName);
59             if (groupsForThisPackage == null) {
60                 groupsForThisPackage = new ArrayList<>();
61                 groupsByPackage.put(group.getApp().packageName, groupsForThisPackage);
62             }
63 
64             groupsForThisPackage.add(group);
65             if (group.getBackgroundPermissions() != null) {
66                 groupsForThisPackage.add(group.getBackgroundPermissions());
67             }
68         }
69 
70         int numPackages = groupsByPackage.size();
71         for (int i = 0; i < numPackages; i++) {
72             EventLog.writeEvent(SNET_NET_EVENT_LOG_TAG, PERMISSIONS_TOGGLED,
73                     android.os.Process.myUid(), buildChangedPermissionForPackageMessage(
74                             groupsByPackage.keyAt(i), groupsByPackage.valueAt(i)));
75         }
76     }
77 
buildChangedPermissionForPackageMessage(String packageName, List<AppPermissionGroup> groups)78     private static String buildChangedPermissionForPackageMessage(String packageName,
79             List<AppPermissionGroup> groups) {
80         StringBuilder builder = new StringBuilder();
81 
82         builder.append(packageName).append(':');
83 
84         int groupCount = groups.size();
85         for (int groupNum = 0; groupNum < groupCount; groupNum++) {
86             AppPermissionGroup group = groups.get(groupNum);
87 
88             buildChangedPermissionForGroup(group, builder);
89             if (group.getBackgroundPermissions() != null) {
90                 buildChangedPermissionForGroup(group.getBackgroundPermissions(), builder);
91             }
92         }
93 
94         return builder.toString();
95     }
96 
buildChangedPermissionForGroup(AppPermissionGroup group, StringBuilder builder)97     private static void buildChangedPermissionForGroup(AppPermissionGroup group,
98             StringBuilder builder) {
99         int permissionCount = group.getPermissions().size();
100         for (int permissionNum = 0; permissionNum < permissionCount; permissionNum++) {
101             Permission permission = group.getPermissions().get(permissionNum);
102 
103             if (builder.length() > 0) {
104                 builder.append(';');
105             }
106 
107             builder.append(permission.getName()).append('|');
108             builder.append(permission.isGrantedIncludingAppOp()).append('|');
109             builder.append(permission.getFlags());
110         }
111     }
112 }
113