1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.widget;
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.Cursor;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Bitmap;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.Spannable;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.SpannableString;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.format.DateUtils;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.format.Formatter;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.style.ForegroundColorSpan;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.RemoteViews;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.RemoteViewsService;
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R;
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.MessagingContentProvider;
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ConversationMessageData;
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessageData;
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessagePartData;
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.ImageResource;
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.MediaRequest;
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.MediaResourceManager;
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.MessagePartImageRequestDescriptor;
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.MessagePartVideoThumbnailRequestDescriptor;
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.UriImageRequestDescriptor;
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.media.VideoThumbnailRequest;
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsUtils;
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.UIIntents;
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.AvatarUriUtil;
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Dates;
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil;
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.OsUtil;
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.PhoneUtils;
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.List;
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class WidgetConversationService extends RemoteViewsService {
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final String TAG = LogUtil.BUGLE_WIDGET_TAG;
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static final int IMAGE_ATTACHMENT_SIZE = 400;
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public RemoteViewsFactory onGetViewFactory(Intent intent) {
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            LogUtil.v(TAG, "onGetViewFactory intent: " + intent);
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return new WidgetConversationFactory(getApplicationContext(), intent);
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Remote Views Factory for the conversation widget.
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static class WidgetConversationFactory extends BaseWidgetFactory {
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private ImageResource mImageResource;
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private String mConversationId;
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public WidgetConversationFactory(Context context, Intent intent) {
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            super(context, intent);
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mConversationId = intent.getStringExtra(UIIntents.UI_INTENT_EXTRA_CONVERSATION_ID);
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.v(TAG, "BugleFactory intent: " + intent + "widget id: " + mAppWidgetId);
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mIconSize = (int) context.getResources()
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    .getDimension(R.dimen.contact_icon_view_normal_size);
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public void onCreate() {
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.v(TAG, "onCreate");
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            super.onCreate();
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // If the conversation for this widget has been removed, we want to update the widget to
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // "Tap to configure" mode.
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (!WidgetConversationProvider.isWidgetConfigured(mAppWidgetId)) {
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                WidgetConversationProvider.rebuildWidget(mContext, mAppWidgetId);
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected Cursor doQuery() {
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (TextUtils.isEmpty(mConversationId)) {
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.w(TAG, "doQuery no conversation id");
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return null;
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Uri uri = MessagingContentProvider.buildConversationMessagesUri(mConversationId);
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (uri != null) {
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.w(TAG, "doQuery uri: " + uri.toString());
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return mContext.getContentResolver().query(uri,
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    ConversationMessageData.getProjection(),
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    null,       // where
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    null,       // selection args
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    null        // sort order
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    );
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        /**
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         * @return the {@link RemoteViews} for a specific position in the list.
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         */
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public RemoteViews getViewAt(final int originalPosition) {
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            synchronized (sWidgetLock) {
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // "View more messages" view.
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (mCursor == null
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        || (mShouldShowViewMore && originalPosition == 0)) {
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return getViewMoreItemsView();
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // The message cursor is in reverse order for performance reasons.
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final int position = getCount() - originalPosition - 1;
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (!mCursor.moveToPosition(position)) {
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    // If we ever fail to move to a position, return the "View More messages"
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    // view.
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    LogUtil.w(TAG, "Failed to move to position: " + position);
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return getViewMoreItemsView();
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final ConversationMessageData message = new ConversationMessageData();
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                message.bind(mCursor);
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Inflate and fill out the remote view
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final RemoteViews remoteViews = new RemoteViews(
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        mContext.getPackageName(), message.getIsIncoming() ?
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                R.layout.widget_message_item_incoming :
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                    R.layout.widget_message_item_outgoing);
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final boolean hasUnreadMessages = false; //!message.getIsRead();
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Date
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setTextViewText(R.id.date, boldifyIfUnread(
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        Dates.getWidgetTimeString(message.getReceivedTimeStamp(),
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                false /*abbreviated*/),
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        hasUnreadMessages));
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // On click intent.
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Intent intent = UIIntents.get().getIntentForConversationActivity(mContext,
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        mConversationId, null /* draft */);
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Attachments
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                int attachmentStringId = 0;
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setViewVisibility(R.id.attachmentFrame, View.GONE);
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                int scrollToPosition = originalPosition;
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final int cursorCount = mCursor.getCount();
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (cursorCount > MAX_ITEMS_TO_SHOW) {
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    scrollToPosition += cursorCount - MAX_ITEMS_TO_SHOW;
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    LogUtil.v(TAG, "getViewAt position: " + originalPosition +
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            " computed position: " + position +
173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            " scrollToPosition: " + scrollToPosition +
174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            " cursorCount: " + cursorCount +
175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            " MAX_ITEMS_TO_SHOW: " + MAX_ITEMS_TO_SHOW);
176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                intent.putExtra(UIIntents.UI_INTENT_EXTRA_MESSAGE_POSITION, scrollToPosition);
179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (message.hasAttachments()) {
180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final List<MessagePartData> attachments = message.getAttachments();
181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    for (MessagePartData part : attachments) {
182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        final boolean videoWithThumbnail = part.isVideo()
183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                && (VideoThumbnailRequest.shouldShowIncomingVideoThumbnails()
184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                || !message.getIsIncoming());
185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        if (part.isImage() || videoWithThumbnail) {
186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            final Uri uri = part.getContentUri();
187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            remoteViews.setViewVisibility(R.id.attachmentFrame, View.VISIBLE);
188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            remoteViews.setViewVisibility(R.id.playButton, part.isVideo() ?
189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                    View.VISIBLE : View.GONE);
190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            remoteViews.setImageViewBitmap(R.id.attachment,
191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                    getAttachmentBitmap(part));
192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            intent.putExtra(UIIntents.UI_INTENT_EXTRA_ATTACHMENT_URI ,
193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                    uri.toString());
194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            intent.putExtra(UIIntents.UI_INTENT_EXTRA_ATTACHMENT_TYPE ,
195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                    part.getContentType());
196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            break;
197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        } else if (part.isVideo()) {
198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            attachmentStringId = R.string.conversation_list_snippet_video;
199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            break;
200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        if (part.isAudio()) {
202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            attachmentStringId = R.string.conversation_list_snippet_audio_clip;
203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            break;
204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        if (part.isVCard()) {
206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            attachmentStringId = R.string.conversation_list_snippet_vcard;
207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            break;
208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setOnClickFillInIntent(message.getIsIncoming() ?
213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        R.id.widget_message_item_incoming :
214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            R.id.widget_message_item_outgoing,
215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        intent);
216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Avatar
218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                boolean includeAvatar;
219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (OsUtil.isAtLeastJB()) {
220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final Bundle options = mAppWidgetManager.getAppWidgetOptions(mAppWidgetId);
221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        LogUtil.v(TAG, "getViewAt BugleWidgetProvider.WIDGET_SIZE_KEY: " +
223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                options.getInt(BugleWidgetProvider.WIDGET_SIZE_KEY));
224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    includeAvatar = options.getInt(BugleWidgetProvider.WIDGET_SIZE_KEY)
227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            == BugleWidgetProvider.SIZE_LARGE;
228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } else {
229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    includeAvatar = true;
230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Show the avatar (and shadow) when grande size, otherwise hide it.
233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setViewVisibility(R.id.avatarView, includeAvatar ?
234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        View.VISIBLE : View.GONE);
235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setViewVisibility(R.id.avatarShadow, includeAvatar ?
236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        View.VISIBLE : View.GONE);
237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Uri avatarUri = AvatarUriUtil.createAvatarUri(
239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        message.getSenderProfilePhotoUri(),
240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        message.getSenderFullName(),
241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        message.getSenderNormalizedDestination(),
242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        message.getSenderContactLookupKey());
243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setImageViewBitmap(R.id.avatarView, includeAvatar ?
245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        getAvatarBitmap(avatarUri) : null);
246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                String text = message.getText();
248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (attachmentStringId != 0) {
249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final String attachment = mContext.getString(attachmentStringId);
250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (!TextUtils.isEmpty(text)) {
251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        text += '\n' + attachment;
252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        text = attachment;
254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setViewVisibility(R.id.message, View.VISIBLE);
258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                updateViewContent(text, message, remoteViews);
259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return remoteViews;
261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // updateViewContent figures out what to show in the message and date fields based on
265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // the message status. This code came from ConversationMessageView.updateViewContent, but
266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // had to be simplified to work with our simple widget list item.
267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // updateViewContent also builds the accessibility content description for the list item.
268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private void updateViewContent(final String messageText,
269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final ConversationMessageData message,
270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final RemoteViews remoteViews) {
271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            int titleResId = -1;
272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            int statusResId = -1;
273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            boolean showInRed = false;
274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            String statusText = null;
275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            switch(message.getStatus()) {
276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING:
277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING:
278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD:
279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD:
280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    titleResId = R.string.message_title_downloading;
281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    statusResId = R.string.message_status_downloading;
282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_YET_TO_MANUAL_DOWNLOAD:
285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (!OsUtil.isSecondaryUser()) {
286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        titleResId = R.string.message_title_manual_download;
287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        statusResId = R.string.message_status_download;
288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_EXPIRED_OR_NOT_AVAILABLE:
292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (!OsUtil.isSecondaryUser()) {
293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        titleResId = R.string.message_title_download_failed;
294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        statusResId = R.string.message_status_download_error;
295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        showInRed = true;
296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED:
300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (!OsUtil.isSecondaryUser()) {
301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        titleResId = R.string.message_title_download_failed;
302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        statusResId = R.string.message_status_download;
303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        showInRed = true;
304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_YET_TO_SEND:
308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_SENDING:
309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    statusResId = R.string.message_status_sending;
310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_RESENDING:
313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_AWAITING_RETRY:
314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    statusResId = R.string.message_status_send_retrying;
315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_FAILED_EMERGENCY_NUMBER:
318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    statusResId = R.string.message_status_send_failed_emergency_number;
319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    showInRed = true;
320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_FAILED:
323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    // don't show the error state unless we're the default sms app
324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (PhoneUtils.getDefault().isDefaultSmsApp()) {
325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        statusResId = MmsUtils.mapRawStatusToErrorResourceId(
326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                message.getStatus(), message.getRawTelephonyStatus());
327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        showInRed = true;
328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        break;
329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    // FALL THROUGH HERE
331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_OUTGOING_COMPLETE:
333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                case MessageData.BUGLE_STATUS_INCOMING_COMPLETE:
334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                default:
335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (!message.getCanClusterWithNextMessage()) {
336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        statusText = Dates.getWidgetTimeString(message.getReceivedTimeStamp(),
337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                false /*abbreviated*/).toString();
338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    break;
340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // Build the content description while we're populating the various fields.
343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final StringBuilder description = new StringBuilder();
344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String separator = mContext.getString(R.string.enumeration_comma);
345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // Sender information
346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean hasPlainTextMessage = !(TextUtils.isEmpty(message.getText()));
347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (message.getIsIncoming()) {
348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                int senderResId = hasPlainTextMessage
349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    ? R.string.incoming_text_sender_content_description
350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    : R.string.incoming_sender_content_description;
351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(mContext.getString(senderResId, message.getSenderDisplayName()));
352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                int senderResId = hasPlainTextMessage
354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    ? R.string.outgoing_text_sender_content_description
355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    : R.string.outgoing_sender_content_description;
356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(mContext.getString(senderResId));
357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean titleVisible = (titleResId >= 0);
360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (titleVisible) {
361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String titleText = mContext.getString(titleResId);
362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setTextViewText(R.id.message, titleText);
363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String mmsInfoText = mContext.getString(
365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        R.string.mms_info,
366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        Formatter.formatFileSize(mContext, message.getSmsMessageSize()),
367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        DateUtils.formatDateTime(
368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                mContext,
369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                message.getMmsExpiry(),
370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                DateUtils.FORMAT_SHOW_DATE |
371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                DateUtils.FORMAT_SHOW_TIME |
372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                DateUtils.FORMAT_NUMERIC_DATE |
373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                DateUtils.FORMAT_NO_YEAR));
374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setTextViewText(R.id.date, mmsInfoText);
375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(separator);
376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(mmsInfoText);
377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else if (!TextUtils.isEmpty(messageText)) {
378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setTextViewText(R.id.message, messageText);
379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(separator);
380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(messageText);
381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setViewVisibility(R.id.message, View.GONE);
383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String subjectText = MmsUtils.cleanseMmsSubject(mContext.getResources(),
386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    message.getMmsSubject());
387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (!TextUtils.isEmpty(subjectText)) {
388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(separator);
389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(subjectText);
390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (statusResId >= 0) {
393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                statusText = mContext.getString(statusResId);
394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Spannable colorStr = new SpannableString(statusText);
395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (showInRed) {
396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    colorStr.setSpan(new ForegroundColorSpan(
397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            mContext.getResources().getColor(R.color.timestamp_text_failed)),
398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            0, statusText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                remoteViews.setTextViewText(R.id.date, colorStr);
401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(separator);
402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(colorStr);
403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(separator);
405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                description.append(Dates.getWidgetTimeString(message.getReceivedTimeStamp(),
406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        false /*abbreviated*/));
407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (message.hasAttachments()) {
410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final List<MessagePartData> attachments = message.getAttachments();
411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                int stringId;
412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                for (MessagePartData part : attachments) {
413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (part.isImage()) {
414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        stringId = R.string.conversation_list_snippet_picture;
415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else if (part.isVideo()) {
416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        stringId = R.string.conversation_list_snippet_video;
417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else if (part.isAudio()) {
418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        stringId = R.string.conversation_list_snippet_audio_clip;
419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else if (part.isVCard()) {
420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        stringId = R.string.conversation_list_snippet_vcard;
421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        stringId = 0;
423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (stringId > 0) {
425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        description.append(separator);
426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        description.append(mContext.getString(stringId));
427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            remoteViews.setContentDescription(message.getIsIncoming() ?
431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.id.widget_message_item_incoming :
432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        R.id.widget_message_item_outgoing, description);
433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private Bitmap getAttachmentBitmap(final MessagePartData part) {
436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            UriImageRequestDescriptor descriptor;
437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (part.isImage()) {
438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                descriptor = new MessagePartImageRequestDescriptor(part,
439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        IMAGE_ATTACHMENT_SIZE, // desiredWidth
440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        IMAGE_ATTACHMENT_SIZE,  // desiredHeight
441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        true // isStatic
442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        );
443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else if (part.isVideo()) {
444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                descriptor = new MessagePartVideoThumbnailRequestDescriptor(part);
445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return null;
447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final MediaRequest<ImageResource> imageRequest =
450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    descriptor.buildSyncMediaRequest(mContext);
451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final ImageResource imageResource =
452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    MediaResourceManager.get().requestMediaResourceSync(imageRequest);
453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (imageResource != null && imageResource.getBitmap() != null) {
454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                setImageResource(imageResource);
455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return Bitmap.createBitmap(imageResource.getBitmap());
456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                releaseImageResource();
458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return null;
459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        /**
463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         * @return the "View more messages" view. When the user taps this item, they're
464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         * taken to the conversation in Bugle.
465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd         */
466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected RemoteViews getViewMoreItemsView() {
468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.v(TAG, "getViewMoreConversationsView");
470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final RemoteViews view = new RemoteViews(mContext.getPackageName(),
472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.layout.widget_loading);
473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            view.setTextViewText(
474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.id.loading_text, mContext.getText(R.string.view_more_messages));
475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // Tapping this "More messages" item should take us to the conversation.
477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Intent intent = UIIntents.get().getIntentForConversationActivity(mContext,
478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    mConversationId, null /* draft */);
479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            view.setOnClickFillInIntent(R.id.widget_loading, intent);
480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return view;
481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public RemoteViews getLoadingView() {
485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final RemoteViews view = new RemoteViews(mContext.getPackageName(),
486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.layout.widget_loading);
487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            view.setTextViewText(
488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.id.loading_text, mContext.getText(R.string.loading_messages));
489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return view;
490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public int getViewTypeCount() {
494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return 3;   // Number of different list items that can be returned -
495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // 1- incoming list item
496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // 2- outgoing list item
497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // 3- more items list item
498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        @Override
501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        protected int getMainLayoutId() {
502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return R.layout.widget_conversation;
503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private void setImageResource(final ImageResource resource) {
506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (mImageResource != resource) {
507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Clear out any information for what is currently used
508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                releaseImageResource();
509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mImageResource = resource;
510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private void releaseImageResource() {
514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (mImageResource != null) {
515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mImageResource.release();
516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mImageResource = null;
518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
522