blob: 230e63431702400264ca380e1abf3032027aed14 [file] [log] [blame]
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -07001/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mail.browse;
19
20import android.app.AlertDialog;
Paul Westbrook8081df42012-09-10 15:43:36 -070021import android.app.FragmentManager;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070022import android.content.ActivityNotFoundException;
23import android.content.Context;
24import android.content.Intent;
Andrew Sapperstein2fd167d2014-01-28 10:07:38 -080025import android.support.v4.text.BidiFormatter;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070026import android.text.TextUtils;
27import android.util.AttributeSet;
28import android.view.LayoutInflater;
29import android.view.Menu;
30import android.view.MenuItem;
31import android.view.View;
32import android.view.View.OnClickListener;
33import android.view.ViewGroup;
Mark Weie18f42d2012-10-17 15:06:19 -070034import android.widget.FrameLayout;
Andrew Sapperstein4c7d8b52012-06-11 18:44:42 -070035import android.widget.ImageButton;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070036import android.widget.ImageView;
37import android.widget.PopupMenu;
38import android.widget.PopupMenu.OnMenuItemClickListener;
39import android.widget.ProgressBar;
40import android.widget.TextView;
41
42import com.android.mail.R;
Andy Huange003b4c2013-08-16 10:32:05 -070043import com.android.mail.analytics.Analytics;
Andrew Sappersteinf59d01c2014-02-20 10:27:06 -080044import com.android.mail.providers.Account;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070045import com.android.mail.providers.Attachment;
46import com.android.mail.providers.UIProvider.AttachmentDestination;
47import com.android.mail.providers.UIProvider.AttachmentState;
Andrew Sappersteinf59d01c2014-02-20 10:27:06 -080048import com.android.mail.ui.AccountFeedbackActivity;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070049import com.android.mail.utils.AttachmentUtils;
Paul Westbrookb334c902012-06-25 11:42:46 -070050import com.android.mail.utils.LogTag;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070051import com.android.mail.utils.LogUtils;
52import com.android.mail.utils.MimeType;
53import com.android.mail.utils.Utils;
Andrew Sapperstein4cb51db2012-07-20 15:54:27 -070054
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070055/**
56 * View for a single attachment in conversation view. Shows download status and allows launching
57 * intents to act on an attachment.
58 *
59 */
Mark Weie18f42d2012-10-17 15:06:19 -070060public class MessageAttachmentBar extends FrameLayout implements OnClickListener,
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070061 OnMenuItemClickListener, AttachmentViewInterface {
62
63 private Attachment mAttachment;
64 private TextView mTitle;
65 private TextView mSubTitle;
66 private String mAttachmentSizeText;
67 private String mDisplayType;
68 private ProgressBar mProgress;
Andrew Sapperstein4c7d8b52012-06-11 18:44:42 -070069 private ImageButton mCancelButton;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070070 private PopupMenu mPopup;
71 private ImageView mOverflowButton;
72
73 private final AttachmentActionHandler mActionHandler;
Andrew Sappersteinc445aba2012-08-01 15:38:40 -070074 private boolean mSaveClicked;
Andrew Sappersteinf59d01c2014-02-20 10:27:06 -080075 private Account mAccount;
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070076
Mark Wei74313d92012-10-18 12:51:50 -070077 private final Runnable mUpdateRunnable = new Runnable() {
78 @Override
79 public void run() {
80 updateActionsInternal();
81 }
82 };
83
Paul Westbrookb334c902012-06-25 11:42:46 -070084 private static final String LOG_TAG = LogTag.getLogTag();
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070085
Andrew Sapperstein7638a102013-06-25 13:54:52 -070086
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -070087 public MessageAttachmentBar(Context context) {
88 this(context, null);
89 }
90
91 public MessageAttachmentBar(Context context, AttributeSet attrs) {
92 super(context, attrs);
93
94 mActionHandler = new AttachmentActionHandler(context, this);
95 }
96
Paul Westbrook8081df42012-09-10 15:43:36 -070097 public void initialize(FragmentManager fragmentManager) {
98 mActionHandler.initialize(fragmentManager);
99 }
100
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700101 public static MessageAttachmentBar inflate(LayoutInflater inflater, ViewGroup parent) {
102 MessageAttachmentBar view = (MessageAttachmentBar) inflater.inflate(
103 R.layout.conversation_message_attachment_bar, parent, false);
104 return view;
105 }
106
107 /**
108 * Render or update an attachment's view. This happens immediately upon instantiation, and
109 * repeatedly as status updates stream in, so only properties with new or changed values will
110 * cause sub-views to update.
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700111 */
Andy Huang4f347e82014-02-25 17:32:28 -0800112 public void render(Attachment attachment, Account account, ConversationMessage message,
Andrew Sapperstein2fd167d2014-01-28 10:07:38 -0800113 boolean loaderResult, BidiFormatter bidiFormatter) {
Andrew Sapperstein7638a102013-06-25 13:54:52 -0700114 // get account uri for potential eml viewer usage
Andrew Sappersteinf59d01c2014-02-20 10:27:06 -0800115 mAccount = account;
Andrew Sapperstein7638a102013-06-25 13:54:52 -0700116
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700117 final Attachment prevAttachment = mAttachment;
118 mAttachment = attachment;
Andy Huang023f8bd2014-03-26 17:44:53 -0700119 mActionHandler.setAccount(mAccount.getEmailAddress());
Andy Huang4f347e82014-02-25 17:32:28 -0800120 mActionHandler.setMessage(message);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700121 mActionHandler.setAttachment(mAttachment);
122
Andrew Sappersteinc445aba2012-08-01 15:38:40 -0700123 // reset mSaveClicked if we are not currently downloading
124 // So if the download fails or the download completes, we stop
125 // showing progress, etc
126 mSaveClicked = !attachment.isDownloading() ? false : mSaveClicked;
127
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700128 LogUtils.d(LOG_TAG, "got attachment list row: name=%s state/dest=%d/%d dled=%d" +
Martin Hibdon519c2182013-09-20 17:27:57 -0700129 " contentUri=%s MIME=%s flags=%d", attachment.getName(), attachment.state,
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700130 attachment.destination, attachment.downloadedSize, attachment.contentUri,
Martin Hibdon519c2182013-09-20 17:27:57 -0700131 attachment.getContentType(), attachment.flags);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700132
Andrew Sapperstein7348cf22014-02-20 10:53:23 -0800133 final String attachmentName = attachment.getName();
Martin Hibdon519c2182013-09-20 17:27:57 -0700134 if ((attachment.flags & Attachment.FLAG_DUMMY_ATTACHMENT) != 0) {
135 mTitle.setText(R.string.load_attachment);
136 } else if (prevAttachment == null
Andrew Sapperstein7348cf22014-02-20 10:53:23 -0800137 || !TextUtils.equals(attachmentName, prevAttachment.getName())) {
Andrew Sappersteinf59d01c2014-02-20 10:27:06 -0800138 mTitle.setText(attachmentName);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700139 }
140
141 if (prevAttachment == null || attachment.size != prevAttachment.size) {
Andrew Sapperstein2fd167d2014-01-28 10:07:38 -0800142 mAttachmentSizeText = bidiFormatter.unicodeWrap(
143 AttachmentUtils.convertToHumanReadableSize(getContext(), attachment.size));
144 mDisplayType = bidiFormatter.unicodeWrap(
145 AttachmentUtils.getDisplayType(getContext(), attachment));
Mark Weic40e5e82013-01-08 18:12:08 -0800146 updateSubtitleText();
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700147 }
148
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700149 updateActions();
Paul Westbrook8081df42012-09-10 15:43:36 -0700150 mActionHandler.updateStatus(loaderResult);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700151 }
152
153 @Override
154 protected void onFinishInflate() {
155 super.onFinishInflate();
156
157 mTitle = (TextView) findViewById(R.id.attachment_title);
158 mSubTitle = (TextView) findViewById(R.id.attachment_subtitle);
159 mProgress = (ProgressBar) findViewById(R.id.attachment_progress);
160 mOverflowButton = (ImageView) findViewById(R.id.overflow);
Andrew Sapperstein4c7d8b52012-06-11 18:44:42 -0700161 mCancelButton = (ImageButton) findViewById(R.id.cancel_attachment);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700162
163 setOnClickListener(this);
164 mOverflowButton.setOnClickListener(this);
165 mCancelButton.setOnClickListener(this);
166 }
167
168 @Override
169 public void onClick(View v) {
170 onClick(v.getId(), v);
171 }
172
173 @Override
174 public boolean onMenuItemClick(MenuItem item) {
175 mPopup.dismiss();
176 return onClick(item.getItemId(), null);
177 }
178
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700179 private boolean onClick(final int res, final View v) {
180 if (res == R.id.preview_attachment) {
181 previewAttachment();
182 } else if (res == R.id.save_attachment) {
183 if (mAttachment.canSave()) {
184 mActionHandler.startDownloadingAttachment(AttachmentDestination.EXTERNAL);
185 mSaveClicked = true;
Andy Huange003b4c2013-08-16 10:32:05 -0700186
187 Analytics.getInstance().sendEvent(
188 "save_attachment", Utils.normalizeMimeType(mAttachment.getContentType()),
189 "attachment_bar", mAttachment.size);
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700190 }
191 } else if (res == R.id.download_again) {
192 if (mAttachment.isPresentLocally()) {
Mark Weice9db802013-08-08 14:57:29 -0700193 mActionHandler.showDownloadingDialog();
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700194 mActionHandler.startRedownloadingAttachment(mAttachment);
Andy Huange003b4c2013-08-16 10:32:05 -0700195
196 Analytics.getInstance().sendEvent("redownload_attachment",
197 Utils.normalizeMimeType(mAttachment.getContentType()), "attachment_bar",
198 mAttachment.size);
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700199 }
200 } else if (res == R.id.cancel_attachment) {
201 mActionHandler.cancelAttachment();
202 mSaveClicked = false;
Andy Huange003b4c2013-08-16 10:32:05 -0700203
204 Analytics.getInstance().sendEvent(
205 "cancel_attachment", Utils.normalizeMimeType(mAttachment.getContentType()),
206 "attachment_bar", mAttachment.size);
Andy Huang4f347e82014-02-25 17:32:28 -0800207 } else if (res == R.id.attachment_extra_option1) {
208 mActionHandler.handleOption1();
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700209 } else if (res == R.id.overflow) {
210 // If no overflow items are visible, just bail out.
211 // We shouldn't be able to get here anyhow since the overflow
212 // button should be hidden.
213 if (shouldShowOverflow()) {
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700214 if (mPopup == null) {
215 mPopup = new PopupMenu(getContext(), v);
216 mPopup.getMenuInflater().inflate(R.menu.message_footer_overflow_menu,
217 mPopup.getMenu());
218 mPopup.setOnMenuItemClickListener(this);
219 }
220
221 final Menu menu = mPopup.getMenu();
Mark Wei856200a2012-11-09 17:26:09 -0800222 menu.findItem(R.id.preview_attachment).setVisible(shouldShowPreview());
223 menu.findItem(R.id.save_attachment).setVisible(shouldShowSave());
224 menu.findItem(R.id.download_again).setVisible(shouldShowDownloadAgain());
Andy Huang4f347e82014-02-25 17:32:28 -0800225 menu.findItem(R.id.attachment_extra_option1).setVisible(shouldShowExtraOption1());
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700226
227 mPopup.show();
Andrew Sapperstein381c3222014-04-20 12:23:57 -0700228
229 AttachmentActionHandler.onOverflowOpened(getContext());
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700230 }
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700231 } else {
232 // Handles clicking the attachment
233 // in any area that is not the overflow
234 // button or cancel button or one of the
235 // overflow items.
Andy Huange003b4c2013-08-16 10:32:05 -0700236 final String mime = Utils.normalizeMimeType(mAttachment.getContentType());
237 final String action;
238
Martin Hibdon519c2182013-09-20 17:27:57 -0700239 if ((mAttachment.flags & Attachment.FLAG_DUMMY_ATTACHMENT) != 0) {
240 // This is a dummy. We need to download it, but not attempt to open or preview.
241 mActionHandler.showDownloadingDialog();
242 mActionHandler.setViewOnFinish(false);
243 mActionHandler.startDownloadingAttachment(AttachmentDestination.CACHE);
244
245 action = null;
246 }
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700247 // If we can install, install.
248 else if (MimeType.isInstallable(mAttachment.getContentType())) {
249 // Save to external because the package manager only handles
250 // file:// uris not content:// uris. We do the same
251 // workaround in
252 // UiProvider#getUiAttachmentsCursorForUIAttachments()
253 mActionHandler.showAttachment(AttachmentDestination.EXTERNAL);
Andy Huange003b4c2013-08-16 10:32:05 -0700254
255 action = "attachment_bar_install";
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700256 }
257 // If we can view or play with an on-device app,
258 // view or play.
259 else if (MimeType.isViewable(
260 getContext(), mAttachment.contentUri, mAttachment.getContentType())) {
261 mActionHandler.showAttachment(AttachmentDestination.CACHE);
Andy Huange003b4c2013-08-16 10:32:05 -0700262
263 action = "attachment_bar";
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700264 }
265 // If we can only preview the attachment, preview.
266 else if (mAttachment.canPreview()) {
267 previewAttachment();
Andy Huange003b4c2013-08-16 10:32:05 -0700268
269 action = null;
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700270 }
271 // Otherwise, if we cannot do anything, show the info dialog.
272 else {
273 AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
274 int dialogMessage = R.string.no_application_found;
275 builder.setTitle(R.string.more_info_attachment)
276 .setMessage(dialogMessage)
277 .show();
Andy Huange003b4c2013-08-16 10:32:05 -0700278
279 action = "attachment_bar_no_viewer";
280 }
281
282 if (action != null) {
283 Analytics.getInstance()
284 .sendEvent("view_attachment", mime, action, mAttachment.size);
Scott Kennedy2b9d80e2013-07-30 23:03:45 -0700285 }
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700286 }
287
288 return true;
289 }
290
Mark Wei856200a2012-11-09 17:26:09 -0800291 private boolean shouldShowPreview() {
292 // state could be anything
293 return mAttachment.canPreview();
294 }
295
296 private boolean shouldShowSave() {
297 return mAttachment.canSave() && !mSaveClicked;
298 }
299
300 private boolean shouldShowDownloadAgain() {
Mark Weib5ef9a92013-01-30 17:32:37 -0800301 // implies state == SAVED || state == FAILED
Andrew Sapperstein7434e802013-06-21 11:26:49 -0700302 // and the attachment supports re-download
303 return mAttachment.supportsDownloadAgain() && mAttachment.isDownloadFinishedOrFailed();
Mark Wei856200a2012-11-09 17:26:09 -0800304 }
305
Andy Huang4f347e82014-02-25 17:32:28 -0800306 private boolean shouldShowExtraOption1() {
307 return mActionHandler.shouldShowExtraOption1();
308 }
309
Mark Wei856200a2012-11-09 17:26:09 -0800310 private boolean shouldShowOverflow() {
Andy Huang4f347e82014-02-25 17:32:28 -0800311 return (shouldShowPreview() || shouldShowSave() || shouldShowDownloadAgain()
312 || shouldShowExtraOption1()) && !shouldShowCancel();
Mark Wei856200a2012-11-09 17:26:09 -0800313 }
314
315 private boolean shouldShowCancel() {
316 return mAttachment.isDownloading() && mSaveClicked;
317 }
318
Mark Weic40e5e82013-01-08 18:12:08 -0800319 @Override
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700320 public void viewAttachment() {
Paul Westbrook591eb372012-07-25 12:07:20 -0700321 if (mAttachment.contentUri == null) {
322 LogUtils.e(LOG_TAG, "viewAttachment with null content uri");
323 return;
324 }
325
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700326 Intent intent = new Intent(Intent.ACTION_VIEW);
327 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
328 | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
Andrew Sapperstein8d4791c2013-06-11 15:04:38 -0700329
330 final String contentType = mAttachment.getContentType();
Mark Weibf3a5c52013-02-14 15:18:43 -0800331 Utils.setIntentDataAndTypeAndNormalize(
Andrew Sapperstein8d4791c2013-06-11 15:04:38 -0700332 intent, mAttachment.contentUri, contentType);
333
334 // For EML files, we want to open our dedicated
335 // viewer rather than let any activity open it.
336 if (MimeType.isEmlMimeType(contentType)) {
Andrew Sappersteinf59d01c2014-02-20 10:27:06 -0800337 intent.setClass(getContext().getApplicationContext(), EmlViewerActivity.class);
338 intent.putExtra(AccountFeedbackActivity.EXTRA_ACCOUNT_URI,
339 mAccount != null ? mAccount.uri : null);
Andrew Sapperstein8d4791c2013-06-11 15:04:38 -0700340 }
341
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700342 try {
343 getContext().startActivity(intent);
344 } catch (ActivityNotFoundException e) {
345 // couldn't find activity for View intent
Paul Westbrook591eb372012-07-25 12:07:20 -0700346 LogUtils.e(LOG_TAG, e, "Couldn't find Activity for intent");
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700347 }
348 }
349
350 private void previewAttachment() {
Andrew Sappersteind6318e52012-08-06 10:27:07 -0700351 if (mAttachment.canPreview()) {
Paul Westbrookd49db8e2012-08-03 17:58:46 -0700352 final Intent previewIntent =
353 new Intent(Intent.ACTION_VIEW, mAttachment.previewIntentUri);
354 getContext().startActivity(previewIntent);
Andy Huange003b4c2013-08-16 10:32:05 -0700355
356 Analytics.getInstance().sendEvent(
357 "preview_attachment", Utils.normalizeMimeType(mAttachment.getContentType()),
358 null, mAttachment.size);
Paul Westbrookd49db8e2012-08-03 17:58:46 -0700359 }
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700360 }
361
Scott Kennedy3b965d72013-06-25 14:36:55 -0700362 private static void setButtonVisible(View button, boolean visible) {
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700363 button.setVisibility(visible ? VISIBLE : GONE);
364 }
365
366 /**
367 * Update all actions based on current downloading state.
368 */
369 private void updateActions() {
Mark Wei74313d92012-10-18 12:51:50 -0700370 removeCallbacks(mUpdateRunnable);
371 post(mUpdateRunnable);
372 }
373
374 private void updateActionsInternal() {
Andrew Sappersteina95161c2012-07-31 16:00:21 -0700375 // If the progress dialog is visible, skip any of the updating
Mark Weibbe74ae2012-11-19 11:20:09 -0800376 if (mActionHandler.isProgressDialogVisible()) {
Andrew Sappersteina95161c2012-07-31 16:00:21 -0700377 return;
378 }
379
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700380 // To avoid visibility state transition bugs, every button's visibility should be touched
381 // once by this routine.
Mark Wei856200a2012-11-09 17:26:09 -0800382 setButtonVisible(mCancelButton, shouldShowCancel());
383 setButtonVisible(mOverflowButton, shouldShowOverflow());
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700384 }
385
Mark Weic40e5e82013-01-08 18:12:08 -0800386 @Override
Andrew Sapperstein532f4822012-06-14 12:48:35 -0700387 public void onUpdateStatus() {
Mark Weic40e5e82013-01-08 18:12:08 -0800388 updateSubtitleText();
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700389 }
390
Mark Weic40e5e82013-01-08 18:12:08 -0800391 @Override
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700392 public void updateProgress(boolean showProgress) {
Paul Westbrook4dabcc92012-09-19 16:31:23 -0700393 if (mAttachment.isDownloading()) {
Andrew Sappersteinc445aba2012-08-01 15:38:40 -0700394 mProgress.setMax(mAttachment.size);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700395 mProgress.setProgress(mAttachment.downloadedSize);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700396 mProgress.setIndeterminate(!showProgress);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700397 mProgress.setVisibility(VISIBLE);
Mark Weie18f42d2012-10-17 15:06:19 -0700398 mSubTitle.setVisibility(INVISIBLE);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700399 } else {
400 mProgress.setVisibility(INVISIBLE);
Mark Weie18f42d2012-10-17 15:06:19 -0700401 mSubTitle.setVisibility(VISIBLE);
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700402 }
403 }
404
Mark Weic40e5e82013-01-08 18:12:08 -0800405 private void updateSubtitleText() {
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700406 // TODO: make this a formatted resource when we have a UX design.
407 // not worth translation right now.
Mark Weic40e5e82013-01-08 18:12:08 -0800408 final StringBuilder sb = new StringBuilder();
409 if (mAttachment.state == AttachmentState.FAILED) {
410 sb.append(getResources().getString(R.string.download_failed));
411 } else {
412 if (mAttachment.isSavedToExternal()) {
413 sb.append(getResources().getString(R.string.saved, mAttachmentSizeText));
414 } else {
415 sb.append(mAttachmentSizeText);
416 }
Martin Hibdon519c2182013-09-20 17:27:57 -0700417 if (mDisplayType != null) {
418 sb.append(' ');
419 sb.append(mDisplayType);
420 }
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700421 }
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700422 mSubTitle.setText(sb.toString());
423 }
Andrew Sapperstein4aa1c132012-06-08 17:53:41 -0700424}