PageRenderTime 109ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/android/mms/ui/DeliveryReportActivity.java

https://gitlab.com/mihai.v.chiorean/platform_packages_apps_mms
Java | 398 lines | 305 code | 54 blank | 39 comment | 54 complexity | e4bc9c2ebb5274b6b2762c370f3be689 MD5 | raw file
  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. package com.android.mms.ui;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Set;
  24. import android.app.ListActivity;
  25. import android.content.Intent;
  26. import android.database.Cursor;
  27. import android.database.sqlite.SqliteWrapper;
  28. import android.net.Uri;
  29. import android.os.Bundle;
  30. import android.provider.Telephony.Mms;
  31. import android.provider.Telephony.Sms;
  32. import android.telephony.PhoneNumberUtils;
  33. import android.text.TextUtils;
  34. import android.util.Log;
  35. import android.view.LayoutInflater;
  36. import android.view.View;
  37. import android.view.Window;
  38. import android.widget.ListView;
  39. import com.android.mms.LogTag;
  40. import com.android.mms.R;
  41. import com.google.android.mms.pdu.PduHeaders;
  42. /**
  43. * This is the UI for displaying a delivery report:
  44. *
  45. * This activity can handle the following parameters from the intent
  46. * by which it is launched:
  47. *
  48. * thread_id long The id of the conversation from which to get the recipients
  49. * for the report.
  50. * message_id long The id of the message about which a report should be displayed.
  51. * message_type String The type of message (Sms or Mms). This is used in
  52. * conjunction with the message id to retrive the particular message that
  53. * the report will be about.
  54. */
  55. public class DeliveryReportActivity extends ListActivity {
  56. private static final String LOG_TAG = LogTag.TAG;
  57. static final String[] MMS_REPORT_REQUEST_PROJECTION = new String[] {
  58. Mms.Addr.ADDRESS, //0
  59. Mms.DELIVERY_REPORT, //1
  60. Mms.READ_REPORT //2
  61. };
  62. static final String[] MMS_REPORT_STATUS_PROJECTION = new String[] {
  63. Mms.Addr.ADDRESS, //0
  64. "delivery_status", //1
  65. "read_status" //2
  66. };
  67. static final String[] SMS_REPORT_STATUS_PROJECTION = new String[] {
  68. Sms.ADDRESS, //0
  69. Sms.STATUS, //1
  70. Sms.DATE_SENT, //2
  71. Sms.TYPE //3
  72. };
  73. // These indices must sync up with the projections above.
  74. static final int COLUMN_RECIPIENT = 0;
  75. static final int COLUMN_DELIVERY_REPORT = 1;
  76. static final int COLUMN_READ_REPORT = 2;
  77. static final int COLUMN_DELIVERY_STATUS = 1;
  78. static final int COLUMN_READ_STATUS = 2;
  79. static final int COLUMN_DATE_SENT = 2;
  80. static final int COLUMN_MESSAGE_TYPE = 3;
  81. private long mMessageId;
  82. private String mMessageType;
  83. @Override
  84. protected void onCreate(Bundle icicle) {
  85. super.onCreate(icicle);
  86. requestWindowFeature(Window.FEATURE_NO_TITLE);
  87. setContentView(R.layout.delivery_report_activity);
  88. Intent intent = getIntent();
  89. mMessageId = getMessageId(icicle, intent);
  90. mMessageType = getMessageType(icicle, intent);
  91. initListView();
  92. initListAdapter();
  93. }
  94. private void initListView() {
  95. // Add the header for the list view.
  96. LayoutInflater inflater = getLayoutInflater();
  97. View header = inflater.inflate(R.layout.delivery_report_header, null);
  98. getListView().addHeaderView(header, null, true);
  99. }
  100. private void initListAdapter() {
  101. List<DeliveryReportItem> items = getReportItems();
  102. if (items == null) {
  103. items = new ArrayList<DeliveryReportItem>(1);
  104. items.add(new DeliveryReportItem("", getString(R.string.status_none), null));
  105. Log.w(LOG_TAG, "cursor == null");
  106. }
  107. setListAdapter(new DeliveryReportAdapter(this, items));
  108. }
  109. @Override
  110. public void onResume() {
  111. super.onResume();
  112. refreshDeliveryReport();
  113. }
  114. private void refreshDeliveryReport() {
  115. ListView list = getListView();
  116. list.invalidateViews();
  117. list.requestFocus();
  118. }
  119. private long getMessageId(Bundle icicle, Intent intent) {
  120. long msgId = 0L;
  121. if (icicle != null) {
  122. msgId = icicle.getLong("message_id");
  123. }
  124. if (msgId == 0L) {
  125. msgId = intent.getLongExtra("message_id", 0L);
  126. }
  127. return msgId;
  128. }
  129. private String getMessageType(Bundle icicle, Intent intent) {
  130. String msgType = null;
  131. if (icicle != null) {
  132. msgType = icicle.getString("message_type");
  133. }
  134. if (msgType == null) {
  135. msgType = intent.getStringExtra("message_type");
  136. }
  137. return msgType;
  138. }
  139. private List<DeliveryReportItem> getReportItems() {
  140. if (mMessageType.equals("sms")) {
  141. return getSmsReportItems();
  142. } else {
  143. return getMmsReportItems();
  144. }
  145. }
  146. private List<DeliveryReportItem> getSmsReportItems() {
  147. String selection = "_id = " + mMessageId;
  148. Cursor c = SqliteWrapper.query(this, getContentResolver(), Sms.CONTENT_URI,
  149. SMS_REPORT_STATUS_PROJECTION, selection, null, null);
  150. if (c == null) {
  151. return null;
  152. }
  153. try {
  154. if (c.getCount() <= 0) {
  155. return null;
  156. }
  157. List<DeliveryReportItem> items = new ArrayList<DeliveryReportItem>();
  158. while (c.moveToNext()) {
  159. // For sent messages with delivery reports, we stick the delivery time in the
  160. // date_sent column (see MessageStatusReceiver).
  161. String deliveryDateString = null;
  162. long deliveryDate = c.getLong(COLUMN_DATE_SENT);
  163. int messageType = c.getInt(COLUMN_MESSAGE_TYPE);
  164. if (messageType == Sms.MESSAGE_TYPE_SENT && deliveryDate > 0) {
  165. deliveryDateString = getString(R.string.delivered_label) +
  166. MessageUtils.formatTimeStampString(this,
  167. deliveryDate, true);
  168. }
  169. items.add(new DeliveryReportItem(
  170. getString(R.string.recipient_label) + c.getString(COLUMN_RECIPIENT),
  171. getString(R.string.status_label) +
  172. getSmsStatusText(c.getInt(COLUMN_DELIVERY_STATUS)),
  173. deliveryDateString));
  174. }
  175. return items;
  176. } finally {
  177. c.close();
  178. }
  179. }
  180. private String getMmsReportStatusText(
  181. MmsReportRequest request,
  182. Map<String, MmsReportStatus> reportStatus) {
  183. if (reportStatus == null) {
  184. // haven't received any reports.
  185. return getString(R.string.status_pending);
  186. }
  187. String recipient = request.getRecipient();
  188. recipient = (Mms.isEmailAddress(recipient))?
  189. Mms.extractAddrSpec(recipient): PhoneNumberUtils.stripSeparators(recipient);
  190. MmsReportStatus status = queryStatusByRecipient(reportStatus, recipient);
  191. if (status == null) {
  192. // haven't received any reports.
  193. return getString(R.string.status_pending);
  194. }
  195. if (request.isReadReportRequested()) {
  196. if (status.readStatus != 0) {
  197. switch (status.readStatus) {
  198. case PduHeaders.READ_STATUS_READ:
  199. return getString(R.string.status_read);
  200. case PduHeaders.READ_STATUS__DELETED_WITHOUT_BEING_READ:
  201. return getString(R.string.status_unread);
  202. }
  203. }
  204. }
  205. switch (status.deliveryStatus) {
  206. case 0: // No delivery report received so far.
  207. return getString(R.string.status_pending);
  208. case PduHeaders.STATUS_FORWARDED:
  209. case PduHeaders.STATUS_RETRIEVED:
  210. return getString(R.string.status_received);
  211. case PduHeaders.STATUS_REJECTED:
  212. return getString(R.string.status_rejected);
  213. default:
  214. return getString(R.string.status_failed);
  215. }
  216. }
  217. private static MmsReportStatus queryStatusByRecipient(
  218. Map<String, MmsReportStatus> status, String recipient) {
  219. Set<String> recipientSet = status.keySet();
  220. Iterator<String> iterator = recipientSet.iterator();
  221. while (iterator.hasNext()) {
  222. String r = iterator.next();
  223. if (Mms.isEmailAddress(recipient)) {
  224. if (TextUtils.equals(r, recipient)) {
  225. return status.get(r);
  226. }
  227. }
  228. else if (PhoneNumberUtils.compare(r, recipient)) {
  229. return status.get(r);
  230. }
  231. }
  232. return null;
  233. }
  234. private List<DeliveryReportItem> getMmsReportItems() {
  235. List<MmsReportRequest> reportReqs = getMmsReportRequests();
  236. if (null == reportReqs) {
  237. return null;
  238. }
  239. if (reportReqs.size() == 0) {
  240. return null;
  241. }
  242. Map<String, MmsReportStatus> reportStatus = getMmsReportStatus();
  243. List<DeliveryReportItem> items = new ArrayList<DeliveryReportItem>();
  244. for (MmsReportRequest reportReq : reportReqs) {
  245. String statusText = getString(R.string.status_label) +
  246. getMmsReportStatusText(reportReq, reportStatus);
  247. items.add(new DeliveryReportItem(getString(R.string.recipient_label) +
  248. reportReq.getRecipient(), statusText, null));
  249. }
  250. return items;
  251. }
  252. private Map<String, MmsReportStatus> getMmsReportStatus() {
  253. Uri uri = Uri.withAppendedPath(Mms.REPORT_STATUS_URI,
  254. String.valueOf(mMessageId));
  255. Cursor c = SqliteWrapper.query(this, getContentResolver(), uri,
  256. MMS_REPORT_STATUS_PROJECTION, null, null, null);
  257. if (c == null) {
  258. return null;
  259. }
  260. try {
  261. Map<String, MmsReportStatus> statusMap =
  262. new HashMap<String, MmsReportStatus>();
  263. while (c.moveToNext()) {
  264. String recipient = c.getString(COLUMN_RECIPIENT);
  265. recipient = (Mms.isEmailAddress(recipient))?
  266. Mms.extractAddrSpec(recipient):
  267. PhoneNumberUtils.stripSeparators(recipient);
  268. MmsReportStatus status = new MmsReportStatus(
  269. c.getInt(COLUMN_DELIVERY_STATUS),
  270. c.getInt(COLUMN_READ_STATUS));
  271. statusMap.put(recipient, status);
  272. }
  273. return statusMap;
  274. } finally {
  275. c.close();
  276. }
  277. }
  278. private List<MmsReportRequest> getMmsReportRequests() {
  279. Uri uri = Uri.withAppendedPath(Mms.REPORT_REQUEST_URI,
  280. String.valueOf(mMessageId));
  281. Cursor c = SqliteWrapper.query(this, getContentResolver(), uri,
  282. MMS_REPORT_REQUEST_PROJECTION, null, null, null);
  283. if (c == null) {
  284. return null;
  285. }
  286. try {
  287. if (c.getCount() <= 0) {
  288. return null;
  289. }
  290. List<MmsReportRequest> reqList = new ArrayList<MmsReportRequest>();
  291. while (c.moveToNext()) {
  292. reqList.add(new MmsReportRequest(
  293. c.getString(COLUMN_RECIPIENT),
  294. c.getInt(COLUMN_DELIVERY_REPORT),
  295. c.getInt(COLUMN_READ_REPORT)));
  296. }
  297. return reqList;
  298. } finally {
  299. c.close();
  300. }
  301. }
  302. private String getSmsStatusText(int status) {
  303. if (status == Sms.STATUS_NONE) {
  304. // No delivery report requested
  305. return getString(R.string.status_none);
  306. } else if (status >= Sms.STATUS_FAILED) {
  307. // Failure
  308. return getString(R.string.status_failed);
  309. } else if (status >= Sms.STATUS_PENDING) {
  310. // Pending
  311. return getString(R.string.status_pending);
  312. } else {
  313. // Success
  314. return getString(R.string.status_received);
  315. }
  316. }
  317. private static final class MmsReportStatus {
  318. final int deliveryStatus;
  319. final int readStatus;
  320. public MmsReportStatus(int drStatus, int rrStatus) {
  321. deliveryStatus = drStatus;
  322. readStatus = rrStatus;
  323. }
  324. }
  325. private static final class MmsReportRequest {
  326. private final String mRecipient;
  327. private final boolean mIsDeliveryReportRequsted;
  328. private final boolean mIsReadReportRequested;
  329. public MmsReportRequest(String recipient, int drValue, int rrValue) {
  330. mRecipient = recipient;
  331. mIsDeliveryReportRequsted = drValue == PduHeaders.VALUE_YES;
  332. mIsReadReportRequested = rrValue == PduHeaders.VALUE_YES;
  333. }
  334. public String getRecipient() {
  335. return mRecipient;
  336. }
  337. public boolean isDeliveryReportRequested() {
  338. return mIsDeliveryReportRequsted;
  339. }
  340. public boolean isReadReportRequested() {
  341. return mIsReadReportRequested;
  342. }
  343. }
  344. }