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