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