blob: 3483c30c19ea5e5bd36d2729117205f3bb7dbd35 [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
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
17package com.android.browser;
18
The Android Open Source Project0c908882009-03-03 19:32:16 -080019import android.app.AlertDialog;
Leon Scroggins24837452010-01-13 13:43:35 -050020import android.app.ExpandableListActivity;
The Android Open Source Project0c908882009-03-03 19:32:16 -080021import android.content.ActivityNotFoundException;
22import android.content.ContentValues;
23import android.content.DialogInterface;
24import android.content.Intent;
25import android.content.ContentUris;
26import android.content.pm.PackageManager;
27import android.content.pm.ResolveInfo;
28import android.database.Cursor;
Leon Scroggins9be17332010-01-14 15:44:06 -050029import android.database.DatabaseUtils;
The Android Open Source Project0c908882009-03-03 19:32:16 -080030import android.net.Uri;
31import android.os.Bundle;
32import android.provider.Downloads;
Leon Scroggins9be17332010-01-14 15:44:06 -050033import android.provider.MediaStore;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034import android.view.ContextMenu;
35import android.view.ContextMenu.ContextMenuInfo;
36import android.view.LayoutInflater;
37import android.view.Menu;
38import android.view.MenuItem;
39import android.view.MenuInflater;
40import android.view.View;
41import android.view.ViewGroup.LayoutParams;
42import android.widget.AdapterView;
Leon Scroggins24837452010-01-13 13:43:35 -050043import android.widget.ExpandableListView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080044
45import java.io.File;
46import java.util.List;
47
48/**
49 * View showing the user's current browser downloads
50 */
Leon Scroggins24837452010-01-13 13:43:35 -050051public class BrowserDownloadPage extends ExpandableListActivity {
The Android Open Source Project0c908882009-03-03 19:32:16 -080052
Leon Scroggins24837452010-01-13 13:43:35 -050053 private ExpandableListView mListView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080054 private Cursor mDownloadCursor;
55 private BrowserDownloadAdapter mDownloadAdapter;
56 private int mStatusColumnId;
57 private int mIdColumnId;
58 private int mTitleColumnId;
Leon Scroggins24837452010-01-13 13:43:35 -050059 private long mContextMenuPosition;
The Android Open Source Project0c908882009-03-03 19:32:16 -080060
61 @Override
62 public void onCreate(Bundle icicle) {
63 super.onCreate(icicle);
64 setContentView(R.layout.browser_downloads_page);
65
66 setTitle(getText(R.string.download_title));
67
Leon Scroggins24837452010-01-13 13:43:35 -050068 mListView = (ExpandableListView) findViewById(android.R.id.list);
Mihai Preda83817df2009-04-28 14:24:47 +020069 mListView.setEmptyView(findViewById(R.id.empty));
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080070 mDownloadCursor = managedQuery(Downloads.Impl.CONTENT_URI,
71 new String [] {"_id", Downloads.Impl.COLUMN_TITLE, Downloads.Impl.COLUMN_STATUS,
72 Downloads.Impl.COLUMN_TOTAL_BYTES, Downloads.Impl.COLUMN_CURRENT_BYTES,
73 Downloads.Impl._DATA, Downloads.Impl.COLUMN_DESCRIPTION,
74 Downloads.Impl.COLUMN_MIME_TYPE, Downloads.Impl.COLUMN_LAST_MODIFICATION,
75 Downloads.Impl.COLUMN_VISIBILITY},
76 null, Downloads.Impl.COLUMN_LAST_MODIFICATION + " DESC");
The Android Open Source Project0c908882009-03-03 19:32:16 -080077
78 // only attach everything to the listbox if we can access
79 // the download database. Otherwise, just show it empty
80 if (mDownloadCursor != null) {
81 mStatusColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080082 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
The Android Open Source Project0c908882009-03-03 19:32:16 -080083 mIdColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080084 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -080085 mTitleColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080086 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE);
The Android Open Source Project0c908882009-03-03 19:32:16 -080087
88 // Create a list "controller" for the data
89 mDownloadAdapter = new BrowserDownloadAdapter(this,
Leon Scroggins24837452010-01-13 13:43:35 -050090 mDownloadCursor, mDownloadCursor.getColumnIndexOrThrow(
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080091 Downloads.Impl.COLUMN_LAST_MODIFICATION));
Mihai Preda83817df2009-04-28 14:24:47 +020092
Leon Scroggins24837452010-01-13 13:43:35 -050093 setListAdapter(mDownloadAdapter);
The Android Open Source Project0c908882009-03-03 19:32:16 -080094 mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
95 mListView.setOnCreateContextMenuListener(this);
Leon Scroggins24837452010-01-13 13:43:35 -050096
The Android Open Source Project0c908882009-03-03 19:32:16 -080097 Intent intent = getIntent();
Leon Scroggins24837452010-01-13 13:43:35 -050098 final int groupToShow = intent == null || intent.getData() == null
99 ? 0 : checkStatus(ContentUris.parseId(intent.getData()));
100 if (mDownloadAdapter.getGroupCount() > groupToShow) {
101 mListView.post(new Runnable() {
102 public void run() {
103 if (mDownloadAdapter.getGroupCount() > groupToShow) {
104 mListView.expandGroup(groupToShow);
105 }
106 }
107 });
The Android Open Source Project0c908882009-03-03 19:32:16 -0800108 }
109 }
110 }
111
112 @Override
113 public boolean onCreateOptionsMenu(Menu menu) {
114 if (mDownloadCursor != null) {
115 MenuInflater inflater = getMenuInflater();
116 inflater.inflate(R.menu.downloadhistory, menu);
117 }
118 return true;
119 }
120
121 @Override
122 public boolean onPrepareOptionsMenu(Menu menu) {
123 boolean showCancel = getCancelableCount() > 0;
124 menu.findItem(R.id.download_menu_cancel_all).setEnabled(showCancel);
125
126 boolean showClear = getClearableCount() > 0;
127 menu.findItem(R.id.download_menu_clear_all).setEnabled(showClear);
128 return super.onPrepareOptionsMenu(menu);
129 }
130
131 @Override
132 public boolean onOptionsItemSelected(MenuItem item) {
133 switch (item.getItemId()) {
134 case R.id.download_menu_cancel_all:
135 promptCancelAll();
136 return true;
137
138 case R.id.download_menu_clear_all:
139 promptClearList();
140 return true;
141 }
142 return false;
143 }
144
Leon Scroggins9be17332010-01-14 15:44:06 -0500145 /**
146 * Remove the file from the list of downloads.
147 * @param id Unique ID of the download to remove.
148 */
149 private void clearFromDownloads(long id) {
150 getContentResolver().delete(ContentUris.withAppendedId(
151 Downloads.Impl.CONTENT_URI, id), null, null);
152 }
153
154 /**
155 * Remove the file from the SD card
156 * @param filename Name of the file to delete.
157 * @param mimetype Mimetype of the file to delete.
158 * @return boolean True on success, false on failure.
159 */
160 private boolean deleteFile(String filename, String mimetype) {
161 Uri uri;
162 if (mimetype.startsWith("image")) {
163 uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
164 } else if (mimetype.startsWith("audio")) {
165 uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
166 } else if (mimetype.startsWith("video")) {
167 uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
168 } else {
169 File file = new File(filename);
170 return file.delete();
171 }
172 return getContentResolver().delete(uri, MediaStore.MediaColumns.DATA
173 + " = " + DatabaseUtils.sqlEscapeString(filename), null) > 0;
174 }
175
The Android Open Source Project0c908882009-03-03 19:32:16 -0800176 @Override
177 public boolean onContextItemSelected(MenuItem item) {
Leon Scroggins24837452010-01-13 13:43:35 -0500178 if (!mDownloadAdapter.moveCursorToPackedChildPosition(
179 mContextMenuPosition)) {
180 return false;
181 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800182 switch (item.getItemId()) {
183 case R.id.download_menu_open:
184 hideCompletedDownload();
185 openCurrentDownload();
186 return true;
Leon Scroggins9be17332010-01-14 15:44:06 -0500187
188 case R.id.download_menu_delete:
189 int filenameColumnId =
190 mDownloadCursor.getColumnIndexOrThrow(Downloads._DATA);
191 final String filename = mDownloadCursor.getString(
192 filenameColumnId);
193 int mimetypeColumnId = mDownloadCursor.getColumnIndexOrThrow(
194 Downloads.Impl.COLUMN_MIME_TYPE);
195 final String mimetype = mDownloadCursor.getString(
196 mimetypeColumnId);
197 final long id = mDownloadCursor.getLong(mIdColumnId);
198 new AlertDialog.Builder(this)
199 .setTitle(R.string.download_delete_file)
200 .setIcon(android.R.drawable.ic_dialog_alert)
201 .setMessage(filename)
202 .setNegativeButton(R.string.cancel, null)
203 .setPositiveButton(R.string.ok,
204 new DialogInterface.OnClickListener() {
205 public void onClick(DialogInterface dialog,
206 int whichButton) {
207 if (deleteFile(filename, mimetype)) {
208 clearFromDownloads(id);
209 }
210 }
211 })
212 .show();
213 break;
214
The Android Open Source Project0c908882009-03-03 19:32:16 -0800215 case R.id.download_menu_clear:
216 case R.id.download_menu_cancel:
Leon Scroggins9be17332010-01-14 15:44:06 -0500217 clearFromDownloads(mDownloadCursor.getLong(mIdColumnId));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800218 return true;
219 }
220 return false;
221 }
222
223 @Override
224 public void onCreateContextMenu(ContextMenu menu, View v,
225 ContextMenuInfo menuInfo) {
226 if (mDownloadCursor != null) {
Leon Scroggins24837452010-01-13 13:43:35 -0500227 ExpandableListView.ExpandableListContextMenuInfo info
228 = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
229 long packedPosition = info.packedPosition;
230 // Only show a context menu for the child views
231 if (!mDownloadAdapter.moveCursorToPackedChildPosition(
232 packedPosition)) {
233 return;
234 }
235 mContextMenuPosition = packedPosition;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800236 menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId));
237
238 MenuInflater inflater = getMenuInflater();
239 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800240 if (Downloads.Impl.isStatusSuccess(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800241 inflater.inflate(R.menu.downloadhistorycontextfinished, menu);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800242 } else if (Downloads.Impl.isStatusError(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800243 inflater.inflate(R.menu.downloadhistorycontextfailed, menu);
244 } else {
245 inflater.inflate(R.menu.downloadhistorycontextrunning, menu);
246 }
247 }
Leon Scroggins24837452010-01-13 13:43:35 -0500248 super.onCreateContextMenu(menu, v, menuInfo);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800249 }
250
251 /**
252 * This function is called to check the status of the download and if it
253 * has an error show an error dialog.
254 * @param id Row id of the download to check
Leon Scroggins24837452010-01-13 13:43:35 -0500255 * @return Group which contains the download
The Android Open Source Project0c908882009-03-03 19:32:16 -0800256 */
Leon Scroggins24837452010-01-13 13:43:35 -0500257 private int checkStatus(final long id) {
258 int groupToShow = mDownloadAdapter.groupFromChildId(id);
259 if (-1 == groupToShow) return 0;
260 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800261 if (!Downloads.Impl.isStatusError(status)) {
Leon Scroggins24837452010-01-13 13:43:35 -0500262 return groupToShow;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800263 }
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800264 if (status == Downloads.Impl.STATUS_FILE_ERROR) {
Leon Scroggins24837452010-01-13 13:43:35 -0500265 String title = mDownloadCursor.getString(mTitleColumnId);
266 if (title == null || title.length() == 0) {
267 title = getString(R.string.download_unknown_filename);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800268 }
Leon Scroggins24837452010-01-13 13:43:35 -0500269 String msg = getString(R.string.download_file_error_dlg_msg, title);
270 new AlertDialog.Builder(this)
271 .setTitle(R.string.download_file_error_dlg_title)
272 .setIcon(android.R.drawable.ic_popup_disk_full)
273 .setMessage(msg)
274 .setPositiveButton(R.string.ok, null)
275 .setNegativeButton(R.string.retry,
276 new DialogInterface.OnClickListener() {
277 public void onClick(DialogInterface dialog,
278 int whichButton) {
279 resumeDownload(id);
280 }
281 })
282 .show();
283 } else {
284 new AlertDialog.Builder(this)
285 .setTitle(R.string.download_failed_generic_dlg_title)
286 .setIcon(R.drawable.ssl_icon)
287 .setMessage(BrowserDownloadAdapter.getErrorText(status))
288 .setPositiveButton(R.string.ok, null)
289 .show();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800290 }
Leon Scroggins24837452010-01-13 13:43:35 -0500291 return groupToShow;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800292 }
293
294 /**
295 * Resume a given download
296 * @param id Row id of the download to resume
297 */
298 private void resumeDownload(final long id) {
299 // the relevant functionality doesn't exist in the download manager
300 }
301
302 /**
303 * Prompt the user if they would like to clear the download history
304 */
305 private void promptClearList() {
306 new AlertDialog.Builder(this)
307 .setTitle(R.string.download_clear_dlg_title)
308 .setIcon(R.drawable.ssl_icon)
309 .setMessage(R.string.download_clear_dlg_msg)
310 .setPositiveButton(R.string.ok,
311 new DialogInterface.OnClickListener() {
312 public void onClick(DialogInterface dialog,
313 int whichButton) {
314 clearAllDownloads();
315 }
316 })
317 .setNegativeButton(R.string.cancel, null)
318 .show();
319 }
320
321 /**
322 * Return the number of items in the list that can be canceled.
323 * @return count
324 */
325 private int getCancelableCount() {
326 // Count the number of items that will be canceled.
327 int count = 0;
328 if (mDownloadCursor != null) {
329 for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast();
330 mDownloadCursor.moveToNext()) {
331 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800332 if (!Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800333 count++;
334 }
335 }
336 }
337
338 return count;
339 }
340
341 /**
342 * Prompt the user if they would like to clear the download history
343 */
344 private void promptCancelAll() {
345 int count = getCancelableCount();
346
347 // If there is nothing to do, just return
348 if (count == 0) {
349 return;
350 }
351
352 // Don't show the dialog if there is only one download
353 if (count == 1) {
354 cancelAllDownloads();
355 return;
356 }
357 String msg =
358 getString(R.string.download_cancel_dlg_msg, count);
359 new AlertDialog.Builder(this)
360 .setTitle(R.string.download_cancel_dlg_title)
361 .setIcon(R.drawable.ssl_icon)
362 .setMessage(msg)
363 .setPositiveButton(R.string.ok,
364 new DialogInterface.OnClickListener() {
365 public void onClick(DialogInterface dialog,
366 int whichButton) {
367 cancelAllDownloads();
368 }
369 })
370 .setNegativeButton(R.string.cancel, null)
371 .show();
372 }
373
374 /**
375 * Cancel all downloads. As canceled downloads are not
376 * listed, we removed them from the db. Removing a download
377 * record, cancels the download.
378 */
379 private void cancelAllDownloads() {
380 if (mDownloadCursor.moveToFirst()) {
381 StringBuilder where = new StringBuilder();
382 boolean firstTime = true;
383 while (!mDownloadCursor.isAfterLast()) {
384 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800385 if (!Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800386 if (firstTime) {
387 firstTime = false;
388 } else {
389 where.append(" OR ");
390 }
391 where.append("( ");
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800392 where.append(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800393 where.append(" = '");
394 where.append(mDownloadCursor.getLong(mIdColumnId));
395 where.append("' )");
396 }
397 mDownloadCursor.moveToNext();
398 }
399 if (!firstTime) {
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800400 getContentResolver().delete(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800401 where.toString(), null);
402 }
403 }
404 }
405
406 private int getClearableCount() {
407 int count = 0;
408 if (mDownloadCursor.moveToFirst()) {
409 while (!mDownloadCursor.isAfterLast()) {
410 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800411 if (Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800412 count++;
413 }
414 mDownloadCursor.moveToNext();
415 }
416 }
417 return count;
418 }
419
420 /**
421 * Clear all stopped downloads, ie canceled (though should not be
422 * there), error and success download items.
423 */
424 private void clearAllDownloads() {
425 if (mDownloadCursor.moveToFirst()) {
426 StringBuilder where = new StringBuilder();
427 boolean firstTime = true;
428 while (!mDownloadCursor.isAfterLast()) {
429 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800430 if (Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800431 if (firstTime) {
432 firstTime = false;
433 } else {
434 where.append(" OR ");
435 }
436 where.append("( ");
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800437 where.append(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800438 where.append(" = '");
439 where.append(mDownloadCursor.getLong(mIdColumnId));
440 where.append("' )");
441 }
442 mDownloadCursor.moveToNext();
443 }
444 if (!firstTime) {
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800445 getContentResolver().delete(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800446 where.toString(), null);
447 }
448 }
449 }
450
451 /**
452 * Open the content where the download db cursor currently is
453 */
454 private void openCurrentDownload() {
455 int filenameColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800456 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl._DATA);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800457 String filename = mDownloadCursor.getString(filenameColumnId);
458 int mimetypeColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800459 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_MIME_TYPE);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800460 String mimetype = mDownloadCursor.getString(mimetypeColumnId);
461 Uri path = Uri.parse(filename);
462 // If there is no scheme, then it must be a file
463 if (path.getScheme() == null) {
464 path = Uri.fromFile(new File(filename));
465 }
466 Intent intent = new Intent(Intent.ACTION_VIEW);
467 intent.setDataAndType(path, mimetype);
468 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
469 try {
470 startActivity(intent);
471 } catch (ActivityNotFoundException ex) {
472 new AlertDialog.Builder(this)
473 .setTitle(R.string.download_failed_generic_dlg_title)
474 .setIcon(R.drawable.ssl_icon)
475 .setMessage(R.string.download_no_application)
476 .setPositiveButton(R.string.ok, null)
477 .show();
478 }
479 }
480
Leon Scroggins24837452010-01-13 13:43:35 -0500481 @Override
482 public boolean onChildClick(ExpandableListView parent, View v,
483 int groupPosition, int childPosition, long id) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800484 // Open the selected item
Leon Scroggins24837452010-01-13 13:43:35 -0500485 mDownloadAdapter.moveCursorToChildPosition(groupPosition,
486 childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800487
488 hideCompletedDownload();
489
490 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800491 if (Downloads.Impl.isStatusSuccess(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800492 // Open it if it downloaded successfully
493 openCurrentDownload();
494 } else {
495 // Check to see if there is an error.
496 checkStatus(id);
497 }
Leon Scroggins24837452010-01-13 13:43:35 -0500498 return true;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800499 }
500
501 /**
502 * hides the notification for the download pointed by mDownloadCursor
503 * if the download has completed.
504 */
505 private void hideCompletedDownload() {
506 int status = mDownloadCursor.getInt(mStatusColumnId);
507
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800508 int visibilityColumn = mDownloadCursor.getColumnIndexOrThrow(
509 Downloads.Impl.COLUMN_VISIBILITY);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800510 int visibility = mDownloadCursor.getInt(visibilityColumn);
511
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800512 if (Downloads.Impl.isStatusCompleted(status) &&
513 visibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800514 ContentValues values = new ContentValues();
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800515 values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800516 getContentResolver().update(
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800517 ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800518 mDownloadCursor.getLong(mIdColumnId)), values, null, null);
519 }
520 }
521}