1 /* 2 * Copyright (C) 2021 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.content.pm; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.Person; 22 import android.app.appsearch.AppSearchSchema; 23 import android.app.appsearch.GenericDocument; 24 import android.net.UriCodec; 25 26 import com.android.internal.annotations.VisibleForTesting; 27 28 import java.nio.charset.StandardCharsets; 29 import java.util.Objects; 30 import java.util.UUID; 31 32 /** 33 * @hide 34 */ 35 public class AppSearchPerson extends GenericDocument { 36 37 /** The name of the schema type for {@link Person} documents.*/ 38 public static final String SCHEMA_TYPE = "Person"; 39 40 public static final String KEY_NAME = "name"; 41 public static final String KEY_KEY = "key"; 42 public static final String KEY_IS_BOT = "isBot"; 43 public static final String KEY_IS_IMPORTANT = "isImportant"; 44 AppSearchPerson(@onNull GenericDocument document)45 public AppSearchPerson(@NonNull GenericDocument document) { 46 super(document); 47 } 48 49 public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE) 50 .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_NAME) 51 .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL) 52 .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE) 53 .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE) 54 .build() 55 56 ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_KEY) 57 .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL) 58 .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE) 59 .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE) 60 .build() 61 62 ).addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(KEY_IS_BOT) 63 .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED) 64 .build() 65 66 ).addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(KEY_IS_IMPORTANT) 67 .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED) 68 .build() 69 70 ).build(); 71 72 /** hide */ 73 @NonNull instance(@onNull final Person person)74 public static AppSearchPerson instance(@NonNull final Person person) { 75 Objects.requireNonNull(person); 76 final String id; 77 if (person.getUri() != null) { 78 id = person.getUri(); 79 } else { 80 // NOTE: an identifier is required even when uri is null. 81 id = UUID.randomUUID().toString(); 82 } 83 return new Builder(id).setName(person.getName()) 84 .setKey(person.getKey()).setIsBot(person.isBot()) 85 .setIsImportant(person.isImportant()).build(); 86 } 87 88 /** hide */ 89 @NonNull toPerson()90 public Person toPerson() { 91 String uri; 92 try { 93 uri = UriCodec.decode( 94 getId(), false /* convertPlus */, StandardCharsets.UTF_8, 95 true /* throwOnFailure */); 96 } catch (IllegalArgumentException e) { 97 uri = null; 98 } 99 return new Person.Builder().setName(getPropertyString(KEY_NAME)) 100 .setUri(uri).setKey(getPropertyString(KEY_KEY)) 101 .setBot(getPropertyBoolean(KEY_IS_BOT)) 102 .setImportant(getPropertyBoolean(KEY_IS_IMPORTANT)).build(); 103 } 104 105 /** @hide */ 106 @VisibleForTesting 107 public static class Builder extends GenericDocument.Builder<Builder> { 108 Builder(@onNull final String id)109 public Builder(@NonNull final String id) { 110 super(/*namespace=*/ "", id, SCHEMA_TYPE); 111 } 112 113 /** @hide */ 114 @NonNull setName(@ullable final CharSequence name)115 public Builder setName(@Nullable final CharSequence name) { 116 if (name != null) { 117 setPropertyString(KEY_NAME, name.toString()); 118 } 119 return this; 120 } 121 122 /** @hide */ 123 @NonNull setKey(@ullable final String key)124 public Builder setKey(@Nullable final String key) { 125 if (key != null) { 126 setPropertyString(KEY_KEY, key); 127 } 128 return this; 129 } 130 131 /** @hide */ 132 @NonNull setIsBot(final boolean isBot)133 public Builder setIsBot(final boolean isBot) { 134 setPropertyBoolean(KEY_IS_BOT, isBot); 135 return this; 136 } 137 138 /** @hide */ 139 @NonNull setIsImportant(final boolean isImportant)140 public Builder setIsImportant(final boolean isImportant) { 141 setPropertyBoolean(KEY_IS_IMPORTANT, isImportant); 142 return this; 143 } 144 145 @NonNull 146 @Override build()147 public AppSearchPerson build() { 148 return new AppSearchPerson(super.build()); 149 } 150 } 151 } 152