MessageUtils.java revision bb8edcae15a50b3651261db70791afc668aae294
172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.ui;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20bb8edcae15a50b3651261db70791afc668aae294Tom Taylorimport com.android.mms.MmsApp;
2186a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylorimport com.android.mms.MmsConfig;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R;
23812391ad832f3fdac054ad3a50af563da16e99b5Wei Huangimport com.android.mms.LogTag;
24b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrickimport com.android.mms.data.WorkingMessage;
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.MediaModel;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.SlideModel;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.model.SlideshowModel;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.transaction.MmsMessageSender;
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.AddressUtils;
3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.ContentType;
3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.MmsException;
3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.CharacterSets;
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.EncodedStringValue;
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.MultimediaMessagePdu;
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.NotificationInd;
36b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrickimport com.google.android.mms.pdu.PduBody;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduHeaders;
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduPart;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduPersister;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.RetrieveConf;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.SendReq;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.util.SqliteWrapper;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlertDialog;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnClickListener;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.res.Resources;
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Bitmap;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Bitmap.CompressFormat;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.media.RingtoneManager;
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.Mms;
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.Sms;
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.PhoneNumberUtils;
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.TelephonyManager;
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.DateUtils;
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.Time;
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.URLSpan;
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
681224b6560c48e146ee304f9c807296f6c22cdefbTom Taylorimport android.widget.Toast;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.ByteArrayOutputStream;
719242286c35743422051d439d7460cd0a1426899cWei Huangimport java.io.IOException;
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.HashMap;
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Map;
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.concurrent.ConcurrentHashMap;
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * An utility class for managing messages.
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessageUtils {
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    interface ResizeImageResultCallback {
82edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        void onResizeResult(PduPart part, boolean append);
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
859242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = LogTag.TAG;
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String sLocalNumber;
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Cache of both groups of space-separated ids to their full
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // comma-separated display names, as well as individual ids to
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // display names.
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // TODO: is it possible for canonical address ID keys to be
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // re-used?  SQLite does reuse IDs on NULL id_ insert, but does
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // anything ever delete from the mmssms.db canonical_addresses
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // table?  Nothing that I could find.
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final Map<String, String> sRecipientAddress =
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            new ConcurrentHashMap<String, String>(20 /* initial capacity */);
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9878f81825431c8c52cad57bc4a363747533a701abWei Huang
9978f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
10078f81825431c8c52cad57bc4a363747533a701abWei Huang     * MMS address parsing data structures
10178f81825431c8c52cad57bc4a363747533a701abWei Huang     */
10278f81825431c8c52cad57bc4a363747533a701abWei Huang    // allowable phone number separators
10378f81825431c8c52cad57bc4a363747533a701abWei Huang    private static final char[] NUMERIC_CHARS_SUGAR = {
10478f81825431c8c52cad57bc4a363747533a701abWei Huang        '-', '.', ',', '(', ')', ' ', '/', '\\', '*', '#', '+'
10578f81825431c8c52cad57bc4a363747533a701abWei Huang    };
10678f81825431c8c52cad57bc4a363747533a701abWei Huang
10778f81825431c8c52cad57bc4a363747533a701abWei Huang    private static HashMap numericSugarMap = new HashMap (NUMERIC_CHARS_SUGAR.length);
10878f81825431c8c52cad57bc4a363747533a701abWei Huang
10978f81825431c8c52cad57bc4a363747533a701abWei Huang    static {
11078f81825431c8c52cad57bc4a363747533a701abWei Huang        for (int i = 0; i < NUMERIC_CHARS_SUGAR.length; i++) {
11178f81825431c8c52cad57bc4a363747533a701abWei Huang            numericSugarMap.put(NUMERIC_CHARS_SUGAR[i], NUMERIC_CHARS_SUGAR[i]);
11278f81825431c8c52cad57bc4a363747533a701abWei Huang        }
11378f81825431c8c52cad57bc4a363747533a701abWei Huang    }
11478f81825431c8c52cad57bc4a363747533a701abWei Huang
11578f81825431c8c52cad57bc4a363747533a701abWei Huang
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private MessageUtils() {
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Forbidden being instantiated.
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String getMessageDetails(Context context, Cursor cursor, int size) {
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor == null) {
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return null;
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ("mms".equals(cursor.getString(MessageListAdapter.COLUMN_MSG_TYPE))) {
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (type) {
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return getNotificationIndDetails(context, cursor);
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case PduHeaders.MESSAGE_TYPE_SEND_REQ:
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return getMultimediaMessageDetails(context, cursor, size);
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                default:
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "No details could be retrieved.");
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return "";
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return getTextMessageDetails(context, cursor);
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getNotificationIndDetails(Context context, Cursor cursor) {
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NotificationInd nInd;
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            nInd = (NotificationInd) PduPersister.getPduPersister(
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context).load(uri);
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Failed to load the message: " + uri, e);
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return context.getResources().getString(R.string.cannot_get_details);
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Mms Notification.
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.multimedia_notification));
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // From: ***
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String from = extractEncStr(context, nInd.getFrom());
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.from_label));
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(!TextUtils.isEmpty(from)? from:
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                 res.getString(R.string.hidden_sender_address));
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                R.string.expire_on,
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                MessageUtils.formatTimeStampString(
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                        context, nInd.getExpiry() * 1000L, true)));
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Subject: ***
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.subject_label));
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue subject = nInd.getSubject();
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (subject != null) {
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(subject.getString());
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message class: Personal/Advertisement/Infomational/Auto
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_class_label));
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(new String(nInd.getMessageClass()));
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message size: *** KB
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_size_label));
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(String.valueOf((nInd.getMessageSize() + 1023) / 1024));
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(context.getString(R.string.kilobyte));
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getMultimediaMessageDetails(
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, Cursor cursor, int size) {
20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (type == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return getNotificationIndDetails(context, cursor);
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MultimediaMessagePdu msg;
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            msg = (MultimediaMessagePdu) PduPersister.getPduPersister(
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context).load(uri);
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Failed to load the message: " + uri, e);
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return context.getResources().getString(R.string.cannot_get_details);
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Text message.
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.multimedia_message));
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msg instanceof RetrieveConf) {
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // From: ***
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String from = extractEncStr(context, ((RetrieveConf) msg).getFrom());
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append('\n');
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.from_label));
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(!TextUtils.isEmpty(from)? from:
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                  res.getString(R.string.hidden_sender_address));
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // To: ***
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.to_address_label));
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue[] to = msg.getTo();
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (to != null) {
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(EncodedStringValue.concat(to));
24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        else {
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.w(TAG, "recipient list is empty!");
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
2449c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Bcc: ***
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msg instanceof SendReq) {
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            EncodedStringValue[] values = ((SendReq) msg).getBcc();
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ((values != null) && (values.length > 0)) {
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append('\n');
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append(res.getString(R.string.bcc_label));
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                details.append(EncodedStringValue.concat(values));
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgBox = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_BOX);
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msgBox == Mms.MESSAGE_BOX_DRAFTS) {
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.saved_label));
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (msgBox == Mms.MESSAGE_BOX_INBOX) {
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.received_label));
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.sent_label));
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(MessageUtils.formatTimeStampString(
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                context, msg.getDate() * 1000L, true));
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Subject: ***
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.subject_label));
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EncodedStringValue subject = msg.getSubject();
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (subject != null) {
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String subStr = subject.getString();
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Message size should include size of subject.
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            size += subStr.length();
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(subStr);
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Priority: High/Normal/Low
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.priority_label));
28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(getPriorityDescription(context, msg.getPriority()));
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message size: *** KB
28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_size_label));
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append((size - 1)/1000 + 1);
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(" KB");
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String getTextMessageDetails(Context context, Cursor cursor) {
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder details = new StringBuilder();
29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Message Type: Text message.
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.message_type_label));
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(res.getString(R.string.text_message));
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Address: ***
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int smsType = cursor.getInt(MessageListAdapter.COLUMN_SMS_TYPE);
30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (Sms.isOutgoingFolder(smsType)) {
30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.to_address_label));
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.from_label));
31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(cursor.getString(MessageListAdapter.COLUMN_SMS_ADDRESS));
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Date: ***
31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append('\n');
31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (smsType == Sms.MESSAGE_TYPE_DRAFT) {
31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.saved_label));
31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (smsType == Sms.MESSAGE_TYPE_INBOX) {
31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.received_label));
32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            details.append(res.getString(R.string.sent_label));
32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long date = cursor.getLong(MessageListAdapter.COLUMN_SMS_DATE);
32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        details.append(MessageUtils.formatTimeStampString(context, date, true));
32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
327161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        // Error code: ***
328161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        int errorCode = cursor.getInt(MessageListAdapter.COLUMN_SMS_ERROR_CODE);
329161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        if (errorCode != 0) {
330161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor            details.append('\n')
331161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor                .append(res.getString(R.string.error_code_label))
332161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor                .append(errorCode);
333161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor        }
334161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return details.toString();
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    static private String getPriorityDescription(Context context, int PriorityValue) {
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources res = context.getResources();
34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch(PriorityValue) {
34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_HIGH:
34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_high);
34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_LOW:
34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_low);
34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case PduHeaders.PRIORITY_NORMAL:
34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            default:
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return res.getString(R.string.priority_normal);
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static int getAttachmentType(SlideshowModel model) {
35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (model == null) {
353b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return WorkingMessage.TEXT;
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int numberOfSlides = model.size();
35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (numberOfSlides > 1) {
358b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return WorkingMessage.SLIDESHOW;
35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (numberOfSlides == 1) {
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Only one slide in the slide-show.
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = model.get(0);
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasVideo()) {
363b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.VIDEO;
36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasAudio() && slide.hasImage()) {
367b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.SLIDESHOW;
36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasAudio()) {
371b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.AUDIO;
37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasImage()) {
375b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.IMAGE;
37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (slide.hasText()) {
379b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return WorkingMessage.TEXT;
38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
383b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        return WorkingMessage.TEXT;
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
3859c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String formatTimeStampString(Context context, long when) {
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return formatTimeStampString(context, when, false);
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String formatTimeStampString(Context context, long when, boolean fullFormat) {
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Time then = new Time();
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        then.set(when);
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Time now = new Time();
39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        now.setToNow();
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Basic settings for formatDateTime() we want for all cases.
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int format_flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT |
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                           DateUtils.FORMAT_ABBREV_ALL |
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                           DateUtils.FORMAT_CAP_AMPM;
400836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project
40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If the message is from a different year, show the date and year.
40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (then.year != now.year) {
40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (then.yearDay != now.yearDay) {
40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // If it is from a different day than today, show only the date.
40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_DATE;
40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Otherwise, if the message is from today, show the time.
40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            format_flags |= DateUtils.FORMAT_SHOW_TIME;
41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
412836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // If the caller has asked for full details, make sure to show the date
413836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // and time no matter what we've determined above (but still make showing
414836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        // the year only happen if it is a different year from today).
415836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        if (fullFormat) {
416836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            format_flags |= (DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
417836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        }
418836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return DateUtils.formatDateTime(context, when, format_flags);
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * @parameter recipientIds space-separated list of ids
42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String getRecipientsByIds(Context context, String recipientIds,
42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                            boolean allowQuery) {
42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String value = sRecipientAddress.get(recipientIds);
42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (value != null) {
42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return value;
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!TextUtils.isEmpty(recipientIds)) {
43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            StringBuilder addressBuf = extractIdsToAddresses(
43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context, recipientIds, allowQuery);
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (addressBuf == null) {
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // temporary error?  Don't memoize.
43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return "";
43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            value = addressBuf.toString();
43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            value = "";
44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sRecipientAddress.put(recipientIds, value);
44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return value;
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static StringBuilder extractIdsToAddresses(Context context, String recipients,
44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                                       boolean allowQuery) {
44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder addressBuf = new StringBuilder();
44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String[] recipientIds = recipients.split(" ");
45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean firstItem = true;
45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (String recipientId : recipientIds) {
45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String value = sRecipientAddress.get(recipientId);
4532f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project
4542f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            if (value == null) {
4552f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                if (!allowQuery) {
4562f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // when allowQuery is false, if any value from sRecipientAddress.get() is null,
4572f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // return null for the whole thing. We don't want to stick partial result
4582f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // into sRecipientAddress for multiple recipient ids.
4592f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    return null;
4602f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                }
4612f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project
46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Uri uri = Uri.parse("content://mms-sms/canonical-address/" + recipientId);
46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                               uri, null, null, null, null);
46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (c != null) {
46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    try {
46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (c.moveToFirst()) {
46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            value = c.getString(0);
4699c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor                            sRecipientAddress.put(recipientId, value);
47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    } finally {
47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        c.close();
47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (value == null) {
47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                continue;
47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (firstItem) {
48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                firstItem = false;
48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                addressBuf.append(";");
48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            addressBuf.append(value);
48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return (addressBuf.length() == 0) ? null : addressBuf;
48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectAudio(Context context, int requestCode) {
49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (context instanceof Activity) {
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
4955c0aff95e0c161d22fad145fe344430fd3474bc1Dave Sparks            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_INCLUDE_DRM, false);
4969c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context.getString(R.string.select_audio));
49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(intent, requestCode);
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void recordSound(Context context, int requestCode) {
50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (context instanceof Activity) {
50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.setType(ContentType.AUDIO_AMR);
50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.setClassName("com.android.soundrecorder",
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "com.android.soundrecorder.SoundRecorder");
50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(intent, requestCode);
51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectVideo(Context context, int requestCode) {
51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        selectMediaByType(context, requestCode, ContentType.VIDEO_UNSPECIFIED);
51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void selectImage(Context context, int requestCode) {
51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        selectMediaByType(context, requestCode, ContentType.IMAGE_UNSPECIFIED);
51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static void selectMediaByType(
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, int requestCode, String contentType) {
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project         if (context instanceof Activity) {
52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT);
52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            innerIntent.setType(contentType);
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent wrapperIntent = Intent.createChooser(innerIntent, null);
53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((Activity) context).startActivityForResult(wrapperIntent, requestCode);
53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void viewSimpleSlideshow(Context context, SlideshowModel slideshow) {
53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!slideshow.isSimple()) {
53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new IllegalArgumentException(
53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "viewSimpleSlideshow() called on a non-simple slideshow");
53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = slideshow.get(0);
54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MediaModel mm = null;
54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide.hasImage()) {
54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mm = slide.getImage();
54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (slide.hasVideo()) {
54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mm = slide.getVideo();
54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
5479c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW);
54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
5509c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
5519c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        String contentType;
5529c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        if (mm.isDrmProtected()) {
5539c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            contentType = mm.getDrmObject().getContentType();
5549c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        } else {
5559c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor            contentType = mm.getContentType();
5569c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        }
5579c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor        intent.setDataAndType(mm.getUri(), contentType);
55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        context.startActivity(intent);
55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
5609c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void showErrorDialog(Context context,
56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String title, String message) {
56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(context);
56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setIcon(R.drawable.ic_sms_mms_not_delivered);
56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(title);
56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setMessage(message);
56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setPositiveButton(android.R.string.ok, null);
56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
572bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project    /**
573bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project     * The quality parameter which is used to compress JPEG images.
574bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project     */
575bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project    public static final int IMAGE_COMPRESSION_QUALITY = 80;
5769242286c35743422051d439d7460cd0a1426899cWei Huang    /**
5779242286c35743422051d439d7460cd0a1426899cWei Huang     * The minimum quality parameter which is used to compress JPEG images.
5789242286c35743422051d439d7460cd0a1426899cWei Huang     */
5799242286c35743422051d439d7460cd0a1426899cWei Huang    public static final int MINIMUM_IMAGE_COMPRESSION_QUALITY = 50;
580bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project
58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static Uri saveBitmapAsPart(Context context, Uri messageUri, Bitmap bitmap)
58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throws MmsException {
583812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ByteArrayOutputStream os = new ByteArrayOutputStream();
585bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project        bitmap.compress(CompressFormat.JPEG, IMAGE_COMPRESSION_QUALITY, os);
58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPart part = new PduPart();
58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        part.setContentType("image/jpeg".getBytes());
59072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String contentId = "Image" + System.currentTimeMillis();
59172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        part.setContentLocation((contentId + ".jpg").getBytes());
59272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        part.setContentId(contentId.getBytes());
59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        part.setData(os.toByteArray());
59472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
595812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        Uri retVal = PduPersister.getPduPersister(context).persistPart(part,
59672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        ContentUris.parseId(messageUri));
597812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
598812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
599812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            log("saveBitmapAsPart: persisted part with uri=" + retVal);
600812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
601812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
602812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        return retVal;
60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
605f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson    /**
606f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * Message overhead that reduces the maximum image byte size.
607f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * 5000 is a realistic overhead number that allows for user to also include
608f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     * a small MIDI file or a couple pages of text along with the picture.
609f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson     */
610f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson    public static final int MESSAGE_OVERHEAD = 5000;
611f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson
61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void resizeImageAsync(final Context context,
61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final Uri imageUri, final Handler handler,
614edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            final ResizeImageResultCallback cb,
615edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            final boolean append) {
61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6171224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor        // Show a progress toast if the resize hasn't finished
61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // within one second.
61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Stash the runnable for showing it away so we can cancel
62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // it later if the resize completes ahead of the deadline.
62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Runnable showProgress = new Runnable() {
62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
6231224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                Toast.makeText(context, R.string.compressing, Toast.LENGTH_SHORT).show();
62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Schedule it for one second from now.
62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        handler.postDelayed(showProgress, 1000);
6289c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new Thread(new Runnable() {
63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                final PduPart part;
63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    UriImage image = new UriImage(context, imageUri);
63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part = image.getResizedImageAsPart(
63586a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylor                        MmsConfig.getMaxImageWidth(),
636f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson                        MmsConfig.getMaxImageHeight(),
637f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson                        MmsConfig.getMaxMessageSize() - MESSAGE_OVERHEAD);
63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } finally {
6391224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                    // Cancel pending show of the progress toast if necessary.
64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    handler.removeCallbacks(showProgress);
64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                handler.post(new Runnable() {
64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    public void run() {
645edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                        cb.onResizeResult(part, append);
64672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
64772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                });
64872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
64972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }).start();
65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void showDiscardDraftConfirmDialog(Context context,
65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnClickListener listener) {
65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new AlertDialog.Builder(context)
65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setTitle(R.string.discard_message)
65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setMessage(R.string.discard_message_reason)
65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setPositiveButton(R.string.yes, listener)
65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .setNegativeButton(R.string.no, null)
66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                .show();
66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
66313dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang    public static String getLocalNumber() {
66472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null == sLocalNumber) {
665bb8edcae15a50b3651261db70791afc668aae294Tom Taylor            sLocalNumber = MmsApp.getApplication().getTelephonyManager().getLine1Number();
66672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return sLocalNumber;
66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
67072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static boolean isLocalNumber(String number) {
671f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        if (number == null) {
672f1bf432304bcc277397b028192eaf01a94c6417dWei Huang            return false;
673f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        }
674f1bf432304bcc277397b028192eaf01a94c6417dWei Huang
675f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // we don't use Mms.isEmailAddress() because it is too strict for comparing addresses like
676f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // "foo+caf_=6505551212=tmomail.net@gmail.com", which is the 'from' address from a forwarded email
677f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // message from Gmail. We don't want to treat "foo+caf_=6505551212=tmomail.net@gmail.com" and
678f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        // "6505551212" to be the same.
679f1bf432304bcc277397b028192eaf01a94c6417dWei Huang        if (number.indexOf('@') >= 0) {
680b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang            return false;
681b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang        }
682b6a0383dc77efea9a48e43e4e21a4290e89bf0a4Wei Huang
68372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return PhoneNumberUtils.compare(number, getLocalNumber());
68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void handleReadReport(final Context context,
68772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final long threadId,
68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final int status,
68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final Runnable callback) {
69072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String selection = Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF
69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            + " AND " + Mms.READ + " = 0"
69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            + " AND " + Mms.READ_REPORT + " = " + PduHeaders.VALUE_YES;
69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (threadId != -1) {
69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            selection = selection + " AND " + Mms.THREAD_ID + " = " + threadId;
69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Mms.Inbox.CONTENT_URI, new String[] {Mms._ID, Mms.MESSAGE_ID},
70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        selection, null, null);
70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (c == null) {
70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Map<String, String> map = new HashMap<String, String>();
70772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
70872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (c.getCount() == 0) {
70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
71172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return;
71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            while (c.moveToNext()) {
71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, c.getLong(0));
71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                map.put(c.getString(1), AddressUtils.getFrom(context, uri));
71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } finally {
72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            c.close();
72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnClickListener positiveListener = new OnClickListener() {
72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (final Map.Entry<String, String> entry : map.entrySet()) {
72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MmsMessageSender.sendReadRec(context, entry.getValue(),
72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                                 entry.getKey(), status);
72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
73172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnClickListener negativeListener = new OnClickListener() {
73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
73972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
74272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        OnCancelListener cancelListener = new OnCancelListener() {
74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onCancel(DialogInterface dialog) {
74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (callback != null) {
74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    callback.run();
74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        };
75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        confirmReadReportDialog(context, positiveListener,
75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                         negativeListener,
75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                         cancelListener);
75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static void confirmReadReportDialog(Context context,
75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnClickListener positiveListener, OnClickListener negativeListener,
75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            OnCancelListener cancelListener) {
76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(context);
76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setCancelable(true);
76272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(R.string.confirm);
76372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setMessage(R.string.message_send_read_report);
76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setPositiveButton(R.string.yes, positiveListener);
76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setNegativeButton(R.string.no, negativeListener);
76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setOnCancelListener(cancelListener);
76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
76872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static String extractEncStrFromCursor(Cursor cursor,
77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int columnRawBytes, int columnCharset) {
77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String rawBytes = cursor.getString(columnRawBytes);
77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int charset = cursor.getInt(columnCharset);
77472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (TextUtils.isEmpty(rawBytes)) {
77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return "";
77772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (charset == CharacterSets.ANY_CHARSET) {
77872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return rawBytes;
77972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
78072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return new EncodedStringValue(charset, PduPersister.getBytes(rawBytes)).getString();
78172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
78272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
78372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
78472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static String extractEncStr(Context context, EncodedStringValue value) {
78572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (value != null) {
78672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return value.getString();
78772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
78872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return "";
78972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
79072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
7919c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static ArrayList<String> extractUris(URLSpan[] spans) {
79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int size = spans.length;
79472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<String> accumulator = new ArrayList<String>();
79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
79672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < size; i++) {
79772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            accumulator.add(spans[i].getURL());
79872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
79972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return accumulator;
80072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
80172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8024522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    /**
8034522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * Play/view the message attachments.
8044522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * TOOD: We need to save the draft before launching another activity to view the attachments.
8054522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       This is hacky though since we will do saveDraft twice and slow down the UI.
8064522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       We should pass the slideshow in intent extra to the view activity instead of
8074522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     *       asking it to read attachments from database.
8084522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param context
8094522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param msgUri the MMS message URI in database
8104522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param slideshow the slideshow to save
8114522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param persister the PDU persister for updating the database
8124522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     * @param sendReq the SendReq for updating the database
8134522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen     */
8144522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    public static void viewMmsMessageAttachment(Context context, Uri msgUri,
815b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            SlideshowModel slideshow) {
8164522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        boolean isSimple = (slideshow == null) ? false : slideshow.isSimple();
8174522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        if (isSimple) {
8184522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            // In attachment-editor mode, we only ever have one slide.
8194522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            MessageUtils.viewSimpleSlideshow(context, slideshow);
8204522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        } else {
821b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            // If a slideshow was provided, save it to disk first.
822b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            if (slideshow != null) {
823b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                PduPersister persister = PduPersister.getPduPersister(context);
824b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                try {
825b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    PduBody pb = slideshow.toPduBody();
826b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    persister.updateParts(msgUri, pb);
827b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    slideshow.sync(pb);
828b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                } catch (MmsException e) {
829b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    Log.e(TAG, "Unable to save message for preview");
830b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    return;
831b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                }
8324522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            }
8334522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            // Launch the slideshow activity to play/view.
8344522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            Intent intent = new Intent(context, SlideshowActivity.class);
8354522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            intent.setData(msgUri);
8364522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen            context.startActivity(intent);
8374522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen        }
8384522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen    }
8399c5e0566f91c7622a7cf9d53a6a84c56ed4139c1Tom Taylor
840b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    public static void viewMmsMessageAttachment(Context context, WorkingMessage msg) {
841b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        SlideshowModel slideshow = msg.getSlideshow();
842b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (slideshow == null) {
843b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            throw new IllegalStateException("msg.getSlideshow() == null");
844b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
845b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (slideshow.isSimple()) {
846b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            MessageUtils.viewSimpleSlideshow(context, slideshow);
847b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        } else {
84816f98e62c279550854e665e25c212ea0b04a6b6bTom Taylor            Uri uri = msg.saveAsMms(false);
849b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            viewMmsMessageAttachment(context, uri, slideshow);
850b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
851b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
852812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
8539242286c35743422051d439d7460cd0a1426899cWei Huang    /**
8549242286c35743422051d439d7460cd0a1426899cWei Huang     * Debugging
8559242286c35743422051d439d7460cd0a1426899cWei Huang     */
8569242286c35743422051d439d7460cd0a1426899cWei Huang    public static void writeHprofDataToFile(){
8579242286c35743422051d439d7460cd0a1426899cWei Huang        String filename = "/sdcard/mms_oom_hprof_data";
8589242286c35743422051d439d7460cd0a1426899cWei Huang        try {
8599242286c35743422051d439d7460cd0a1426899cWei Huang            android.os.Debug.dumpHprofData(filename);
8609242286c35743422051d439d7460cd0a1426899cWei Huang            Log.i(TAG, "##### written hprof data to " + filename);
8619242286c35743422051d439d7460cd0a1426899cWei Huang        } catch (IOException ex) {
8629242286c35743422051d439d7460cd0a1426899cWei Huang            Log.e(TAG, "writeHprofDataToFile: caught " + ex);
8639242286c35743422051d439d7460cd0a1426899cWei Huang        }
8649242286c35743422051d439d7460cd0a1426899cWei Huang    }
8659242286c35743422051d439d7460cd0a1426899cWei Huang
866817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    public static boolean isAlias(String string) {
867f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (!MmsConfig.isAliasEnabled()) {
868f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
869f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
870f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
871f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (TextUtils.isEmpty(string)) {
872f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
873f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
874f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
87578f81825431c8c52cad57bc4a363747533a701abWei Huang        // TODO: not sure if this is the right thing to use. Mms.isPhoneNumber() is
87678f81825431c8c52cad57bc4a363747533a701abWei Huang        // intended for searching for things that look like they might be phone numbers
87778f81825431c8c52cad57bc4a363747533a701abWei Huang        // in arbitrary text, not for validating whether something is in fact a phone number.
87878f81825431c8c52cad57bc4a363747533a701abWei Huang        // It will miss many things that are legitimate phone numbers.
879f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (Mms.isPhoneNumber(string)) {
880f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
881f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
882f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
883f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (!isAlphaNumeric(string)) {
884f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
885f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
886f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
887f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        int len = string.length();
888f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
889f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        if (len < MmsConfig.getAliasMinChars() || len > MmsConfig.getAliasMaxChars()) {
890f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang            return false;
891f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        }
892f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang
893f6ddd0bb7fff9f479f6c306d3d3e154c6c533061Wei Huang        return true;
894817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    }
895817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom
896817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    public static boolean isAlphaNumeric(String s) {
897817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        char[] chars = s.toCharArray();
898817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        for (int x = 0; x < chars.length; x++) {
899817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom            char c = chars[x];
90078f81825431c8c52cad57bc4a363747533a701abWei Huang
90178f81825431c8c52cad57bc4a363747533a701abWei Huang            if ((c >= 'a') && (c <= 'z')) {
90278f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
90378f81825431c8c52cad57bc4a363747533a701abWei Huang            }
90478f81825431c8c52cad57bc4a363747533a701abWei Huang            if ((c >= 'A') && (c <= 'Z')) {
90578f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
90678f81825431c8c52cad57bc4a363747533a701abWei Huang            }
90778f81825431c8c52cad57bc4a363747533a701abWei Huang            if ((c >= '0') && (c <= '9')) {
90878f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
90978f81825431c8c52cad57bc4a363747533a701abWei Huang            }
91078f81825431c8c52cad57bc4a363747533a701abWei Huang
91178f81825431c8c52cad57bc4a363747533a701abWei Huang            return false;
912817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        }
913817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom        return true;
914817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom    }
915817eb982a66303a8f87fc3061e3493a232627e96Satish Roddom
91678f81825431c8c52cad57bc4a363747533a701abWei Huang
91778f81825431c8c52cad57bc4a363747533a701abWei Huang
91878f81825431c8c52cad57bc4a363747533a701abWei Huang
91978f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
92078f81825431c8c52cad57bc4a363747533a701abWei Huang     * Given a phone number, return the string without syntactic sugar, meaning parens,
92178f81825431c8c52cad57bc4a363747533a701abWei Huang     * spaces, slashes, dots, dashes, etc. If the input string contains non-numeric
92278f81825431c8c52cad57bc4a363747533a701abWei Huang     * non-punctuation characters, return null.
92378f81825431c8c52cad57bc4a363747533a701abWei Huang     */
92478f81825431c8c52cad57bc4a363747533a701abWei Huang    private static String parsePhoneNumberForMms(String address) {
92578f81825431c8c52cad57bc4a363747533a701abWei Huang        StringBuilder builder = new StringBuilder();
92678f81825431c8c52cad57bc4a363747533a701abWei Huang        int len = address.length();
92778f81825431c8c52cad57bc4a363747533a701abWei Huang
92878f81825431c8c52cad57bc4a363747533a701abWei Huang        for (int i = 0; i < len; i++) {
92978f81825431c8c52cad57bc4a363747533a701abWei Huang            char c = address.charAt(i);
93078f81825431c8c52cad57bc4a363747533a701abWei Huang
93178f81825431c8c52cad57bc4a363747533a701abWei Huang            // accept the first '+' in the address
93278f81825431c8c52cad57bc4a363747533a701abWei Huang            if (c == '+' && builder.length() == 0) {
93378f81825431c8c52cad57bc4a363747533a701abWei Huang                builder.append(c);
93478f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
93578f81825431c8c52cad57bc4a363747533a701abWei Huang            }
93678f81825431c8c52cad57bc4a363747533a701abWei Huang
93778f81825431c8c52cad57bc4a363747533a701abWei Huang            if (Character.isDigit(c)) {
93878f81825431c8c52cad57bc4a363747533a701abWei Huang                builder.append(c);
93978f81825431c8c52cad57bc4a363747533a701abWei Huang                continue;
94078f81825431c8c52cad57bc4a363747533a701abWei Huang            }
94178f81825431c8c52cad57bc4a363747533a701abWei Huang
94278f81825431c8c52cad57bc4a363747533a701abWei Huang            if (numericSugarMap.get(c) == null) {
94378f81825431c8c52cad57bc4a363747533a701abWei Huang                return null;
94478f81825431c8c52cad57bc4a363747533a701abWei Huang            }
94578f81825431c8c52cad57bc4a363747533a701abWei Huang        }
94678f81825431c8c52cad57bc4a363747533a701abWei Huang        return builder.toString();
94778f81825431c8c52cad57bc4a363747533a701abWei Huang    }
94878f81825431c8c52cad57bc4a363747533a701abWei Huang
94978f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
95078f81825431c8c52cad57bc4a363747533a701abWei Huang     * Returns true if the address passed in is a valid MMS address.
95178f81825431c8c52cad57bc4a363747533a701abWei Huang     */
95278f81825431c8c52cad57bc4a363747533a701abWei Huang    public static boolean isValidMmsAddress(String address) {
95378f81825431c8c52cad57bc4a363747533a701abWei Huang        String retVal = parseMmsAddress(address);
95478f81825431c8c52cad57bc4a363747533a701abWei Huang        return (retVal != null);
95578f81825431c8c52cad57bc4a363747533a701abWei Huang    }
95678f81825431c8c52cad57bc4a363747533a701abWei Huang
95778f81825431c8c52cad57bc4a363747533a701abWei Huang    /**
95878f81825431c8c52cad57bc4a363747533a701abWei Huang     * parse the input address to be a valid MMS address.
95978f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address is an email address, leave it as is.
96078f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address can be parsed into a valid MMS phone number, return the parsed number.
96178f81825431c8c52cad57bc4a363747533a701abWei Huang     * - if the address is a compliant alias address, leave it as is.
96278f81825431c8c52cad57bc4a363747533a701abWei Huang     */
96378f81825431c8c52cad57bc4a363747533a701abWei Huang    public static String parseMmsAddress(String address) {
96478f81825431c8c52cad57bc4a363747533a701abWei Huang        // if it's a valid Email address, use that.
96578f81825431c8c52cad57bc4a363747533a701abWei Huang        if (Mms.isEmailAddress(address)) {
96678f81825431c8c52cad57bc4a363747533a701abWei Huang            return address;
96778f81825431c8c52cad57bc4a363747533a701abWei Huang        }
96878f81825431c8c52cad57bc4a363747533a701abWei Huang
96978f81825431c8c52cad57bc4a363747533a701abWei Huang        // if we are able to parse the address to a MMS compliant phone number, take that.
97078f81825431c8c52cad57bc4a363747533a701abWei Huang        String retVal = parsePhoneNumberForMms(address);
97178f81825431c8c52cad57bc4a363747533a701abWei Huang        if (retVal != null) {
97278f81825431c8c52cad57bc4a363747533a701abWei Huang            return retVal;
97378f81825431c8c52cad57bc4a363747533a701abWei Huang        }
97478f81825431c8c52cad57bc4a363747533a701abWei Huang
97578f81825431c8c52cad57bc4a363747533a701abWei Huang        // if it's an alias compliant address, use that.
97678f81825431c8c52cad57bc4a363747533a701abWei Huang        if (isAlias(address)) {
97778f81825431c8c52cad57bc4a363747533a701abWei Huang            return address;
97878f81825431c8c52cad57bc4a363747533a701abWei Huang        }
97978f81825431c8c52cad57bc4a363747533a701abWei Huang
98078f81825431c8c52cad57bc4a363747533a701abWei Huang        // it's not a valid MMS address, return null
98178f81825431c8c52cad57bc4a363747533a701abWei Huang        return null;
98278f81825431c8c52cad57bc4a363747533a701abWei Huang    }
98378f81825431c8c52cad57bc4a363747533a701abWei Huang
984812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    private static void log(String msg) {
985812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        Log.d(TAG, "[MsgUtils] " + msg);
986812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    }
98772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
988