blob: c8b2c5bc378c3795289e6a3aab2babde45d8f050 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.appsearch.contactsindexer.appsearchtypes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
import android.net.Uri;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Represents a Person in AppSearch.
*
* @hide
*/
public class Person extends GenericDocument {
static final String SCHEMA_TYPE = "builtin:Person";
// Properties
static final String PERSON_PROPERTY_NAME = "name";
static final String PERSON_PROPERTY_GIVEN_NAME = "givenName";
static final String PERSON_PROPERTY_MIDDLE_NAME = "middleName";
static final String PERSON_PROPERTY_FAMILY_NAME = "familyName";
static final String PERSON_PROPERTY_EXTERNAL_URI = "externalUri";
static final String PERSON_PROPERTY_ADDITIONAL_NAME = "additionalName";
static final String PERSON_PROPERTY_IS_IMPORTANT = "isImportant";
static final String PERSON_PROPERTY_IS_BOT = "isBot";
static final String PERSON_PROPERTY_IMAGE_URI = "imageUri";
static final String PERSON_PROPERTY_CONTACT_POINT = "contactPoint";
static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
// full display name
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(PERSON_PROPERTY_NAME)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
// given name from CP2
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
PERSON_PROPERTY_GIVEN_NAME)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// middle name from CP2
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
PERSON_PROPERTY_MIDDLE_NAME)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// family name from CP2
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
PERSON_PROPERTY_FAMILY_NAME)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// lookup uri from CP2
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
PERSON_PROPERTY_EXTERNAL_URI)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// additional names e.g. nick names and phonetic names.
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
PERSON_PROPERTY_ADDITIONAL_NAME)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.setIndexingType(
AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
// isImportant. It could be used to store isStarred from CP2.
.addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
PERSON_PROPERTY_IS_IMPORTANT)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// isBot
.addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
PERSON_PROPERTY_IS_BOT)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// imageUri
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
PERSON_PROPERTY_IMAGE_URI)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
// ContactPoint
.addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
PERSON_PROPERTY_CONTACT_POINT,
ContactPoint.SCHEMA.getSchemaType())
.setShouldIndexNestedProperties(true)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.build();
/** Constructs a {@link Person}. */
Person(@NonNull GenericDocument document) {
super(document);
}
@NonNull
public String getName() {
return getPropertyString(PERSON_PROPERTY_NAME);
}
@Nullable
public String getGivenName() {
return getPropertyString(PERSON_PROPERTY_GIVEN_NAME);
}
@Nullable
public String getMiddleName() {
return getPropertyString(PERSON_PROPERTY_MIDDLE_NAME);
}
@Nullable
public String getFamilyName() {
return getPropertyString(PERSON_PROPERTY_FAMILY_NAME);
}
@Nullable
public Uri getExternalUri() {
String uriStr = getPropertyString(PERSON_PROPERTY_EXTERNAL_URI);
if (uriStr == null) {
return null;
}
return Uri.parse(uriStr);
}
@Nullable
public Uri getImageUri() {
String uriStr = getPropertyString(PERSON_PROPERTY_IMAGE_URI);
if (uriStr == null) {
return null;
}
return Uri.parse(uriStr);
}
public boolean isImportant() {
return getPropertyBoolean(PERSON_PROPERTY_IS_IMPORTANT);
}
public boolean isBot() {
return getPropertyBoolean(PERSON_PROPERTY_IS_BOT);
}
@NonNull
public String[] getAdditionalNames() {
return getPropertyStringArray(PERSON_PROPERTY_ADDITIONAL_NAME);
}
// This method is expensive, and is intended to be used in tests only.
@NonNull
public ContactPoint[] getContactPoints() {
GenericDocument[] docs = getPropertyDocumentArray(PERSON_PROPERTY_CONTACT_POINT);
ContactPoint[] contactPoints = new ContactPoint[docs.length];
for (int i = 0; i < contactPoints.length; ++i) {
contactPoints[i] = new ContactPoint(docs[i]);
}
return contactPoints;
}
/** Builder for {@link Person}. */
public static final class Builder extends GenericDocument.Builder<Builder> {
private final List<String> mAdditionalNames = new ArrayList<>();
private final List<ContactPoint> mContactPoints = new ArrayList<>();
/**
* Creates a new {@link ContactPoint.Builder}
*
* @param namespace The namespace of the Email.
* @param id The ID of the Email.
* @param name The name of the {@link Person}.
*/
public Builder(@NonNull String namespace, @NonNull String id, @NonNull String name) {
super(namespace, id, SCHEMA_TYPE);
setName(name);
}
/** Sets the full display name. */
@NonNull
private Builder setName(@NonNull String name) {
setPropertyString(PERSON_PROPERTY_NAME, name);
return this;
}
@NonNull
public Builder setGivenName(@NonNull String givenName) {
setPropertyString(PERSON_PROPERTY_GIVEN_NAME, givenName);
return this;
}
@NonNull
public Builder setMiddleName(@NonNull String middleName) {
setPropertyString(PERSON_PROPERTY_MIDDLE_NAME, middleName);
return this;
}
@NonNull
public Builder setFamilyName(@NonNull String familyName) {
setPropertyString(PERSON_PROPERTY_FAMILY_NAME, familyName);
return this;
}
@NonNull
public Builder setExternalUri(@NonNull Uri externalUri) {
setPropertyString(PERSON_PROPERTY_EXTERNAL_URI,
Objects.requireNonNull(externalUri).toString());
return this;
}
@NonNull
public Builder setImageUri(@NonNull Uri imageUri) {
setPropertyString(PERSON_PROPERTY_IMAGE_URI,
Objects.requireNonNull(imageUri).toString());
return this;
}
@NonNull
public Builder setIsImportant(boolean isImportant) {
setPropertyBoolean(PERSON_PROPERTY_IS_IMPORTANT, isImportant);
return this;
}
@NonNull
public Builder setIsBot(boolean isBot) {
setPropertyBoolean(PERSON_PROPERTY_IS_BOT, isBot);
return this;
}
@NonNull
public Builder addAdditionalName(@NonNull String additionalName) {
Objects.requireNonNull(additionalName);
mAdditionalNames.add(additionalName);
return this;
}
@NonNull
public Builder addContactPoint(@NonNull ContactPoint contactPoint) {
Objects.requireNonNull(contactPoint);
mContactPoints.add(contactPoint);
return this;
}
@NonNull
public Person build() {
setPropertyString(PERSON_PROPERTY_ADDITIONAL_NAME,
mAdditionalNames.toArray(new String[0]));
setPropertyDocument(PERSON_PROPERTY_CONTACT_POINT,
mContactPoints.toArray(new ContactPoint[0]));
return new Person(super.build());
}
}
}