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