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