Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / android / java / src / org / chromium / components / browser / autofill / PersonalAutofillPopulator.java
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.NEIGHBORHOOD,
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_ITEM_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 contentResolver) {
124         String sortDescriptor = ContactsContract.Contacts.Data.IS_PRIMARY + " DESC";
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, contentResolver);
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, contentResolver);
193         mEmailAddresses = new String[emailCursor.getCount()];
194         for (int i = 0; emailCursor.moveToNext(); i++) {
195             mEmailAddresses[i] = emailCursor.getString(emailProfileQuery.EMAIL_ADDRESS);
196         }
197         emailCursor.close();
198     }
199
200     private void populateAddress(ContentResolver contentResolver) {
201         AddressProfileQuery addressProfileQuery = new AddressProfileQuery();
202         Cursor addressCursor = cursorFromProfileQuery(addressProfileQuery, contentResolver);
203         if(addressCursor.moveToNext()) {
204             mPobox = addressCursor.getString(addressProfileQuery.POBOX);
205             mStreet = addressCursor.getString(addressProfileQuery.STREET);
206             mNeighborhood = addressCursor.getString(addressProfileQuery.NEIGHBORHOOD);
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, contentResolver);
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 PersonalAutofillPopulator.
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 }