1217149efdc4a559c38442da179f548e125c0afc5Steve Howard/*
2217149efdc4a559c38442da179f548e125c0afc5Steve Howard * Copyright (C) 2010 The Android Open Source Project
3217149efdc4a559c38442da179f548e125c0afc5Steve Howard *
4217149efdc4a559c38442da179f548e125c0afc5Steve Howard * Licensed under the Apache License, Version 2.0 (the "License");
5217149efdc4a559c38442da179f548e125c0afc5Steve Howard * you may not use this file except in compliance with the License.
6217149efdc4a559c38442da179f548e125c0afc5Steve Howard * You may obtain a copy of the License at
7217149efdc4a559c38442da179f548e125c0afc5Steve Howard *
8217149efdc4a559c38442da179f548e125c0afc5Steve Howard *      http://www.apache.org/licenses/LICENSE-2.0
9217149efdc4a559c38442da179f548e125c0afc5Steve Howard *
10217149efdc4a559c38442da179f548e125c0afc5Steve Howard * Unless required by applicable law or agreed to in writing, software
11217149efdc4a559c38442da179f548e125c0afc5Steve Howard * distributed under the License is distributed on an "AS IS" BASIS,
12217149efdc4a559c38442da179f548e125c0afc5Steve Howard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13217149efdc4a559c38442da179f548e125c0afc5Steve Howard * See the License for the specific language governing permissions and
14217149efdc4a559c38442da179f548e125c0afc5Steve Howard * limitations under the License.
15217149efdc4a559c38442da179f548e125c0afc5Steve Howard */
16217149efdc4a559c38442da179f548e125c0afc5Steve Howard
17217149efdc4a559c38442da179f548e125c0afc5Steve Howardpackage com.android.providers.downloads.ui;
18217149efdc4a559c38442da179f548e125c0afc5Steve Howard
1914961f94d762e733a733e3268fca1074d8da5f8cSteve Howardimport android.app.DownloadManager;
20217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.content.Context;
21217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.content.Intent;
22217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.content.pm.PackageManager;
23217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.content.pm.ResolveInfo;
24217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.content.res.Resources;
25217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.database.Cursor;
26217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.graphics.drawable.Drawable;
27217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.net.Uri;
28217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.text.format.Formatter;
29217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.view.LayoutInflater;
30217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.view.View;
31217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.view.ViewGroup;
32217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.widget.CursorAdapter;
33217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.widget.ImageView;
34217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport android.widget.TextView;
35217149efdc4a559c38442da179f548e125c0afc5Steve Howard
36217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport java.text.DateFormat;
3778f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howardimport java.util.Calendar;
38217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport java.util.Date;
3978f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howardimport java.util.GregorianCalendar;
40217149efdc4a559c38442da179f548e125c0afc5Steve Howardimport java.util.List;
41217149efdc4a559c38442da179f548e125c0afc5Steve Howard
42217149efdc4a559c38442da179f548e125c0afc5Steve Howard/**
43217149efdc4a559c38442da179f548e125c0afc5Steve Howard * List adapter for Cursors returned by {@link DownloadManager}.
44217149efdc4a559c38442da179f548e125c0afc5Steve Howard */
45217149efdc4a559c38442da179f548e125c0afc5Steve Howardpublic class DownloadAdapter extends CursorAdapter {
46daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori    private final DownloadList mDownloadList;
47217149efdc4a559c38442da179f548e125c0afc5Steve Howard    private Cursor mCursor;
48217149efdc4a559c38442da179f548e125c0afc5Steve Howard    private Resources mResources;
49217149efdc4a559c38442da179f548e125c0afc5Steve Howard    private DateFormat mDateFormat;
5078f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard    private DateFormat mTimeFormat;
51217149efdc4a559c38442da179f548e125c0afc5Steve Howard
52d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mTitleColumnId;
53d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mDescriptionColumnId;
54d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mStatusColumnId;
55d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mReasonColumnId;
56d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mTotalBytesColumnId;
57d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mMediaTypeColumnId;
58d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mDateColumnId;
59d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mIdColumnId;
60d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori    private final int mFileNameColumnId;
61217149efdc4a559c38442da179f548e125c0afc5Steve Howard
62daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori    public DownloadAdapter(DownloadList downloadList, Cursor cursor) {
63daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori        super(downloadList, cursor);
64daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori        mDownloadList = downloadList;
65217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mCursor = cursor;
66daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori        mResources = mDownloadList.getResources();
67217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mDateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
6878f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        mTimeFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
69217149efdc4a559c38442da179f548e125c0afc5Steve Howard
70217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mIdColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID);
71217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mTitleColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TITLE);
72217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mDescriptionColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_DESCRIPTION);
73217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mStatusColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS);
74b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        mReasonColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON);
75217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mTotalBytesColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
76217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mMediaTypeColumnId = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_MEDIA_TYPE);
77217149efdc4a559c38442da179f548e125c0afc5Steve Howard        mDateColumnId =
78217149efdc4a559c38442da179f548e125c0afc5Steve Howard                cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP);
79d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori        mFileNameColumnId =
80d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori                cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_FILENAME);
81217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
82217149efdc4a559c38442da179f548e125c0afc5Steve Howard
83217149efdc4a559c38442da179f548e125c0afc5Steve Howard    public View newView() {
84d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori        final DownloadItem view = (DownloadItem) LayoutInflater.from(mDownloadList)
85217149efdc4a559c38442da179f548e125c0afc5Steve Howard                .inflate(R.layout.download_list_item, null);
86daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori        view.setDownloadListObj(mDownloadList);
87217149efdc4a559c38442da179f548e125c0afc5Steve Howard        return view;
88217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
89217149efdc4a559c38442da179f548e125c0afc5Steve Howard
90daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori    public void bindView(View convertView, int position) {
91217149efdc4a559c38442da179f548e125c0afc5Steve Howard        if (!(convertView instanceof DownloadItem)) {
92217149efdc4a559c38442da179f548e125c0afc5Steve Howard            return;
93217149efdc4a559c38442da179f548e125c0afc5Steve Howard        }
94217149efdc4a559c38442da179f548e125c0afc5Steve Howard
95217149efdc4a559c38442da179f548e125c0afc5Steve Howard        long downloadId = mCursor.getLong(mIdColumnId);
96d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori        ((DownloadItem) convertView).setData(downloadId, position,
97d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori                mCursor.getString(mFileNameColumnId),
98d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori                mCursor.getString(mMediaTypeColumnId));
99217149efdc4a559c38442da179f548e125c0afc5Steve Howard
100217149efdc4a559c38442da179f548e125c0afc5Steve Howard        // Retrieve the icon for this download
101217149efdc4a559c38442da179f548e125c0afc5Steve Howard        retrieveAndSetIcon(convertView);
102217149efdc4a559c38442da179f548e125c0afc5Steve Howard
10371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        String title = mCursor.getString(mTitleColumnId);
10471e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        if (title.isEmpty()) {
10571e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard            title = mResources.getString(R.string.missing_title);
10671e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        }
10771e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        setTextForView(convertView, R.id.download_title, title);
108217149efdc4a559c38442da179f548e125c0afc5Steve Howard        setTextForView(convertView, R.id.domain, mCursor.getString(mDescriptionColumnId));
109217149efdc4a559c38442da179f548e125c0afc5Steve Howard        setTextForView(convertView, R.id.size_text, getSizeText());
1103843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey
1113843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        final int status = mCursor.getInt(mStatusColumnId);
1123843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        final CharSequence statusText;
1133843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        if (status == DownloadManager.STATUS_SUCCESSFUL) {
1143843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey            statusText = getDateString();
1153843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        } else {
1163843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey            statusText = mResources.getString(getStatusStringId(status));
1173843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        }
1183843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        setTextForView(convertView, R.id.status_text, statusText);
119217149efdc4a559c38442da179f548e125c0afc5Steve Howard
120d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori        ((DownloadItem) convertView).getCheckBox()
121d58f7c299ec6e1164e3b5e9e2e3fe5e0e57e63b9Vasu Nori                .setChecked(mDownloadList.isDownloadSelected(downloadId));
122217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
123217149efdc4a559c38442da179f548e125c0afc5Steve Howard
124217149efdc4a559c38442da179f548e125c0afc5Steve Howard    private String getDateString() {
125217149efdc4a559c38442da179f548e125c0afc5Steve Howard        Date date = new Date(mCursor.getLong(mDateColumnId));
12678f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        if (date.before(getStartOfToday())) {
12778f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard            return mDateFormat.format(date);
12878f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        } else {
12978f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard            return mTimeFormat.format(date);
13078f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        }
13178f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard    }
13278f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard
13378f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard    private Date getStartOfToday() {
13478f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        Calendar today = new GregorianCalendar();
13578f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        today.set(Calendar.HOUR_OF_DAY, 0);
13678f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        today.set(Calendar.MINUTE, 0);
13778f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        today.set(Calendar.SECOND, 0);
13878f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        today.set(Calendar.MILLISECOND, 0);
13978f433c68f14dfba605ceb0e5f3dc54243efd2b2Steve Howard        return today.getTime();
140217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
141217149efdc4a559c38442da179f548e125c0afc5Steve Howard
142217149efdc4a559c38442da179f548e125c0afc5Steve Howard    private String getSizeText() {
143217149efdc4a559c38442da179f548e125c0afc5Steve Howard        long totalBytes = mCursor.getLong(mTotalBytesColumnId);
144217149efdc4a559c38442da179f548e125c0afc5Steve Howard        String sizeText = "";
145217149efdc4a559c38442da179f548e125c0afc5Steve Howard        if (totalBytes >= 0) {
146217149efdc4a559c38442da179f548e125c0afc5Steve Howard            sizeText = Formatter.formatFileSize(mContext, totalBytes);
147217149efdc4a559c38442da179f548e125c0afc5Steve Howard        }
148217149efdc4a559c38442da179f548e125c0afc5Steve Howard        return sizeText;
149217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
150217149efdc4a559c38442da179f548e125c0afc5Steve Howard
1513843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey    private int getStatusStringId(int status) {
1523843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey        switch (status) {
153217149efdc4a559c38442da179f548e125c0afc5Steve Howard            case DownloadManager.STATUS_FAILED:
154217149efdc4a559c38442da179f548e125c0afc5Steve Howard                return R.string.download_error;
155217149efdc4a559c38442da179f548e125c0afc5Steve Howard
156217149efdc4a559c38442da179f548e125c0afc5Steve Howard            case DownloadManager.STATUS_SUCCESSFUL:
157217149efdc4a559c38442da179f548e125c0afc5Steve Howard                return R.string.download_success;
158217149efdc4a559c38442da179f548e125c0afc5Steve Howard
159217149efdc4a559c38442da179f548e125c0afc5Steve Howard            case DownloadManager.STATUS_PENDING:
160217149efdc4a559c38442da179f548e125c0afc5Steve Howard            case DownloadManager.STATUS_RUNNING:
161217149efdc4a559c38442da179f548e125c0afc5Steve Howard                return R.string.download_running;
162b108a273b150e81bf26553b8851d6241bc711f98Steve Howard
163b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case DownloadManager.STATUS_PAUSED:
164961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                final int reason = mCursor.getInt(mReasonColumnId);
165961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                switch (reason) {
166961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                    case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
167961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                        return R.string.download_queued;
168961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                    default:
169961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                        return R.string.download_running;
170b108a273b150e81bf26553b8851d6241bc711f98Steve Howard                }
171217149efdc4a559c38442da179f548e125c0afc5Steve Howard        }
172217149efdc4a559c38442da179f548e125c0afc5Steve Howard        throw new IllegalStateException("Unknown status: " + mCursor.getInt(mStatusColumnId));
173217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
174217149efdc4a559c38442da179f548e125c0afc5Steve Howard
175217149efdc4a559c38442da179f548e125c0afc5Steve Howard    private void retrieveAndSetIcon(View convertView) {
176217149efdc4a559c38442da179f548e125c0afc5Steve Howard        String mediaType = mCursor.getString(mMediaTypeColumnId);
177217149efdc4a559c38442da179f548e125c0afc5Steve Howard        ImageView iconView = (ImageView) convertView.findViewById(R.id.download_icon);
178217149efdc4a559c38442da179f548e125c0afc5Steve Howard        iconView.setVisibility(View.INVISIBLE);
179217149efdc4a559c38442da179f548e125c0afc5Steve Howard
180217149efdc4a559c38442da179f548e125c0afc5Steve Howard        if (mediaType == null) {
181217149efdc4a559c38442da179f548e125c0afc5Steve Howard            return;
182217149efdc4a559c38442da179f548e125c0afc5Steve Howard        }
183217149efdc4a559c38442da179f548e125c0afc5Steve Howard
184a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang        Intent intent = new Intent(Intent.ACTION_VIEW);
185a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang        intent.setDataAndType(Uri.fromParts("file", "", null), mediaType);
186a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang        PackageManager pm = mContext.getPackageManager();
187a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang        List<ResolveInfo> list = pm.queryIntentActivities(intent,
188a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang                PackageManager.MATCH_DEFAULT_ONLY);
189a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang        if (list.size() == 0) {
190a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang            // no icon found for this mediatype. use "unknown" icon
191a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang            iconView.setImageResource(R.drawable.ic_download_misc_file_type);
192217149efdc4a559c38442da179f548e125c0afc5Steve Howard        } else {
193a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang            Drawable icon = list.get(0).activityInfo.loadIcon(pm);
194a1902f4d26a5c87dddf52e2e855bcd6ed9734ab2Gloria Wang            iconView.setImageDrawable(icon);
195217149efdc4a559c38442da179f548e125c0afc5Steve Howard        }
196217149efdc4a559c38442da179f548e125c0afc5Steve Howard        iconView.setVisibility(View.VISIBLE);
197217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
198217149efdc4a559c38442da179f548e125c0afc5Steve Howard
1993843960b466dbcd1733648095e750ccb3fa6d184Jeff Sharkey    private void setTextForView(View parent, int textViewId, CharSequence text) {
200217149efdc4a559c38442da179f548e125c0afc5Steve Howard        TextView view = (TextView) parent.findViewById(textViewId);
201217149efdc4a559c38442da179f548e125c0afc5Steve Howard        view.setText(text);
202217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
203217149efdc4a559c38442da179f548e125c0afc5Steve Howard
204217149efdc4a559c38442da179f548e125c0afc5Steve Howard    // CursorAdapter overrides
205217149efdc4a559c38442da179f548e125c0afc5Steve Howard
206217149efdc4a559c38442da179f548e125c0afc5Steve Howard    @Override
207217149efdc4a559c38442da179f548e125c0afc5Steve Howard    public View newView(Context context, Cursor cursor, ViewGroup parent) {
208217149efdc4a559c38442da179f548e125c0afc5Steve Howard        return newView();
209217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
210217149efdc4a559c38442da179f548e125c0afc5Steve Howard
211217149efdc4a559c38442da179f548e125c0afc5Steve Howard    @Override
212217149efdc4a559c38442da179f548e125c0afc5Steve Howard    public void bindView(View view, Context context, Cursor cursor) {
213daed066d4dcc8873d3463ae65e16fa2e7fbcafe5Vasu Nori        bindView(view, cursor.getPosition());
214217149efdc4a559c38442da179f548e125c0afc5Steve Howard    }
215217149efdc4a559c38442da179f548e125c0afc5Steve Howard}
216