1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.googlecode.android_scripting.facade;
18 
19 import android.app.Service;
20 import android.content.ContentResolver;
21 import android.content.ContentUris;
22 import android.content.ContentValues;
23 import android.database.ContentObserver;
24 import android.database.Cursor;
25 import android.net.Uri;
26 import android.provider.CallLog.Calls;
27 import android.util.Log;
28 
29 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
30 import com.googlecode.android_scripting.rpc.Rpc;
31 import com.googlecode.android_scripting.rpc.RpcParameter;
32 
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 import org.json.JSONException;
37 import org.json.JSONObject;
38 
39 /**
40  * Provides access to contacts related functionality.
41  */
42 public class CallLogFacade extends RpcReceiver {
43     private static final String TAG = "CallLogFacade";
44     private static final Uri CONTACTS_URI = Uri.parse("content://contacts/people");
45 
46     // Fields for use in messages from SL4A scripts
47     private static final String JSON_TYPE = "type";
48     private static final String JSON_NUMBER = "number";
49     private static final String JSON_TIME = "time";
50 
51     private final ContentResolver mContentResolver;
52     private final Service mService;
53     private final CallLogStatusReceiver mCallLogStatusReceiver;
54     private final EventFacade mEventFacade;
55 
CallLogFacade(FacadeManager manager)56     public CallLogFacade(FacadeManager manager) {
57         super(manager);
58         mService = manager.getService();
59         mContentResolver = mService.getContentResolver();
60         mCallLogStatusReceiver = new CallLogStatusReceiver();
61         mContentResolver.registerContentObserver(Calls.CONTENT_URI, true, mCallLogStatusReceiver);
62         mEventFacade = manager.getReceiver(EventFacade.class);
63     }
64 
buildUri(Integer id)65     private Uri buildUri(Integer id) {
66         Uri uri = ContentUris.withAppendedId(Calls.CONTENT_URI, id);
67         return uri;
68     }
69 
70     @Rpc(description = "Erase all contacts in phone book.")
callLogsEraseAll()71     public void callLogsEraseAll() {
72         Log.d(TAG, "callLogsEraseAll");
73         mContentResolver.delete(Calls.CONTENT_URI, null, null);
74         return;
75     }
76 
77     @Rpc(description = "Adds a list of calls to call log.", returns = "Number of calls added")
callLogsPut(@pcParametername = "logs") JSONObject log)78     public Integer callLogsPut(@RpcParameter(name = "logs") JSONObject log) throws JSONException {
79         Log.d(TAG, "callLogsPut");
80         int startingCount = callLogGetCount();
81         ContentValues values = new ContentValues();
82         String type = log.getString(JSON_TYPE);
83         String number = log.getString(JSON_NUMBER);
84         String time = log.getString(JSON_TIME);
85         values.put(Calls.TYPE, type);
86         values.put(Calls.NUMBER, number);
87         values.put(Calls.DATE, time);
88         mContentResolver.insert(Calls.CONTENT_URI, values);
89 
90         return callLogGetCount() - startingCount;
91     }
92 
93     @Rpc(description = "Returns a List of all contacts.", returns = "a List of contacts as Maps")
callLogsGet(@pcParametername = "type") String type)94     public List<JSONObject> callLogsGet(@RpcParameter(name = "type") String type)
95             throws JSONException {
96         Log.d(TAG, "callLogsGet");
97         List<JSONObject> result = new ArrayList<JSONObject>();
98         String[] query = new String[] {Calls.NUMBER, Calls.DATE, Calls.TYPE};
99 
100         Cursor cursor =
101                 mContentResolver.query(
102                         Calls.CONTENT_URI,
103                         query,
104                         Calls.TYPE + "= " + type,
105                         null,
106                         Calls.DATE + ", " + Calls.NUMBER);
107         if (cursor != null) {
108             while (cursor.moveToNext()) {
109                 JSONObject message = new JSONObject();
110                 for (int i = 0; i < query.length; i++) {
111                     String key = query[i];
112                     String value = cursor.getString(cursor.getColumnIndex(key));
113                     message.put(key, value);
114                 }
115                 result.add(message);
116             }
117             cursor.close();
118         }
119         return result;
120     }
121 
122     @Rpc(description = "Returns the number of contacts.")
callLogGetCount()123     public Integer callLogGetCount() {
124         Log.d(TAG, "callLogGetCount");
125         Integer result = 0;
126         Cursor cursor = mContentResolver.query(Calls.CONTENT_URI, null, null, null, null);
127         if (cursor != null) {
128             result = cursor.getCount();
129             cursor.close();
130         }
131         return result;
132     }
133 
134     private class CallLogStatusReceiver extends ContentObserver {
CallLogStatusReceiver()135         public CallLogStatusReceiver() {
136             super(null);
137         }
138 
onChange(boolean updated)139         public void onChange(boolean updated) {
140             Log.d(TAG, "CallLogStatusReceiver:onChange");
141             mEventFacade.postEvent("CallLogChanged", null);
142         }
143     }
144 
145     @Override
shutdown()146     public void shutdown() {
147         mContentResolver.unregisterContentObserver(mCallLogStatusReceiver);
148     }
149 }
150