Upstream version 6.34.113.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / extension / api / contacts / ContactUtils.java
1 // Copyright (c) 2013 Intel Corporation. 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 package org.xwalk.core.extension.api.contacts;
6
7 import android.content.ContentProviderOperation;
8 import android.content.ContentProviderResult;
9 import android.content.ContentResolver;
10 import android.content.ContentUris;
11 import android.content.OperationApplicationException;
12 import android.database.Cursor;
13 import android.net.Uri;
14 import android.os.RemoteException;
15 import android.provider.ContactsContract;
16 import android.provider.ContactsContract.Data;
17 import android.provider.ContactsContract.Groups;
18 import android.provider.ContactsContract.RawContacts;
19 import android.util.Log;
20
21 import java.text.ParseException;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27
28 public class ContactUtils {
29     private static final String TAG = "ContactUtils";
30     public ContentResolver mResolver;
31     public ContactUtils(ContentResolver resolver) {
32         mResolver = resolver;
33     }
34
35     public static <K, V> K getKeyFromValue(Map<K, V> map, V value) {
36         K key = null;
37         for (Map.Entry<K, V> entry : map.entrySet()) {
38             if (value != null && value.equals(entry.getValue())) {
39                 key = entry.getKey();
40                 break;
41             }
42         }
43         return key;
44     }
45
46     /**
47      * @param strings e.g. ["apple", "orange", "banana"]
48      * @return A list of question marks to be used in SQL clause, e.g. "?,?,?"
49      */
50     public static String makeQuestionMarkList(Set<String> strings) {
51         String ret = "";
52         for (int i = 0; i < strings.size(); ++i) {
53             ret += "?,";
54         }
55         return ret.substring(0, ret.length()-1);
56     }
57
58     public boolean hasID(String id) {
59         if (id == null) return false;
60         Cursor c = null;
61         try {
62             c = mResolver.query(ContactsContract.Contacts.CONTENT_URI,
63                                 null, ContactsContract.Contacts._ID + " = ?",
64                                 new String[]{id}, null);
65             return (c.getCount() != 0);
66         } catch (SecurityException e) {
67             Log.e(TAG, "hasID: " + e.toString());
68             return false;
69         } finally {
70             if (c != null) c.close();
71         }
72     }
73
74     public String getRawId(String id) {
75         Cursor c = null;
76         try {
77             c = mResolver.query(RawContacts.CONTENT_URI, new String[]{RawContacts._ID},
78                                 RawContacts.CONTACT_ID + "=?", new String[]{id}, null);
79             if (c.moveToFirst()) {
80                 // Actually it is possible that for one contact id there are multiple rawIds.
81                 return c.getString(0);
82             } else {
83                 return null;
84             }
85         } catch (SecurityException e) {
86             Log.e(TAG, "getRawId: " + e.toString());
87             return null;
88         } finally {
89             if (c != null) c.close();
90         }
91     }
92
93     public String getId(String rawId) {
94         Cursor c = null;
95         try {
96             c = mResolver.query(RawContacts.CONTENT_URI, new String[]{RawContacts.CONTACT_ID},
97                                 RawContacts._ID + "=?", new String[]{rawId}, null);
98             if (c.moveToFirst()) {
99                 return c.getString(0);
100             } else {
101                 return null;
102             }
103         } catch (SecurityException e) {
104             Log.e(TAG, "getId: " + e.toString());
105             return null;
106         } finally {
107             if (c != null) c.close();
108         }
109     }
110
111     /**
112      * Get lastUpdatedTimestamp and return as JS date format
113      * @param long e.g. 987654321012
114      * @return string e.g. "2001-04-19T04:25:21.012Z"
115      */
116     @android.annotation.TargetApi(android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
117     public String getLastUpdated(long contactId) {
118         String[] projection = new String[]{ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP};
119
120         Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
121         Cursor cursor = mResolver.query(uri, projection, null, null, null);
122         try {
123             if (cursor.moveToNext()) {
124                 return timeConvertToJS(cursor.getLong(0));
125             }
126         } finally {
127             if (cursor != null) {
128                 cursor.close();
129             }
130         }
131         return null;
132     }
133
134     public Set<String> getCurrentRawIds() {
135         Cursor c = null;
136         try {
137             c = mResolver.query(RawContacts.CONTENT_URI,
138                                 new String[]{RawContacts._ID}, null, null, null);
139             Set<String> rawIds = new HashSet<String>();
140             while (c.moveToNext()) {
141                 rawIds.add(c.getString(0));
142             }
143             return rawIds;
144         } catch (SecurityException e) {
145             Log.e(TAG, "getCurrentRawIds: " + e.toString());
146             return null;
147         } finally {
148             if (c != null) c.close();
149         }
150     }
151
152     public String[] getDefaultAccountNameAndType() {
153         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
154         ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
155                 .withValue(RawContacts.ACCOUNT_NAME, null)
156                 .withValue(RawContacts.ACCOUNT_TYPE, null)
157                 .build());
158
159         ContentProviderResult[] results = null;
160         try {
161             results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
162         } catch (Exception e) {
163             if (e instanceof RemoteException ||
164                 e instanceof OperationApplicationException ||
165                 e instanceof SecurityException) {
166                 Log.e(TAG, "getDefaultAccountNameAndType - Failed to apply batch: " + e.toString());
167                 return null;
168             } else {
169                 throw new RuntimeException(e);
170             }
171         }
172
173         Uri rawContactUri = null;
174         long rawContactId = 0;
175         for (ContentProviderResult result : results) {
176             rawContactUri = result.uri;
177             rawContactId = ContentUris.parseId(rawContactUri);
178         }
179
180         Cursor c = null;
181         String accountType = "";
182         String accountName = "";
183         try {
184             c = mResolver.query(RawContacts.CONTENT_URI,
185                                 new String[] {RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_NAME},
186                                 RawContacts._ID + "=?",
187                                 new String[] {String.valueOf(rawContactId)}, null);
188             if (c.moveToFirst()) {
189                 if (!c.isAfterLast()) {
190                     accountType = c.getString(c.getColumnIndex(RawContacts.ACCOUNT_TYPE));
191                     accountName = c.getString(c.getColumnIndex(RawContacts.ACCOUNT_NAME));
192                 }
193             }
194         } catch (SecurityException e) {
195             Log.e(TAG, "getDefaultAccountNameAndType: " + e.toString());
196             return null;
197         } finally {
198             if (c != null) c.close();
199         }
200
201         mResolver.delete(rawContactUri, null, null);
202
203         return new String[] { accountName, accountType };
204     }
205
206     public String getGroupId(String groupTitle) {
207         final String selection = Groups.DELETED + "=? and " + Groups.GROUP_VISIBLE + "=?";
208         Cursor c = null;
209         try {
210             c = mResolver.query(Groups.CONTENT_URI, null, selection, new String[]{"0", "1"}, null);
211             c.moveToFirst();
212             for (int i = 0; i < c.getCount(); i++) {
213                 final String title = c.getString(c.getColumnIndex(Groups.TITLE));
214                 if (title.equals(groupTitle)) {
215                     return c.getString(c.getColumnIndex(Groups._ID));
216                 }
217                 c.moveToNext();
218             }
219             return null;
220         } catch (SecurityException e) {
221             Log.e(TAG, "getGroupId: " + e.toString());
222             return null;
223         } finally {
224             if (c != null) c.close();
225         }
226     }
227
228     public String getGroupTitle(String groupId) {
229         final String selection = Groups.DELETED + "=? and " + Groups.GROUP_VISIBLE + "=?";
230         Cursor c = null;
231         try {
232             c = mResolver.query(Groups.CONTENT_URI, null, selection, new String[]{"0", "1"}, null);
233             c.moveToFirst();
234             for (int i = 0; i < c.getCount(); i++) {
235                 final String id = c.getString(c.getColumnIndex(Groups._ID));
236                 if (id.equals(groupId)) {
237                     return c.getString(c.getColumnIndex(Groups.TITLE));
238                 }
239                 c.moveToNext();
240             }
241             return null;
242         } catch (SecurityException e) {
243             Log.e(TAG, "getGroupTitle: " + e.toString());
244             return null;
245         } finally {
246             if (c != null) c.close();
247         }
248     }
249
250     public String getEnsuredGroupId(String groupTitle) {
251         String groupId = getGroupId(groupTitle);
252         if (groupId == null) {
253             newGroup(groupTitle);
254             groupId = getGroupId(groupTitle);
255             if (groupId == null) return null;
256         }
257         return groupId;
258     }
259
260     public void newGroup(String groupTitle) {
261         final String accountNameType[] = getDefaultAccountNameAndType();
262         ArrayList<ContentProviderOperation> o = new ArrayList<ContentProviderOperation>();
263         o.add(ContentProviderOperation.newInsert(Groups.CONTENT_URI)
264                 .withValue(Groups.TITLE, groupTitle)
265                 .withValue(Groups.GROUP_VISIBLE, true)
266                 .withValue(Groups.ACCOUNT_NAME, accountNameType[0])
267                 .withValue(Groups.ACCOUNT_TYPE, accountNameType[1])
268                 .build());
269         try {
270             mResolver.applyBatch(ContactsContract.AUTHORITY, o);
271         } catch (Exception e) {
272             if (e instanceof RemoteException ||
273                 e instanceof OperationApplicationException ||
274                 e instanceof SecurityException) {
275                 Log.e(TAG, "newGroup - Failed to create new contact group: " + e.toString());
276             } else {
277                 throw new RuntimeException(e);
278             }
279         }
280     }
281
282     public void cleanByMimeType(String id, String mimeType) {
283         mResolver.delete(Data.CONTENT_URI,
284                          String.format("%s = ? AND %s = ?", Data.CONTACT_ID, Data.MIMETYPE),
285                          new String[] {id, mimeType});
286     }
287
288     /**
289      * Get date only from a JSON date string
290      * @param string e.g. "1969-12-31T16:00:20.012-0800"
291      * @return string e.g. "1969-12-31"
292      */
293     public String dateTrim(String string) {
294         String date = null;
295         try {
296             final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", java.util.Locale.getDefault());
297             date = df.format(df.parse(string));
298         } catch (ParseException e) {
299             Log.e(TAG, "dateFormat - parse failed: " + e.toString());
300         }
301         return date;
302     }
303
304     /**
305      * Convert epoch seconds to JS date format
306      * @param long e.g. 61
307      * @return string e.g. "1969-12-31T00:01:01Z"
308      */
309     private String timeConvertToJS(long seconds) {
310         final SimpleDateFormat df =
311                 new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", java.util.Locale.getDefault());
312         return df.format(new java.util.Date(seconds));
313     }
314 }