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.extension.api.messaging;
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;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
25 import org.json.JSONArray;
26 import org.json.JSONException;
27 import org.json.JSONObject;
28 import org.xwalk.core.extension.api.messaging.Messaging;
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;
42 private abstract class MessagingReceiver extends BroadcastReceiver {
43 protected Messaging mMessaging;
45 public MessagingReceiver(Messaging messaging) {
46 mMessaging = messaging;
50 MessagingSmsManager(Activity activity, Messaging messaging) {
51 mMainActivity = activity;
52 mMessagingHandler = messaging;
55 private boolean checkService(String serviceID) {
57 (TelephonyManager)mMainActivity.getSystemService(Context.TELEPHONY_SERVICE);
58 return (TelephonyManager.SIM_STATE_READY == tm.getSimState());
61 public void onSmsSend(int instanceID, JSONObject jsonMsg) {
62 if (!checkService(DEFAULT_SERVICE_ID)) {
63 Log.e(TAG, "No Sim Card");
66 String promise_id = null;
67 JSONObject eventBody = null;
69 String smsMessage = null;
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) {
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,
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,
99 PendingIntent.FLAG_ONE_SHOT);
100 sms.sendTextMessage(phone, null, smsMessage, piSent, piDelivered);
103 public void onSmsClear(int instanceID, JSONObject jsonMsg) {
104 String promise_id = null, cmd = null;
105 JSONObject eventBody = null;
106 String serviceID = null;
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) {
117 ContentResolver cr = mMainActivity.getContentResolver();
118 cr.delete(Uri.parse("content://sms"), null, null);
120 JSONObject jsonMsgRet = null;
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) {
136 mMessagingHandler.postMessage(instanceID, jsonMsgRet.toString());
139 public void onSmsSegmentInfo(int instanceID, JSONObject jsonMsg) {
140 String promise_id = null;
141 JSONObject eventBody = null;
144 promise_id = jsonMsg.getString("_promise_id");
145 eventBody = jsonMsg.getJSONObject("data");
146 text = eventBody.getString("text");
149 Log.e(TAG, "No \"text\" attribute.");
152 } catch (JSONException e) {
157 SmsManager sms = SmsManager.getDefault();
158 ArrayList<String> segs = sms.divideMessage(text);
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());
172 mMessagingHandler.postMessage(instanceID, jsonMsgRet.toString());
173 } catch (JSONException e) {
179 public void registerIntentFilters() {
180 mSmsReceiveReceiver = new MessagingReceiver(mMessagingHandler) {
182 public void onReceive(Context context, Intent intent) {
183 Bundle bundle = intent.getExtras();
189 Object[] pdus = (Object[]) bundle.get("pdus");
190 for (int i=0; i < pdus.length; ++i) {
192 JSONObject jsonMsg = new JSONObject();
193 jsonMsg.put("cmd", "received");
195 SmsMessage msgs = SmsMessage.createFromPdu((byte[])pdus[i]);
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());
209 mMessaging.broadcastMessage(jsonMsg.toString());
210 } catch (JSONException e) {
218 mSmsSentReceiver = new MessagingReceiver(mMessagingHandler) {
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));
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");
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);
246 mMessaging.postMessage(instanceID, jsonMsgPromise.toString());
248 JSONObject jsonMsgEvent = new JSONObject();
249 jsonMsgEvent.put("cmd", "sent");
250 jsonMsgEvent.put("data", jsSentMsg);
252 mMessaging.broadcastMessage(jsonMsgEvent.toString());
253 } catch (JSONException e) {
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);
265 mSmsDeliveredReceiver = new MessagingReceiver(mMessagingHandler) {
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));
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) {
294 mSmsServiceReceiver = new MessagingReceiver(mMessagingHandler) {
296 public void onReceive(Context content, Intent intent) {
298 JSONObject jsonMsg = new JSONObject();
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) {
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"));
324 public void unregisterIntentFilters() {
325 mMainActivity.unregisterReceiver(mSmsReceiveReceiver);
326 mMainActivity.unregisterReceiver(mSmsSentReceiver);
327 mMainActivity.unregisterReceiver(mSmsDeliveredReceiver);
328 mMainActivity.unregisterReceiver(mSmsServiceReceiver);
331 public String getServiceIds() {
332 JSONArray serviceIds = new JSONArray();
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();