1fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie/*
2fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Copyright (C) 2013 Samsung System LSI
3fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Licensed under the Apache License, Version 2.0 (the "License");
4fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* you may not use this file except in compliance with the License.
5fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* You may obtain a copy of the License at
6fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*
7fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*      http://www.apache.org/licenses/LICENSE-2.0
8fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*
9fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Unless required by applicable law or agreed to in writing, software
10fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* distributed under the License is distributed on an "AS IS" BASIS,
11fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* See the License for the specific language governing permissions and
13fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* limitations under the License.
14fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*/
15fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepackage com.android.bluetooth.map;
16fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
17fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.ByteArrayInputStream;
18fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.FileNotFoundException;
19fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.IOException;
20fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.OutputStream;
21fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.StringWriter;
22fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.UnsupportedEncodingException;
23fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.ArrayList;
24fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Arrays;
25fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Collections;
26fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.HashMap;
27fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.HashSet;
28fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Map;
29fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Set;
30fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
31fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport org.xmlpull.v1.XmlSerializer;
32fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
33fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.app.Activity;
34fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.app.PendingIntent;
35fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.BroadcastReceiver;
36fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentResolver;
37fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentUris;
38fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentValues;
39fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Context;
40fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Intent;
41fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.IntentFilter;
42fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.database.ContentObserver;
43fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.database.Cursor;
44fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.net.Uri;
45fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.os.Handler;
46fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.BaseColumns;
47fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony;
48fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Mms;
49fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.MmsSms;
50fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Sms;
51fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Sms.Inbox;
52fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.PhoneStateListener;
53fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.ServiceState;
54fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.SmsManager;
55fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.SmsMessage;
56fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.TelephonyManager;
57fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Log;
58fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Xml;
59fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
60fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.map.BluetoothMapUtils.TYPE;
61fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.map.BluetoothMapbMessageMmsEmail.MimePart;
62fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.google.android.mms.pdu.PduHeaders;
63fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
64fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepublic class BluetoothMapContentObserver {
65fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private static final String TAG = "BluetoothMapContentObserver";
66fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
6770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz    private static final boolean D = false;
6870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz    private static final boolean V = false;
69fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
70fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private Context mContext;
71fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private ContentResolver mResolver;
72fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private BluetoothMnsObexClient mMnsClient;
73fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private int mMasId;
74fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
75fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public static final int DELETED_THREAD_ID = -1;
76fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
77fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    /* X-Mms-Message-Type field types. These are from PduHeaders.java */
78fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84;
79fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
80fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private TYPE mSmsType;
81fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
82fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    static final String[] SMS_PROJECTION = new String[] {
83fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        BaseColumns._ID,
84fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.THREAD_ID,
85fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.ADDRESS,
86fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.BODY,
87fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.DATE,
88fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.READ,
89fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.TYPE,
90fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.STATUS,
91fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.LOCKED,
92fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Sms.ERROR_CODE,
93fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    };
94fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
95fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    static final String[] MMS_PROJECTION = new String[] {
96fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        BaseColumns._ID,
97fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.THREAD_ID,
98fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.MESSAGE_ID,
99fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.MESSAGE_SIZE,
100fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.SUBJECT,
101fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.CONTENT_TYPE,
102fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.TEXT_ONLY,
103fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.DATE,
104fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.DATE_SENT,
105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.READ,
106fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.MESSAGE_BOX,
107fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.MESSAGE_TYPE,
108fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Mms.STATUS,
109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    };
110fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
111fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public BluetoothMapContentObserver(final Context context) {
112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mContext = context;
113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mResolver = mContext.getContentResolver();
114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mSmsType = getSmsType();
116fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
118fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private TYPE getSmsType() {
119fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        TYPE smsType = null;
120fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
121fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
122fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
123fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            smsType = TYPE.SMS_GSM;
124fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } else if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
125fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            smsType = TYPE.SMS_CDMA;
126fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
128fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return smsType;
129fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
130fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
131fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private final ContentObserver mObserver = new ContentObserver(new Handler()) {
132fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        @Override
133fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public void onChange(boolean selfChange) {
134fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            onChange(selfChange, null);
135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
136fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
137fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        @Override
138fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public void onChange(boolean selfChange, Uri uri) {
139fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (V) Log.d(TAG, "onChange on thread: " + Thread.currentThread().getId()
140fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                + " Uri: " + uri.toString() + " selfchange: " + selfChange);
141fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
142fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            handleMsgListChanges();
143fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
144fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    };
145fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
146fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private static final String folderSms[] = {
147fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "",
148fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "inbox",
149fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "sent",
150fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "draft",
151fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "outbox",
152fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "outbox",
153fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "outbox",
154fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "inbox",
155fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "inbox",
156fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    };
157fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
158fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private static final String folderMms[] = {
159fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "",
160fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "inbox",
161fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "sent",
162fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "draft",
163fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "outbox",
164fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    };
165fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
166fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private class Event {
167fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        String eventType;
168fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        long handle;
169fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        String folder;
170fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        String oldFolder;
171fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        TYPE msgType;
172fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
173fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public Event(String eventType, long handle, String folder,
174fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            String oldFolder, TYPE msgType) {
175fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            String PATH = "telecom/msg/";
176fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.eventType = eventType;
177fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.handle = handle;
178fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (folder != null) {
179fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                this.folder = PATH + folder;
180fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
181fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                this.folder = null;
182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (oldFolder != null) {
184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                this.oldFolder = PATH + oldFolder;
185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                this.oldFolder = null;
187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.msgType = msgType;
189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
191fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public byte[] encode() throws UnsupportedEncodingException {
192fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            StringWriter sw = new StringWriter();
193fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            XmlSerializer xmlEvtReport = Xml.newSerializer();
194fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            try {
195fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.setOutput(sw);
196fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.startDocument(null, null);
197fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.text("\n");
19870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                xmlEvtReport.startTag("", "MAP-event-report");
199fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.attribute("", "version", "1.0");
200fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
201fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.startTag("", "event");
202fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.attribute("", "type", eventType);
203fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.attribute("", "handle", BluetoothMapUtils.getMapHandle(handle, msgType));
204fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (folder != null) {
205fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    xmlEvtReport.attribute("", "folder", folder);
206fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
207fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (oldFolder != null) {
208fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    xmlEvtReport.attribute("", "old_folder", oldFolder);
209fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
210fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.attribute("", "msg_type", msgType.name());
211fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.endTag("", "event");
212fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
21370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                xmlEvtReport.endTag("", "MAP-event-report");
214fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                xmlEvtReport.endDocument();
215fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } catch (IllegalArgumentException e) {
216fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                e.printStackTrace();
217fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } catch (IllegalStateException e) {
218fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                e.printStackTrace();
219fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } catch (IOException e) {
220fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                e.printStackTrace();
221fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
222fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
223fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (V) System.out.println(sw.toString());
224fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
225fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            return sw.toString().getBytes("UTF-8");
226fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
227fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
228fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
229fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private class Msg {
230fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        long id;
231fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int type;
232fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
233fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public Msg(long id, int type) {
234fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.id = id;
235fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.type = type;
236fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
237fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
238fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
239fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private Map<Long, Msg> mMsgListSms =
240fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Collections.synchronizedMap(new HashMap<Long, Msg>());
241fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
242fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private Map<Long, Msg> mMsgListMms =
243fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Collections.synchronizedMap(new HashMap<Long, Msg>());
244fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
245fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public void registerObserver(BluetoothMnsObexClient mns, int masId) {
246fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (V) Log.d(TAG, "registerObserver");
247fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* Use MmsSms Uri since the Sms Uri is not notified on deletes */
248fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mMasId = masId;
249fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mMnsClient = mns;
250fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mResolver.registerContentObserver(MmsSms.CONTENT_URI, false, mObserver);
251fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        initMsgList();
252fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
253fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
254fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public void unregisterObserver() {
255fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (V) Log.d(TAG, "unregisterObserver");
256fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mResolver.unregisterContentObserver(mObserver);
25770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        mMnsClient = null;
258fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
259fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
260fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void sendEvent(Event evt) {
261fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Log.d(TAG, "sendEvent: " + evt.eventType + " " + evt.handle + " "
262fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        + evt.folder + " " + evt.oldFolder + " " + evt.msgType.name());
263fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
264fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (mMnsClient == null) {
265fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.d(TAG, "sendEvent: No MNS client registered - don't send event");
266fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            return;
267fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
268fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
269fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        try {
270fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mMnsClient.sendEvent(evt.encode(), mMasId);
271fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } catch (UnsupportedEncodingException ex) {
272fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            /* do nothing */
273fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
274fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
275fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
276fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void initMsgList() {
277fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (V) Log.d(TAG, "initMsgList");
278fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
279fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mMsgListSms.clear();
280fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mMsgListMms.clear();
281fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
282fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
283fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
284fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(Sms.CONTENT_URI,
285fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            SMS_PROJECTION, null, null, null);
286fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
287fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
288fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            do {
289fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
290fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                int type = c.getInt(c.getColumnIndex(Sms.TYPE));
291fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
292fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Msg msg = new Msg(id, type);
293fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                msgListSms.put(id, msg);
294fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } while (c.moveToNext());
295fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
296fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
297fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
298fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mMsgListSms = msgListSms;
299fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
300fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>();
301fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
302fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        c = mResolver.query(Mms.CONTENT_URI,
303fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            MMS_PROJECTION, null, null, null);
304fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
305fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
306fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            do {
307fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
308fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
309fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
310fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Msg msg = new Msg(id, type);
311fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                msgListMms.put(id, msg);
312fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } while (c.moveToNext());
313fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
314fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
315fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
316fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mMsgListMms = msgListMms;
317fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
318fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
319fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void handleMsgListChangesSms() {
320fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (V) Log.d(TAG, "handleMsgListChangesSms");
321fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
322fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
323fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
324fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(Sms.CONTENT_URI,
325fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            SMS_PROJECTION, null, null, null);
326fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
327fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        synchronized(mMsgListSms) {
328fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (c != null && c.moveToFirst()) {
329fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                do {
330fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
331fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    int type = c.getInt(c.getColumnIndex(Sms.TYPE));
332fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
333fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Msg msg = mMsgListSms.remove(id);
334fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
335fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    if (msg == null) {
336fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* New message */
337fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        msg = new Msg(id, type);
338fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        msgListSms.put(id, msg);
339fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
340fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (folderSms[type].equals("inbox")) {
341fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Event evt = new Event("NewMessage", id, folderSms[type],
342fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                null, mSmsType);
343fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            sendEvent(evt);
344fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
345fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    } else {
346fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* Existing message */
347fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (type != msg.type) {
348fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Log.d(TAG, "new type: " + type + " old type: " + msg.type);
349fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Event evt = new Event("MessageShift", id, folderSms[type],
350fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                folderSms[msg.type], mSmsType);
351fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            sendEvent(evt);
352fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            msg.type = type;
353fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
354fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        msgListSms.put(id, msg);
355fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
356fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                } while (c.moveToNext());
357fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                c.close();
358fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
359fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
360fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            for (Msg msg : mMsgListSms.values()) {
361fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Event evt = new Event("MessageDeleted", msg.id, "deleted",
362fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    folderSms[msg.type], mSmsType);
363fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                sendEvent(evt);
364fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
365fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
366fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mMsgListSms = msgListSms;
367fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
368fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
369fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
370fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void handleMsgListChangesMms() {
371fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (V) Log.d(TAG, "handleMsgListChangesMms");
372fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
373fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>();
374fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
375fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(Mms.CONTENT_URI,
376fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            MMS_PROJECTION, null, null, null);
377fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
378fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        synchronized(mMsgListMms) {
379fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (c != null && c.moveToFirst()) {
380fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                do {
381fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
382fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
383fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE));
384fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
385fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Msg msg = mMsgListMms.remove(id);
386fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
387fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    if (msg == null) {
388fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* New message - only notify on retrieve conf */
389fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (folderMms[type].equals("inbox") &&
390fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            mtype != MESSAGE_TYPE_RETRIEVE_CONF) {
391fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                continue;
392fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
393fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
394fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        msg = new Msg(id, type);
395fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        msgListMms.put(id, msg);
396fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
397fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (folderMms[type].equals("inbox")) {
398fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Event evt = new Event("NewMessage", id, folderMms[type],
399fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                null, TYPE.MMS);
400fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            sendEvent(evt);
401fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
402fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    } else {
403fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* Existing message */
404fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (type != msg.type) {
405fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Log.d(TAG, "new type: " + type + " old type: " + msg.type);
406fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Event evt = new Event("MessageShift", id, folderMms[type],
407fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                folderMms[msg.type], TYPE.MMS);
408fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            sendEvent(evt);
409fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            msg.type = type;
410fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
411fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            if (folderMms[type].equals("sent")) {
412fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                evt = new Event("SendingSuccess", id,
413fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                    folderSms[type], null, TYPE.MMS);
414fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                sendEvent(evt);
415fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            }
416fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
417fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        msgListMms.put(id, msg);
418fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
419fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                } while (c.moveToNext());
420fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                c.close();
421fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
422fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
423fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            for (Msg msg : mMsgListMms.values()) {
424fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Event evt = new Event("MessageDeleted", msg.id, "deleted",
425fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    folderMms[msg.type], TYPE.MMS);
426fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                sendEvent(evt);
427fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
428fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
429fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mMsgListMms = msgListMms;
430fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
431fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
432fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
433fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void handleMsgListChanges() {
434fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        handleMsgListChangesSms();
435fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        handleMsgListChangesMms();
436fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
437fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
438fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private boolean deleteMessageMms(long handle) {
439fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean res = false;
440fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
441fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(uri, null, null, null, null);
442fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
443fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            /* Move to deleted folder, or delete if already in deleted folder */
444fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
445fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (threadId != DELETED_THREAD_ID) {
446fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Set deleted thread id */
447fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                ContentValues contentValues = new ContentValues();
448fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                contentValues.put(Mms.THREAD_ID, DELETED_THREAD_ID);
449fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mResolver.update(uri, contentValues, null, null);
450fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
451fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Delete from observer message list to avoid delete notifications */
452fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mMsgListMms.remove(handle);
453fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Delete message */
454fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mResolver.delete(uri, null, null);
455fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
456fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            res = true;
457fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
458fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null) {
459fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
460fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
461fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return res;
462fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
463fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
464fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void updateThreadIdMms(Uri uri, long threadId) {
465fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ContentValues contentValues = new ContentValues();
466fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        contentValues.put(Mms.THREAD_ID, threadId);
467fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mResolver.update(uri, contentValues, null, null);
468fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
469fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
470fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private boolean unDeleteMessageMms(long handle) {
471fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean res = false;
472fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
473fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(uri, null, null, null, null);
474fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
475fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
476fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
477fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (threadId == DELETED_THREAD_ID) {
478fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Restore thread id from address, or if no thread for address
479fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                 * create new thread by insert and remove of fake message */
480fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                String address;
481fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
482fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
483fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgBox == Mms.MESSAGE_BOX_INBOX) {
484fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    address = BluetoothMapContent.getAddressMms(mResolver, id,
485fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        BluetoothMapContent.MMS_FROM);
486fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                } else {
487fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    address = BluetoothMapContent.getAddressMms(mResolver, id,
488fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        BluetoothMapContent.MMS_TO);
489fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
490fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Set<String> recipients = new HashSet<String>();
491fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                recipients.addAll(Arrays.asList(address));
492fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                updateThreadIdMms(uri, Telephony.Threads.getOrCreateThreadId(mContext, recipients));
493fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
494fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "Message not in deleted folder: handle " + handle
495fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    + " threadId " + threadId);
496fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
497fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            res = true;
498fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
499fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null) {
500fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
501fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
502fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return res;
503fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
504fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
505fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private boolean deleteMessageSms(long handle) {
506fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean res = false;
507fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
508fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(uri, null, null, null, null);
509fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
510fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
511fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            /* Move to deleted folder, or delete if already in deleted folder */
512fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
513fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (threadId != DELETED_THREAD_ID) {
514fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Set deleted thread id */
515fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                ContentValues contentValues = new ContentValues();
516fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                contentValues.put(Sms.THREAD_ID, DELETED_THREAD_ID);
517fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mResolver.update(uri, contentValues, null, null);
518fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
519fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Delete from observer message list to avoid delete notifications */
520fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mMsgListSms.remove(handle);
521fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Delete message */
522fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mResolver.delete(uri, null, null);
523fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
524fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            res = true;
525fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
526fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null) {
527fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
528fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
529fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return res;
530fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
531fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
532fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void updateThreadIdSms(Uri uri, long threadId) {
533fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ContentValues contentValues = new ContentValues();
534fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        contentValues.put(Sms.THREAD_ID, threadId);
535fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mResolver.update(uri, contentValues, null, null);
536fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
537fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
538fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private boolean unDeleteMessageSms(long handle) {
539fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean res = false;
540fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
541fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(uri, null, null, null, null);
542fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
543fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
544fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
545fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (threadId == DELETED_THREAD_ID) {
546fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                String address = c.getString(c.getColumnIndex(Sms.ADDRESS));
547fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Set<String> recipients = new HashSet<String>();
548fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                recipients.addAll(Arrays.asList(address));
549fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                updateThreadIdSms(uri, Telephony.Threads.getOrCreateThreadId(mContext, recipients));
550fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
551fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "Message not in deleted folder: handle " + handle
552fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    + " threadId " + threadId);
553fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
554fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            res = true;
555fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
556fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null) {
557fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
558fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
559fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return res;
560fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
561fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
562fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public boolean setMessageStatusDeleted(long handle, TYPE type, int statusValue) {
563fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean res = false;
564fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (D) Log.d(TAG, "setMessageStatusDeleted: handle " + handle
565fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            + " type " + type + " value " + statusValue);
566fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
567fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (statusValue == BluetoothMapAppParams.STATUS_VALUE_YES) {
568fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
569fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                res = deleteMessageSms(handle);
570fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else if (type == TYPE.MMS) {
571fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                res = deleteMessageMms(handle);
572fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
573fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } else if (statusValue == BluetoothMapAppParams.STATUS_VALUE_NO) {
574fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
575fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                res = unDeleteMessageSms(handle);
576fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else if (type == TYPE.MMS) {
577fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                res = unDeleteMessageMms(handle);
578fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
579fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
580fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return res;
581fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
582fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
583fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public boolean setMessageStatusRead(long handle, TYPE type, int statusValue) {
584fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean res = true;
585fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
586fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (D) Log.d(TAG, "setMessageStatusRead: handle " + handle
587fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            + " type " + type + " value " + statusValue);
588fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
589fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* Approved MAP spec errata 3445 states that read status initiated */
590fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* by the MCE shall change the MSE read status. */
591fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
592fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
593fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
594fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Cursor c = mResolver.query(uri, null, null, null, null);
595fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
596fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            ContentValues contentValues = new ContentValues();
597fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            contentValues.put(Sms.READ, statusValue);
598fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mResolver.update(uri, contentValues, null, null);
599fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } else if (type == TYPE.MMS) {
600fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
601fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Cursor c = mResolver.query(uri, null, null, null, null);
602fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
603fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            ContentValues contentValues = new ContentValues();
604fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            contentValues.put(Mms.READ, statusValue);
605fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mResolver.update(uri, contentValues, null, null);
606fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
607fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
608fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return res;
609fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
610fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
611fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private class PushMsgInfo {
612fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        long id;
613fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int transparent;
614fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int retry;
615fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        String phone;
616fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri uri;
617fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int parts;
618fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int partsSent;
619fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int partsDelivered;
620fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        boolean resend;
621fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
622fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public PushMsgInfo(long id, int transparent,
623fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int retry, String phone, Uri uri) {
624fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.id = id;
625fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.transparent = transparent;
626fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.retry = retry;
627fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.phone = phone;
628fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.uri = uri;
629fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            this.resend = false;
630fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        };
631fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
632fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
633fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private Map<Long, PushMsgInfo> mPushMsgList =
634fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Collections.synchronizedMap(new HashMap<Long, PushMsgInfo>());
635fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
636fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public long pushMessage(BluetoothMapbMessage msg, String folder,
637fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        BluetoothMapAppParams ap) throws IllegalArgumentException {
638fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (D) Log.d(TAG, "pushMessage");
639fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ArrayList<BluetoothMapbMessage.vCard> recipientList = msg.getRecipients();
640fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ?
641fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                0 : ap.getTransparent();
642fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int retry = ap.getRetry();
643fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        int charset = ap.getCharset();
644fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        long handle = -1;
645fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
646fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (recipientList == null) {
647fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.d(TAG, "empty recipient list");
648fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            return -1;
649fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
650fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
651fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        for (BluetoothMapbMessage.vCard recipient : recipientList) {
652fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if(recipient.getEnvLevel() == 0) // Only send the message to the top level recipient
653fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            {
654fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Only send to first address */
655fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                String phone = recipient.getFirstPhoneNumber();
656fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                boolean read = false;
657fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                boolean deliveryReport = true;
658fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
659fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                switch(msg.getType()){
660fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    case MMS:
661fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    {
662fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* Send message if folder is outbox */
663c3ec58fcc54cb33635f4dee746ee22cb8b0e3210Zhihai Xu                        /* to do, support MMS in the future */
664c3ec58fcc54cb33635f4dee746ee22cb8b0e3210Zhihai Xu                        /*
665fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (folder.equals("outbox")) {
666fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                           handle = sendMmsMessage(folder, phone, (BluetoothMapbMessageMmsEmail)msg);
667fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
668c3ec58fcc54cb33635f4dee746ee22cb8b0e3210Zhihai Xu                        */
669fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        break;
670fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
671fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    case SMS_GSM: //fall-through
672fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    case SMS_CDMA:
673fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    {
674fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* Add the message to the database */
675fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        String msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody();
676fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        Uri contentUri = Uri.parse("content://sms/" + folder);
677fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        Uri uri = Sms.addMessageToUri(mResolver, contentUri, phone, msgBody,
678fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            "", System.currentTimeMillis(), read, deliveryReport);
679fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
680fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (uri == null) {
681fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Log.d(TAG, "pushMessage - failure on add to uri " + contentUri);
682fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            return -1;
683fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
684fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
685fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        handle = Long.parseLong(uri.getLastPathSegment());
686fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
687fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        /* Send message if folder is outbox */
688fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (folder.equals("outbox")) {
689fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            PushMsgInfo msgInfo = new PushMsgInfo(handle, transparent,
690fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                retry, phone, uri);
691fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            mPushMsgList.put(handle, msgInfo);
692fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            sendMessage(msgInfo, msgBody);
693fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
694fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        break;
695fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
696fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    case EMAIL:
697fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    {
698fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        break;
699fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
700fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
701fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
702fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
703fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
704fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
705fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* If multiple recipients return handle of last */
706fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return handle;
707fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
708fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
709fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
710fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
711fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public long sendMmsMessage(String folder,String to_address, BluetoothMapbMessageMmsEmail msg) {
712fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /*
713fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *strategy:
714fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *1) parse message into parts
715fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *if folder is outbox/drafts:
716fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *2) push message to draft
717fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *if folder is outbox:
718fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *3) move message to outbox (to trigger the mms app to add msg to pending_messages list)
719fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *4) send intent to mms app in order to wake it up.
720fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *else if folder !outbox:
721fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         *1) push message to folder
722fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         * */
723fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (folder != null && (folder.equalsIgnoreCase("outbox")||  folder.equalsIgnoreCase("drafts"))) {
724fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            long handle = pushMmsToFolder(Mms.MESSAGE_BOX_DRAFTS, to_address, msg);
725fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            /* if invalid handle (-1) then just return the handle - else continue sending (if folder is outbox) */
726fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle && folder.equalsIgnoreCase("outbox")) {
727fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                moveDraftToOutbox(handle);
728fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
729fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Intent sendIntent = new Intent("android.intent.action.MMS_SEND_OUTBOX_MSG");
730fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "broadcasting intent: "+sendIntent.toString());
731fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mContext.sendBroadcast(sendIntent);
732fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
733fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            return handle;
734fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } else {
735fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            /* not allowed to push mms to anything but outbox/drafts */
736fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            throw  new IllegalArgumentException("Cannot push message to other folders than outbox/drafts");
737fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
738fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
739fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
740fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
741fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
742fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void moveDraftToOutbox(long handle) {
743fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ContentResolver contentResolver = mContext.getContentResolver();
744fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /*Move message by changing the msg_box value in the content provider database */
745fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (handle != -1) {
746fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            String whereClause = " _id= " + handle;
747fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Uri uri = Uri.parse("content://mms");
748fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Cursor queryResult = contentResolver.query(uri, null, whereClause, null, null);
749fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (queryResult != null) {
750fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (queryResult.getCount() > 0) {
751fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    queryResult.moveToFirst();
752fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    ContentValues data = new ContentValues();
753fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    /* set folder to be outbox */
754fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    data.put("msg_box", Mms.MESSAGE_BOX_OUTBOX);
755fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    contentResolver.update(uri, data, whereClause, null);
756fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Log.d(TAG, "moved draft MMS to outbox");
757fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
758fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                queryResult.close();
759fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }else {
760fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "Could not move draft to outbox ");
761fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
762fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
763fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
764fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private long pushMmsToFolder(int folder, String to_address, BluetoothMapbMessageMmsEmail msg) {
765fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /**
766fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         * strategy:
767fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         * 1) parse msg into parts + header
768fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         * 2) create thread id (abuse the ease of adding an SMS to get id for thread)
769fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         * 3) push parts into content://mms/parts/ table
770fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         * 3)
771fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie         */
772fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
773fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ContentValues values = new ContentValues();
774fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("msg_box", folder);
775fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
776fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("read", 0);
777fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("seen", 0);
77870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        values.put("sub", msg.getSubject());
779fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("sub_cs", 106);
780fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("ct_t", "application/vnd.wap.multipart.related");
781fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("exp", 604800);
782fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("m_cls", PduHeaders.MESSAGE_CLASS_PERSONAL_STR);
783fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("m_type", PduHeaders.MESSAGE_TYPE_SEND_REQ);
784fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("v", PduHeaders.CURRENT_MMS_VERSION);
785fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("pri", PduHeaders.PRIORITY_NORMAL);
786fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("rr", PduHeaders.VALUE_NO);
787fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("tr_id", "T"+ Long.toHexString(System.currentTimeMillis()));
788fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("d_rpt", PduHeaders.VALUE_NO);
789fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("locked", 0);
79070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        if(msg.getTextOnly() == true)
79170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("text_only", true);
79270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz
79370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        values.put("m_size", msg.getSize());
79470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz
795fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie     // Get thread id
796fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Set<String> recipients = new HashSet<String>();
797fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        recipients.addAll(Arrays.asList(to_address));
798fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("thread_id", Telephony.Threads.getOrCreateThreadId(mContext, recipients));
799fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri uri = Uri.parse("content://mms");
800fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
801fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ContentResolver cr = mContext.getContentResolver();
802fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        uri = cr.insert(uri, values);
803fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
804fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (uri == null) {
805fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            // unable to insert MMS
806fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.e(TAG, "Unabled to insert MMS " + values + "Uri: " + uri);
807fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            return -1;
808fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
809fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
810fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        long handle = Long.parseLong(uri.getLastPathSegment());
811fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (V){
812fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.v(TAG, " NEW URI " + uri.toString());
813fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
814fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        try {
81570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            if(V) Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base.");
816fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        for(MimePart part : msg.getMimeParts()) {
81770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            int count = 0;
81870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            count++;
819fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            values.clear();
820fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if(part.contentType != null &&  part.contentType.toUpperCase().contains("TEXT")) {
821fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("ct", "text/plain");
822fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("chset", 106);
82370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.partName != null) {
82470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("fn", part.partName);
82570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("name", part.partName);
82670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                } else if(part.contentId == null && part.contentLocation == null) {
82770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    /* We must set at least one part identifier */
82870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("fn", "text_" + count +".txt");
82970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("name", "text_" + count +".txt");
83070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                }
83170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.contentId != null) {
83270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("cid", part.contentId);
83370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                }
83470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.contentLocation != null)
83570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("cl", part.contentLocation);
83670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.contentDisposition != null)
83770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("cd", part.contentDisposition);
838fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("text", new String(part.data, "UTF-8"));
839fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                uri = Uri.parse("content://mms/" + handle + "/part");
840fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                uri = cr.insert(uri, values);
84170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(V) Log.v(TAG, "Added TEXT part");
842fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
843fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else if (part.contentType != null &&  part.contentType.toUpperCase().contains("SMIL")){
844fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
845fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("seq", -1);
846fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("ct", "application/smil");
84770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.contentId != null)
84870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("cid", part.contentId);
84970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.contentLocation != null)
85070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("cl", part.contentLocation);
85170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(part.contentDisposition != null)
85270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                    values.put("cd", part.contentDisposition);
853fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("fn", "smil.xml");
854fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("name", "smil.xml");
855fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                values.put("text", new String(part.data, "UTF-8"));
856fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
857fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                uri = Uri.parse("content://mms/" + handle + "/part");
858fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                uri = cr.insert(uri, values);
85970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(V) Log.v(TAG, "Added SMIL part");
860fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
861fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }else /*VIDEO/AUDIO/IMAGE*/ {
86270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                writeMmsDataPart(handle, part, count);
86370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz                if(V) Log.v(TAG, "Added OTHER part");
864fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
865fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (uri != null && V){
866fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.v(TAG, "Added part with content-type: "+ part.contentType + " to Uri: " + uri.toString());
867fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
868fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
869fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } catch (UnsupportedEncodingException e) {
87070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            Log.w(TAG, e);
871fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        } catch (IOException e) {
87270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            Log.w(TAG, e);
873fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
874fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
875fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.clear();
876fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("contact_id", "null");
877fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("address", "insert-address-token");
878fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("type", BluetoothMapContent.MMS_FROM);
879fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("charset", 106);
880fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
881fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        uri = Uri.parse("content://mms/" + handle + "/addr");
882fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        uri = cr.insert(uri, values);
883fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (uri != null && V){
884fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.v(TAG, " NEW URI " + uri.toString());
885fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
886fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
887fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.clear();
888fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("contact_id", "null");
889fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("address", to_address);
890fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("type", BluetoothMapContent.MMS_TO);
891fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("charset", 106);
892fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
893fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        uri = Uri.parse("content://mms/" + handle + "/addr");
894fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        uri = cr.insert(uri, values);
895fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (uri != null && V){
896fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.v(TAG, " NEW URI " + uri.toString());
897fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
898fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        return handle;
899fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
900fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
901fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
90270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz    private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException{
903fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ContentValues values = new ContentValues();
904fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        values.put("mid", handle);
90570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        if(part.contentType != null)
90670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("ct", part.contentType);
90770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        if(part.contentId != null)
90870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("cid", part.contentId);
90970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        if(part.contentLocation != null)
91070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("cl", part.contentLocation);
91170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        if(part.contentDisposition != null)
91270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("cd", part.contentDisposition);
91370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        if(part.partName != null) {
91470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("fn", part.partName);
91570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("name", part.partName);
91670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        } else if(part.contentId == null && part.contentLocation == null) {
91770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            /* We must set at least one part identifier */
91870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("fn", "part_" + count + ".dat");
91970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz            values.put("name", "part_" + count + ".dat");
92070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        }
921fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri partUri = Uri.parse("content://mms/" + handle + "/part");
922fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Uri res = mResolver.insert(partUri, values);
923fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
924fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        // Add data to part
925fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        OutputStream os = mResolver.openOutputStream(res);
92670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz        os.write(part.data);
927fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        os.close();
928fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
929fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
930fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
931fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public void sendMessage(PushMsgInfo msgInfo, String msgBody) {
932fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
933fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        SmsManager smsMng = SmsManager.getDefault();
934fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ArrayList<String> parts = smsMng.divideMessage(msgBody);
935fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        msgInfo.parts = parts.size();
936fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
937fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(msgInfo.parts);
938fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(msgInfo.parts);
939fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
940fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        for (int i = 0; i < msgInfo.parts; i++) {
941fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Intent intent;
942fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            intent = new Intent(ACTION_MESSAGE_DELIVERY, null);
943fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            intent.putExtra("HANDLE", msgInfo.id);
944fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            deliveryIntents.add(PendingIntent.getBroadcast(mContext, 0, intent,
945fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                PendingIntent.FLAG_UPDATE_CURRENT));
946fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
947fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            intent = new Intent(ACTION_MESSAGE_SENT, null);
948fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            intent.putExtra("HANDLE", msgInfo.id);
949fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            sentIntents.add(PendingIntent.getBroadcast(mContext, 0, intent,
950fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                PendingIntent.FLAG_UPDATE_CURRENT));
951fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
952fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
953fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Log.d(TAG, "sendMessage to " + msgInfo.phone);
954fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
955fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        smsMng.sendMultipartTextMessage(msgInfo.phone, null, parts, sentIntents,
956fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            deliveryIntents);
957fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
958fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
959fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private static final String ACTION_MESSAGE_DELIVERY =
960fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY";
961fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private static final String ACTION_MESSAGE_SENT =
962fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT";
963fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
964fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private SmsBroadcastReceiver mSmsBroadcastReceiver = new SmsBroadcastReceiver();
965fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
966fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private class SmsBroadcastReceiver extends BroadcastReceiver {
967fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        private final String[] ID_PROJECTION = new String[] { Sms._ID };
968fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        private final Uri UPDATE_STATUS_URI = Uri.parse("content://sms/status");
969fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
970fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public void register() {
971fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Handler handler = new Handler();
972fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
973fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            IntentFilter intentFilter = new IntentFilter();
974fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            intentFilter.addAction(ACTION_MESSAGE_DELIVERY);
975fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            intentFilter.addAction(ACTION_MESSAGE_SENT);
976fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mContext.registerReceiver(this, intentFilter, null, handler);
977fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
978fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
979fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public void unregister() {
980fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            try {
981fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mContext.unregisterReceiver(this);
982fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } catch (IllegalArgumentException e) {
983fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* do nothing */
984fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
985fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
986fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
987fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        @Override
988fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public void onReceive(Context context, Intent intent) {
989fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            String action = intent.getAction();
990fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            long handle = intent.getLongExtra("HANDLE", -1);
991fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            PushMsgInfo msgInfo = mPushMsgList.get(handle);
992fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
993fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.d(TAG, "onReceive: action"  + action);
994fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
995fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (msgInfo == null) {
996fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "onReceive: no msgInfo found for handle " + handle);
997fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                return;
998fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
999fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1000fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (action.equals(ACTION_MESSAGE_SENT)) {
1001fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                msgInfo.partsSent++;
1002fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgInfo.partsSent == msgInfo.parts) {
1003fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    actionMessageSent(context, intent, msgInfo);
1004fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1005fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else if (action.equals(ACTION_MESSAGE_DELIVERY)) {
1006fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                msgInfo.partsDelivered++;
1007fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgInfo.partsDelivered == msgInfo.parts) {
1008fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    actionMessageDelivery(context, intent, msgInfo);
1009fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1010fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
1011fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "onReceive: Unknown action " + action);
1012fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1013fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
1014fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1015fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        private void actionMessageSent(Context context, Intent intent,
1016fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            PushMsgInfo msgInfo) {
1017fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int result = getResultCode();
1018fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            boolean delete = false;
1019fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1020fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (result == Activity.RESULT_OK) {
1021fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "actionMessageSent: result OK");
1022fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgInfo.transparent == 0) {
1023fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    if (!Sms.moveMessageToFolder(context, msgInfo.uri,
1024fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Sms.MESSAGE_TYPE_SENT, 0)) {
1025fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        Log.d(TAG, "Failed to move " + msgInfo.uri + " to SENT");
1026fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
1027fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                } else {
1028fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    delete = true;
1029fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1030fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1031fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Event evt = new Event("SendingSuccess", msgInfo.id,
1032fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType);
1033fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                sendEvent(evt);
1034fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1035fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
1036fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgInfo.retry == 1) {
1037fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    /* Notify failure, but keep message in outbox for resending */
1038fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    msgInfo.resend = true;
1039fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Event evt = new Event("SendingFailure", msgInfo.id,
1040fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        folderSms[Sms.MESSAGE_TYPE_OUTBOX], null, mSmsType);
1041fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    sendEvent(evt);
1042fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                } else {
1043fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    if (msgInfo.transparent == 0) {
1044fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        if (!Sms.moveMessageToFolder(context, msgInfo.uri,
1045fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                Sms.MESSAGE_TYPE_FAILED, 0)) {
1046fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                            Log.d(TAG, "Failed to move " + msgInfo.uri + " to FAILED");
1047fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        }
1048fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    } else {
1049fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        delete = true;
1050fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    }
1051fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1052fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Event evt = new Event("SendingFailure", msgInfo.id,
1053fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                        folderSms[Sms.MESSAGE_TYPE_FAILED], null, mSmsType);
1054fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    sendEvent(evt);
1055fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1056fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1057fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1058fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (delete == true) {
1059fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Delete from Observer message list to avoid delete notifications */
1060fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mMsgListSms.remove(msgInfo.id);
1061fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1062fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                /* Delete from DB */
1063fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                mResolver.delete(msgInfo.uri, null, null);
1064fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1065fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
1066fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1067fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        private void actionMessageDelivery(Context context, Intent intent,
1068fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            PushMsgInfo msgInfo) {
1069fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Uri messageUri = intent.getData();
1070fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            byte[] pdu = intent.getByteArrayExtra("pdu");
1071fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            String format = intent.getStringExtra("format");
1072fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1073fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            SmsMessage message = SmsMessage.createFromPdu(pdu, format);
1074fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (message == null) {
1075fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Log.d(TAG, "actionMessageDelivery: Can't get message from pdu");
1076fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                return;
1077fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1078fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            int status = message.getStatus();
1079fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1080fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Cursor cursor = mResolver.query(msgInfo.uri, ID_PROJECTION, null, null, null);
1081fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1082fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            try {
1083fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (cursor.moveToFirst()) {
1084fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    int messageId = cursor.getInt(0);
1085fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1086fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Uri updateUri = ContentUris.withAppendedId(UPDATE_STATUS_URI, messageId);
1087fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    boolean isStatusReport = message.isStatusReportMessage();
1088fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1089fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Log.d(TAG, "actionMessageDelivery: uri=" + messageUri + ", status=" + status +
1090fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                                ", isStatusReport=" + isStatusReport);
1091fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1092fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    ContentValues contentValues = new ContentValues(2);
1093fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1094fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    contentValues.put(Sms.STATUS, status);
1095fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    contentValues.put(Inbox.DATE_SENT, System.currentTimeMillis());
1096fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    mResolver.update(updateUri, contentValues, null, null);
1097fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                } else {
1098fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Log.d(TAG, "Can't find message for status update: " + messageUri);
1099fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1100fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } finally {
1101fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                cursor.close();
1102fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1103fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1104fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (status == 0) {
1105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Event evt = new Event("DeliverySuccess", msgInfo.id,
1106fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType);
1107fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                sendEvent(evt);
1108fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } else {
1109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Event evt = new Event("DeliveryFailure", msgInfo.id,
1110fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType);
1111fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                sendEvent(evt);
1112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            mPushMsgList.remove(msgInfo.id);
1115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
1116fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1118fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void registerPhoneServiceStateListener() {
1119fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
1120fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_SERVICE_STATE);
1121fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1122fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1123fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void unRegisterPhoneServiceStateListener() {
1124fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
1125fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);
1126fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1128fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void resendPendingMessages() {
1129fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* Send pending messages in outbox */
1130fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
1131fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
1132fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            null);
1133fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1134fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
1135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            do {
1136fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
1137fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
1138fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                PushMsgInfo msgInfo = mPushMsgList.get(id);
1139fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgInfo == null || msgInfo.resend == false) {
1140fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    continue;
1141fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1142fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                sendMessage(msgInfo, msgBody);
1143fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } while (c.moveToNext());
1144fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            c.close();
1145fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
1146fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1147fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1148fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void failPendingMessages() {
1149fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* Move pending messages from outbox to failed */
1150fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
1151fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
1152fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            null);
1153fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1154fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        if (c != null && c.moveToFirst()) {
1155fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            do {
1156fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
1157fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
1158fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                PushMsgInfo msgInfo = mPushMsgList.get(id);
1159fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                if (msgInfo == null || msgInfo.resend == false) {
1160fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    continue;
1161fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                }
1162fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                Sms.moveMessageToFolder(mContext, msgInfo.uri,
1163fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                    Sms.MESSAGE_TYPE_FAILED, 0);
1164fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            } while (c.moveToNext());
1165fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
1166fac695e2dc25510b12684217d066b86dbbbba176Zhihai Xu        if (c != null) c.close();
1167fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1168fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1169fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private void removeDeletedMessages() {
1170fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        /* Remove messages from virtual "deleted" folder (thread_id -1) */
1171fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mResolver.delete(Uri.parse("content://sms/"),
1172fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                "thread_id = " + DELETED_THREAD_ID, null);
1173fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1174fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1175fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
1176fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        @Override
1177fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        public void onServiceStateChanged(ServiceState serviceState) {
1178fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            Log.d(TAG, "Phone service state change: " + serviceState.getState());
1179fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
1180fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie                resendPendingMessages();
1181fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie            }
1182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        }
1183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    };
1184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public void init() {
1186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mSmsBroadcastReceiver.register();
1187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        registerPhoneServiceStateListener();
1188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie
1190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    public void deinit() {
1191fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        mSmsBroadcastReceiver.unregister();
1192fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        unRegisterPhoneServiceStateListener();
1193fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        failPendingMessages();
1194fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie        removeDeletedMessages();
1195fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie    }
1196fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie}
1197