1 /*
2  * Copyright (C) 2022 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.appsearch.contactsindexer.appsearchtypes;
18 
19 import android.annotation.NonNull;
20 import android.app.appsearch.AppSearchSchema;
21 import android.app.appsearch.GenericDocument;
22 
23 import com.android.internal.annotations.VisibleForTesting;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Objects;
28 
29 /**
30  * Represents a ContactPoint in AppSearch.
31  *
32  * @hide
33  */
34 public final class ContactPoint extends GenericDocument {
35     public static final String SCHEMA_TYPE = "builtin:ContactPoint";
36 
37     // Properties
38     public static final String CONTACT_POINT_PROPERTY_LABEL = "label";
39     public static final String CONTACT_POINT_PROPERTY_APP_ID = "appId";
40     public static final String CONTACT_POINT_PROPERTY_ADDRESS = "address";
41     public static final String CONTACT_POINT_PROPERTY_EMAIL = "email";
42     public static final String CONTACT_POINT_PROPERTY_TELEPHONE = "telephone";
43 
44     // Schema
45     public static final AppSearchSchema SCHEMA =
46             new AppSearchSchema.Builder(SCHEMA_TYPE)
47                     .addProperty(
48                             new AppSearchSchema.StringPropertyConfig.Builder(
49                                             CONTACT_POINT_PROPERTY_LABEL)
50                                     .setCardinality(
51                                             AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
52                                     .setIndexingType(
53                                             AppSearchSchema.StringPropertyConfig
54                                                     .INDEXING_TYPE_PREFIXES)
55                                     .setTokenizerType(
56                                             AppSearchSchema.StringPropertyConfig
57                                                     .TOKENIZER_TYPE_PLAIN)
58                                     .build())
59                     // appIds
60                     .addProperty(
61                             new AppSearchSchema.StringPropertyConfig.Builder(
62                                             CONTACT_POINT_PROPERTY_APP_ID)
63                                     .setCardinality(
64                                             AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
65                                     .build())
66                     // address
67                     .addProperty(
68                             new AppSearchSchema.StringPropertyConfig.Builder(
69                                             CONTACT_POINT_PROPERTY_ADDRESS)
70                                     .setCardinality(
71                                             AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
72                                     .setIndexingType(
73                                             AppSearchSchema.StringPropertyConfig
74                                                     .INDEXING_TYPE_PREFIXES)
75                                     .setTokenizerType(
76                                             AppSearchSchema.StringPropertyConfig
77                                                     .TOKENIZER_TYPE_PLAIN)
78                                     .build())
79                     // email
80                     .addProperty(
81                             new AppSearchSchema.StringPropertyConfig.Builder(
82                                             CONTACT_POINT_PROPERTY_EMAIL)
83                                     .setCardinality(
84                                             AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
85                                     .setIndexingType(
86                                             AppSearchSchema.StringPropertyConfig
87                                                     .INDEXING_TYPE_PREFIXES)
88                                     .setTokenizerType(
89                                             AppSearchSchema.StringPropertyConfig
90                                                     .TOKENIZER_TYPE_PLAIN)
91                                     .build())
92                     // telephone
93                     .addProperty(
94                             new AppSearchSchema.StringPropertyConfig.Builder(
95                                             CONTACT_POINT_PROPERTY_TELEPHONE)
96                                     .setCardinality(
97                                             AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
98                                     .setIndexingType(
99                                             AppSearchSchema.StringPropertyConfig
100                                                     .INDEXING_TYPE_PREFIXES)
101                                     .setTokenizerType(
102                                             AppSearchSchema.StringPropertyConfig
103                                                     .TOKENIZER_TYPE_PLAIN)
104                                     .build())
105                     .build();
106 
107     /** Constructs a {@link ContactPoint}. */
108     @VisibleForTesting
ContactPoint(@onNull GenericDocument document)109     public ContactPoint(@NonNull GenericDocument document) {
110         super(document);
111     }
112 
113     @NonNull
getLabel()114     public String getLabel() {
115         return getPropertyString(CONTACT_POINT_PROPERTY_LABEL);
116     }
117 
118     @NonNull
getAppIds()119     public String[] getAppIds() {
120         return getPropertyStringArray(CONTACT_POINT_PROPERTY_APP_ID);
121     }
122 
123     @NonNull
getAddresses()124     public String[] getAddresses() {
125         return getPropertyStringArray(CONTACT_POINT_PROPERTY_ADDRESS);
126     }
127 
128     @NonNull
getEmails()129     public String[] getEmails() {
130         return getPropertyStringArray(CONTACT_POINT_PROPERTY_EMAIL);
131     }
132 
133     @NonNull
getPhones()134     public String[] getPhones() {
135         return getPropertyStringArray(CONTACT_POINT_PROPERTY_TELEPHONE);
136     }
137 
138     /** Builder for {@link ContactPoint}. */
139     public static final class Builder extends GenericDocument.Builder<Builder> {
140         private List<String> mAppIds = new ArrayList<>();
141         private List<String> mAddresses = new ArrayList<>();
142         private List<String> mEmails = new ArrayList<>();
143         private List<String> mTelephones = new ArrayList<>();
144 
145         /**
146          * Creates a new {@link Builder}
147          *
148          * @param namespace The namespace for this document.
149          * @param id The id of this {@link ContactPoint}. It doesn't matter if it is used as a
150          *     nested documents in {@link Person}.
151          * @param label The label for this {@link ContactPoint}.
152          */
Builder(@onNull String namespace, @NonNull String id, @NonNull String label)153         public Builder(@NonNull String namespace, @NonNull String id, @NonNull String label) {
154             super(namespace, id, SCHEMA_TYPE);
155             setLabel(label);
156         }
157 
158         @NonNull
setLabel(@onNull String label)159         private Builder setLabel(@NonNull String label) {
160             setPropertyString(CONTACT_POINT_PROPERTY_LABEL, label);
161             return this;
162         }
163 
164         /**
165          * Add a unique AppId for this {@link ContactPoint}.
166          *
167          * @param appId a unique identifier for the application.
168          */
169         @NonNull
addAppId(@onNull String appId)170         public Builder addAppId(@NonNull String appId) {
171             Objects.requireNonNull(appId);
172             mAppIds.add(appId);
173             return this;
174         }
175 
176         @NonNull
addAddress(@onNull String address)177         public Builder addAddress(@NonNull String address) {
178             Objects.requireNonNull(address);
179             mAddresses.add(address);
180             return this;
181         }
182 
183         @NonNull
addEmail(@onNull String email)184         public Builder addEmail(@NonNull String email) {
185             Objects.requireNonNull(email);
186             mEmails.add(email);
187             return this;
188         }
189 
190         @NonNull
addPhone(@onNull String phone)191         public Builder addPhone(@NonNull String phone) {
192             Objects.requireNonNull(phone);
193             mTelephones.add(phone);
194             return this;
195         }
196 
197         @NonNull
build()198         public ContactPoint build() {
199             setPropertyString(CONTACT_POINT_PROPERTY_APP_ID, mAppIds.toArray(new String[0]));
200             setPropertyString(CONTACT_POINT_PROPERTY_EMAIL, mEmails.toArray(new String[0]));
201             setPropertyString(CONTACT_POINT_PROPERTY_ADDRESS, mAddresses.toArray(new String[0]));
202             setPropertyString(CONTACT_POINT_PROPERTY_TELEPHONE, mTelephones.toArray(new String[0]));
203             return new ContactPoint(super.build());
204         }
205     }
206 }
207