• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.mms.transaction;
19 
20 import com.android.mms.LogTag;
21 import com.android.mms.ui.MessagingPreferenceActivity;
22 import com.google.android.mms.MmsException;
23 import android.database.sqlite.SqliteWrapper;
24 
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.SharedPreferences;
28 import android.database.Cursor;
29 import android.database.sqlite.SQLiteException;
30 import android.net.Uri;
31 import android.preference.PreferenceManager;
32 import android.provider.Telephony.Sms;
33 import android.util.Log;
34 
35 public class SmsMessageSender implements MessageSender {
36     protected final Context mContext;
37     protected final int mNumberOfDests;
38     private final String[] mDests;
39     protected final String mMessageText;
40     protected final String mServiceCenter;
41     protected final long mThreadId;
42     protected long mTimestamp;
43     private static final String TAG = "SmsMessageSender";
44 
45     // Default preference values
46     private static final boolean DEFAULT_DELIVERY_REPORT_MODE  = false;
47 
48     private static final String[] SERVICE_CENTER_PROJECTION = new String[] {
49         Sms.Conversations.REPLY_PATH_PRESENT,
50         Sms.Conversations.SERVICE_CENTER,
51     };
52 
53     private static final int COLUMN_REPLY_PATH_PRESENT = 0;
54     private static final int COLUMN_SERVICE_CENTER     = 1;
55 
SmsMessageSender(Context context, String[] dests, String msgText, long threadId)56     public SmsMessageSender(Context context, String[] dests, String msgText, long threadId) {
57         mContext = context;
58         mMessageText = msgText;
59         if (dests != null) {
60             mNumberOfDests = dests.length;
61             mDests = new String[mNumberOfDests];
62             System.arraycopy(dests, 0, mDests, 0, mNumberOfDests);
63         } else {
64             mNumberOfDests = 0;
65             mDests = null;
66         }
67         mTimestamp = System.currentTimeMillis();
68         mThreadId = threadId;
69         mServiceCenter = getOutgoingServiceCenter(mThreadId);
70     }
71 
sendMessage(long token)72     public boolean sendMessage(long token) throws MmsException {
73         // In order to send the message one by one, instead of sending now, the message will split,
74         // and be put into the queue along with each destinations
75         return queueMessage(token);
76     }
77 
queueMessage(long token)78     private boolean queueMessage(long token) throws MmsException {
79         if ((mMessageText == null) || (mNumberOfDests == 0)) {
80             // Don't try to send an empty message.
81             throw new MmsException("Null message body or dest.");
82         }
83 
84         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
85         boolean requestDeliveryReport = prefs.getBoolean(
86                 MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE,
87                 DEFAULT_DELIVERY_REPORT_MODE);
88 
89         for (int i = 0; i < mNumberOfDests; i++) {
90             try {
91                 if (LogTag.DEBUG_SEND) {
92                     Log.v(TAG, "queueMessage mDests[i]: " + mDests[i] + " mThreadId: " + mThreadId);
93                 }
94                 Sms.addMessageToUri(mContext.getContentResolver(),
95                         Uri.parse("content://sms/queued"), mDests[i],
96                         mMessageText, null, mTimestamp,
97                         true /* read */,
98                         requestDeliveryReport,
99                         mThreadId);
100             } catch (SQLiteException e) {
101                 if (LogTag.DEBUG_SEND) {
102                     Log.e(TAG, "queueMessage SQLiteException", e);
103                 }
104                 SqliteWrapper.checkSQLiteException(mContext, e);
105             }
106         }
107         // Notify the SmsReceiverService to send the message out
108         mContext.sendBroadcast(new Intent(SmsReceiverService.ACTION_SEND_MESSAGE,
109                 null,
110                 mContext,
111                 SmsReceiver.class));
112         return false;
113     }
114 
115     /**
116      * Get the service center to use for a reply.
117      *
118      * The rule from TS 23.040 D.6 is that we send reply messages to
119      * the service center of the message to which we're replying, but
120      * only if we haven't already replied to that message and only if
121      * <code>TP-Reply-Path</code> was set in that message.
122      *
123      * Therefore, return the service center from the most recent
124      * message in the conversation, but only if it is a message from
125      * the other party, and only if <code>TP-Reply-Path</code> is set.
126      * Otherwise, return null.
127      */
getOutgoingServiceCenter(long threadId)128     private String getOutgoingServiceCenter(long threadId) {
129         Cursor cursor = null;
130 
131         try {
132             cursor = SqliteWrapper.query(mContext, mContext.getContentResolver(),
133                             Sms.CONTENT_URI, SERVICE_CENTER_PROJECTION,
134                             "thread_id = " + threadId, null, "date DESC");
135 
136             if ((cursor == null) || !cursor.moveToFirst()) {
137                 return null;
138             }
139 
140             boolean replyPathPresent = (1 == cursor.getInt(COLUMN_REPLY_PATH_PRESENT));
141             return replyPathPresent ? cursor.getString(COLUMN_SERVICE_CENTER) : null;
142         } finally {
143             if (cursor != null) {
144                 cursor.close();
145             }
146         }
147     }
148 
log(String msg)149     private void log(String msg) {
150         Log.d(LogTag.TAG, "[SmsMsgSender] " + msg);
151     }
152 }
153