OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Populates data fields from Android contacts profile API (i.e. "me" contact). | |
6 | |
7 package org.chromium.components.browser.autofill; | |
8 | |
9 import android.content.ContentResolver; | |
10 import android.content.Context; | |
11 import android.content.pm.PackageManager; | |
12 import android.database.Cursor; | |
13 import android.net.Uri; | |
14 import android.provider.ContactsContract; | |
15 | |
16 import org.chromium.base.CalledByNative; | |
17 import org.chromium.base.JNINamespace; | |
18 | |
19 /** | |
20 * Loads user profile information stored under the "Me" contact. | |
21 * Requires permissions: READ_CONTACTS and READ_PROFILE. | |
22 */ | |
23 @JNINamespace("autofill") | |
24 public class PersonalAutofillPopulator { | |
25 /** | |
26 * SQL query definitions for obtaining specific profile information. | |
27 */ | |
28 private abstract static class ProfileQuery { | |
29 Uri profileDataUri = Uri.withAppendedPath( | |
30 ContactsContract.Profile.CONTENT_URI, | |
31 ContactsContract.Contacts.Data.CONTENT_DIRECTORY | |
32 ); | |
33 public abstract String[] projection(); | |
34 public abstract String mimeType(); | |
35 } | |
36 | |
37 private static class EmailProfileQuery extends ProfileQuery { | |
38 private static final int EMAIL_ADDRESS = 0; | |
39 | |
40 @Override | |
41 public String[] projection() { | |
42 return new String[] { | |
43 ContactsContract.CommonDataKinds.Email.ADDRESS, | |
44 }; | |
45 } | |
46 | |
47 @Override | |
48 public String mimeType() { | |
49 return ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE; | |
50 } | |
51 } | |
52 | |
53 private static class PhoneProfileQuery extends ProfileQuery { | |
54 private static final int NUMBER = 0; | |
55 | |
56 @Override | |
57 public String[] projection() { | |
58 return new String[] { | |
59 ContactsContract.CommonDataKinds.Phone.NUMBER, | |
60 }; | |
61 } | |
62 | |
63 @Override | |
64 public String mimeType() { | |
65 return ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE; | |
66 } | |
67 } | |
68 | |
69 private static class AddressProfileQuery extends ProfileQuery { | |
70 private static final int STREET = 0; | |
71 private static final int POBOX = 1; | |
72 private static final int NEIGHBORHOOD = 2; | |
73 private static final int CITY = 3; | |
74 private static final int REGION = 4; | |
75 private static final int POSTALCODE = 5; | |
76 private static final int COUNTRY = 6; | |
77 | |
78 @Override | |
79 public String[] projection() { | |
80 return new String[] { | |
81 ContactsContract.CommonDataKinds.StructuredPostal.STREET, | |
82 ContactsContract.CommonDataKinds.StructuredPostal.POBOX, | |
83 ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHO
OD, | |
84 ContactsContract.CommonDataKinds.StructuredPostal.CITY, | |
85 ContactsContract.CommonDataKinds.StructuredPostal.REGION, | |
86 ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, | |
87 ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, | |
88 }; | |
89 } | |
90 | |
91 @Override | |
92 public String mimeType() { | |
93 return ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITE
M_TYPE; | |
94 } | |
95 } | |
96 | |
97 private static class NameProfileQuery extends ProfileQuery { | |
98 private static final int GIVEN_NAME = 0; | |
99 private static final int MIDDLE_NAME = 1; | |
100 private static final int FAMILY_NAME = 2; | |
101 private static final int SUFFIX = 3; | |
102 | |
103 @Override | |
104 public String[] projection() { | |
105 return new String[] { | |
106 ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, | |
107 ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, | |
108 ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, | |
109 ContactsContract.CommonDataKinds.StructuredName.SUFFIX | |
110 }; | |
111 } | |
112 | |
113 @Override | |
114 public String mimeType() { | |
115 return ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_
TYPE; | |
116 } | |
117 } | |
118 | |
119 /** | |
120 * Takes a query object, transforms into actual query and returns cursor. | |
121 * Primary contact values will be first. | |
122 */ | |
123 private Cursor cursorFromProfileQuery(ProfileQuery query, ContentResolver co
ntentResolver) { | |
124 String sortDescriptor = ContactsContract.Contacts.Data.IS_PRIMARY + " DE
SC"; | |
125 return contentResolver.query( | |
126 query.profileDataUri, | |
127 query.projection(), | |
128 ContactsContract.Contacts.Data.MIMETYPE + " = ?", | |
129 new String[]{query.mimeType()}, | |
130 sortDescriptor | |
131 ); | |
132 } | |
133 // Extracted data variables. | |
134 private String[] mEmailAddresses; | |
135 private String mGivenName; | |
136 private String mMiddleName; | |
137 private String mFamilyName; | |
138 private String mSuffix; | |
139 private String mPobox; | |
140 private String mStreet; | |
141 private String mNeighborhood; | |
142 private String mCity; | |
143 private String mRegion; | |
144 private String mCountry; | |
145 private String mPostalCode; | |
146 private String[] mPhoneNumbers; | |
147 private boolean mHasPermissions; | |
148 | |
149 /** | |
150 * Constructor | |
151 * @param context a valid android context reference | |
152 */ | |
153 PersonalAutofillPopulator(Context context) { | |
154 mHasPermissions = hasPermissions(context); | |
155 if (mHasPermissions) { | |
156 ContentResolver contentResolver = context.getContentResolver(); | |
157 populateName(contentResolver); | |
158 populateEmail(contentResolver); | |
159 populateAddress(contentResolver); | |
160 populatePhone(contentResolver); | |
161 } | |
162 } | |
163 | |
164 // Check if the user has granted permissions. | |
165 private boolean hasPermissions(Context context) { | |
166 String [] permissions = { | |
167 "android.permission.READ_CONTACTS", | |
168 "android.permission.READ_PROFILE" | |
169 }; | |
170 for (String permission : permissions) { | |
171 int res = context.checkCallingOrSelfPermission(permission); | |
172 if (res != PackageManager.PERMISSION_GRANTED) return false; | |
173 } | |
174 return true; | |
175 } | |
176 | |
177 // Populating data fields. | |
178 private void populateName(ContentResolver contentResolver) { | |
179 NameProfileQuery nameProfileQuery = new NameProfileQuery(); | |
180 Cursor nameCursor = cursorFromProfileQuery(nameProfileQuery, contentReso
lver); | |
181 if (nameCursor.moveToNext()) { | |
182 mGivenName = nameCursor.getString(nameProfileQuery.GIVEN_NAME); | |
183 mMiddleName = nameCursor.getString(nameProfileQuery.MIDDLE_NAME); | |
184 mFamilyName = nameCursor.getString(nameProfileQuery.FAMILY_NAME); | |
185 mSuffix = nameCursor.getString(nameProfileQuery.SUFFIX); | |
186 } | |
187 nameCursor.close(); | |
188 } | |
189 | |
190 private void populateEmail(ContentResolver contentResolver) { | |
191 EmailProfileQuery emailProfileQuery = new EmailProfileQuery(); | |
192 Cursor emailCursor = cursorFromProfileQuery(emailProfileQuery, contentRe
solver); | |
193 mEmailAddresses = new String[emailCursor.getCount()]; | |
194 for (int i = 0; emailCursor.moveToNext(); i++) { | |
195 mEmailAddresses[i] = emailCursor.getString(emailProfileQuery.EMAIL_A
DDRESS); | |
196 } | |
197 emailCursor.close(); | |
198 } | |
199 | |
200 private void populateAddress(ContentResolver contentResolver) { | |
201 AddressProfileQuery addressProfileQuery = new AddressProfileQuery(); | |
202 Cursor addressCursor = cursorFromProfileQuery(addressProfileQuery, conte
ntResolver); | |
203 if(addressCursor.moveToNext()) { | |
204 mPobox = addressCursor.getString(addressProfileQuery.POBOX); | |
205 mStreet = addressCursor.getString(addressProfileQuery.STREET); | |
206 mNeighborhood = addressCursor.getString(addressProfileQuery.NEIGHBOR
HOOD); | |
207 mCity = addressCursor.getString(addressProfileQuery.CITY); | |
208 mRegion = addressCursor.getString(addressProfileQuery.REGION); | |
209 mPostalCode = addressCursor.getString(addressProfileQuery.POSTALCODE
); | |
210 mCountry = addressCursor.getString(addressProfileQuery.COUNTRY); | |
211 } | |
212 addressCursor.close(); | |
213 } | |
214 | |
215 private void populatePhone(ContentResolver contentResolver) { | |
216 PhoneProfileQuery phoneProfileQuery = new PhoneProfileQuery(); | |
217 Cursor phoneCursor = cursorFromProfileQuery(phoneProfileQuery, contentRe
solver); | |
218 mPhoneNumbers = new String[phoneCursor.getCount()]; | |
219 for (int i = 0; phoneCursor.moveToNext(); i++) { | |
220 mPhoneNumbers[i] = phoneCursor.getString(phoneProfileQuery.NUMBER); | |
221 } | |
222 phoneCursor.close(); | |
223 } | |
224 | |
225 /** | |
226 * Static factory method for instance creation. | |
227 * @param context valid Android context. | |
228 * @return PersonalAutofillPopulator new instance of PersonalAutofillPopulat
or. | |
229 */ | |
230 @CalledByNative | |
231 static PersonalAutofillPopulator create(Context context) { | |
232 return new PersonalAutofillPopulator(context); | |
233 } | |
234 | |
235 @CalledByNative | |
236 private String getFirstName() { | |
237 return mGivenName; | |
238 } | |
239 | |
240 @CalledByNative | |
241 private String getLastName() { | |
242 return mFamilyName; | |
243 } | |
244 | |
245 @CalledByNative | |
246 private String getMiddleName() { | |
247 return mMiddleName; | |
248 } | |
249 | |
250 @CalledByNative | |
251 private String getSuffix() { | |
252 return mSuffix; | |
253 } | |
254 | |
255 @CalledByNative | |
256 private String[] getEmailAddresses() { | |
257 return mEmailAddresses; | |
258 } | |
259 | |
260 @CalledByNative | |
261 private String getStreet() { | |
262 return mStreet; | |
263 } | |
264 | |
265 @CalledByNative | |
266 private String getPobox() { | |
267 return mPobox; | |
268 } | |
269 | |
270 @CalledByNative | |
271 private String getNeighborhood() { | |
272 return mNeighborhood; | |
273 } | |
274 | |
275 @CalledByNative | |
276 private String getCity() { | |
277 return mCity; | |
278 } | |
279 | |
280 @CalledByNative | |
281 private String getRegion() { | |
282 return mRegion; | |
283 } | |
284 | |
285 @CalledByNative | |
286 private String getPostalCode() { | |
287 return mPostalCode; | |
288 } | |
289 | |
290 @CalledByNative | |
291 private String getCountry() { | |
292 return mCountry; | |
293 } | |
294 | |
295 @CalledByNative | |
296 private String[] getPhoneNumbers() { | |
297 return mPhoneNumbers; | |
298 } | |
299 | |
300 @CalledByNative | |
301 private boolean getHasPermissions() { | |
302 return mHasPermissions; | |
303 } | |
304 } | |
OLD | NEW |