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.
5 package org.xwalk.core.internal.extension.api.contacts;
7 import android.app.Activity;
8 import android.content.ContentProviderOperation;
9 import android.content.ContentResolver;
10 import android.content.Context;
11 import android.content.OperationApplicationException;
12 import android.database.Cursor;
13 import android.net.Uri;
14 import android.os.Handler;
15 import android.os.RemoteException;
16 import android.provider.ContactsContract;
17 import android.provider.ContactsContract.RawContacts;
18 import android.util.Log;
20 import java.util.ArrayList;
22 import org.chromium.base.ActivityState;
23 import org.json.JSONArray;
24 import org.json.JSONException;
25 import org.json.JSONObject;
27 import org.xwalk.core.internal.extension.XWalkExtensionWithActivityStateListener;
29 public class Contacts extends XWalkExtensionWithActivityStateListener {
30 public static final String JS_API_PATH = "jsapi/contacts_api.js";
32 private static final String TAG = "Contacts";
33 private static final String NAME = "xwalk.experimental.contacts";
35 private final ContactEventListener mObserver;
36 private final ContentResolver mResolver;
38 public Contacts(String jsApiContent, Activity activity) {
39 super(NAME, jsApiContent, activity);
40 mResolver = activity.getContentResolver();
41 mObserver = new ContactEventListener(new Handler(), this, mResolver);
42 mResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, mObserver);
47 public String onSyncMessage(int instanceID, String message) {
52 public void onMessage(int instanceID, String message) {
53 if (message.isEmpty()) return;
55 JSONObject jsonInput = new JSONObject(message);
56 String cmd = jsonInput.getString("cmd");
57 if (cmd.equals("addEventListener")) {
58 mObserver.startListening();
61 JSONObject jsonOutput = new JSONObject();
62 jsonOutput.put("asyncCallId", jsonInput.getString("asyncCallId"));
63 if (cmd.equals("save")) {
64 ContactSaver saver = new ContactSaver(mResolver);
65 jsonOutput.put("data", saver.save(jsonInput.getString("contact")));
66 } else if (cmd.equals("find")) {
67 ContactFinder finder = new ContactFinder(mResolver);
68 String options = jsonInput.has("options") ? jsonInput.getString("options") : null;
69 JSONArray results = finder.find(options);
70 jsonOutput.put("data", results);
71 } else if (cmd.equals("remove")) {
72 ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
73 String[] args = new String[] { jsonInput.getString("contactId") };
74 ops.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
75 .withSelection(RawContacts.CONTACT_ID + "=?", args).build());
77 mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
78 } catch (Exception e) {
79 if (e instanceof RemoteException ||
80 e instanceof OperationApplicationException ||
81 e instanceof SecurityException) {
82 Log.e(TAG, "onMessage - Failed to apply batch: " + e.toString());
85 throw new RuntimeException(e);
88 } else if (cmd.equals("clear")) {
91 Log.e(TAG, "Unexpected message received: " + message);
94 this.postMessage(instanceID, jsonOutput.toString());
95 } catch (JSONException e) {
96 Log.e(TAG, e.toString());
100 // Remove all contacts.
101 private void handleClear() {
104 c = mResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
105 while (c.moveToNext()) {
106 String key = c.getString(c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
107 Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, key);
108 mResolver.delete(uri, null, null);
110 } catch (SecurityException e) {
111 Log.e(TAG, "handleClear - failed to query: " + e.toString());
113 if (c != null) c.close();
119 public void onActivityStateChange(Activity activity, int newState) {
121 case ActivityState.RESUMED:
122 mObserver.onResume();
123 mResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, mObserver);
125 case ActivityState.PAUSED:
126 case ActivityState.DESTROYED:
127 mResolver.unregisterContentObserver(mObserver);