1 /*
2  * Copyright (C) 2024 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 android.app.sdksandbox.testutils;
18 
19 import android.util.ArrayMap;
20 import android.util.ArraySet;
21 import android.util.Base64;
22 
23 import com.android.server.sdksandbox.proto.Activity.ActivityAllowlists;
24 import com.android.server.sdksandbox.proto.Activity.AllowedActivities;
25 import com.android.server.sdksandbox.proto.BroadcastReceiver.AllowedBroadcastReceivers;
26 import com.android.server.sdksandbox.proto.BroadcastReceiver.BroadcastReceiverAllowlists;
27 import com.android.server.sdksandbox.proto.ContentProvider.AllowedContentProviders;
28 import com.android.server.sdksandbox.proto.ContentProvider.ContentProviderAllowlists;
29 import com.android.server.sdksandbox.proto.Services.AllowedService;
30 import com.android.server.sdksandbox.proto.Services.AllowedServices;
31 import com.android.server.sdksandbox.proto.Services.ServiceAllowlists;
32 
33 import java.util.List;
34 
35 /** Utility class to get encoded string for various restrictions */
36 public class ProtoUtil {
37     /** Encode authorities for ContentProvider Allowlist */
encodeContentProviderAllowlist( ArrayMap<Integer, List<String>> authorities)38     public static String encodeContentProviderAllowlist(
39             ArrayMap<Integer, List<String>> authorities) {
40         ContentProviderAllowlists.Builder contentProviderAllowlistsBuilder =
41                 ContentProviderAllowlists.newBuilder();
42 
43         authorities.entrySet().stream()
44                 .forEach(
45                         x -> {
46                             AllowedContentProviders allowedContentProvidersBuilder =
47                                     AllowedContentProviders.newBuilder()
48                                             .addAllAuthorities(x.getValue())
49                                             .build();
50                             contentProviderAllowlistsBuilder.putAllowlistPerTargetSdk(
51                                     x.getKey(), allowedContentProvidersBuilder);
52                         });
53         ContentProviderAllowlists contentProviderAllowlists =
54                 contentProviderAllowlistsBuilder.build();
55 
56         return Base64.encodeToString(
57                 contentProviderAllowlists.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
58     }
59 
60     /** Encode authorities for ContentProvider Allowlist */
encodeContentProviderAllowlist(ArraySet<String> authorities)61     public static String encodeContentProviderAllowlist(ArraySet<String> authorities) {
62         AllowedContentProviders allowedContentProvidersBuilder =
63                 AllowedContentProviders.newBuilder().addAllAuthorities(authorities).build();
64         return Base64.encodeToString(
65                 allowedContentProvidersBuilder.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
66     }
67 
68     /** Encode intent actions for startActivity Allowlist */
encodeActivityAllowlist(ArrayMap<Integer, List<String>> actions)69     public static String encodeActivityAllowlist(ArrayMap<Integer, List<String>> actions) {
70         ActivityAllowlists.Builder activityAllowlistsBuilder = ActivityAllowlists.newBuilder();
71 
72         actions.entrySet().stream()
73                 .forEach(
74                         x -> {
75                             AllowedActivities allowedActivitiesBuilder =
76                                     AllowedActivities.newBuilder()
77                                             .addAllActions(x.getValue())
78                                             .build();
79                             activityAllowlistsBuilder.putAllowlistPerTargetSdk(
80                                     x.getKey(), allowedActivitiesBuilder);
81                         });
82         ActivityAllowlists activityAllowlists = activityAllowlistsBuilder.build();
83         String res =
84                 Base64.encodeToString(
85                         activityAllowlists.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
86 
87         return res;
88     }
89 
90     /** Encode intent actions for startActivity Allowlist */
encodeActivityAllowlist(ArraySet<String> actions)91     public static String encodeActivityAllowlist(ArraySet<String> actions) {
92         AllowedActivities allowedActivitiesBuilder =
93                 AllowedActivities.newBuilder().addAllActions(actions).build();
94         return Base64.encodeToString(
95                 allowedActivitiesBuilder.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
96     }
97 
98     /** Encode intent actions for broadcastReceivers Allowlist */
encodeBroadcastReceiverAllowlist( ArrayMap<Integer, List<String>> intentActions)99     public static String encodeBroadcastReceiverAllowlist(
100             ArrayMap<Integer, List<String>> intentActions) {
101         BroadcastReceiverAllowlists.Builder broadcastReceiverAllowlistBuilder =
102                 BroadcastReceiverAllowlists.newBuilder();
103 
104         intentActions.entrySet().stream()
105                 .forEach(
106                         x -> {
107                             AllowedBroadcastReceivers allowedBroadcastReceivers =
108                                     AllowedBroadcastReceivers.newBuilder()
109                                             .addAllIntentActions(x.getValue())
110                                             .build();
111 
112                             broadcastReceiverAllowlistBuilder.putAllowlistPerTargetSdk(
113                                     x.getKey(), allowedBroadcastReceivers);
114                         });
115         BroadcastReceiverAllowlists broadcastReceiverAllowlist =
116                 broadcastReceiverAllowlistBuilder.build();
117         return Base64.encodeToString(
118                 broadcastReceiverAllowlist.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
119     }
120 
121     /** Encode intent actions for broadcastReceivers Allowlist */
encodeBroadcastReceiverAllowlist(ArraySet<String> actions)122     public static String encodeBroadcastReceiverAllowlist(ArraySet<String> actions) {
123         AllowedBroadcastReceivers allowedBroadcastReceivers =
124                 AllowedBroadcastReceivers.newBuilder().addAllIntentActions(actions).build();
125         return Base64.encodeToString(
126                 allowedBroadcastReceivers.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
127     }
128 
129     /**
130      * Encode intent action, packageName, component className, component packageName for Service
131      * Allowlist
132      */
encodeServiceAllowlist( ArrayMap<Integer, List<ArrayMap<String, String>>> services)133     public static String encodeServiceAllowlist(
134             ArrayMap<Integer, List<ArrayMap<String, String>>> services) {
135         ServiceAllowlists.Builder serviceAllowlistsBuilder = ServiceAllowlists.newBuilder();
136 
137         services.entrySet().stream()
138                 .forEach(
139                         x -> {
140                             serviceAllowlistsBuilder.putAllowlistPerTargetSdk(
141                                     x.getKey(), encodeAllowedServices(x.getValue()));
142                         });
143         ServiceAllowlists serviceAllowlists = serviceAllowlistsBuilder.build();
144         return Base64.encodeToString(
145                 serviceAllowlists.toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
146     }
147 
148     /**
149      * Encode intent action, packageName, component className, component packageName for Service
150      * Allowlist
151      */
encodeServiceAllowlist(List<ArrayMap<String, String>> services)152     public static String encodeServiceAllowlist(List<ArrayMap<String, String>> services) {
153         return Base64.encodeToString(
154                 encodeAllowedServices(services).toByteArray(), Base64.NO_PADDING | Base64.NO_WRAP);
155     }
156 
encodeAllowedServices(List<ArrayMap<String, String>> services)157     private static AllowedServices encodeAllowedServices(List<ArrayMap<String, String>> services) {
158         AllowedServices.Builder allowedServicesBuilder = AllowedServices.newBuilder();
159         services.forEach(
160                 service -> {
161                     allowedServicesBuilder.addAllowedServices(getAllowedService(service));
162                 });
163         return allowedServicesBuilder.build();
164     }
165 
getAllowedService(ArrayMap<String, String> service)166     private static AllowedService getAllowedService(ArrayMap<String, String> service) {
167         return AllowedService.newBuilder()
168                 .setAction(service.get("action"))
169                 .setPackageName(service.get("packageName"))
170                 .setComponentClassName(service.get("componentClassName"))
171                 .setComponentPackageName(service.get("componentPackageName"))
172                 .build();
173     }
174 }
175