1f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein/*
2f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * Copyright (C) 2011 The Android Open Source Project
3f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein *
4f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License");
5f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * you may not use this file except in compliance with the License.
6f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * You may obtain a copy of the License at
7f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein *
8f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein *      http://www.apache.org/licenses/LICENSE-2.0
9f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein *
10f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * Unless required by applicable law or agreed to in writing, software
11f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS,
12f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * See the License for the specific language governing permissions and
14f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * limitations under the License.
15f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein */
16f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
17237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sappersteinpackage com.android.mail.ui;
18f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
198081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrookimport android.app.FragmentManager;
20f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.content.Context;
2162066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport android.graphics.Bitmap;
22f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.net.Uri;
23e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sappersteinimport android.util.AttributeSet;
24f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.view.LayoutInflater;
25f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.view.View;
26f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.widget.FrameLayout;
27f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
28e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sappersteinimport com.android.mail.R;
29237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sappersteinimport com.android.mail.browse.MessageAttachmentTile;
30237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sappersteinimport com.android.mail.compose.ComposeAttachmentTile;
31f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport com.android.mail.providers.Attachment;
3262066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.android.mail.ui.AttachmentTile.AttachmentPreview;
3362066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.android.mail.ui.AttachmentTile.AttachmentPreviewCache;
346d15a75aac7dd468ed94a97f324f6920d89cf28dMark Wei
3562066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.google.common.collect.Lists;
3662066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.google.common.collect.Maps;
3762066e47fe69c33b60ed970e46809ba81d044064Mark Wei
3862066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport java.util.ArrayList;
3962066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport java.util.HashMap;
40f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport java.util.List;
41f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
42f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein/**
43237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein * Acts as a grid composed of {@link AttachmentTile}s.
44f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein */
4562066e47fe69c33b60ed970e46809ba81d044064Mark Weipublic class AttachmentTileGrid extends FrameLayout implements AttachmentPreviewCache {
4669c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei    private final LayoutInflater mInflater;
47f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    private Uri mAttachmentsListUri;
48e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    private final int mTileMinSize;
49e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    private int mColumnCount;
504cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein    private List<Attachment> mAttachments;
5169c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei    private final HashMap<String, AttachmentPreview> mAttachmentPreviews;
528081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook    private FragmentManager mFragmentManager;
53f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
54e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    public AttachmentTileGrid(Context context, AttributeSet attrs) {
55e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        super(context, attrs);
56f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        mInflater = LayoutInflater.from(context);
57e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        mTileMinSize = context.getResources()
58e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                .getDimensionPixelSize(R.dimen.attachment_tile_min_size);
5962066e47fe69c33b60ed970e46809ba81d044064Mark Wei        mAttachmentPreviews = Maps.newHashMap();
60f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    }
61f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
62f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    /**
63e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein     * Configures the grid to add {@link Attachment}s information to the views.
64f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein     */
658081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook    public void configureGrid(FragmentManager fragmentManager, Uri attachmentsListUri,
668081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook            List<Attachment> list, boolean loaderResult) {
678081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook        mFragmentManager = fragmentManager;
68e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        mAttachmentsListUri = attachmentsListUri;
694cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein        mAttachments = list;
70e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Adding tiles to grid and filling in attachment information
71e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        int index = 0;
72e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        for (Attachment attachment : list) {
738081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook            addMessageTileFromAttachment(attachment, index++, loaderResult);
74f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        }
75f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    }
76f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
778081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook    private void addMessageTileFromAttachment(Attachment attachment, int index,
788081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook            boolean loaderResult) {
798081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook        final MessageAttachmentTile attachmentTile;
80f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
81e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        if (getChildCount() <= index) {
82f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            attachmentTile = MessageAttachmentTile.inflate(mInflater, this);
838081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook            attachmentTile.initialize(mFragmentManager);
84f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            addView(attachmentTile);
85f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        } else {
868081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook            attachmentTile = (MessageAttachmentTile) getChildAt(index);
87f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        }
88f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
898081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook        attachmentTile.render(attachment, mAttachmentsListUri, index, this, loaderResult);
90f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    }
91f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
92237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein    public ComposeAttachmentTile addComposeTileFromAttachment(Attachment attachment) {
93237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein        final ComposeAttachmentTile attachmentTile =
94237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein                ComposeAttachmentTile.inflate(mInflater, this);
95237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein
96237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein        addView(attachmentTile);
978081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook        attachmentTile.render(attachment, null, -1, this, false);
98237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein
99237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein        return attachmentTile;
100237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein    }
101237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein
102f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    @Override
103f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
104f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        onMeasureForTiles(widthMeasureSpec);
105f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    }
106f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
107f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    private void onMeasureForTiles(int widthMeasureSpec) {
108f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        final int width = MeasureSpec.getSize(widthMeasureSpec);
109f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
110f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        final int childCount = getChildCount();
111f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        if (childCount == 0) {
112f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            // Just in case...
113f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            setMeasuredDimension(width, 0);
114f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            return;
115f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        }
116f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
117e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Divide width by minimum tile size to get the number of columns.
118e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Truncation will ensure that the minimum will always be the minimum
119e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // but that the tiles can (and likely will) grow larger.
120e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        mColumnCount = width / mTileMinSize;
121e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
122e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Just in case...
123e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        if (mColumnCount == 0) {
124e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            mColumnCount = 1;
125e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        }
126e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
127f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // 1. Calculate image size.
128f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        //      = [total width] / [child count]
129f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        //
130f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // 2. Set it to width/height of each children.
131e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        //    If we have a remainder, some tiles will have
132e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        //    1 pixel larger width than its height.
133f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        //
134f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // 3. Set the dimensions of itself.
135f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        //    Let width = given width.
136e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        //    Let height = image size + bottom padding.
137a6e8789043b567a54cb930dd785fba573cf65f5cMark Wei
1384071c2f73218ce75750345557bb31a9110737841Mark Wei        final int imageSize = (width) / mColumnCount;
139f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        final int remainder = width - (imageSize * mColumnCount);
140f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
141f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        for (int i = 0; i < childCount; i++) {
142f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            final View child = getChildAt(i);
143e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            // Compensate for the remainder
144e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            final int childWidth = imageSize + (i < remainder ? 1 : 0);
145f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein            child.measure(
146f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein                    MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
147e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                    MeasureSpec.makeMeasureSpec(imageSize, MeasureSpec.EXACTLY)
148f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein                    );
149f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        }
150e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
151e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Calculate the number of rows so we can get the proper height.
152e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Then multiply by the height of one tile to get the grid height.
153e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        final int numRows = ((childCount - 1) / mColumnCount) + 1;
154e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        setMeasuredDimension(width,
155e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                numRows*(imageSize + getChildAt(0).getPaddingBottom()));
156e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    }
157e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
158e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    @Override
159e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
160e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        onLayoutForTiles();
161e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    }
162e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
163e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein    private void onLayoutForTiles() {
164e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        final int count = getChildCount();
165e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        int childLeft = 0;
166e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        int childTop = 0;
167e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        boolean skipBeginningOfRowFirstTime = true;
168e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
169e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        // Layout the grid.
170e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        for (int i = 0; i < count; i++) {
171e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            final View child = getChildAt(i);
172e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
173e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            // Note MeasuredWidth and MeasuredHeight include the padding.
174e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            final int childWidth = child.getMeasuredWidth();
175e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            final int childHeight = child.getMeasuredHeight();
176e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
177e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            // If we're at the beginning of a row and it is not the first row
178e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            // in the grid, reset childLeft to 0 and update childTop
179e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            // to reflect the top of the new row.
180e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            if (!skipBeginningOfRowFirstTime && i % mColumnCount == 0) {
181e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                childLeft = 0;
182e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                childTop += childHeight;
183e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            } else {
184e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                skipBeginningOfRowFirstTime = false;
185e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            }
186e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein
187e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            child.layout(childLeft, childTop,
188e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein                    childLeft + childWidth, childTop + childHeight);
189e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein            childLeft += childWidth;
190e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein        }
191f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    }
192f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein
193f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    @Override
194f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    public void sendAccessibilityEvent(int eventType) {
195f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // This method is called when the child tile is INVISIBLE (meaning "empty"), and the
196f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // Accessibility Manager needs to find alternative content description to speak.
197f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // Here, we ignore the default behavior, since we don't want to let the manager speak
198f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein        // a contact name for the tile next to the INVISIBLE tile.
199f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein    }
2004cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein
2014cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein    public List<Attachment> getAttachments() {
2024cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein        return mAttachments;
2034cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein    }
20462066e47fe69c33b60ed970e46809ba81d044064Mark Wei
20562066e47fe69c33b60ed970e46809ba81d044064Mark Wei    public ArrayList<AttachmentPreview> getAttachmentPreviews() {
20662066e47fe69c33b60ed970e46809ba81d044064Mark Wei        return Lists.newArrayList(mAttachmentPreviews.values());
20762066e47fe69c33b60ed970e46809ba81d044064Mark Wei    }
20862066e47fe69c33b60ed970e46809ba81d044064Mark Wei
20962066e47fe69c33b60ed970e46809ba81d044064Mark Wei    public void setAttachmentPreviews(ArrayList<AttachmentPreview> previews) {
21062066e47fe69c33b60ed970e46809ba81d044064Mark Wei        if (previews != null) {
21162066e47fe69c33b60ed970e46809ba81d044064Mark Wei            for (AttachmentPreview preview : previews) {
21262066e47fe69c33b60ed970e46809ba81d044064Mark Wei                mAttachmentPreviews.put(preview.attachmentIdentifier, preview);
21362066e47fe69c33b60ed970e46809ba81d044064Mark Wei            }
21462066e47fe69c33b60ed970e46809ba81d044064Mark Wei        }
21562066e47fe69c33b60ed970e46809ba81d044064Mark Wei    }
21662066e47fe69c33b60ed970e46809ba81d044064Mark Wei
21762066e47fe69c33b60ed970e46809ba81d044064Mark Wei    /*
21862066e47fe69c33b60ed970e46809ba81d044064Mark Wei     * Save the preview for an attachment
21962066e47fe69c33b60ed970e46809ba81d044064Mark Wei     */
22062066e47fe69c33b60ed970e46809ba81d044064Mark Wei    @Override
22162066e47fe69c33b60ed970e46809ba81d044064Mark Wei    public void set(Attachment attachment, Bitmap preview) {
22269c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei        final String attachmentIdentifier = attachment.getIdentifierUri().toString();
22362066e47fe69c33b60ed970e46809ba81d044064Mark Wei        if (attachmentIdentifier != null) {
22462066e47fe69c33b60ed970e46809ba81d044064Mark Wei            mAttachmentPreviews.put(
22562066e47fe69c33b60ed970e46809ba81d044064Mark Wei                    attachmentIdentifier, new AttachmentPreview(attachment, preview));
22662066e47fe69c33b60ed970e46809ba81d044064Mark Wei        }
22762066e47fe69c33b60ed970e46809ba81d044064Mark Wei    }
22862066e47fe69c33b60ed970e46809ba81d044064Mark Wei
22962066e47fe69c33b60ed970e46809ba81d044064Mark Wei    /*
23062066e47fe69c33b60ed970e46809ba81d044064Mark Wei     * Returns a saved preview that was previously set
23162066e47fe69c33b60ed970e46809ba81d044064Mark Wei     */
23262066e47fe69c33b60ed970e46809ba81d044064Mark Wei    @Override
23362066e47fe69c33b60ed970e46809ba81d044064Mark Wei    public Bitmap get(Attachment attachment) {
23469c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei        final String attachmentIdentifier = attachment.getIdentifierUri().toString();
23562066e47fe69c33b60ed970e46809ba81d044064Mark Wei        if (attachmentIdentifier != null) {
23662066e47fe69c33b60ed970e46809ba81d044064Mark Wei            final AttachmentPreview attachmentPreview = mAttachmentPreviews.get(
23762066e47fe69c33b60ed970e46809ba81d044064Mark Wei                    attachmentIdentifier);
23862066e47fe69c33b60ed970e46809ba81d044064Mark Wei            if (attachmentPreview != null) {
23962066e47fe69c33b60ed970e46809ba81d044064Mark Wei                return attachmentPreview.preview;
24062066e47fe69c33b60ed970e46809ba81d044064Mark Wei            }
24162066e47fe69c33b60ed970e46809ba81d044064Mark Wei        }
24262066e47fe69c33b60ed970e46809ba81d044064Mark Wei        return null;
24362066e47fe69c33b60ed970e46809ba81d044064Mark Wei    }
244f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein}
245