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