1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 package com.android.browser; 19 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.PackageManager; 23 import android.content.pm.ResolveInfo; 24 import android.content.res.Resources; 25 import android.database.Cursor; 26 import android.drm.mobile1.DrmRawContent; 27 import android.graphics.drawable.Drawable; 28 import android.net.Uri; 29 import android.provider.Downloads; 30 import android.text.format.Formatter; 31 import android.view.LayoutInflater; 32 import android.view.View; 33 import android.view.ViewGroup; 34 import android.widget.ImageView; 35 import android.widget.ProgressBar; 36 import android.widget.RelativeLayout; 37 import android.widget.TextView; 38 39 import java.text.DateFormat; 40 import java.util.Date; 41 import java.util.List; 42 43 /** 44 * This class is used to represent the data for the download list box. The only 45 * real work done by this class is to construct a custom view for the line 46 * items. 47 */ 48 public class BrowserDownloadAdapter extends DateSortedExpandableListAdapter { 49 50 private int mTitleColumnId; 51 private int mDescColumnId; 52 private int mStatusColumnId; 53 private int mTotalBytesColumnId; 54 private int mCurrentBytesColumnId; 55 private int mMimetypeColumnId; 56 private int mDateColumnId; 57 58 public BrowserDownloadAdapter(Context context, Cursor c, int index) { 59 super(context, c, index); 60 mTitleColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE); 61 mDescColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_DESCRIPTION); 62 mStatusColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS); 63 mTotalBytesColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TOTAL_BYTES); 64 mCurrentBytesColumnId = 65 c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_CURRENT_BYTES); 66 mMimetypeColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_MIME_TYPE); 67 mDateColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_LAST_MODIFICATION); 68 } 69 70 @Override 71 public View getChildView(int groupPosition, int childPosition, 72 boolean isLastChild, View convertView, ViewGroup parent) { 73 Context context = getContext(); 74 // The layout file uses a RelativeLayout, whereas the GroupViews use 75 // TextView. 76 if (null == convertView || !(convertView instanceof RelativeLayout)) { 77 convertView = LayoutInflater.from(context).inflate( 78 R.layout.browser_download_item, null); 79 } 80 81 // Bail early if the Cursor is closed. 82 if (!moveCursorToChildPosition(groupPosition, childPosition)) { 83 return convertView; 84 } 85 86 Resources r = context.getResources(); 87 88 // Retrieve the icon for this download 89 String mimeType = getString(mMimetypeColumnId); 90 ImageView iv = (ImageView) convertView.findViewById(R.id.download_icon); 91 if (DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mimeType)) { 92 iv.setImageResource(R.drawable.ic_launcher_drm_file); 93 } else if (mimeType == null) { 94 iv.setVisibility(View.INVISIBLE); 95 } else { 96 Intent intent = new Intent(Intent.ACTION_VIEW); 97 intent.setDataAndType(Uri.fromParts("file", "", null), mimeType); 98 PackageManager pm = context.getPackageManager(); 99 List<ResolveInfo> list = pm.queryIntentActivities(intent, 100 PackageManager.MATCH_DEFAULT_ONLY); 101 if (list.size() > 0) { 102 Drawable icon = list.get(0).activityInfo.loadIcon(pm); 103 iv.setImageDrawable(icon); 104 iv.setVisibility(View.VISIBLE); 105 } else { 106 iv.setVisibility(View.INVISIBLE); 107 } 108 } 109 110 TextView tv = (TextView) convertView.findViewById(R.id.download_title); 111 String title = getString(mTitleColumnId); 112 if (title == null) { 113 title = r.getString(R.string.download_unknown_filename); 114 } 115 tv.setText(title); 116 117 tv = (TextView) convertView.findViewById(R.id.domain); 118 tv.setText(getString(mDescColumnId)); 119 120 long totalBytes = getLong(mTotalBytesColumnId); 121 122 int status = getInt(mStatusColumnId); 123 if (Downloads.Impl.isStatusCompleted(status)) { // Download stopped 124 View v = convertView.findViewById(R.id.progress_text); 125 v.setVisibility(View.GONE); 126 127 v = convertView.findViewById(R.id.download_progress); 128 v.setVisibility(View.GONE); 129 130 tv = (TextView) convertView.findViewById(R.id.complete_text); 131 tv.setVisibility(View.VISIBLE); 132 if (Downloads.Impl.isStatusError(status)) { 133 tv.setText(getErrorText(status)); 134 } else { 135 tv.setText(r.getString(R.string.download_success, 136 Formatter.formatFileSize(context, totalBytes))); 137 } 138 139 long time = getLong(mDateColumnId); 140 Date d = new Date(time); 141 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); 142 tv = (TextView) convertView.findViewById(R.id.complete_date); 143 tv.setVisibility(View.VISIBLE); 144 tv.setText(df.format(d)); 145 146 } else { // Download is still running 147 tv = (TextView) convertView.findViewById(R.id.progress_text); 148 tv.setVisibility(View.VISIBLE); 149 150 View progress = convertView.findViewById(R.id.download_progress); 151 progress.setVisibility(View.VISIBLE); 152 153 View v = convertView.findViewById(R.id.complete_date); 154 v.setVisibility(View.GONE); 155 156 v = convertView.findViewById(R.id.complete_text); 157 v.setVisibility(View.GONE); 158 159 if (status == Downloads.Impl.STATUS_PENDING) { 160 tv.setText(r.getText(R.string.download_pending)); 161 } else if (status == Downloads.Impl.STATUS_PENDING_PAUSED) { 162 tv.setText(r.getText(R.string.download_pending_network)); 163 } else { 164 ProgressBar pb = (ProgressBar) progress; 165 166 StringBuilder sb = new StringBuilder(); 167 if (status == Downloads.Impl.STATUS_RUNNING) { 168 sb.append(r.getText(R.string.download_running)); 169 } else { 170 sb.append(r.getText(R.string.download_running_paused)); 171 } 172 if (totalBytes > 0) { 173 long currentBytes = getLong(mCurrentBytesColumnId); 174 int progressAmount = (int)(currentBytes * 100 / totalBytes); 175 sb.append(' '); 176 sb.append(progressAmount); 177 sb.append("% ("); 178 sb.append(Formatter.formatFileSize(context, currentBytes)); 179 sb.append("/"); 180 sb.append(Formatter.formatFileSize(context, totalBytes)); 181 sb.append(")"); 182 pb.setIndeterminate(false); 183 pb.setProgress(progressAmount); 184 } else { 185 pb.setIndeterminate(true); 186 } 187 tv.setText(sb.toString()); 188 } 189 } 190 return convertView; 191 } 192 193 /** 194 * Provide the resource id for the error string. 195 * @param status status of the download item 196 * @return resource id for the error string. 197 */ 198 public static int getErrorText(int status) { 199 switch (status) { 200 case Downloads.Impl.STATUS_NOT_ACCEPTABLE: 201 return R.string.download_not_acceptable; 202 203 case Downloads.Impl.STATUS_LENGTH_REQUIRED: 204 return R.string.download_length_required; 205 206 case Downloads.Impl.STATUS_PRECONDITION_FAILED: 207 return R.string.download_precondition_failed; 208 209 case Downloads.Impl.STATUS_CANCELED: 210 return R.string.download_canceled; 211 212 case Downloads.Impl.STATUS_FILE_ERROR: 213 return R.string.download_file_error; 214 215 case Downloads.Impl.STATUS_BAD_REQUEST: 216 case Downloads.Impl.STATUS_UNKNOWN_ERROR: 217 default: 218 return R.string.download_error; 219 } 220 } 221 } 222