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");
65 String promise_id = null;
66 JSONObject eventBody = null;
68 String smsMessage = null;
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) {
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,
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,
98 PendingIntent.FLAG_ONE_SHOT);
100 sms.sendTextMessage(phone, null, smsMessage, piSent, piDelivered);
101 } catch (Exception e) {
102 Log.e(TAG, "Failed to send SMS message.", e);
106 public void onSmsClear(int instanceID, JSONObject jsonMsg) {
107 String promise_id = null, cmd = null;
108 JSONObject eventBody = null;
109 String serviceID = null;
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) {
120 ContentResolver cr = mMainActivity.getContentResolver();
121 cr.delete(Uri.parse("content://sms"), null, null);
123 JSONObject jsonMsgRet = null;
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) {
139 mMessagingHandler.postMessage(instanceID, jsonMsgRet.toString());
142 public void onSmsSegmentInfo(int instanceID, JSONObject jsonMsg) {
143 String promise_id = null;
144 JSONObject eventBody = null;
147 promise_id = jsonMsg.getString("_promise_id");
148 eventBody = jsonMsg.getJSONObject("data");
149 text = eventBody.getString("text");
152 Log.e(TAG, "No \"text\" attribute.");
155 } catch (JSONException e) {
160 SmsManager sms = SmsManager.getDefault();
161 ArrayList<String> segs = sms.divideMessage(text);
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());
175 mMessagingHandler.postMessage(instanceID, jsonMsgRet.toString());
176 } catch (JSONException e) {
182 public void registerIntentFilters() {
183 mSmsReceiveReceiver = new MessagingReceiver(mMessagingHandler) {
185 public void onReceive(Context context, Intent intent) {
186 Bundle bundle = intent.getExtras();
192 Object[] pdus = (Object[]) bundle.get("pdus");
193 for (int i=0; i < pdus.length; ++i) {
195 JSONObject jsonMsg = new JSONObject();
196 jsonMsg.put("cmd", "received");
198 SmsMessage msgs = SmsMessage.createFromPdu((byte[])pdus[i]);
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());
212 mMessaging.broadcastMessage(jsonMsg.toString());
213 } catch (JSONException e) {
221 mSmsSentReceiver = new MessagingReceiver(mMessagingHandler) {
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));
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");
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);
249 mMessaging.postMessage(instanceID, jsonMsgPromise.toString());
251 JSONObject jsonMsgEvent = new JSONObject();
252 jsonMsgEvent.put("cmd", "sent");
253 jsonMsgEvent.put("data", jsSentMsg);
255 mMessaging.broadcastMessage(jsonMsgEvent.toString());
256 } catch (JSONException e) {
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);
268 mSmsDeliveredReceiver = new MessagingReceiver(mMessagingHandler) {
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));
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) {
297 mSmsServiceReceiver = new MessagingReceiver(mMessagingHandler) {
299 public void onReceive(Context content, Intent intent) {
301 JSONObject jsonMsg = new JSONObject();
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) {
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"));
327 public void unregisterIntentFilters() {
328 mMainActivity.unregisterReceiver(mSmsReceiveReceiver);
329 mMainActivity.unregisterReceiver(mSmsSentReceiver);
330 mMainActivity.unregisterReceiver(mSmsDeliveredReceiver);
331 mMainActivity.unregisterReceiver(mSmsServiceReceiver);
334 public String getServiceIds() {
335 JSONArray serviceIds = new JSONArray();
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();