MessageUtils.java revision 1009d4bf5ee9fd1f2523e530828de5babb78eb19
172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.ui;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20bb8edcae15a50b3651261db70791afc668aae294Tom Taylorimport com.android.mms.MmsApp;
2186a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylorimport com.android.mms.MmsConfig;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R;
23812391ad832f3fdac054ad3a50af563da16e99b5Wei Huangimport com.android.mms.LogTag;
24b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrickimport com.android.mms.data.WorkingMessage;
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.MediaModel;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.SlideModel;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.SlideshowModel;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.transaction.MmsMessageSender;
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.AddressUtils;
30f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.ContentType;
31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException;
32f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.CharacterSets;
33f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.EncodedStringValue;
34f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.MultimediaMessagePdu;
35f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.NotificationInd;
36f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduBody;
37f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders;
38f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPart;
39f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
40f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.RetrieveConf;
41f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.SendReq;
42fd644551e8506266aad2b76463b51b44154ed62fTom Taylorimport android.database.sqlite.SqliteWrapper;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlertDialog;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnClickListener;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.res.Resources;
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
5415057746d75afb5fec583f30064b382c18403608Tom Taylorimport android.media.CamcorderProfile;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.media.RingtoneManager;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
57ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylorimport android.os.Environment;
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler;
5915057746d75afb5fec583f30064b382c18403608Tom Taylorimport android.provider.MediaStore;
60f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms;
61f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms;
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.PhoneNumberUtils;
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.DateUtils;
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.Time;
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.URLSpan;
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
681224b6560c48e146ee304f9c807296f6c22cdefbTom Taylorimport android.widget.Toast;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
709242286c35743422051d439d7460cd0a1426899cWei Huangimport java.io.IOException;
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.HashMap;
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Map;
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.concurrent.ConcurrentHashMap;
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * An utility class for managing messages.
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessageUtils {
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    interface ResizeImageResultCallback {
81edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        void onResizeResult(PduPart part, boolean append);
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
849242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = LogTag.TAG;
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String sLocalNumber;
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Cache of both groups of space-separated ids to their full
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // comma-separated display names, as well as individual ids to
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // display names.
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // TODO: is it possible for canonical address ID keys to be
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // re-used?  SQLite does reuse IDs on NULL id_ insert, but does
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // anything ever delete from the mmssms.db canonical_addresses
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // table?  Nothing that I could find.
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final Map<String, String> sRecipientAddress =
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            new ConcurrentHashMap<String, String>(20 /* initial capacity */);
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9778f81825431c8c52cad57bc4a363747533a701abWei Huang
9878f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
9978f81825431c8c52cad57bc4a363747533a701abWei Huang     * MMS address parsing data structures
10078f81825431c8c52cad57bc4a363747533a701abWei Huang     */
10178f81825431c8c52cad57bc4a363747533a701abWei Huang    // allowable phone number separators
10278f81825431c8c52cad57bc4a363747533a701abWei Huang    private static final char[] NUMERIC_CHARS_SUGAR = {
10378f81825431c8c52cad57bc4a363747533a701abWei Huang        '-', '.', ',', '(', ')', ' ', '/', '\\', '*', '#', '+'
10478f81825431c8c52cad57bc4a363747533a701abWei Huang    };
10578f81825431c8c52cad57bc4a363747533a701abWei Huang
10678f81825431c8c52cad57bc4a363747533a701abWei Huang    private static HashMap numericSugarMap = new HashMap (NUMERIC_CHARS_SUGAR.length);
10778f81825431c8c52cad57bc4a363747533a701abWei Huang
10878f81825431c8c52cad57bc4a363747533a701abWei Huang    static {
10978f81825431c8c52cad57bc4a363747533a701abWei Huang        for (int i = 0; i < NUMERIC_CHARS_SUGAR.length; i++) {
11078f81825431c8c52cad57bc4a363747533a701abWei Huang            numericSugarMap.put(NUMERIC_CHARS_SUGAR[i], NUMERIC_CHARS_SUGAR[i]);
11178f81825431c8c52cad57bc4a363747533a701abWei Huang        }
11278f81825431c8c52cad57bc4a363747533a701abWei Huang    }
11378f81825431c8c52cad57bc4a363747533a701abWei Huang
11478f81825431c8c52cad57bc4a363747533a701abWei Huang
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private MessageUtils() {
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Forbidden being instantiated.
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String getMessageDetails(Context context, Cursor cursor, int size) {
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor == null) {
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return null;
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ("mms".equals(cursor.getString(MessageListAdapter.COLUMN_MSG_TYPE))) {
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (type) {
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return getNotificationIndDetails(context, cursor);
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_SEND_REQ:
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return getMultimediaMessageDetails(context, cursor, size);
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                default:
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "No details could be retrieved.");
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return "";
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return getTextMessageDetails(context, cursor);
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getNotificationIndDetails(Context context, Cursor cursor) {
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NotificationInd nInd;
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            nInd = (NotificationInd) PduPersister.getPduPersister(
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context).load(uri);
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Failed to load the message: " + uri, e);
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return context.getResources().getString(R.string.cannot_get_details);
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Mms Notification.
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.multimedia_notification));
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // From: ***
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String from = extractEncStr(context, nInd.getFrom());
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.from_label));
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(!TextUtils.isEmpty(from)? from:
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                 res.getString(R.string.hidden_sender_address));
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                R.string.expire_on,
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                MessageUtils.formatTimeStampString(
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                        context, nInd.getExpiry() * 1000L, true)));
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Subject: ***
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.subject_label));
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue subject = nInd.getSubject();
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (subject != null) {
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(subject.getString());
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message class: Personal/Advertisement/Infomational/Auto
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_class_label));
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(new String(nInd.getMessageClass()));
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message size: *** KB
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_size_label));
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(String.valueOf((nInd.getMessageSize() + 1023) / 1024));
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(context.getString(R.string.kilobyte));
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getMultimediaMessageDetails(
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, Cursor cursor, int size) {
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (type == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return getNotificationIndDetails(context, cursor);
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MultimediaMessagePdu msg;
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            msg = (MultimediaMessagePdu) PduPersister.getPduPersister(
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context).load(uri);
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Failed to load the message: " + uri, e);
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return context.getResources().getString(R.string.cannot_get_details);
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Text message.
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.multimedia_message));
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msg instanceof RetrieveConf) {
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // From: ***
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String from = extractEncStr(context, ((RetrieveConf) msg).getFrom());
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append('\n');
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.from_label));
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(!TextUtils.isEmpty(from)? from:
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                  res.getString(R.string.hidden_sender_address));
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // To: ***
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.to_address_label));
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue[] to = msg.getTo();
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (to != null) {
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(EncodedStringValue.concat(to));
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        else {
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.w(TAG, "recipient list is empty!");
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
2439c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Bcc: ***
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msg instanceof SendReq) {
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            EncodedStringValue[] values = ((SendReq) msg).getBcc();
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ((values != null) && (values.length > 0)) {
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append('\n');
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append(res.getString(R.string.bcc_label));
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append(EncodedStringValue.concat(values));
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgBox = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_BOX);
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msgBox == Mms.MESSAGE_BOX_DRAFTS) {
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.saved_label));
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (msgBox == Mms.MESSAGE_BOX_INBOX) {
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.received_label));
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.sent_label));
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(MessageUtils.formatTimeStampString(
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                context, msg.getDate() * 1000L, true));
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Subject: ***
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.subject_label));
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue subject = msg.getSubject();
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (subject != null) {
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String subStr = subject.getString();
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Message size should include size of subject.
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            size += subStr.length();
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(subStr);
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Priority: High/Normal/Low
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.priority_label));
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(getPriorityDescription(context, msg.getPriority()));
28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message size: *** KB
28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_size_label));
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append((size - 1)/1000 + 1);
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(" KB");
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getTextMessageDetails(Context context, Cursor cursor) {
296b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        Log.d(TAG, "getTextMessageDetails");
297b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor
29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Text message.
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.text_message));
30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Address: ***
30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int smsType = cursor.getInt(MessageListAdapter.COLUMN_SMS_TYPE);
30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (Sms.isOutgoingFolder(smsType)) {
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.to_address_label));
31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.from_label));
31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(cursor.getString(MessageListAdapter.COLUMN_SMS_ADDRESS));
31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31554711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        // Sent: ***
31654711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        if (smsType == Sms.MESSAGE_TYPE_INBOX) {
31754711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert            long date_sent = cursor.getLong(MessageListAdapter.COLUMN_SMS_DATE_SENT);
31854711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert            if (date_sent > 0) {
31954711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert                details.append('\n');
32054711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert                details.append(res.getString(R.string.sent_label));
32154711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert                details.append(MessageUtils.formatTimeStampString(context, date_sent, true));
32254711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert            }
32354711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        }
32454711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert
32554711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        // Received: ***
32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (smsType == Sms.MESSAGE_TYPE_DRAFT) {
32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.saved_label));
32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (smsType == Sms.MESSAGE_TYPE_INBOX) {
33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.received_label));
33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.sent_label));
33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long date = cursor.getLong(MessageListAdapter.COLUMN_SMS_DATE);
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(MessageUtils.formatTimeStampString(context, date, true));
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
338161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        // Error code: ***
339161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        int errorCode = cursor.getInt(MessageListAdapter.COLUMN_SMS_ERROR_CODE);
340161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        if (errorCode != 0) {
341161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor            details.append('\n')
342161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor                .append(res.getString(R.string.error_code_label))
343161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor                .append(errorCode);
344161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        }
345161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor
34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    static private String getPriorityDescription(Context context, int PriorityValue) {
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch(PriorityValue) {
35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_HIGH:
35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_high);
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_LOW:
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_low);
35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_NORMAL:
35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            default:
35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_normal);
35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static int getAttachmentType(SlideshowModel model) {
36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (model == null) {
364b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return WorkingMessage.TEXT;
36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int numberOfSlides = model.size();
36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (numberOfSlides > 1) {
369b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return WorkingMessage.SLIDESHOW;
37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (numberOfSlides == 1) {
37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Only one slide in the slide-show.
37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = model.get(0);
37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasVideo()) {
374b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.VIDEO;
37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasAudio() && slide.hasImage()) {
378b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.SLIDESHOW;
37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasAudio()) {
382b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.AUDIO;
38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasImage()) {
386b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.IMAGE;
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasText()) {
390b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.TEXT;
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
394b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        return WorkingMessage.TEXT;
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
3969c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String formatTimeStampString(Context context, long when) {
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return formatTimeStampString(context, when, false);
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String formatTimeStampString(Context context, long when, boolean fullFormat) {
40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Time then = new Time();
40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        then.set(when);
40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Time now = new Time();
40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        now.setToNow();
40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Basic settings for formatDateTime() we want for all cases.
40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int format_flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT |
40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                           DateUtils.FORMAT_ABBREV_ALL |
41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                           DateUtils.FORMAT_CAP_AMPM;
411836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project
41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If the message is from a different year, show the date and year.
41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (then.year != now.year) {
41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (then.yearDay != now.yearDay) {
41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // If it is from a different day than today, show only the date.
41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_DATE;
41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Otherwise, if the message is from today, show the time.
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_TIME;
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
423836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // If the caller has asked for full details, make sure to show the date
424836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // and time no matter what we've determined above (but still make showing
425836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // the year only happen if it is a different year from today).
426836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        if (fullFormat) {
427836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            format_flags |= (DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
428836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        }
429836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return DateUtils.formatDateTime(context, when, format_flags);
43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectAudio(Context context, int requestCode) {
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (context instanceof Activity) {
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
4385c0aff95e0c161d22fad145fe344430fd3474bc1Dave Sparks            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_INCLUDE_DRM, false);
4399c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context.getString(R.string.select_audio));
44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(intent, requestCode);
44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44515057746d75afb5fec583f30064b382c18403608Tom Taylor    public static void recordSound(Context context, int requestCode, long sizeLimit) {
44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (context instanceof Activity) {
44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.setType(ContentType.AUDIO_AMR);
44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.setClassName("com.android.soundrecorder",
45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "com.android.soundrecorder.SoundRecorder");
45115057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra(android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES, sizeLimit);
45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(intent, requestCode);
45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
45715057746d75afb5fec583f30064b382c18403608Tom Taylor    public static void recordVideo(Context context, int requestCode, long sizeLimit) {
45815057746d75afb5fec583f30064b382c18403608Tom Taylor        if (context instanceof Activity) {
45915057746d75afb5fec583f30064b382c18403608Tom Taylor            int durationLimit = getVideoCaptureDurationLimit();
46015057746d75afb5fec583f30064b382c18403608Tom Taylor            Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
46115057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
46215057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra("android.intent.extra.sizeLimit", sizeLimit);
46315057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra("android.intent.extra.durationLimit", durationLimit);
46415057746d75afb5fec583f30064b382c18403608Tom Taylor
46515057746d75afb5fec583f30064b382c18403608Tom Taylor            ((Activity) context).startActivityForResult(intent, requestCode);
46615057746d75afb5fec583f30064b382c18403608Tom Taylor        }
46715057746d75afb5fec583f30064b382c18403608Tom Taylor    }
46815057746d75afb5fec583f30064b382c18403608Tom Taylor
46915057746d75afb5fec583f30064b382c18403608Tom Taylor    private static int getVideoCaptureDurationLimit() {
4707a0d891850d3a57c6358f1a2c8798f4f84a47e7cTom Taylor        CamcorderProfile camcorder = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
4717a0d891850d3a57c6358f1a2c8798f4f84a47e7cTom Taylor        return camcorder == null ? 0 : camcorder.duration;
47215057746d75afb5fec583f30064b382c18403608Tom Taylor    }
47315057746d75afb5fec583f30064b382c18403608Tom Taylor
47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectVideo(Context context, int requestCode) {
47502277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor        selectMediaByType(context, requestCode, ContentType.VIDEO_UNSPECIFIED, true);
47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectImage(Context context, int requestCode) {
47902277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor        selectMediaByType(context, requestCode, ContentType.IMAGE_UNSPECIFIED, false);
48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static void selectMediaByType(
48302277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor            Context context, int requestCode, String contentType, boolean localFilesOnly) {
48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project         if (context instanceof Activity) {
48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT);
48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            innerIntent.setType(contentType);
48902277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor            if (localFilesOnly) {
49002277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor                innerIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
49102277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor            }
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent wrapperIntent = Intent.createChooser(innerIntent, null);
49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(wrapperIntent, requestCode);
49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void viewSimpleSlideshow(Context context, SlideshowModel slideshow) {
50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!slideshow.isSimple()) {
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new IllegalArgumentException(
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "viewSimpleSlideshow() called on a non-simple slideshow");
50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = slideshow.get(0);
50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MediaModel mm = null;
50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide.hasImage()) {
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mm = slide.getImage();
50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (slide.hasVideo()) {
50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mm = slide.getVideo();
51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
5119c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW);
51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
5149c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
5159c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        String contentType;
5169c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        if (mm.isDrmProtected()) {
5179c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            contentType = mm.getDrmObject().getContentType();
5189c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        } else {
5199c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            contentType = mm.getContentType();
5209c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        }
5219c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        intent.setDataAndType(mm.getUri(), contentType);
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        context.startActivity(intent);
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
5249c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void showErrorDialog(Context context,
52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String title, String message) {
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(context);
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setIcon(R.drawable.ic_sms_mms_not_delivered);
53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(title);
53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setMessage(message);
53293b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor        builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
5331009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
53493b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor            public void onClick(DialogInterface dialog, int which) {
53593b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor                if (which == DialogInterface.BUTTON_POSITIVE) {
53693b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor                    dialog.dismiss();
53793b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor                }
53893b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor            }
53993b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor        });
54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
543bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project    /**
544bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project     * The quality parameter which is used to compress JPEG images.
545bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project     */
5468c86a52a2c13083a25761256ab0dfc416260c162Tom Taylor    public static final int IMAGE_COMPRESSION_QUALITY = 95;
5479242286c35743422051d439d7460cd0a1426899cWei Huang    /**
5489242286c35743422051d439d7460cd0a1426899cWei Huang     * The minimum quality parameter which is used to compress JPEG images.
5499242286c35743422051d439d7460cd0a1426899cWei Huang     */
5509242286c35743422051d439d7460cd0a1426899cWei Huang    public static final int MINIMUM_IMAGE_COMPRESSION_QUALITY = 50;
551bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project
552f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson    /**
553f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * Message overhead that reduces the maximum image byte size.
554f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * 5000 is a realistic overhead number that allows for user to also include
555f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * a small MIDI file or a couple pages of text along with the picture.
556f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     */
557f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson    public static final int MESSAGE_OVERHEAD = 5000;
558f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson
55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void resizeImageAsync(final Context context,
56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final Uri imageUri, final Handler handler,
561edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            final ResizeImageResultCallback cb,
562edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            final boolean append) {
56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5641224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor        // Show a progress toast if the resize hasn't finished
56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // within one second.
56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Stash the runnable for showing it away so we can cancel
56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // it later if the resize completes ahead of the deadline.
56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Runnable showProgress = new Runnable() {
5691009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
5711224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                Toast.makeText(context, R.string.compressing, Toast.LENGTH_SHORT).show();
57272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
57372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Schedule it for one second from now.
57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        handler.postDelayed(showProgress, 1000);
5769c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new Thread(new Runnable() {
5781009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                final PduPart part;
58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    UriImage image = new UriImage(context, imageUri);
5831009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    int widthLimit = MmsConfig.getMaxImageWidth();
5841009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    int heightLimit = MmsConfig.getMaxImageHeight();
5851009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    // In mms_config.xml, the max width has always been declared larger than the max
5861009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    // height. Swap the width and height limits if necessary so we scale the picture
5871009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    // as little as possible.
5881009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    if (image.getHeight() > image.getWidth()) {
5891009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        int temp = widthLimit;
5901009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        widthLimit = heightLimit;
5911009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        heightLimit = temp;
5921009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    }
5931009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev
59472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part = image.getResizedImageAsPart(
5951009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        widthLimit,
5961009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        heightLimit,
597f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson                        MmsConfig.getMaxMessageSize() - MESSAGE_OVERHEAD);
59872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } finally {
5991224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                    // Cancel pending show of the progress toast if necessary.
60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    handler.removeCallbacks(showProgress);
60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                handler.post(new Runnable() {
6041009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    @Override
60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    public void run() {
606edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                        cb.onResizeResult(part, append);
60772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                });
60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
61072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }).start();
61172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void showDiscardDraftConfirmDialog(Context context,
61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnClickListener listener) {
61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new AlertDialog.Builder(context)
61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setTitle(R.string.discard_message)
61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setMessage(R.string.discard_message_reason)
61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setPositiveButton(R.string.yes, listener)
62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setNegativeButton(R.string.no, null)
62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .show();
62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
62413dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang    public static String getLocalNumber() {
62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null == sLocalNumber) {
626bb8edcae15a50b3651261db70791afc668aae294Tom Taylor            sLocalNumber = MmsApp.getApplication().getTelephonyManager().getLine1Number();
62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return sLocalNumber;
62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static boolean isLocalNumber(String number) {
632f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        if (number == null) {
633f1bf432304bcc277397b028192eaf01a94c6417dWei Huang            return false;
634f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        }
635f1bf432304bcc277397b028192eaf01a94c6417dWei Huang
636f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // we don't use Mms.isEmailAddress() because it is too strict for comparing addresses like
637f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // "foo+caf_=6505551212=tmomail.net@gmail.com", which is the 'from' address from a forwarded email
638f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // message from Gmail. We don't want to treat "foo+caf_=6505551212=tmomail.net@gmail.com" and
639f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // "6505551212" to be the same.
640f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        if (number.indexOf('@') >= 0) {
641b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang            return false;
642b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang        }
643b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang
64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return PhoneNumberUtils.compare(number, getLocalNumber());
64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
64672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
64772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void handleReadReport(final Context context,
648b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            final ArrayList<Long> threadIds,
64972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final int status,
65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final Runnable callback) {
651b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor        StringBuilder selectionBuilder = new StringBuilder(Mms.MESSAGE_TYPE + " = "
652b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF
653b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                + " AND " + Mms.READ + " = 0"
654b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                + " AND " + Mms.READ_REPORT + " = " + PduHeaders.VALUE_YES);
655b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor
656b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor        String[] selectionArgs = null;
657b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor        if (threadIds != null) {
658b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            String threadIdSelection = null;
659b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            StringBuilder buf = new StringBuilder();
660b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            selectionArgs = new String[threadIds.size()];
661b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            int i = 0;
662b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor
663b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            for (long threadId : threadIds) {
664b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                if (i > 0) {
665b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                    buf.append(" OR ");
666b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                }
667b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                buf.append(Mms.THREAD_ID).append("=?");
668b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                selectionArgs[i++] = Long.toString(threadId);
669b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            }
670b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            threadIdSelection = buf.toString();
67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
672b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            selectionBuilder.append(" AND (" + threadIdSelection + ")");
67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Mms.Inbox.CONTENT_URI, new String[] {Mms._ID, Mms.MESSAGE_ID},
677b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                        selectionBuilder.toString(), selectionArgs, null);
67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
67972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (c == null) {
68072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
68172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
68272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
68372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Map<String, String> map = new HashMap<String, String>();
68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (c.getCount() == 0) {
68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
68772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return;
69072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            while (c.moveToNext()) {
69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, c.getLong(0));
69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                map.put(c.getString(1), AddressUtils.getFrom(context, uri));
69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } finally {
69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            c.close();
69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnClickListener positiveListener = new OnClickListener() {
7011009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (final Map.Entry<String, String> entry : map.entrySet()) {
70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MmsMessageSender.sendReadRec(context, entry.getValue(),
70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                                 entry.getKey(), status);
70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
70772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
711c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor                dialog.dismiss();
71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnClickListener negativeListener = new OnClickListener() {
7161009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
721c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor                dialog.dismiss();
72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnCancelListener cancelListener = new OnCancelListener() {
7261009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onCancel(DialogInterface dialog) {
72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
731c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor                dialog.dismiss();
73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        confirmReadReportDialog(context, positiveListener,
73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                         negativeListener,
73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                         cancelListener);
73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
73972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static void confirmReadReportDialog(Context context,
74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnClickListener positiveListener, OnClickListener negativeListener,
74272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnCancelListener cancelListener) {
74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(context);
74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setCancelable(true);
74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(R.string.confirm);
74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setMessage(R.string.message_send_read_report);
74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setPositiveButton(R.string.yes, positiveListener);
74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setNegativeButton(R.string.no, negativeListener);
74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setOnCancelListener(cancelListener);
75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String extractEncStrFromCursor(Cursor cursor,
75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int columnRawBytes, int columnCharset) {
75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String rawBytes = cursor.getString(columnRawBytes);
75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int charset = cursor.getInt(columnCharset);
75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (TextUtils.isEmpty(rawBytes)) {
75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return "";
76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (charset == CharacterSets.ANY_CHARSET) {
76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return rawBytes;
76272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
76372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return new EncodedStringValue(charset, PduPersister.getBytes(rawBytes)).getString();
76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String extractEncStr(Context context, EncodedStringValue value) {
76872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (value != null) {
76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return value.getString();
77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return "";
77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
7749c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static ArrayList<String> extractUris(URLSpan[] spans) {
77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int size = spans.length;
77772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<String> accumulator = new ArrayList<String>();
77872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
77972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < size; i++) {
78072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            accumulator.add(spans[i].getURL());
78172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
78272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return accumulator;
78372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
78472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7854522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    /**
7864522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * Play/view the message attachments.
7874522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * TOOD: We need to save the draft before launching another activity to view the attachments.
7884522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       This is hacky though since we will do saveDraft twice and slow down the UI.
7894522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       We should pass the slideshow in intent extra to the view activity instead of
7904522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       asking it to read attachments from database.
7914522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param context
7924522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param msgUri the MMS message URI in database
7934522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param slideshow the slideshow to save
7944522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param persister the PDU persister for updating the database
7954522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param sendReq the SendReq for updating the database
7964522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     */
7974522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    public static void viewMmsMessageAttachment(Context context, Uri msgUri,
798b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            SlideshowModel slideshow) {
7994522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        boolean isSimple = (slideshow == null) ? false : slideshow.isSimple();
8004522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        if (isSimple) {
8014522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            // In attachment-editor mode, we only ever have one slide.
8024522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            MessageUtils.viewSimpleSlideshow(context, slideshow);
8034522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        } else {
804b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            // If a slideshow was provided, save it to disk first.
805b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            if (slideshow != null) {
806b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                PduPersister persister = PduPersister.getPduPersister(context);
807b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                try {
808b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    PduBody pb = slideshow.toPduBody();
809b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    persister.updateParts(msgUri, pb);
810b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    slideshow.sync(pb);
811b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                } catch (MmsException e) {
812b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    Log.e(TAG, "Unable to save message for preview");
813b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    return;
814b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                }
8154522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            }
8164522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            // Launch the slideshow activity to play/view.
8174522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            Intent intent = new Intent(context, SlideshowActivity.class);
8184522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            intent.setData(msgUri);
8194522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            context.startActivity(intent);
8204522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        }
8214522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    }
8229c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
823b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    public static void viewMmsMessageAttachment(Context context, WorkingMessage msg) {
824b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        SlideshowModel slideshow = msg.getSlideshow();
825b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (slideshow == null) {
826b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            throw new IllegalStateException("msg.getSlideshow() == null");
827b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
828b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (slideshow.isSimple()) {
829b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            MessageUtils.viewSimpleSlideshow(context, slideshow);
830b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        } else {
83116f98e62c279550854e665e25c212ea0b04a6b6bTom Taylor            Uri uri = msg.saveAsMms(false);
8323877692b0f782ca321ce3a857b4168f771cf2ab6Tom Taylor            if (uri != null) {
8333877692b0f782ca321ce3a857b4168f771cf2ab6Tom Taylor                viewMmsMessageAttachment(context, uri, slideshow);
8343877692b0f782ca321ce3a857b4168f771cf2ab6Tom Taylor            }
835b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
836b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
837812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
8389242286c35743422051d439d7460cd0a1426899cWei Huang    /**
8399242286c35743422051d439d7460cd0a1426899cWei Huang     * Debugging
8409242286c35743422051d439d7460cd0a1426899cWei Huang     */
8419242286c35743422051d439d7460cd0a1426899cWei Huang    public static void writeHprofDataToFile(){
842ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylor        String filename = Environment.getExternalStorageDirectory() + "/mms_oom_hprof_data";
8439242286c35743422051d439d7460cd0a1426899cWei Huang        try {
8449242286c35743422051d439d7460cd0a1426899cWei Huang            android.os.Debug.dumpHprofData(filename);
8459242286c35743422051d439d7460cd0a1426899cWei Huang            Log.i(TAG, "##### written hprof data to " + filename);
8469242286c35743422051d439d7460cd0a1426899cWei Huang        } catch (IOException ex) {
8479242286c35743422051d439d7460cd0a1426899cWei Huang            Log.e(TAG, "writeHprofDataToFile: caught " + ex);
8489242286c35743422051d439d7460cd0a1426899cWei Huang        }
8499242286c35743422051d439d7460cd0a1426899cWei Huang    }
8509242286c35743422051d439d7460cd0a1426899cWei Huang
851817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    public static boolean isAlias(String string) {
852f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (!MmsConfig.isAliasEnabled()) {
853f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
854f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
855f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
856f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (TextUtils.isEmpty(string)) {
857f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
858f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
859f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
86078f81825431c8c52cad57bc4a363747533a701abWei Huang        // TODO: not sure if this is the right thing to use. Mms.isPhoneNumber() is
86178f81825431c8c52cad57bc4a363747533a701abWei Huang        // intended for searching for things that look like they might be phone numbers
86278f81825431c8c52cad57bc4a363747533a701abWei Huang        // in arbitrary text, not for validating whether something is in fact a phone number.
86378f81825431c8c52cad57bc4a363747533a701abWei Huang        // It will miss many things that are legitimate phone numbers.
864f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (Mms.isPhoneNumber(string)) {
865f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
866f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
867f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
868f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (!isAlphaNumeric(string)) {
869f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
870f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
871f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
872f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        int len = string.length();
873f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
874f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (len < MmsConfig.getAliasMinChars() || len > MmsConfig.getAliasMaxChars()) {
875f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
876f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
877f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
878f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        return true;
879817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    }
880817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom
881817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    public static boolean isAlphaNumeric(String s) {
882817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        char[] chars = s.toCharArray();
883817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        for (int x = 0; x < chars.length; x++) {
884817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom            char c = chars[x];
88578f81825431c8c52cad57bc4a363747533a701abWei Huang
88678f81825431c8c52cad57bc4a363747533a701abWei Huang            if ((c >= 'a') && (c <= 'z')) {
88778f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
88878f81825431c8c52cad57bc4a363747533a701abWei Huang            }
88978f81825431c8c52cad57bc4a363747533a701abWei Huang            if ((c >= 'A') && (c <= 'Z')) {
89078f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
89178f81825431c8c52cad57bc4a363747533a701abWei Huang            }
89278f81825431c8c52cad57bc4a363747533a701abWei Huang            if ((c >= '0') && (c <= '9')) {
89378f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
89478f81825431c8c52cad57bc4a363747533a701abWei Huang            }
89578f81825431c8c52cad57bc4a363747533a701abWei Huang
89678f81825431c8c52cad57bc4a363747533a701abWei Huang            return false;
897817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        }
898817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        return true;
899817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    }
900817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom
90178f81825431c8c52cad57bc4a363747533a701abWei Huang
90278f81825431c8c52cad57bc4a363747533a701abWei Huang
90378f81825431c8c52cad57bc4a363747533a701abWei Huang
90478f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
90578f81825431c8c52cad57bc4a363747533a701abWei Huang     * Given a phone number, return the string without syntactic sugar, meaning parens,
90678f81825431c8c52cad57bc4a363747533a701abWei Huang     * spaces, slashes, dots, dashes, etc. If the input string contains non-numeric
90778f81825431c8c52cad57bc4a363747533a701abWei Huang     * non-punctuation characters, return null.
90878f81825431c8c52cad57bc4a363747533a701abWei Huang     */
90978f81825431c8c52cad57bc4a363747533a701abWei Huang    private static String parsePhoneNumberForMms(String address) {
91078f81825431c8c52cad57bc4a363747533a701abWei Huang        StringBuilder builder = new StringBuilder();
91178f81825431c8c52cad57bc4a363747533a701abWei Huang        int len = address.length();
91278f81825431c8c52cad57bc4a363747533a701abWei Huang
91378f81825431c8c52cad57bc4a363747533a701abWei Huang        for (int i = 0; i < len; i++) {
91478f81825431c8c52cad57bc4a363747533a701abWei Huang            char c = address.charAt(i);
91578f81825431c8c52cad57bc4a363747533a701abWei Huang
91678f81825431c8c52cad57bc4a363747533a701abWei Huang            // accept the first '+' in the address
91778f81825431c8c52cad57bc4a363747533a701abWei Huang            if (c == '+' && builder.length() == 0) {
91878f81825431c8c52cad57bc4a363747533a701abWei Huang                builder.append(c);
91978f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
92078f81825431c8c52cad57bc4a363747533a701abWei Huang            }
92178f81825431c8c52cad57bc4a363747533a701abWei Huang
92278f81825431c8c52cad57bc4a363747533a701abWei Huang            if (Character.isDigit(c)) {
92378f81825431c8c52cad57bc4a363747533a701abWei Huang                builder.append(c);
92478f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
92578f81825431c8c52cad57bc4a363747533a701abWei Huang            }
92678f81825431c8c52cad57bc4a363747533a701abWei Huang
92778f81825431c8c52cad57bc4a363747533a701abWei Huang            if (numericSugarMap.get(c) == null) {
92878f81825431c8c52cad57bc4a363747533a701abWei Huang                return null;
92978f81825431c8c52cad57bc4a363747533a701abWei Huang            }
93078f81825431c8c52cad57bc4a363747533a701abWei Huang        }
93178f81825431c8c52cad57bc4a363747533a701abWei Huang        return builder.toString();
93278f81825431c8c52cad57bc4a363747533a701abWei Huang    }
93378f81825431c8c52cad57bc4a363747533a701abWei Huang
93478f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
93578f81825431c8c52cad57bc4a363747533a701abWei Huang     * Returns true if the address passed in is a valid MMS address.
93678f81825431c8c52cad57bc4a363747533a701abWei Huang     */
93778f81825431c8c52cad57bc4a363747533a701abWei Huang    public static boolean isValidMmsAddress(String address) {
93878f81825431c8c52cad57bc4a363747533a701abWei Huang        String retVal = parseMmsAddress(address);
93978f81825431c8c52cad57bc4a363747533a701abWei Huang        return (retVal != null);
94078f81825431c8c52cad57bc4a363747533a701abWei Huang    }
94178f81825431c8c52cad57bc4a363747533a701abWei Huang
94278f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
94378f81825431c8c52cad57bc4a363747533a701abWei Huang     * parse the input address to be a valid MMS address.
94478f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address is an email address, leave it as is.
94578f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address can be parsed into a valid MMS phone number, return the parsed number.
94678f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address is a compliant alias address, leave it as is.
94778f81825431c8c52cad57bc4a363747533a701abWei Huang     */
94878f81825431c8c52cad57bc4a363747533a701abWei Huang    public static String parseMmsAddress(String address) {
94978f81825431c8c52cad57bc4a363747533a701abWei Huang        // if it's a valid Email address, use that.
95078f81825431c8c52cad57bc4a363747533a701abWei Huang        if (Mms.isEmailAddress(address)) {
95178f81825431c8c52cad57bc4a363747533a701abWei Huang            return address;
95278f81825431c8c52cad57bc4a363747533a701abWei Huang        }
95378f81825431c8c52cad57bc4a363747533a701abWei Huang
95478f81825431c8c52cad57bc4a363747533a701abWei Huang        // if we are able to parse the address to a MMS compliant phone number, take that.
95578f81825431c8c52cad57bc4a363747533a701abWei Huang        String retVal = parsePhoneNumberForMms(address);
95678f81825431c8c52cad57bc4a363747533a701abWei Huang        if (retVal != null) {
95778f81825431c8c52cad57bc4a363747533a701abWei Huang            return retVal;
95878f81825431c8c52cad57bc4a363747533a701abWei Huang        }
95978f81825431c8c52cad57bc4a363747533a701abWei Huang
96078f81825431c8c52cad57bc4a363747533a701abWei Huang        // if it's an alias compliant address, use that.
96178f81825431c8c52cad57bc4a363747533a701abWei Huang        if (isAlias(address)) {
96278f81825431c8c52cad57bc4a363747533a701abWei Huang            return address;
96378f81825431c8c52cad57bc4a363747533a701abWei Huang        }
96478f81825431c8c52cad57bc4a363747533a701abWei Huang
96578f81825431c8c52cad57bc4a363747533a701abWei Huang        // it's not a valid MMS address, return null
96678f81825431c8c52cad57bc4a363747533a701abWei Huang        return null;
96778f81825431c8c52cad57bc4a363747533a701abWei Huang    }
96878f81825431c8c52cad57bc4a363747533a701abWei Huang
969812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    private static void log(String msg) {
970812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        Log.d(TAG, "[MsgUtils] " + msg);
971812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    }
97272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
973