• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.server.sdksandbox;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.sdksandbox.LogUtil;
22 import android.content.Context;
23 import android.provider.DeviceConfig;
24 import android.text.TextUtils;
25 import android.util.ArrayMap;
26 import android.util.ArraySet;
27 import android.util.Base64;
28 import android.util.Log;
29 
30 import com.android.internal.annotations.GuardedBy;
31 import com.android.internal.annotations.VisibleForTesting;
32 import com.android.server.sdksandbox.proto.Activity.ActivityAllowlists;
33 import com.android.server.sdksandbox.proto.Activity.AllowedActivities;
34 import com.android.server.sdksandbox.proto.BroadcastReceiver.AllowedBroadcastReceivers;
35 import com.android.server.sdksandbox.proto.BroadcastReceiver.BroadcastReceiverAllowlists;
36 import com.android.server.sdksandbox.proto.ContentProvider.AllowedContentProviders;
37 import com.android.server.sdksandbox.proto.ContentProvider.ContentProviderAllowlists;
38 import com.android.server.sdksandbox.proto.Services.AllowedServices;
39 import com.android.server.sdksandbox.proto.Services.ServiceAllowlists;
40 
41 import com.google.protobuf.Parser;
42 
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.Set;
46 
47 class SdkSandboxSettingsListener implements DeviceConfig.OnPropertiesChangedListener {
48 
49     private static final String TAG = "SdkSandboxManager";
50     private static final String PROPERTY_DISABLE_SDK_SANDBOX = "disable_sdk_sandbox";
51     private static final boolean DEFAULT_VALUE_DISABLE_SDK_SANDBOX = true;
52 
53     // Prefix all the keys with sdksandbox_ as the namespace is shared with PPAPI
54     /**
55      * Property to enforce restrictions for SDK sandbox processes. If the value of this property is
56      * {@code true}, the restrictions will be enforced.
57      */
58     private static final String PROPERTY_ENFORCE_RESTRICTIONS = "sdksandbox_enforce_restrictions";
59 
60     private static final boolean DEFAULT_VALUE_ENFORCE_RESTRICTIONS = true;
61 
62     /** We need to keep in sync with the property used in ProcessList */
63     private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
64             "apply_sdk_sandbox_next_restrictions";
65 
66     private static final boolean DEFAULT_VALUE_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = false;
67 
68     private static final String PROPERTY_BROADCASTRECEIVER_ALLOWLIST =
69             "sdksandbox_broadcastreceiver_allowlist_per_targetSdkVersion";
70 
71     // Property for the canary set allowlist indicating which broadcast receivers can be registered
72     // by the sandbox.
73     private static final String PROPERTY_NEXT_BROADCASTRECEIVER_ALLOWLIST =
74             "sdksandbox_next_broadcastreceiver_allowlist";
75 
76     private static final String PROPERTY_CONTENTPROVIDER_ALLOWLIST =
77             "contentprovider_allowlist_per_targetSdkVersion";
78 
79     // Property indicating the ContentProvider canary allowlist.
80     private static final String PROPERTY_NEXT_CONTENTPROVIDER_ALLOWLIST =
81             "sdksandbox_next_contentprovider_allowlist";
82 
83     private static final String PROPERTY_SERVICES_ALLOWLIST =
84             "services_allowlist_per_targetSdkVersion";
85 
86     // Property for canary set for service restrictions
87     private static final String PROPERTY_NEXT_SERVICE_ALLOWLIST =
88             "sdksandbox_next_service_allowlist";
89 
90     private static final String PROPERTY_ACTIVITY_ALLOWLIST =
91             "sdksandbox_activity_allowlist_per_targetSdkVersion";
92     private static final String PROPERTY_NEXT_ACTIVITY_ALLOWLIST =
93             "sdksandbox_next_activity_allowlist";
94 
95     // Bug fix for b/372475678. Adds support for HSUM in SDK storage tests
96     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
97     static final String PROPERTY_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE =
98             "SdkSandbox__enable_hsum_support_for_sdk_storage";
99 
100     // Trivial bug fix. Enabled by default.
101     private static final boolean DEFAULT_VALUE_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE = true;
102 
103     static final String PROPERTY_RECONCILE_ON_VOLUME_MOUNT =
104             "SdkSandboxStorage__reconcile_on_volume_mount";
105 
106     private static final boolean DEFAULT_VALUE_RECONCILE_ON_VOLUME_MOUNT = false;
107 
108     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
109     static final String PROPERTY_FIX_STOP_SANDBOX_DEADLOCK =
110             "SdkSandbox__fix_deadlock_bug_398296192";
111 
112     // Trivial bug fix. Enabled by default.
113     private static final boolean DEFAULT_VALUE_FIX_STOP_SANDBOX_DEADLOCK = true;
114 
115     private final Context mContext;
116     private final Object mLock = new Object();
117     private final SdkSandboxManagerService mSdkSandboxManagerService;
118 
119     // Properties for which we log the onPropertiesChanged values
120     private static final Set<String> LOGGED_PROPERTIES =
121             Set.of(
122                     PROPERTY_DISABLE_SDK_SANDBOX,
123                     PROPERTY_ENFORCE_RESTRICTIONS,
124                     PROPERTY_BROADCASTRECEIVER_ALLOWLIST,
125                     PROPERTY_NEXT_BROADCASTRECEIVER_ALLOWLIST,
126                     PROPERTY_CONTENTPROVIDER_ALLOWLIST,
127                     PROPERTY_NEXT_CONTENTPROVIDER_ALLOWLIST,
128                     PROPERTY_SERVICES_ALLOWLIST,
129                     PROPERTY_NEXT_SERVICE_ALLOWLIST,
130                     PROPERTY_ACTIVITY_ALLOWLIST,
131                     PROPERTY_NEXT_ACTIVITY_ALLOWLIST);
132 
133     @GuardedBy("mLock")
134     private boolean mKillSwitchEnabled =
135             DeviceConfig.getBoolean(
136                     DeviceConfig.NAMESPACE_ADSERVICES,
137                     PROPERTY_DISABLE_SDK_SANDBOX,
138                     DEFAULT_VALUE_DISABLE_SDK_SANDBOX);
139 
140     @GuardedBy("mLock")
141     private boolean mEnforceRestrictions =
142             DeviceConfig.getBoolean(
143                     DeviceConfig.NAMESPACE_ADSERVICES,
144                     PROPERTY_ENFORCE_RESTRICTIONS,
145                     DEFAULT_VALUE_ENFORCE_RESTRICTIONS);
146 
147     @GuardedBy("mLock")
148     private boolean mSdkSandboxApplyRestrictionsNext =
149             DeviceConfig.getBoolean(
150                     DeviceConfig.NAMESPACE_ADSERVICES,
151                     PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
152                     DEFAULT_VALUE_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
153 
154     @GuardedBy("mLock")
155     private boolean mReconcileOnVolumeMount =
156             DeviceConfig.getBoolean(
157                     DeviceConfig.NAMESPACE_ADSERVICES,
158                     PROPERTY_RECONCILE_ON_VOLUME_MOUNT,
159                     DEFAULT_VALUE_RECONCILE_ON_VOLUME_MOUNT);
160 
161     @GuardedBy("mLock")
162     private Map<Integer, AllowedServices> mServiceAllowlistPerTargetSdkVersion =
163             getServicesAllowlist(
164                     DeviceConfig.getProperty(
165                             DeviceConfig.NAMESPACE_ADSERVICES, PROPERTY_SERVICES_ALLOWLIST));
166 
167     @GuardedBy("mLock")
168     private AllowedServices mNextServiceAllowlist =
169             getNextServiceDeviceConfigAllowlist(
170                     DeviceConfig.getProperty(
171                             DeviceConfig.NAMESPACE_ADSERVICES, PROPERTY_NEXT_SERVICE_ALLOWLIST));
172 
173     @GuardedBy("mLock")
174     private ArrayMap<Integer, ArraySet<String>> mContentProviderAllowlistPerTargetSdkVersion =
175             getContentProviderDeviceConfigAllowlist(
176                     DeviceConfig.getProperty(
177                             DeviceConfig.NAMESPACE_ADSERVICES, PROPERTY_CONTENTPROVIDER_ALLOWLIST));
178 
179     @GuardedBy("mLock")
180     private ArraySet<String> mNextContentProviderAllowlist =
181             getNextContentProviderDeviceConfigAllowlist(
182                     DeviceConfig.getProperty(
183                             DeviceConfig.NAMESPACE_ADSERVICES,
184                             PROPERTY_NEXT_CONTENTPROVIDER_ALLOWLIST));
185 
186     @Nullable
187     @GuardedBy("mLock")
188     private ArrayMap<Integer, ArraySet<String>> mBroadcastReceiverAllowlistPerTargetSdkVersion =
189             getBroadcastReceiverDeviceConfigAllowlist(
190                     DeviceConfig.getProperty(
191                             DeviceConfig.NAMESPACE_ADSERVICES,
192                             PROPERTY_BROADCASTRECEIVER_ALLOWLIST));
193 
194     @GuardedBy("mLock")
195     private ArraySet<String> mNextBroadcastReceiverAllowlist =
196             getNextBroadcastReceiverDeviceConfigAllowlist(
197                     DeviceConfig.getProperty(
198                             DeviceConfig.NAMESPACE_ADSERVICES,
199                             PROPERTY_NEXT_BROADCASTRECEIVER_ALLOWLIST));
200 
201     @Nullable
202     @GuardedBy("mLock")
203     private ArrayMap<Integer, ArraySet<String>> mActivityAllowlistPerTargetSdkVersion =
204             getActivityDeviceConfigAllowlist(
205                     DeviceConfig.getProperty(
206                             DeviceConfig.NAMESPACE_ADSERVICES, PROPERTY_ACTIVITY_ALLOWLIST));
207 
208     @Nullable
209     @GuardedBy("mLock")
210     private ArraySet<String> mNextActivityAllowlist =
211             getNextActivityDeviceConfigAllowlist(
212                     DeviceConfig.getProperty(
213                             DeviceConfig.NAMESPACE_ADSERVICES, PROPERTY_NEXT_ACTIVITY_ALLOWLIST));
214 
215     @GuardedBy("mLock")
216     private boolean mEnableHsumSupportForSdkStorage =
217             DeviceConfig.getBoolean(
218                     DeviceConfig.NAMESPACE_ADSERVICES,
219                     PROPERTY_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE,
220                     DEFAULT_VALUE_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE);
221 
222     @GuardedBy("mLock")
223     private boolean mStopSandboxDeadlockFix =
224             DeviceConfig.getBoolean(
225                     DeviceConfig.NAMESPACE_ADSERVICES,
226                     PROPERTY_FIX_STOP_SANDBOX_DEADLOCK,
227                     DEFAULT_VALUE_FIX_STOP_SANDBOX_DEADLOCK);
228 
SdkSandboxSettingsListener(Context context, SdkSandboxManagerService sdkSandboxManagerService)229     SdkSandboxSettingsListener(Context context, SdkSandboxManagerService sdkSandboxManagerService) {
230         mContext = context;
231         mSdkSandboxManagerService = sdkSandboxManagerService;
232         DeviceConfig.addOnPropertiesChangedListener(
233                 DeviceConfig.NAMESPACE_ADSERVICES, mContext.getMainExecutor(), this);
234     }
235 
236     @Override
onPropertiesChanged(@onNull DeviceConfig.Properties properties)237     public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
238         synchronized (mLock) {
239             if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_ADSERVICES)) {
240                 return;
241             }
242             for (String name : properties.getKeyset()) {
243                 if (name == null) {
244                     continue;
245                 }
246 
247                 boolean propertyIsLogged = LOGGED_PROPERTIES.contains(name);
248                 if (propertyIsLogged) {
249                     LogUtil.d(
250                             TAG,
251                             "DeviceConfig property change received for name: "
252                                     + name
253                                     + ", to value: "
254                                     + properties.getString(name, ""));
255                 }
256 
257                 switch (name) {
258                     case PROPERTY_DISABLE_SDK_SANDBOX:
259                         boolean killSwitchPreviouslyEnabled = mKillSwitchEnabled;
260                         mKillSwitchEnabled =
261                                 properties.getBoolean(
262                                         PROPERTY_DISABLE_SDK_SANDBOX,
263                                         DEFAULT_VALUE_DISABLE_SDK_SANDBOX);
264                         if (mKillSwitchEnabled && !killSwitchPreviouslyEnabled) {
265                             Log.i(TAG, "SDK sandbox killswitch has become enabled");
266                             this.mSdkSandboxManagerService.stopAllSandboxes();
267                         }
268                         break;
269                     case PROPERTY_ENFORCE_RESTRICTIONS:
270                         mEnforceRestrictions =
271                                 properties.getBoolean(
272                                         PROPERTY_ENFORCE_RESTRICTIONS,
273                                         DEFAULT_VALUE_ENFORCE_RESTRICTIONS);
274                         break;
275                     case PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS:
276                         mSdkSandboxApplyRestrictionsNext =
277                                 properties.getBoolean(
278                                         PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
279                                         DEFAULT_VALUE_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
280                         break;
281                     case PROPERTY_SERVICES_ALLOWLIST:
282                         mServiceAllowlistPerTargetSdkVersion =
283                                 getServicesAllowlist(
284                                         properties.getString(PROPERTY_SERVICES_ALLOWLIST, null));
285                         break;
286                     case PROPERTY_NEXT_SERVICE_ALLOWLIST:
287                         mNextServiceAllowlist =
288                                 getNextServiceDeviceConfigAllowlist(
289                                         properties.getString(
290                                                 PROPERTY_NEXT_SERVICE_ALLOWLIST, null));
291                         break;
292                     case PROPERTY_CONTENTPROVIDER_ALLOWLIST:
293                         mContentProviderAllowlistPerTargetSdkVersion =
294                                 getContentProviderDeviceConfigAllowlist(
295                                         properties.getString(
296                                                 PROPERTY_CONTENTPROVIDER_ALLOWLIST, null));
297                         break;
298                     case PROPERTY_NEXT_CONTENTPROVIDER_ALLOWLIST:
299                         mNextContentProviderAllowlist =
300                                 getNextContentProviderDeviceConfigAllowlist(
301                                         properties.getString(
302                                                 PROPERTY_NEXT_CONTENTPROVIDER_ALLOWLIST, null));
303                         break;
304                     case PROPERTY_BROADCASTRECEIVER_ALLOWLIST:
305                         mBroadcastReceiverAllowlistPerTargetSdkVersion =
306                                 getBroadcastReceiverDeviceConfigAllowlist(
307                                         properties.getString(
308                                                 PROPERTY_BROADCASTRECEIVER_ALLOWLIST, null));
309                         break;
310                     case PROPERTY_NEXT_BROADCASTRECEIVER_ALLOWLIST:
311                         mNextBroadcastReceiverAllowlist =
312                                 getNextBroadcastReceiverDeviceConfigAllowlist(
313                                         properties.getString(
314                                                 PROPERTY_NEXT_BROADCASTRECEIVER_ALLOWLIST, null));
315                         break;
316                     case PROPERTY_ACTIVITY_ALLOWLIST:
317                         mActivityAllowlistPerTargetSdkVersion =
318                                 getActivityDeviceConfigAllowlist(
319                                         properties.getString(PROPERTY_ACTIVITY_ALLOWLIST, null));
320                         break;
321                     case PROPERTY_NEXT_ACTIVITY_ALLOWLIST:
322                         mNextActivityAllowlist =
323                                 getNextActivityDeviceConfigAllowlist(
324                                         properties.getString(
325                                                 PROPERTY_NEXT_ACTIVITY_ALLOWLIST, null));
326                         break;
327                     case PROPERTY_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE:
328                         boolean previousValue = mEnableHsumSupportForSdkStorage;
329                         mEnableHsumSupportForSdkStorage =
330                                 properties.getBoolean(
331                                         PROPERTY_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE,
332                                         DEFAULT_VALUE_ENABLE_HSUM_SUPPORT_FOR_SDK_STORAGE);
333                         if (mEnableHsumSupportForSdkStorage != previousValue) {
334                             mSdkSandboxManagerService.registerPackageUpdateBroadcastReceiver();
335                         }
336                         break;
337                     case PROPERTY_FIX_STOP_SANDBOX_DEADLOCK:
338                         mStopSandboxDeadlockFix =
339                                 properties.getBoolean(
340                                         PROPERTY_FIX_STOP_SANDBOX_DEADLOCK,
341                                         DEFAULT_VALUE_FIX_STOP_SANDBOX_DEADLOCK);
342                         break;
343                     case PROPERTY_RECONCILE_ON_VOLUME_MOUNT:
344                         boolean previousValueOfReconcileOnVolumeMount = mReconcileOnVolumeMount;
345                         mReconcileOnVolumeMount =
346                                 properties.getBoolean(
347                                         PROPERTY_RECONCILE_ON_VOLUME_MOUNT,
348                                         DEFAULT_VALUE_RECONCILE_ON_VOLUME_MOUNT);
349                         if (mReconcileOnVolumeMount != previousValueOfReconcileOnVolumeMount) {
350                             mSdkSandboxManagerService.onUserUnlocking(
351                                     mSdkSandboxManagerService.getCurrentUserId());
352                         }
353                     default:
354                 }
355                 if (propertyIsLogged) {
356                     LogUtil.d(TAG, "DeviceConfig property change applied for name: " + name);
357                 }
358             }
359         }
360     }
361 
isKillSwitchEnabled()362     public boolean isKillSwitchEnabled() {
363         synchronized (mLock) {
364             return mKillSwitchEnabled;
365         }
366     }
367 
setKillSwitchState(boolean enabled)368     void setKillSwitchState(boolean enabled) {
369         synchronized (mLock) {
370             DeviceConfig.setProperty(
371                     DeviceConfig.NAMESPACE_ADSERVICES,
372                     PROPERTY_DISABLE_SDK_SANDBOX,
373                     Boolean.toString(enabled),
374                     false);
375             mKillSwitchEnabled = enabled;
376         }
377     }
378 
379     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
unregisterPropertiesListener()380     void unregisterPropertiesListener() {
381         DeviceConfig.removeOnPropertiesChangedListener(this);
382     }
383 
areRestrictionsEnforced()384     public boolean areRestrictionsEnforced() {
385         synchronized (mLock) {
386             return mEnforceRestrictions;
387         }
388     }
389 
applySdkSandboxRestrictionsNext()390     public boolean applySdkSandboxRestrictionsNext() {
391         synchronized (mLock) {
392             return mSdkSandboxApplyRestrictionsNext;
393         }
394     }
395 
reconcileOnVolumeMount()396     public boolean reconcileOnVolumeMount() {
397         synchronized (mLock) {
398             return mReconcileOnVolumeMount;
399         }
400     }
401 
getServiceAllowlistForTargetSdkVersion(int targetSdkVersion)402     public AllowedServices getServiceAllowlistForTargetSdkVersion(int targetSdkVersion) {
403         synchronized (mLock) {
404             return mServiceAllowlistPerTargetSdkVersion.get(targetSdkVersion);
405         }
406     }
407 
getNextServiceAllowlist()408     public AllowedServices getNextServiceAllowlist() {
409         synchronized (mLock) {
410             return mNextServiceAllowlist;
411         }
412     }
413 
getContentProviderAllowlistPerTargetSdkVersion()414     public ArrayMap<Integer, ArraySet<String>> getContentProviderAllowlistPerTargetSdkVersion() {
415         synchronized (mLock) {
416             return mContentProviderAllowlistPerTargetSdkVersion;
417         }
418     }
419 
getNextContentProviderAllowlist()420     public ArraySet<String> getNextContentProviderAllowlist() {
421         synchronized (mLock) {
422             return mNextContentProviderAllowlist;
423         }
424     }
425 
426     @Nullable
getBroadcastReceiverAllowlistPerTargetSdkVersion()427     public ArrayMap<Integer, ArraySet<String>> getBroadcastReceiverAllowlistPerTargetSdkVersion() {
428         synchronized (mLock) {
429             return mBroadcastReceiverAllowlistPerTargetSdkVersion;
430         }
431     }
432 
433     @Nullable
getNextBroadcastReceiverAllowlist()434     public ArraySet<String> getNextBroadcastReceiverAllowlist() {
435         synchronized (mLock) {
436             return mNextBroadcastReceiverAllowlist;
437         }
438     }
439 
440     @Nullable
getActivityAllowlistPerTargetSdkVersion()441     public ArrayMap<Integer, ArraySet<String>> getActivityAllowlistPerTargetSdkVersion() {
442         synchronized (mLock) {
443             return mActivityAllowlistPerTargetSdkVersion;
444         }
445     }
446 
447     @Nullable
getNextActivityAllowlist()448     public ArraySet<String> getNextActivityAllowlist() {
449         synchronized (mLock) {
450             return mNextActivityAllowlist;
451         }
452     }
453 
getEnableHsumSupportForSdkStorage()454     public boolean getEnableHsumSupportForSdkStorage() {
455         synchronized (mLock) {
456             return mEnableHsumSupportForSdkStorage;
457         }
458     }
459 
getStopSandboxDeadlockFix()460     public boolean getStopSandboxDeadlockFix() {
461         synchronized (mLock) {
462             return mStopSandboxDeadlockFix;
463         }
464     }
465 
466     /**
467      * Helper function to decode a proto property
468      *
469      * @param property The property which needs to be decoded
470      * @param base64value The base64 value of the property
471      * @return The decoded value of the property passed as the parameter
472      */
getDecodedPropertyValue( @onNull String property, @NonNull String base64value)473     private static byte[] getDecodedPropertyValue(
474             @NonNull String property, @NonNull String base64value) {
475         try {
476             return Base64.decode(base64value, Base64.NO_PADDING | Base64.NO_WRAP);
477         } catch (IllegalArgumentException e) {
478             Log.e(TAG, "Error while decoding " + property + " Error: " + e);
479         }
480         return null;
481     }
482 
483     @Nullable
getDeviceConfigProtoProperty( Parser<T> parser, @NonNull String property, @Nullable String value)484     private static <T> T getDeviceConfigProtoProperty(
485             Parser<T> parser, @NonNull String property, @Nullable String value) {
486         if (TextUtils.isEmpty(value)) {
487             Log.d(TAG, "Property " + property + " is empty.");
488             return null;
489         }
490         final byte[] decode = getDecodedPropertyValue(property, value);
491         if (Objects.isNull(decode)) {
492             return null;
493         }
494 
495         T proto = null;
496         try {
497             proto = parser.parseFrom(decode);
498         } catch (Exception e) {
499             Log.e(TAG, "Error while parsing " + property + ". Error: ", e);
500         }
501 
502         return proto;
503     }
504 
505     @NonNull
getServicesAllowlist(@ullable String value)506     private static Map<Integer, AllowedServices> getServicesAllowlist(@Nullable String value) {
507         final ServiceAllowlists allowedServicesProto =
508                 getDeviceConfigProtoProperty(
509                         ServiceAllowlists.parser(), PROPERTY_SERVICES_ALLOWLIST, value);
510         return allowedServicesProto == null
511                 ? new ArrayMap<>()
512                 : allowedServicesProto.getAllowlistPerTargetSdkMap();
513     }
514 
515     @Nullable
getNextServiceDeviceConfigAllowlist(@ullable String value)516     private AllowedServices getNextServiceDeviceConfigAllowlist(@Nullable String value) {
517         return getDeviceConfigProtoProperty(
518                 AllowedServices.parser(), PROPERTY_NEXT_SERVICE_ALLOWLIST, value);
519     }
520 
521     @NonNull
getContentProviderDeviceConfigAllowlist( @ullable String value)522     private static ArrayMap<Integer, ArraySet<String>> getContentProviderDeviceConfigAllowlist(
523             @Nullable String value) {
524         ContentProviderAllowlists contentProviderAllowlistsProto =
525                 getDeviceConfigProtoProperty(
526                         ContentProviderAllowlists.parser(),
527                         PROPERTY_CONTENTPROVIDER_ALLOWLIST,
528                         value);
529         // Content providers are restricted by default. If the property is not set, or it is an
530         // empty string, there are no content providers to allowlist.
531         if (contentProviderAllowlistsProto == null) {
532             return new ArrayMap<>();
533         }
534 
535         ArrayMap<Integer, ArraySet<String>> allowedContentProviders = new ArrayMap<>();
536 
537         contentProviderAllowlistsProto
538                 .getAllowlistPerTargetSdkMap()
539                 .forEach(
540                         (sdkVersion, allowList) -> {
541                             allowedContentProviders.put(
542                                     sdkVersion, new ArraySet<>(allowList.getAuthoritiesList()));
543                         });
544         return allowedContentProviders;
545     }
546 
547     @Nullable
getNextContentProviderDeviceConfigAllowlist( @ullable String value)548     private static ArraySet<String> getNextContentProviderDeviceConfigAllowlist(
549             @Nullable String value) {
550         AllowedContentProviders allowedContentProviders =
551                 getDeviceConfigProtoProperty(
552                         AllowedContentProviders.parser(),
553                         PROPERTY_NEXT_CONTENTPROVIDER_ALLOWLIST,
554                         value);
555         if (allowedContentProviders == null) {
556             return null;
557         }
558         return new ArraySet<>(allowedContentProviders.getAuthoritiesList());
559     }
560 
561     @Nullable
getBroadcastReceiverDeviceConfigAllowlist( @ullable String value)562     private static ArrayMap<Integer, ArraySet<String>> getBroadcastReceiverDeviceConfigAllowlist(
563             @Nullable String value) {
564         BroadcastReceiverAllowlists broadcastReceiverAllowlistsProto =
565                 getDeviceConfigProtoProperty(
566                         BroadcastReceiverAllowlists.parser(),
567                         PROPERTY_BROADCASTRECEIVER_ALLOWLIST,
568                         value);
569 
570         if (broadcastReceiverAllowlistsProto == null) {
571             return null;
572         }
573 
574         ArrayMap<Integer, ArraySet<String>> allowedBroadcastReceivers = new ArrayMap<>();
575 
576         broadcastReceiverAllowlistsProto
577                 .getAllowlistPerTargetSdkMap()
578                 .forEach(
579                         (sdkVersion, allowList) -> {
580                             allowedBroadcastReceivers.put(
581                                     sdkVersion, new ArraySet<>(allowList.getIntentActionsList()));
582                         });
583         return allowedBroadcastReceivers;
584     }
585 
586     @Nullable
getNextBroadcastReceiverDeviceConfigAllowlist( @ullable String value)587     private static ArraySet<String> getNextBroadcastReceiverDeviceConfigAllowlist(
588             @Nullable String value) {
589         AllowedBroadcastReceivers allowedBroadcastReceivers =
590                 getDeviceConfigProtoProperty(
591                         AllowedBroadcastReceivers.parser(),
592                         PROPERTY_NEXT_BROADCASTRECEIVER_ALLOWLIST,
593                         value);
594         if (allowedBroadcastReceivers == null) {
595             return null;
596         }
597         return new ArraySet<>(allowedBroadcastReceivers.getIntentActionsList());
598     }
599 
600     @Nullable
getActivityDeviceConfigAllowlist( @ullable String value)601     private static ArrayMap<Integer, ArraySet<String>> getActivityDeviceConfigAllowlist(
602             @Nullable String value) {
603         ActivityAllowlists activityAllowlistsProto =
604                 getDeviceConfigProtoProperty(
605                         ActivityAllowlists.parser(), PROPERTY_ACTIVITY_ALLOWLIST, value);
606 
607         if (activityAllowlistsProto == null) {
608             return null;
609         }
610 
611         ArrayMap<Integer, ArraySet<String>> allowedActivities = new ArrayMap<>();
612 
613         activityAllowlistsProto
614                 .getAllowlistPerTargetSdkMap()
615                 .forEach(
616                         (sdkVersion, allowList) -> {
617                             allowedActivities.put(
618                                     sdkVersion, new ArraySet<>(allowList.getActionsList()));
619                         });
620         return allowedActivities;
621     }
622 
623     @Nullable
getNextActivityDeviceConfigAllowlist(@ullable String value)624     private static ArraySet<String> getNextActivityDeviceConfigAllowlist(@Nullable String value) {
625         AllowedActivities allowedActivities =
626                 getDeviceConfigProtoProperty(
627                         AllowedActivities.parser(), PROPERTY_NEXT_ACTIVITY_ALLOWLIST, value);
628         if (allowedActivities == null) {
629             return null;
630         }
631         return new ArraySet<>(allowedActivities.getActionsList());
632     }
633 }
634