1 /* 2 * Copyright 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.appsearch; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.SuppressLint; 21 import android.app.appsearch.annotation.CanIgnoreReturnValue; 22 import android.util.ArrayMap; 23 import android.util.ArraySet; 24 25 import com.android.appsearch.flags.Flags; 26 27 import org.jspecify.annotations.NonNull; 28 29 import java.util.Collections; 30 import java.util.Map; 31 import java.util.Objects; 32 import java.util.Set; 33 34 /** 35 * Request to configure the visibility settings of blobs in AppSearch. 36 * 37 * <p>Used with {@link AppSearchSession#setBlobVisibility} to specify visibility and display 38 * properties for blob namespaces. You can control which blob namespaces are displayed on system UI 39 * surfaces and which are accessible based on specific visibility configurations. 40 * 41 * @see AppSearchSession#openBlobForWrite 42 */ 43 // TODO(b/273591938) linked to GlobalSearchSession when openBlobRead is added there. 44 45 @FlaggedApi(Flags.FLAG_ENABLE_BLOB_STORE) 46 public class SetBlobVisibilityRequest { 47 48 private final Set<String> mNamespacesNotDisplayedBySystem; 49 private final Map<String, Set<SchemaVisibilityConfig>> mNamespacesVisibleToConfigs; 50 SetBlobVisibilityRequest( @onNull Set<String> namespacesNotDisplayedBySystem, @NonNull Map<String, Set<SchemaVisibilityConfig>> namespacesVisibleToConfigs)51 SetBlobVisibilityRequest( 52 @NonNull Set<String> namespacesNotDisplayedBySystem, 53 @NonNull Map<String, Set<SchemaVisibilityConfig>> namespacesVisibleToConfigs) { 54 mNamespacesNotDisplayedBySystem = Objects.requireNonNull(namespacesNotDisplayedBySystem); 55 mNamespacesVisibleToConfigs = Objects.requireNonNull(namespacesVisibleToConfigs); 56 } 57 58 /** 59 * Returns all the blob namespaces that are opted out of being displayed and visible on any 60 * system UI surface. 61 */ getNamespacesNotDisplayedBySystem()62 public @NonNull Set<String> getNamespacesNotDisplayedBySystem() { 63 return Collections.unmodifiableSet(mNamespacesNotDisplayedBySystem); 64 } 65 66 /** 67 * Returns a mapping of blob namespaces to the set of {@link SchemaVisibilityConfig}s that have 68 * access to that namespace. 69 * 70 * <p>All conditions in a single {@link SchemaVisibilityConfig} are "AND" relationship. A caller 71 * must match all conditions to have the access. All {@link SchemaVisibilityConfig}s in the set 72 * of a blob namespace are "OR" relationship. A caller could have access if they matches any 73 * {@link SchemaVisibilityConfig} in the set. 74 * 75 * <p>This method provides the set of {@link SchemaVisibilityConfig} for all blob namespaces. 76 * 77 * @see Builder#addNamespaceVisibleToConfig 78 */ getNamespacesVisibleToConfigs()79 public @NonNull Map<String, Set<SchemaVisibilityConfig>> getNamespacesVisibleToConfigs() { 80 return Collections.unmodifiableMap(mNamespacesVisibleToConfigs); 81 } 82 83 /** Builder for {@link SetBlobVisibilityRequest} objects. */ 84 public static final class Builder { 85 86 private final ArrayMap<String, Set<SchemaVisibilityConfig>> mNamespacesVisibleToConfigs = 87 new ArrayMap<>(); 88 private final ArraySet<String> mNamespacesNotDisplayedBySystem = new ArraySet<>(); 89 90 /** 91 * Sets whether or not blobs in the specified {@code namespace} will be displayed on any 92 * system UI surface. 93 * 94 * <p>This setting applies to the provided {@code namespace} only, all other {@code 95 * namespace}s that are not included here will be reverted to the default displayed setting. 96 * 97 * <p>If this method is not called, the default behavior allows blobs to be displayed on 98 * system UI surfaces. 99 * 100 * @param namespace The name of the namespace to configure visibility for. 101 * @param displayed If {@code false}, blobs in this namespace will not appear on system UI 102 * surfaces. 103 */ 104 // Merged list available from getBlobNamespacesNotDisplayedBySystem 105 @CanIgnoreReturnValue 106 @SuppressLint("MissingGetterMatchingBuilder") setNamespaceDisplayedBySystem( @onNull String namespace, boolean displayed)107 public @NonNull Builder setNamespaceDisplayedBySystem( 108 @NonNull String namespace, boolean displayed) { 109 Objects.requireNonNull(namespace); 110 if (displayed) { 111 mNamespacesNotDisplayedBySystem.remove(namespace); 112 } else { 113 mNamespacesNotDisplayedBySystem.add(namespace); 114 } 115 return this; 116 } 117 118 /** 119 * Specifies that blobs within the given {@code namespace} can be accessed by the caller if 120 * they meet the requirements defined in {@link SchemaVisibilityConfig}. 121 * 122 * <p>The requirements in each {@link SchemaVisibilityConfig} have an "AND" relationship, 123 * meaning that all conditions within a configuration must be met for access. For instance, 124 * the caller may need specific permissions and belong to a specific package. 125 * 126 * <p>Repeated calls to this method can add multiple {@link SchemaVisibilityConfig}s to a 127 * namespace. The caller will have access if they match any of the configurations added, so 128 * the configurations form an "OR" relationship. 129 * 130 * @param namespace The blob namespace to set visibility for. 131 * @param visibilityConfig The config hold specifying visibility settings. 132 */ 133 // Merged list available from getNamespacesVisibleToConfigs 134 @CanIgnoreReturnValue 135 @SuppressLint("MissingGetterMatchingBuilder") addNamespaceVisibleToConfig( @onNull String namespace, @NonNull SchemaVisibilityConfig visibilityConfig)136 public @NonNull Builder addNamespaceVisibleToConfig( 137 @NonNull String namespace, @NonNull SchemaVisibilityConfig visibilityConfig) { 138 Objects.requireNonNull(namespace); 139 Objects.requireNonNull(visibilityConfig); 140 Set<SchemaVisibilityConfig> visibleToConfigs = 141 mNamespacesVisibleToConfigs.get(namespace); 142 if (visibleToConfigs == null) { 143 visibleToConfigs = new ArraySet<>(); 144 mNamespacesVisibleToConfigs.put(namespace, visibleToConfigs); 145 } 146 visibleToConfigs.add(visibilityConfig); 147 return this; 148 } 149 150 /** 151 * Clears all visibility configurations for the specified blob {@code namespace}. 152 * 153 * <p>After calling this method, the specified namespace will have no visibility 154 * configurations, meaning it will only be accessible by default rules. 155 * 156 * @param namespace The blob namespace for which visibility config should be cleared. 157 */ 158 @CanIgnoreReturnValue clearNamespaceVisibleToConfigs(@onNull String namespace)159 public @NonNull Builder clearNamespaceVisibleToConfigs(@NonNull String namespace) { 160 Objects.requireNonNull(namespace); 161 mNamespacesVisibleToConfigs.remove(namespace); 162 return this; 163 } 164 165 /** Builds a new {@link SetBlobVisibilityRequest} object. */ build()166 public @NonNull SetBlobVisibilityRequest build() { 167 return new SetBlobVisibilityRequest( 168 new ArraySet<>(mNamespacesNotDisplayedBySystem), 169 new ArrayMap<>(mNamespacesVisibleToConfigs)); 170 } 171 } 172 } 173