MessageUtils.java revision 661957caeb3110ae3328a995edd467ceedc07a36
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;
242fddde28ed2ccb3c156d596160e3a504c83ce444Tom Taylorimport com.android.mms.TempFileProvider;
25b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrickimport com.android.mms.data.WorkingMessage;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.MediaModel;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.SlideModel;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.SlideshowModel;
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.transaction.MmsMessageSender;
3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.AddressUtils;
31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.ContentType;
32f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException;
33f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.CharacterSets;
34f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.EncodedStringValue;
35f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.MultimediaMessagePdu;
36f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.NotificationInd;
37f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduBody;
38f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders;
39f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPart;
40f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
41f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.RetrieveConf;
42f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.SendReq;
43fd644551e8506266aad2b76463b51b44154ed62fTom Taylorimport android.database.sqlite.SqliteWrapper;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlertDialog;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris;
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnClickListener;
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.res.Resources;
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
5515057746d75afb5fec583f30064b382c18403608Tom Taylorimport android.media.CamcorderProfile;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.media.RingtoneManager;
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
58ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylorimport android.os.Environment;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler;
6015057746d75afb5fec583f30064b382c18403608Tom Taylorimport android.provider.MediaStore;
61f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms;
62f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms;
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.PhoneNumberUtils;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.DateUtils;
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.Time;
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.URLSpan;
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
691224b6560c48e146ee304f9c807296f6c22cdefbTom Taylorimport android.widget.Toast;
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
719242286c35743422051d439d7460cd0a1426899cWei Huangimport java.io.IOException;
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
73b04236e2977ac69e63cc0fa123399a584b606945Tom Taylorimport java.util.Collection;
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.HashMap;
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Map;
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.concurrent.ConcurrentHashMap;
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * An utility class for managing messages.
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessageUtils {
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    interface ResizeImageResultCallback {
83edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        void onResizeResult(PduPart part, boolean append);
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
869242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = LogTag.TAG;
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String sLocalNumber;
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Cache of both groups of space-separated ids to their full
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // comma-separated display names, as well as individual ids to
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // display names.
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // TODO: is it possible for canonical address ID keys to be
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // re-used?  SQLite does reuse IDs on NULL id_ insert, but does
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // anything ever delete from the mmssms.db canonical_addresses
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // table?  Nothing that I could find.
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final Map<String, String> sRecipientAddress =
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            new ConcurrentHashMap<String, String>(20 /* initial capacity */);
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9978f81825431c8c52cad57bc4a363747533a701abWei Huang
10078f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
10178f81825431c8c52cad57bc4a363747533a701abWei Huang     * MMS address parsing data structures
10278f81825431c8c52cad57bc4a363747533a701abWei Huang     */
10378f81825431c8c52cad57bc4a363747533a701abWei Huang    // allowable phone number separators
10478f81825431c8c52cad57bc4a363747533a701abWei Huang    private static final char[] NUMERIC_CHARS_SUGAR = {
10578f81825431c8c52cad57bc4a363747533a701abWei Huang        '-', '.', ',', '(', ')', ' ', '/', '\\', '*', '#', '+'
10678f81825431c8c52cad57bc4a363747533a701abWei Huang    };
10778f81825431c8c52cad57bc4a363747533a701abWei Huang
10878f81825431c8c52cad57bc4a363747533a701abWei Huang    private static HashMap numericSugarMap = new HashMap (NUMERIC_CHARS_SUGAR.length);
10978f81825431c8c52cad57bc4a363747533a701abWei Huang
11078f81825431c8c52cad57bc4a363747533a701abWei Huang    static {
11178f81825431c8c52cad57bc4a363747533a701abWei Huang        for (int i = 0; i < NUMERIC_CHARS_SUGAR.length; i++) {
11278f81825431c8c52cad57bc4a363747533a701abWei Huang            numericSugarMap.put(NUMERIC_CHARS_SUGAR[i], NUMERIC_CHARS_SUGAR[i]);
11378f81825431c8c52cad57bc4a363747533a701abWei Huang        }
11478f81825431c8c52cad57bc4a363747533a701abWei Huang    }
11578f81825431c8c52cad57bc4a363747533a701abWei Huang
11678f81825431c8c52cad57bc4a363747533a701abWei Huang
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private MessageUtils() {
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Forbidden being instantiated.
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String getMessageDetails(Context context, Cursor cursor, int size) {
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor == null) {
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return null;
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ("mms".equals(cursor.getString(MessageListAdapter.COLUMN_MSG_TYPE))) {
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (type) {
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return getNotificationIndDetails(context, cursor);
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_SEND_REQ:
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return getMultimediaMessageDetails(context, cursor, size);
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                default:
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "No details could be retrieved.");
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return "";
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return getTextMessageDetails(context, cursor);
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getNotificationIndDetails(Context context, Cursor cursor) {
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NotificationInd nInd;
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            nInd = (NotificationInd) PduPersister.getPduPersister(
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context).load(uri);
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Failed to load the message: " + uri, e);
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return context.getResources().getString(R.string.cannot_get_details);
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Mms Notification.
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.multimedia_notification));
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // From: ***
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String from = extractEncStr(context, nInd.getFrom());
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.from_label));
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(!TextUtils.isEmpty(from)? from:
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                 res.getString(R.string.hidden_sender_address));
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                R.string.expire_on,
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                MessageUtils.formatTimeStampString(
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                        context, nInd.getExpiry() * 1000L, true)));
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Subject: ***
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.subject_label));
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue subject = nInd.getSubject();
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (subject != null) {
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(subject.getString());
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message class: Personal/Advertisement/Infomational/Auto
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_class_label));
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(new String(nInd.getMessageClass()));
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message size: *** KB
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_size_label));
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(String.valueOf((nInd.getMessageSize() + 1023) / 1024));
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(context.getString(R.string.kilobyte));
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getMultimediaMessageDetails(
20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, Cursor cursor, int size) {
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (type == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return getNotificationIndDetails(context, cursor);
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MultimediaMessagePdu msg;
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            msg = (MultimediaMessagePdu) PduPersister.getPduPersister(
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context).load(uri);
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Failed to load the message: " + uri, e);
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return context.getResources().getString(R.string.cannot_get_details);
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Text message.
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.multimedia_message));
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msg instanceof RetrieveConf) {
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // From: ***
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String from = extractEncStr(context, ((RetrieveConf) msg).getFrom());
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append('\n');
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.from_label));
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(!TextUtils.isEmpty(from)? from:
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                  res.getString(R.string.hidden_sender_address));
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // To: ***
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.to_address_label));
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue[] to = msg.getTo();
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (to != null) {
24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(EncodedStringValue.concat(to));
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        else {
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.w(TAG, "recipient list is empty!");
24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
2459c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Bcc: ***
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msg instanceof SendReq) {
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            EncodedStringValue[] values = ((SendReq) msg).getBcc();
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ((values != null) && (values.length > 0)) {
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append('\n');
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append(res.getString(R.string.bcc_label));
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append(EncodedStringValue.concat(values));
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgBox = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_BOX);
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msgBox == Mms.MESSAGE_BOX_DRAFTS) {
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.saved_label));
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (msgBox == Mms.MESSAGE_BOX_INBOX) {
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.received_label));
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.sent_label));
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(MessageUtils.formatTimeStampString(
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                context, msg.getDate() * 1000L, true));
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Subject: ***
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.subject_label));
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue subject = msg.getSubject();
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (subject != null) {
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String subStr = subject.getString();
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Message size should include size of subject.
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            size += subStr.length();
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(subStr);
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Priority: High/Normal/Low
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.priority_label));
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(getPriorityDescription(context, msg.getPriority()));
28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message size: *** KB
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_size_label));
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append((size - 1)/1000 + 1);
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(" KB");
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getTextMessageDetails(Context context, Cursor cursor) {
298b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        Log.d(TAG, "getTextMessageDetails");
299b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Text message.
30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.text_message));
30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Address: ***
30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int smsType = cursor.getInt(MessageListAdapter.COLUMN_SMS_TYPE);
31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (Sms.isOutgoingFolder(smsType)) {
31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.to_address_label));
31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.from_label));
31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(cursor.getString(MessageListAdapter.COLUMN_SMS_ADDRESS));
31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31754711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        // Sent: ***
31854711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        if (smsType == Sms.MESSAGE_TYPE_INBOX) {
31954711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert            long date_sent = cursor.getLong(MessageListAdapter.COLUMN_SMS_DATE_SENT);
32054711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert            if (date_sent > 0) {
32154711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert                details.append('\n');
32254711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert                details.append(res.getString(R.string.sent_label));
32354711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert                details.append(MessageUtils.formatTimeStampString(context, date_sent, true));
32454711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert            }
32554711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        }
32654711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert
32754711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert        // Received: ***
32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (smsType == Sms.MESSAGE_TYPE_DRAFT) {
33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.saved_label));
33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (smsType == Sms.MESSAGE_TYPE_INBOX) {
33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.received_label));
33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.sent_label));
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long date = cursor.getLong(MessageListAdapter.COLUMN_SMS_DATE);
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(MessageUtils.formatTimeStampString(context, date, true));
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
340831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor        // Delivered: ***
341831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor        if (smsType == Sms.MESSAGE_TYPE_SENT) {
342831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor            // For sent messages with delivery reports, we stick the delivery time in the
343831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor            // date_sent column (see MessageStatusReceiver).
344831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor            long dateDelivered = cursor.getLong(MessageListAdapter.COLUMN_SMS_DATE_SENT);
345831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor            if (dateDelivered > 0) {
346831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor                details.append('\n');
347831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor                details.append(res.getString(R.string.delivered_label));
348831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor                details.append(MessageUtils.formatTimeStampString(context, dateDelivered, true));
349831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor            }
350831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor        }
351831b1232edf7f01b9d31322083ad0180b2b375b9Tom Taylor
352161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        // Error code: ***
353161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        int errorCode = cursor.getInt(MessageListAdapter.COLUMN_SMS_ERROR_CODE);
354161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        if (errorCode != 0) {
355161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor            details.append('\n')
356161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor                .append(res.getString(R.string.error_code_label))
357161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor                .append(errorCode);
358161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        }
359161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    static private String getPriorityDescription(Context context, int PriorityValue) {
36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch(PriorityValue) {
36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_HIGH:
36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_high);
36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_LOW:
36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_low);
37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_NORMAL:
37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            default:
37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_normal);
37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static int getAttachmentType(SlideshowModel model) {
37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (model == null) {
378b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return WorkingMessage.TEXT;
37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int numberOfSlides = model.size();
38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (numberOfSlides > 1) {
383b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return WorkingMessage.SLIDESHOW;
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (numberOfSlides == 1) {
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Only one slide in the slide-show.
38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = model.get(0);
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasVideo()) {
388b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.VIDEO;
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasAudio() && slide.hasImage()) {
392b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.SLIDESHOW;
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasAudio()) {
396b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.AUDIO;
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasImage()) {
400b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.IMAGE;
40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasText()) {
404b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.TEXT;
40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
408b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        return WorkingMessage.TEXT;
40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
4109c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String formatTimeStampString(Context context, long when) {
41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return formatTimeStampString(context, when, false);
41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String formatTimeStampString(Context context, long when, boolean fullFormat) {
41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Time then = new Time();
41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        then.set(when);
41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Time now = new Time();
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        now.setToNow();
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Basic settings for formatDateTime() we want for all cases.
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int format_flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT |
42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                           DateUtils.FORMAT_ABBREV_ALL |
42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                           DateUtils.FORMAT_CAP_AMPM;
425836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project
42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If the message is from a different year, show the date and year.
42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (then.year != now.year) {
42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (then.yearDay != now.yearDay) {
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // If it is from a different day than today, show only the date.
43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_DATE;
43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Otherwise, if the message is from today, show the time.
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_TIME;
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
437836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // If the caller has asked for full details, make sure to show the date
438836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // and time no matter what we've determined above (but still make showing
439836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // the year only happen if it is a different year from today).
440836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        if (fullFormat) {
441836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            format_flags |= (DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
442836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        }
443836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return DateUtils.formatDateTime(context, when, format_flags);
44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectAudio(Context context, int requestCode) {
44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (context instanceof Activity) {
44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
4525c0aff95e0c161d22fad145fe344430fd3474bc1Dave Sparks            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_INCLUDE_DRM, false);
4539c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context.getString(R.string.select_audio));
45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(intent, requestCode);
45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
45915057746d75afb5fec583f30064b382c18403608Tom Taylor    public static void recordSound(Context context, int requestCode, long sizeLimit) {
46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (context instanceof Activity) {
46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.setType(ContentType.AUDIO_AMR);
46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.setClassName("com.android.soundrecorder",
46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "com.android.soundrecorder.SoundRecorder");
46515057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra(android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES, sizeLimit);
46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(intent, requestCode);
46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47115057746d75afb5fec583f30064b382c18403608Tom Taylor    public static void recordVideo(Context context, int requestCode, long sizeLimit) {
47215057746d75afb5fec583f30064b382c18403608Tom Taylor        if (context instanceof Activity) {
47315057746d75afb5fec583f30064b382c18403608Tom Taylor            int durationLimit = getVideoCaptureDurationLimit();
47415057746d75afb5fec583f30064b382c18403608Tom Taylor            Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
47515057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
47615057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra("android.intent.extra.sizeLimit", sizeLimit);
47715057746d75afb5fec583f30064b382c18403608Tom Taylor            intent.putExtra("android.intent.extra.durationLimit", durationLimit);
4782fddde28ed2ccb3c156d596160e3a504c83ce444Tom Taylor            intent.putExtra(MediaStore.EXTRA_OUTPUT, TempFileProvider.SCRAP_CONTENT_URI);
47915057746d75afb5fec583f30064b382c18403608Tom Taylor
48015057746d75afb5fec583f30064b382c18403608Tom Taylor            ((Activity) context).startActivityForResult(intent, requestCode);
48115057746d75afb5fec583f30064b382c18403608Tom Taylor        }
48215057746d75afb5fec583f30064b382c18403608Tom Taylor    }
48315057746d75afb5fec583f30064b382c18403608Tom Taylor
48415057746d75afb5fec583f30064b382c18403608Tom Taylor    private static int getVideoCaptureDurationLimit() {
4857a0d891850d3a57c6358f1a2c8798f4f84a47e7cTom Taylor        CamcorderProfile camcorder = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
4867a0d891850d3a57c6358f1a2c8798f4f84a47e7cTom Taylor        return camcorder == null ? 0 : camcorder.duration;
48715057746d75afb5fec583f30064b382c18403608Tom Taylor    }
48815057746d75afb5fec583f30064b382c18403608Tom Taylor
48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectVideo(Context context, int requestCode) {
49002277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor        selectMediaByType(context, requestCode, ContentType.VIDEO_UNSPECIFIED, true);
49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectImage(Context context, int requestCode) {
49402277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor        selectMediaByType(context, requestCode, ContentType.IMAGE_UNSPECIFIED, false);
49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static void selectMediaByType(
49802277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor            Context context, int requestCode, String contentType, boolean localFilesOnly) {
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project         if (context instanceof Activity) {
50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT);
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            innerIntent.setType(contentType);
50402277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor            if (localFilesOnly) {
50502277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor                innerIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
50602277c6b787e8e29ee22b1df745eb8549d3ff023Tom Taylor            }
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent wrapperIntent = Intent.createChooser(innerIntent, null);
50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(wrapperIntent, requestCode);
51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void viewSimpleSlideshow(Context context, SlideshowModel slideshow) {
51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!slideshow.isSimple()) {
51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new IllegalArgumentException(
51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "viewSimpleSlideshow() called on a non-simple slideshow");
51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = slideshow.get(0);
52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MediaModel mm = null;
52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide.hasImage()) {
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mm = slide.getImage();
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (slide.hasVideo()) {
52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mm = slide.getVideo();
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
5269c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW);
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
52970322de51cc7ef634c4b68b08b1c35b516fede77Todor Kalaydjiev        intent.putExtra("SingleItemOnly", true); // So we don't see "surrounding" images in Gallery
5309c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
5319c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        String contentType;
5320ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor        contentType = mm.getContentType();
5339c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        intent.setDataAndType(mm.getUri(), contentType);
53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        context.startActivity(intent);
53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
5369c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
5373d8877fa3e07c019d1779793ca0081beca177b6aTom Taylor    public static void showErrorDialog(Activity activity,
53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String title, String message) {
5393d8877fa3e07c019d1779793ca0081beca177b6aTom Taylor        if (activity.isFinishing()) {
5403d8877fa3e07c019d1779793ca0081beca177b6aTom Taylor            return;
5413d8877fa3e07c019d1779793ca0081beca177b6aTom Taylor        }
5423d8877fa3e07c019d1779793ca0081beca177b6aTom Taylor        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setIcon(R.drawable.ic_sms_mms_not_delivered);
54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(title);
54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setMessage(message);
54793b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor        builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
5481009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
54993b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor            public void onClick(DialogInterface dialog, int which) {
55093b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor                if (which == DialogInterface.BUTTON_POSITIVE) {
55193b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor                    dialog.dismiss();
55293b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor                }
55393b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor            }
55493b7a8bfa72a932843ecc7de4c9f9baec4ee2087Tom Taylor        });
55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
558bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project    /**
559bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project     * The quality parameter which is used to compress JPEG images.
560bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project     */
5618c86a52a2c13083a25761256ab0dfc416260c162Tom Taylor    public static final int IMAGE_COMPRESSION_QUALITY = 95;
5629242286c35743422051d439d7460cd0a1426899cWei Huang    /**
5639242286c35743422051d439d7460cd0a1426899cWei Huang     * The minimum quality parameter which is used to compress JPEG images.
5649242286c35743422051d439d7460cd0a1426899cWei Huang     */
5659242286c35743422051d439d7460cd0a1426899cWei Huang    public static final int MINIMUM_IMAGE_COMPRESSION_QUALITY = 50;
566bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project
567f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson    /**
568f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * Message overhead that reduces the maximum image byte size.
569f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * 5000 is a realistic overhead number that allows for user to also include
570f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * a small MIDI file or a couple pages of text along with the picture.
571f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     */
572f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson    public static final int MESSAGE_OVERHEAD = 5000;
573f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson
57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void resizeImageAsync(final Context context,
57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final Uri imageUri, final Handler handler,
576edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            final ResizeImageResultCallback cb,
577edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            final boolean append) {
57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5791224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor        // Show a progress toast if the resize hasn't finished
58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // within one second.
58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Stash the runnable for showing it away so we can cancel
58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // it later if the resize completes ahead of the deadline.
58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Runnable showProgress = new Runnable() {
5841009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
5861224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                Toast.makeText(context, R.string.compressing, Toast.LENGTH_SHORT).show();
58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Schedule it for one second from now.
59072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        handler.postDelayed(showProgress, 1000);
5919c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
59272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new Thread(new Runnable() {
5931009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
59472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
59572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                final PduPart part;
59672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
59772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    UriImage image = new UriImage(context, imageUri);
5981009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    int widthLimit = MmsConfig.getMaxImageWidth();
5991009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    int heightLimit = MmsConfig.getMaxImageHeight();
6001009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    // In mms_config.xml, the max width has always been declared larger than the max
6011009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    // height. Swap the width and height limits if necessary so we scale the picture
6021009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    // as little as possible.
6031009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    if (image.getHeight() > image.getWidth()) {
6041009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        int temp = widthLimit;
6051009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        widthLimit = heightLimit;
6061009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        heightLimit = temp;
6071009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    }
6081009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev
60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part = image.getResizedImageAsPart(
6101009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        widthLimit,
6111009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                        heightLimit,
612f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson                        MmsConfig.getMaxMessageSize() - MESSAGE_OVERHEAD);
61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } finally {
6141224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                    // Cancel pending show of the progress toast if necessary.
61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    handler.removeCallbacks(showProgress);
61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                handler.post(new Runnable() {
6191009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                    @Override
62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    public void run() {
621edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                        cb.onResizeResult(part, append);
62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                });
62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
625ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev        }, "MessageUtils.resizeImageAsync").start();
62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void showDiscardDraftConfirmDialog(Context context,
62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnClickListener listener) {
63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new AlertDialog.Builder(context)
63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setMessage(R.string.discard_message_reason)
63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setPositiveButton(R.string.yes, listener)
63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setNegativeButton(R.string.no, null)
63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .show();
63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
63672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
63713dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang    public static String getLocalNumber() {
63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null == sLocalNumber) {
639bb8edcae15a50b3651261db70791afc668aae294Tom Taylor            sLocalNumber = MmsApp.getApplication().getTelephonyManager().getLine1Number();
64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return sLocalNumber;
64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static boolean isLocalNumber(String number) {
645f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        if (number == null) {
646f1bf432304bcc277397b028192eaf01a94c6417dWei Huang            return false;
647f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        }
648f1bf432304bcc277397b028192eaf01a94c6417dWei Huang
649f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // we don't use Mms.isEmailAddress() because it is too strict for comparing addresses like
650f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // "foo+caf_=6505551212=tmomail.net@gmail.com", which is the 'from' address from a forwarded email
651f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // message from Gmail. We don't want to treat "foo+caf_=6505551212=tmomail.net@gmail.com" and
652f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // "6505551212" to be the same.
653f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        if (number.indexOf('@') >= 0) {
654b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang            return false;
655b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang        }
656b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang
65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return PhoneNumberUtils.compare(number, getLocalNumber());
65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void handleReadReport(final Context context,
661b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor            final Collection<Long> threadIds,
66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final int status,
66372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final Runnable callback) {
664b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor        StringBuilder selectionBuilder = new StringBuilder(Mms.MESSAGE_TYPE + " = "
665b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF
666b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                + " AND " + Mms.READ + " = 0"
667b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                + " AND " + Mms.READ_REPORT + " = " + PduHeaders.VALUE_YES);
668b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor
669b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor        String[] selectionArgs = null;
670b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor        if (threadIds != null) {
671b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            String threadIdSelection = null;
672b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            StringBuilder buf = new StringBuilder();
673b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            selectionArgs = new String[threadIds.size()];
674b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            int i = 0;
675b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor
676b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            for (long threadId : threadIds) {
677b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                if (i > 0) {
678b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                    buf.append(" OR ");
679b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                }
680b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                buf.append(Mms.THREAD_ID).append("=?");
681b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                selectionArgs[i++] = Long.toString(threadId);
682b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            }
683b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            threadIdSelection = buf.toString();
68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
685b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor            selectionBuilder.append(" AND (" + threadIdSelection + ")");
68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
68772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Mms.Inbox.CONTENT_URI, new String[] {Mms._ID, Mms.MESSAGE_ID},
690b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor                        selectionBuilder.toString(), selectionArgs, null);
69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (c == null) {
69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Map<String, String> map = new HashMap<String, String>();
69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (c.getCount() == 0) {
69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return;
70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            while (c.moveToNext()) {
70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, c.getLong(0));
70772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                map.put(c.getString(1), AddressUtils.getFrom(context, uri));
70872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } finally {
71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            c.close();
71172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnClickListener positiveListener = new OnClickListener() {
7141009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (final Map.Entry<String, String> entry : map.entrySet()) {
71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MmsMessageSender.sendReadRec(context, entry.getValue(),
71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                                 entry.getKey(), status);
71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
724c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor                dialog.dismiss();
72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnClickListener negativeListener = new OnClickListener() {
7291009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
73172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
734c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor                dialog.dismiss();
73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnCancelListener cancelListener = new OnCancelListener() {
7391009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            @Override
74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onCancel(DialogInterface dialog) {
74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
74272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
744c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor                dialog.dismiss();
74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        confirmReadReportDialog(context, positiveListener,
74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                         negativeListener,
75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                         cancelListener);
75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static void confirmReadReportDialog(Context context,
75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnClickListener positiveListener, OnClickListener negativeListener,
75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnCancelListener cancelListener) {
75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(context);
75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setCancelable(true);
75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(R.string.confirm);
75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setMessage(R.string.message_send_read_report);
76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setPositiveButton(R.string.yes, positiveListener);
76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setNegativeButton(R.string.no, negativeListener);
76272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setOnCancelListener(cancelListener);
76372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String extractEncStrFromCursor(Cursor cursor,
76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int columnRawBytes, int columnCharset) {
76872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String rawBytes = cursor.getString(columnRawBytes);
76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int charset = cursor.getInt(columnCharset);
77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (TextUtils.isEmpty(rawBytes)) {
77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return "";
77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (charset == CharacterSets.ANY_CHARSET) {
77472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return rawBytes;
77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return new EncodedStringValue(charset, PduPersister.getBytes(rawBytes)).getString();
77772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
77872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
77972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
78072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String extractEncStr(Context context, EncodedStringValue value) {
78172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (value != null) {
78272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return value.getString();
78372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
78472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return "";
78572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
78672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
7879c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
78872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static ArrayList<String> extractUris(URLSpan[] spans) {
78972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int size = spans.length;
79072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<String> accumulator = new ArrayList<String>();
79172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < size; i++) {
79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            accumulator.add(spans[i].getURL());
79472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return accumulator;
79672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
79772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7984522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    /**
7994522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * Play/view the message attachments.
8004522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * TOOD: We need to save the draft before launching another activity to view the attachments.
8014522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       This is hacky though since we will do saveDraft twice and slow down the UI.
8024522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       We should pass the slideshow in intent extra to the view activity instead of
8034522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       asking it to read attachments from database.
804661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor     * @param activity
8054522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param msgUri the MMS message URI in database
8064522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param slideshow the slideshow to save
8074522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param persister the PDU persister for updating the database
8084522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param sendReq the SendReq for updating the database
8094522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     */
810661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor    public static void viewMmsMessageAttachment(Activity activity, Uri msgUri,
811661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            SlideshowModel slideshow, AsyncDialog asyncDialog) {
812661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor        viewMmsMessageAttachment(activity, msgUri, slideshow, 0, asyncDialog);
8136767962317b959aa656c61741b1c1de4f9530f99Tom Taylor    }
8146767962317b959aa656c61741b1c1de4f9530f99Tom Taylor
815661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor    public static void viewMmsMessageAttachment(final Activity activity, final Uri msgUri,
816661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            final SlideshowModel slideshow, final int requestCode, AsyncDialog asyncDialog) {
8174522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        boolean isSimple = (slideshow == null) ? false : slideshow.isSimple();
8184522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        if (isSimple) {
8194522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            // In attachment-editor mode, we only ever have one slide.
820661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            MessageUtils.viewSimpleSlideshow(activity, slideshow);
8214522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        } else {
822661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            // The user wants to view the slideshow. We have to persist the slideshow parts
823661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            // in a background task. If the task takes longer than a half second, a progress dialog
824661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            // is displayed. Once the PDU persisting is done, another runnable on the UI thread get
825661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            // executed to start the SlideshowActivity.
826661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            asyncDialog.runAsync(new Runnable() {
827661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                @Override
828661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                public void run() {
829661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                    // If a slideshow was provided, save it to disk first.
830661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                    if (slideshow != null) {
831661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                        PduPersister persister = PduPersister.getPduPersister(activity);
832661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                        try {
833661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                            PduBody pb = slideshow.toPduBody();
834661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                            persister.updateParts(msgUri, pb);
835661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                            slideshow.sync(pb);
836661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                        } catch (MmsException e) {
837661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                            Log.e(TAG, "Unable to save message for preview");
838661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                            return;
839661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                        }
840661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                    }
841b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                }
842661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            }, new Runnable() {
843661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                @Override
844661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                public void run() {
845661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                    // Once the above background thread is complete, this runnable is run
846661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                    // on the UI thread to launch the slideshow activity.
847661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                    launchSlideshowActivity(activity, msgUri, requestCode);
848661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor                }
849661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            }, R.string.building_slideshow_title);
8504522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        }
8514522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    }
8529c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
853661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor    public static void launchSlideshowActivity(Context context, Uri msgUri, int requestCode) {
854661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor        // Launch the slideshow activity to play/view.
855661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor        Intent intent = new Intent(context, SlideshowActivity.class);
856661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor        intent.setData(msgUri);
857661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor        if (requestCode > 0 && context instanceof Activity) {
858661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            ((Activity)context).startActivityForResult(intent, requestCode);
859b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        } else {
860661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor            context.startActivity(intent);
861b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
862661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor
863b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
864812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
8659242286c35743422051d439d7460cd0a1426899cWei Huang    /**
8669242286c35743422051d439d7460cd0a1426899cWei Huang     * Debugging
8679242286c35743422051d439d7460cd0a1426899cWei Huang     */
8689242286c35743422051d439d7460cd0a1426899cWei Huang    public static void writeHprofDataToFile(){
869ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylor        String filename = Environment.getExternalStorageDirectory() + "/mms_oom_hprof_data";
8709242286c35743422051d439d7460cd0a1426899cWei Huang        try {
8719242286c35743422051d439d7460cd0a1426899cWei Huang            android.os.Debug.dumpHprofData(filename);
8729242286c35743422051d439d7460cd0a1426899cWei Huang            Log.i(TAG, "##### written hprof data to " + filename);
8739242286c35743422051d439d7460cd0a1426899cWei Huang        } catch (IOException ex) {
8749242286c35743422051d439d7460cd0a1426899cWei Huang            Log.e(TAG, "writeHprofDataToFile: caught " + ex);
8759242286c35743422051d439d7460cd0a1426899cWei Huang        }
8769242286c35743422051d439d7460cd0a1426899cWei Huang    }
8779242286c35743422051d439d7460cd0a1426899cWei Huang
878f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor    // An alias (or commonly called "nickname") is:
879f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor    // Nickname must begin with a letter.
880f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor    // Only letters a-z, numbers 0-9, or . are allowed in Nickname field.
881817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    public static boolean isAlias(String string) {
882f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (!MmsConfig.isAliasEnabled()) {
883f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
884f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
885f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
886f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor        int len = string == null ? 0 : string.length();
887b19f3b32bd202fa9f25a45e9e3068b33c12b70c0Tom Taylor
888f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor        if (len < MmsConfig.getAliasMinChars() || len > MmsConfig.getAliasMaxChars()) {
889f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
890f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
891f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
892f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor        if (!Character.isLetter(string.charAt(0))) {    // Nickname begins with a letter
893f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
894f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
895f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor        for (int i = 1; i < len; i++) {
896f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor            char c = string.charAt(i);
897f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor            if (!(Character.isLetterOrDigit(c) || c == '.')) {
898f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor                return false;
89978f81825431c8c52cad57bc4a363747533a701abWei Huang            }
900817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        }
901f4a44bba2c6a8cdaa4dd86d9dc4560775f8e0bc0Tom Taylor
902817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        return true;
903817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    }
904817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom
90578f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
90678f81825431c8c52cad57bc4a363747533a701abWei Huang     * Given a phone number, return the string without syntactic sugar, meaning parens,
90778f81825431c8c52cad57bc4a363747533a701abWei Huang     * spaces, slashes, dots, dashes, etc. If the input string contains non-numeric
90878f81825431c8c52cad57bc4a363747533a701abWei Huang     * non-punctuation characters, return null.
90978f81825431c8c52cad57bc4a363747533a701abWei Huang     */
91078f81825431c8c52cad57bc4a363747533a701abWei Huang    private static String parsePhoneNumberForMms(String address) {
91178f81825431c8c52cad57bc4a363747533a701abWei Huang        StringBuilder builder = new StringBuilder();
91278f81825431c8c52cad57bc4a363747533a701abWei Huang        int len = address.length();
91378f81825431c8c52cad57bc4a363747533a701abWei Huang
91478f81825431c8c52cad57bc4a363747533a701abWei Huang        for (int i = 0; i < len; i++) {
91578f81825431c8c52cad57bc4a363747533a701abWei Huang            char c = address.charAt(i);
91678f81825431c8c52cad57bc4a363747533a701abWei Huang
91778f81825431c8c52cad57bc4a363747533a701abWei Huang            // accept the first '+' in the address
91878f81825431c8c52cad57bc4a363747533a701abWei Huang            if (c == '+' && builder.length() == 0) {
91978f81825431c8c52cad57bc4a363747533a701abWei Huang                builder.append(c);
92078f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
92178f81825431c8c52cad57bc4a363747533a701abWei Huang            }
92278f81825431c8c52cad57bc4a363747533a701abWei Huang
92378f81825431c8c52cad57bc4a363747533a701abWei Huang            if (Character.isDigit(c)) {
92478f81825431c8c52cad57bc4a363747533a701abWei Huang                builder.append(c);
92578f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
92678f81825431c8c52cad57bc4a363747533a701abWei Huang            }
92778f81825431c8c52cad57bc4a363747533a701abWei Huang
92878f81825431c8c52cad57bc4a363747533a701abWei Huang            if (numericSugarMap.get(c) == null) {
92978f81825431c8c52cad57bc4a363747533a701abWei Huang                return null;
93078f81825431c8c52cad57bc4a363747533a701abWei Huang            }
93178f81825431c8c52cad57bc4a363747533a701abWei Huang        }
93278f81825431c8c52cad57bc4a363747533a701abWei Huang        return builder.toString();
93378f81825431c8c52cad57bc4a363747533a701abWei Huang    }
93478f81825431c8c52cad57bc4a363747533a701abWei Huang
93578f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
93678f81825431c8c52cad57bc4a363747533a701abWei Huang     * Returns true if the address passed in is a valid MMS address.
93778f81825431c8c52cad57bc4a363747533a701abWei Huang     */
93878f81825431c8c52cad57bc4a363747533a701abWei Huang    public static boolean isValidMmsAddress(String address) {
93978f81825431c8c52cad57bc4a363747533a701abWei Huang        String retVal = parseMmsAddress(address);
94078f81825431c8c52cad57bc4a363747533a701abWei Huang        return (retVal != null);
94178f81825431c8c52cad57bc4a363747533a701abWei Huang    }
94278f81825431c8c52cad57bc4a363747533a701abWei Huang
94378f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
94478f81825431c8c52cad57bc4a363747533a701abWei Huang     * parse the input address to be a valid MMS address.
94578f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address is an email address, leave it as is.
94678f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address can be parsed into a valid MMS phone number, return the parsed number.
94778f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address is a compliant alias address, leave it as is.
94878f81825431c8c52cad57bc4a363747533a701abWei Huang     */
94978f81825431c8c52cad57bc4a363747533a701abWei Huang    public static String parseMmsAddress(String address) {
95078f81825431c8c52cad57bc4a363747533a701abWei Huang        // if it's a valid Email address, use that.
95178f81825431c8c52cad57bc4a363747533a701abWei Huang        if (Mms.isEmailAddress(address)) {
95278f81825431c8c52cad57bc4a363747533a701abWei Huang            return address;
95378f81825431c8c52cad57bc4a363747533a701abWei Huang        }
95478f81825431c8c52cad57bc4a363747533a701abWei Huang
95578f81825431c8c52cad57bc4a363747533a701abWei Huang        // if we are able to parse the address to a MMS compliant phone number, take that.
95678f81825431c8c52cad57bc4a363747533a701abWei Huang        String retVal = parsePhoneNumberForMms(address);
95778f81825431c8c52cad57bc4a363747533a701abWei Huang        if (retVal != null) {
95878f81825431c8c52cad57bc4a363747533a701abWei Huang            return retVal;
95978f81825431c8c52cad57bc4a363747533a701abWei Huang        }
96078f81825431c8c52cad57bc4a363747533a701abWei Huang
96178f81825431c8c52cad57bc4a363747533a701abWei Huang        // if it's an alias compliant address, use that.
96278f81825431c8c52cad57bc4a363747533a701abWei Huang        if (isAlias(address)) {
96378f81825431c8c52cad57bc4a363747533a701abWei Huang            return address;
96478f81825431c8c52cad57bc4a363747533a701abWei Huang        }
96578f81825431c8c52cad57bc4a363747533a701abWei Huang
96678f81825431c8c52cad57bc4a363747533a701abWei Huang        // it's not a valid MMS address, return null
96778f81825431c8c52cad57bc4a363747533a701abWei Huang        return null;
96878f81825431c8c52cad57bc4a363747533a701abWei Huang    }
96978f81825431c8c52cad57bc4a363747533a701abWei Huang
970812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    private static void log(String msg) {
971812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        Log.d(TAG, "[MsgUtils] " + msg);
972812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    }
97372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
974