Upstream version 8.36.156.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / extension / api / messaging / MessagingSmsManager.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.messaging;
6
7 import android.app.Activity;
8 import android.app.PendingIntent;
9 import android.content.BroadcastReceiver;
10 import android.content.ContentResolver;  
11 import android.content.ContentValues;
12 import android.content.Context;
13 import android.content.Intent;
14 import android.content.IntentFilter;
15 import android.os.Bundle;
16 import android.telephony.SmsManager;
17 import android.telephony.SmsMessage;
18 import android.telephony.TelephonyManager;
19 import android.net.Uri; 
20 import android.util.Log; 
21
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24
25 import org.json.JSONArray;
26 import org.json.JSONException;
27 import org.json.JSONObject;
28 import org.xwalk.core.extension.api.messaging.Messaging;
29
30 public class MessagingSmsManager {
31     private final static String TAG = "MessagingSmsManager";
32     private final static String EXTRA_MSGID = "_promise_id";
33     private final static String EXTRA_MSGTEXT = "message";
34     private final static String EXTRA_MSGTO = "to";
35     private final static String EXTRA_MSGINSTANCEID = "instanceid";
36     private final static String DEFAULT_SERVICE_ID = "sim0";
37     private final Activity mMainActivity;
38     private final Messaging mMessagingHandler;
39     private BroadcastReceiver mSmsSentReceiver, mSmsDeliveredReceiver,
40                               mSmsReceiveReceiver, mSmsServiceReceiver;
41
42     private abstract class MessagingReceiver extends BroadcastReceiver {
43         protected Messaging mMessaging;
44
45         public MessagingReceiver(Messaging messaging) {
46             mMessaging = messaging;
47         }
48     }
49
50     MessagingSmsManager(Activity activity, Messaging messaging) {
51         mMainActivity = activity;
52         mMessagingHandler = messaging;
53     }
54
55     private boolean checkService(String serviceID) {
56         TelephonyManager tm = 
57             (TelephonyManager)mMainActivity.getSystemService(Context.TELEPHONY_SERVICE);
58         return (TelephonyManager.SIM_STATE_READY == tm.getSimState());
59     }
60
61     public void onSmsSend(int instanceID, JSONObject jsonMsg) {
62         if (!checkService(DEFAULT_SERVICE_ID)) {
63             Log.e(TAG, "No Sim Card");
64         }
65         String promise_id = null;
66         JSONObject eventBody = null;
67         String phone = null;
68         String smsMessage = null;
69         try {
70             promise_id = jsonMsg.getString("_promise_id");
71             eventBody = jsonMsg.getJSONObject("data");
72             phone = eventBody.getString("phone");
73             smsMessage = eventBody.getString("message");
74         } catch (JSONException e) {
75             e.printStackTrace();
76             return;
77         }
78         
79         SmsManager sms = SmsManager.getDefault();
80         Intent intentSmsSent = new Intent("SMS_SENT");
81         intentSmsSent.putExtra(EXTRA_MSGID, promise_id);
82         intentSmsSent.putExtra(EXTRA_MSGTEXT, smsMessage);
83         intentSmsSent.putExtra(EXTRA_MSGTO, phone);
84         String instanceIDString = Integer.toString(instanceID);
85         intentSmsSent.putExtra(EXTRA_MSGINSTANCEID, instanceIDString);
86         int promiseIdInt = Integer.valueOf(promise_id);
87         PendingIntent piSent = PendingIntent.getBroadcast(mMainActivity, 
88                                                           promiseIdInt, 
89                                                           intentSmsSent, 
90                                                           PendingIntent.FLAG_ONE_SHOT);
91         Intent intentSmsDelivered = new Intent("SMS_DELIVERED");
92         intentSmsDelivered.putExtra(EXTRA_MSGID, promise_id);
93         intentSmsDelivered.putExtra(EXTRA_MSGTEXT, smsMessage);
94         intentSmsDelivered.putExtra(EXTRA_MSGINSTANCEID, instanceIDString);
95         PendingIntent piDelivered = PendingIntent.getBroadcast(mMainActivity, 
96                                                                -promiseIdInt, 
97                                                                intentSmsDelivered,
98                                                                PendingIntent.FLAG_ONE_SHOT);
99         try {
100             sms.sendTextMessage(phone, null, smsMessage, piSent, piDelivered);
101         } catch (Exception e) {
102             Log.e(TAG, "Failed to send SMS message.", e);
103         }
104     }
105
106     public void onSmsClear(int instanceID, JSONObject jsonMsg) {
107         String promise_id = null, cmd = null;
108         JSONObject eventBody = null;
109         String serviceID = null;
110         try {
111             promise_id = jsonMsg.getString("_promise_id");
112             cmd = jsonMsg.getString("cmd");
113             eventBody = jsonMsg.getJSONObject("data");
114             serviceID = eventBody.getString("serviceID");
115         } catch (JSONException e) {
116             e.printStackTrace();
117             return;
118         }
119
120         ContentResolver cr = mMainActivity.getContentResolver();
121         cr.delete(Uri.parse("content://sms"), null, null);
122
123         JSONObject jsonMsgRet = null;
124         try {
125             jsonMsgRet = new JSONObject();
126             jsonMsgRet.put("_promise_id", promise_id);
127             jsonMsgRet.put("cmd", cmd + "_ret");
128             JSONObject jsData = new JSONObject();
129             jsonMsgRet.put("data", jsData);
130             jsData.put("error", false);
131             JSONObject jsBody = new JSONObject();
132             jsData.put("body", jsBody);
133             jsBody.put("value", serviceID);
134         } catch (JSONException e) {
135             e.printStackTrace();
136             return;
137         }
138
139         mMessagingHandler.postMessage(instanceID, jsonMsgRet.toString());
140     }
141
142     public void onSmsSegmentInfo(int instanceID, JSONObject jsonMsg) {
143         String promise_id = null;
144         JSONObject eventBody = null;
145         String text = null;
146         try {
147             promise_id = jsonMsg.getString("_promise_id");
148             eventBody = jsonMsg.getJSONObject("data");
149             text = eventBody.getString("text");
150
151             if (null == text) {
152                 Log.e(TAG, "No \"text\" attribute.");
153                 return;
154             }
155         } catch (JSONException e) {
156             e.printStackTrace();
157             return;
158         }
159         
160         SmsManager sms = SmsManager.getDefault();
161         ArrayList<String> segs = sms.divideMessage(text);
162         try {
163             JSONObject jsonMsgRet = new JSONObject();
164             jsonMsgRet.put("cmd", "msg_smsSegmentInfo_ret");
165             jsonMsgRet.put("_promise_id", promise_id);
166             JSONObject jsData = new JSONObject();
167             jsonMsgRet.put("data", jsData);
168             jsData.put("error", false);
169             JSONObject jsBody = new JSONObject();
170             jsData.put("body", jsBody);
171             jsBody.put("segments", segs.size());
172             jsBody.put("charsPerSegment", segs.get(0).length());
173             jsBody.put("charsAvailableInLastSegment", segs.get(segs.size() - 1).length());
174             
175             mMessagingHandler.postMessage(instanceID, jsonMsgRet.toString());
176          } catch (JSONException e) {
177             e.printStackTrace();
178             return;
179         }        
180     }
181
182     public void registerIntentFilters() {
183         mSmsReceiveReceiver = new MessagingReceiver(mMessagingHandler) {
184             @Override
185             public void onReceive(Context context, Intent intent) {
186                 Bundle bundle = intent.getExtras();        
187                 
188                 if(null == bundle) {
189                     return;
190                 }
191
192                 Object[] pdus = (Object[]) bundle.get("pdus");
193                 for (int i=0; i < pdus.length; ++i) {
194                     try {
195                         JSONObject jsonMsg = new JSONObject();
196                         jsonMsg.put("cmd", "received");
197
198                         SmsMessage msgs = SmsMessage.createFromPdu((byte[])pdus[i]);
199                         
200                         JSONObject jsData = new JSONObject();
201                         jsonMsg.put("data", jsData);
202                         JSONObject jsMsg = new JSONObject();
203                         jsData.put("message", jsMsg);
204                         jsMsg.put("messageID", "");
205                         jsMsg.put("type", "sms");
206                         jsMsg.put("serviceID", DEFAULT_SERVICE_ID);
207                         jsMsg.put("from", msgs.getOriginatingAddress());
208                         SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
209                         jsMsg.put("timestamp", sDateFormat.format(new java.util.Date()));
210                         jsMsg.put("body", msgs.getMessageBody().toString());
211                         
212                         mMessaging.broadcastMessage(jsonMsg.toString());
213                      } catch (JSONException e) {
214                         e.printStackTrace();
215                         return;
216                     }
217                 } 
218             }
219         };
220
221         mSmsSentReceiver = new MessagingReceiver(mMessagingHandler) {
222             @Override
223             public void onReceive(Context content, Intent intent) {
224                 boolean error = getResultCode() != Activity.RESULT_OK;
225                 String promise_id = intent.getStringExtra(EXTRA_MSGID);
226                 String smsMessage = intent.getStringExtra(EXTRA_MSGTEXT);
227                 String to = intent.getStringExtra(EXTRA_MSGTO);
228                 int instanceID = Integer.valueOf(intent.getStringExtra(EXTRA_MSGINSTANCEID));
229
230                 try {
231                     JSONObject jsSentMsg = new JSONObject();
232                     jsSentMsg.put("type", "sms");
233                     jsSentMsg.put("from", "");
234                     jsSentMsg.put("read", true);
235                     jsSentMsg.put("to", to);
236                     jsSentMsg.put("body", smsMessage);
237                     jsSentMsg.put("messageClass", "class1");
238                     jsSentMsg.put("state", error ? "failed" : "sending");
239                     jsSentMsg.put("deliveryStatus", error ? "error" : "pending");
240
241                     JSONObject jsonMsgPromise = new JSONObject();
242                     jsonMsgPromise.put("_promise_id", promise_id);
243                     jsonMsgPromise.put("cmd", "msg_smsSend_ret");
244                     JSONObject jsData = new JSONObject();
245                     jsonMsgPromise.put("data", jsData);
246                     jsData.put("error", error);
247                     jsData.put("body", jsSentMsg);
248
249                     mMessaging.postMessage(instanceID, jsonMsgPromise.toString());
250
251                     JSONObject jsonMsgEvent = new JSONObject();
252                     jsonMsgEvent.put("cmd", "sent");
253                     jsonMsgEvent.put("data", jsSentMsg);
254
255                     mMessaging.broadcastMessage(jsonMsgEvent.toString());
256                 } catch (JSONException e) {
257                     e.printStackTrace();
258                     return;
259                 }
260
261                 ContentValues values = new ContentValues();
262                 values.put("address", to);
263                 values.put("body", smsMessage);
264                 mMainActivity.getContentResolver().insert(Uri.parse("content://sms/sent"), values);
265             }
266         };
267
268         mSmsDeliveredReceiver = new MessagingReceiver(mMessagingHandler) {
269             @Override
270             public void onReceive(Context content, Intent intent) {
271                 boolean error = getResultCode() != Activity.RESULT_OK;
272                 String promise_id = intent.getStringExtra(EXTRA_MSGID);
273                 int instanceID = Integer.valueOf(intent.getStringExtra(EXTRA_MSGINSTANCEID));
274
275                 try {
276                     JSONObject jsonMsg = new JSONObject();
277                     jsonMsg.put("_promise_id", promise_id);
278                     jsonMsg.put("cmd", error ? "deliveryerror": "deliverysuccess");
279                     JSONObject jsData = new JSONObject();
280                     jsonMsg.put("data", jsData);
281                     JSONObject jsEvent = new JSONObject();
282                     jsData.put("event", jsEvent);
283                     jsEvent.put("serviceID", DEFAULT_SERVICE_ID);
284                     jsEvent.put("messageID", "");
285                     jsEvent.put("recipients", "");
286                     SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
287                     jsEvent.put("deliveryTimestamps", sDateFormat.format(new java.util.Date()));
288                     jsData.put("error", error);
289                     mMessaging.postMessage(instanceID, jsonMsg.toString());
290                 } catch (JSONException e) {
291                     e.printStackTrace();
292                     return;
293                 }
294             }
295         };
296
297         mSmsServiceReceiver = new MessagingReceiver(mMessagingHandler) {
298             @Override
299             public void onReceive(Context content, Intent intent) {
300                 try {
301                     JSONObject jsonMsg = new JSONObject();
302                     jsonMsg.put("cmd", 
303                         checkService(DEFAULT_SERVICE_ID) ? "serviceadded": "serviceremoved");
304                     JSONObject jsData = new JSONObject();
305                     jsonMsg.put("data", jsData);
306                     JSONObject jsEvent = new JSONObject();
307                     jsData.put("event", jsEvent);
308                     jsEvent.put("serviceID", DEFAULT_SERVICE_ID);
309                     mMessaging.broadcastMessage(jsonMsg.toString());
310                 } catch (JSONException e) {
311                     e.printStackTrace();
312                     return;
313                 }
314             }
315         };
316
317         mMainActivity.registerReceiver(
318             mSmsReceiveReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
319         mMainActivity.registerReceiver(
320             mSmsSentReceiver, new IntentFilter("SMS_SENT"));
321         mMainActivity.registerReceiver(
322             mSmsDeliveredReceiver,new IntentFilter("SMS_DELIVERED"));
323         mMainActivity.registerReceiver(
324             mSmsServiceReceiver,new IntentFilter("android.intent.action.SIM_STATE_CHANGED"));
325     }
326
327     public void unregisterIntentFilters() {
328         mMainActivity.unregisterReceiver(mSmsReceiveReceiver);
329         mMainActivity.unregisterReceiver(mSmsSentReceiver);
330         mMainActivity.unregisterReceiver(mSmsDeliveredReceiver);
331         mMainActivity.unregisterReceiver(mSmsServiceReceiver);
332     }
333
334     public String getServiceIds() {
335         JSONArray serviceIds = new JSONArray();
336
337         // FIXME:(shawn) Android doesn't has the concept of service ID, which means messages are
338         // bundled to given SIM card. And official SDK does not support multiple SIM cards. 
339         // So mock the default one to satisfy the spec.
340         serviceIds.put(DEFAULT_SERVICE_ID);
341         return serviceIds.toString();
342     }
343 }