blob: c56991e809224795c1bad8319242db25736865da [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;
Leon Scrogginsd080b182010-02-26 14:16:41 -050028import android.database.ContentObserver;
The Android Open Source Project0c908882009-03-03 19:32:16 -080029import android.database.Cursor;
30import android.net.Uri;
31import android.os.Bundle;
Leon Scrogginsd080b182010-02-26 14:16:41 -050032import android.os.Handler;
The Android Open Source Project0c908882009-03-03 19:32:16 -080033import android.provider.Downloads;
34import 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 {
Leon Scroggins24837452010-01-13 13:43:35 -050052 private ExpandableListView mListView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080053 private Cursor mDownloadCursor;
54 private BrowserDownloadAdapter mDownloadAdapter;
55 private int mStatusColumnId;
56 private int mIdColumnId;
57 private int mTitleColumnId;
Leon Scroggins24837452010-01-13 13:43:35 -050058 private long mContextMenuPosition;
Leon Scrogginsd080b182010-02-26 14:16:41 -050059 // Used to update the ContextMenu if an item is being downloaded and the
60 // user opens the ContextMenu.
61 private ContentObserver mContentObserver;
62 // Only meaningful while a ContentObserver is registered. The ContextMenu
63 // will be reopened on this View.
64 private View mSelectedView;
65
The Android Open Source Project0c908882009-03-03 19:32:16 -080066 @Override
67 public void onCreate(Bundle icicle) {
68 super.onCreate(icicle);
69 setContentView(R.layout.browser_downloads_page);
70
71 setTitle(getText(R.string.download_title));
72
Leon Scroggins24837452010-01-13 13:43:35 -050073 mListView = (ExpandableListView) findViewById(android.R.id.list);
Mihai Preda83817df2009-04-28 14:24:47 +020074 mListView.setEmptyView(findViewById(R.id.empty));
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080075 mDownloadCursor = managedQuery(Downloads.Impl.CONTENT_URI,
Leon Scrogginsfedc4932010-01-26 14:15:01 -050076 new String [] {Downloads.Impl._ID, Downloads.Impl.COLUMN_TITLE,
77 Downloads.Impl.COLUMN_STATUS, Downloads.Impl.COLUMN_TOTAL_BYTES,
78 Downloads.Impl.COLUMN_CURRENT_BYTES,
79 Downloads.Impl.COLUMN_DESCRIPTION,
80 Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
81 Downloads.Impl.COLUMN_LAST_MODIFICATION,
82 Downloads.Impl.COLUMN_VISIBILITY,
Leon Scrogginsb67db6b2010-02-26 17:58:31 -050083 Downloads.Impl._DATA,
Leon Scrogginsfedc4932010-01-26 14:15:01 -050084 Downloads.Impl.COLUMN_MIME_TYPE},
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080085 null, Downloads.Impl.COLUMN_LAST_MODIFICATION + " DESC");
The Android Open Source Project0c908882009-03-03 19:32:16 -080086
87 // only attach everything to the listbox if we can access
88 // the download database. Otherwise, just show it empty
89 if (mDownloadCursor != null) {
90 mStatusColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080091 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
The Android Open Source Project0c908882009-03-03 19:32:16 -080092 mIdColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080093 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -080094 mTitleColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080095 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE);
The Android Open Source Project0c908882009-03-03 19:32:16 -080096
97 // Create a list "controller" for the data
98 mDownloadAdapter = new BrowserDownloadAdapter(this,
Leon Scroggins24837452010-01-13 13:43:35 -050099 mDownloadCursor, mDownloadCursor.getColumnIndexOrThrow(
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800100 Downloads.Impl.COLUMN_LAST_MODIFICATION));
Mihai Preda83817df2009-04-28 14:24:47 +0200101
Leon Scroggins24837452010-01-13 13:43:35 -0500102 setListAdapter(mDownloadAdapter);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800103 mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
104 mListView.setOnCreateContextMenuListener(this);
Leon Scroggins24837452010-01-13 13:43:35 -0500105
The Android Open Source Project0c908882009-03-03 19:32:16 -0800106 Intent intent = getIntent();
Leon Scroggins24837452010-01-13 13:43:35 -0500107 final int groupToShow = intent == null || intent.getData() == null
108 ? 0 : checkStatus(ContentUris.parseId(intent.getData()));
109 if (mDownloadAdapter.getGroupCount() > groupToShow) {
110 mListView.post(new Runnable() {
111 public void run() {
112 if (mDownloadAdapter.getGroupCount() > groupToShow) {
113 mListView.expandGroup(groupToShow);
114 }
115 }
116 });
The Android Open Source Project0c908882009-03-03 19:32:16 -0800117 }
118 }
119 }
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500120
The Android Open Source Project0c908882009-03-03 19:32:16 -0800121 @Override
Leon Scrogginsb67db6b2010-02-26 17:58:31 -0500122 protected void onResume() {
123 super.onResume();
124 if (mDownloadCursor != null) {
125 String where = null;
126 for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast();
127 mDownloadCursor.moveToNext()) {
128 if (!Downloads.Impl.isStatusCompleted(
129 mDownloadCursor.getInt(mStatusColumnId))) {
130 // Only want to check files that have completed.
131 continue;
132 }
133 int filenameColumnId = mDownloadCursor.getColumnIndexOrThrow(
134 Downloads.Impl._DATA);
135 String filename = mDownloadCursor.getString(filenameColumnId);
Leon Scroggins3ee3fef2010-03-08 14:34:14 -0500136 if (filename != null) {
137 File file = new File(filename);
138 if (!file.exists()) {
139 long id = mDownloadCursor.getLong(mIdColumnId);
140 if (where == null) {
141 where = Downloads.Impl._ID + " = '" + id + "'";
142 } else {
143 where += " OR " + Downloads.Impl._ID + " = '" + id
144 + "'";
145 }
Leon Scrogginsb67db6b2010-02-26 17:58:31 -0500146 }
147 }
148 }
149 if (where != null) {
150 getContentResolver().delete(Downloads.Impl.CONTENT_URI, where,
151 null);
152 }
153 }
154 }
155
156 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800157 public boolean onCreateOptionsMenu(Menu menu) {
158 if (mDownloadCursor != null) {
159 MenuInflater inflater = getMenuInflater();
160 inflater.inflate(R.menu.downloadhistory, menu);
161 }
162 return true;
163 }
164
165 @Override
166 public boolean onPrepareOptionsMenu(Menu menu) {
167 boolean showCancel = getCancelableCount() > 0;
168 menu.findItem(R.id.download_menu_cancel_all).setEnabled(showCancel);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800169 return super.onPrepareOptionsMenu(menu);
170 }
171
172 @Override
173 public boolean onOptionsItemSelected(MenuItem item) {
174 switch (item.getItemId()) {
175 case R.id.download_menu_cancel_all:
176 promptCancelAll();
177 return true;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800178 }
179 return false;
180 }
181
Leon Scroggins9be17332010-01-14 15:44:06 -0500182 /**
183 * Remove the file from the list of downloads.
184 * @param id Unique ID of the download to remove.
185 */
186 private void clearFromDownloads(long id) {
187 getContentResolver().delete(ContentUris.withAppendedId(
188 Downloads.Impl.CONTENT_URI, id), null, null);
189 }
190
The Android Open Source Project0c908882009-03-03 19:32:16 -0800191 @Override
192 public boolean onContextItemSelected(MenuItem item) {
Leon Scroggins24837452010-01-13 13:43:35 -0500193 if (!mDownloadAdapter.moveCursorToPackedChildPosition(
194 mContextMenuPosition)) {
195 return false;
196 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800197 switch (item.getItemId()) {
198 case R.id.download_menu_open:
199 hideCompletedDownload();
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500200 openOrDeleteCurrentDownload(false);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800201 return true;
Leon Scroggins9be17332010-01-14 15:44:06 -0500202
203 case R.id.download_menu_delete:
Leon Scroggins9be17332010-01-14 15:44:06 -0500204 new AlertDialog.Builder(this)
205 .setTitle(R.string.download_delete_file)
206 .setIcon(android.R.drawable.ic_dialog_alert)
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500207 .setMessage(mDownloadCursor.getString(mTitleColumnId))
Leon Scroggins9be17332010-01-14 15:44:06 -0500208 .setNegativeButton(R.string.cancel, null)
209 .setPositiveButton(R.string.ok,
210 new DialogInterface.OnClickListener() {
211 public void onClick(DialogInterface dialog,
212 int whichButton) {
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500213 openOrDeleteCurrentDownload(true);
Leon Scroggins9be17332010-01-14 15:44:06 -0500214 }
215 })
216 .show();
217 break;
218
The Android Open Source Project0c908882009-03-03 19:32:16 -0800219 case R.id.download_menu_clear:
220 case R.id.download_menu_cancel:
Leon Scroggins9be17332010-01-14 15:44:06 -0500221 clearFromDownloads(mDownloadCursor.getLong(mIdColumnId));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800222 return true;
223 }
224 return false;
225 }
226
227 @Override
Leon Scrogginsd080b182010-02-26 14:16:41 -0500228 protected void onPause() {
229 super.onPause();
230 if (mContentObserver != null) {
231 getContentResolver().unregisterContentObserver(mContentObserver);
232 // Note that we do not need to undo this in onResume, because the
233 // ContextMenu does not get reinvoked when the Activity resumes.
234 }
235 }
236
237 /*
238 * ContentObserver to update the ContextMenu if it is open when the
239 * corresponding download completes.
240 */
241 private class ChangeObserver extends ContentObserver {
242 private final Uri mTrack;
243 public ChangeObserver(Uri track) {
244 super(new Handler());
245 mTrack = track;
246 }
247
248 @Override
249 public boolean deliverSelfNotifications() {
250 return false;
251 }
252
253 @Override
254 public void onChange(boolean selfChange) {
255 Cursor cursor = getContentResolver().query(mTrack,
256 new String[] { Downloads.Impl.COLUMN_STATUS }, null, null,
257 null);
258 if (cursor.moveToFirst() && Downloads.Impl.isStatusSuccess(
259 cursor.getInt(0))) {
260 // Do this right away, so we get no more updates.
261 getContentResolver().unregisterContentObserver(
262 mContentObserver);
263 // Post a runnable in case this ContentObserver gets notified
264 // before the one that updates the ListView.
265 mListView.post(new Runnable() {
266 public void run() {
267 // Close the context menu, reopen with up to date data.
268 closeContextMenu();
269 openContextMenu(mSelectedView);
270 }
271 });
272 }
273 cursor.deactivate();
274 }
275 }
276
277 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800278 public void onCreateContextMenu(ContextMenu menu, View v,
279 ContextMenuInfo menuInfo) {
280 if (mDownloadCursor != null) {
Leon Scroggins24837452010-01-13 13:43:35 -0500281 ExpandableListView.ExpandableListContextMenuInfo info
282 = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
283 long packedPosition = info.packedPosition;
284 // Only show a context menu for the child views
285 if (!mDownloadAdapter.moveCursorToPackedChildPosition(
286 packedPosition)) {
287 return;
288 }
289 mContextMenuPosition = packedPosition;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800290 menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId));
291
292 MenuInflater inflater = getMenuInflater();
293 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800294 if (Downloads.Impl.isStatusSuccess(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800295 inflater.inflate(R.menu.downloadhistorycontextfinished, menu);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800296 } else if (Downloads.Impl.isStatusError(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800297 inflater.inflate(R.menu.downloadhistorycontextfailed, menu);
298 } else {
Leon Scrogginsd080b182010-02-26 14:16:41 -0500299 // In this case, the download is in progress. Set a
300 // ContentObserver so that we can know when it completes,
301 // and if it does, we can then update the context menu
302 Uri track = ContentUris.withAppendedId(
303 Downloads.Impl.CONTENT_URI,
304 mDownloadCursor.getLong(mIdColumnId));
305 if (mContentObserver != null) {
306 getContentResolver().unregisterContentObserver(
307 mContentObserver);
308 }
309 mContentObserver = new ChangeObserver(track);
310 mSelectedView = v;
311 getContentResolver().registerContentObserver(track, false,
312 mContentObserver);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800313 inflater.inflate(R.menu.downloadhistorycontextrunning, menu);
314 }
315 }
Leon Scroggins24837452010-01-13 13:43:35 -0500316 super.onCreateContextMenu(menu, v, menuInfo);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800317 }
318
319 /**
320 * This function is called to check the status of the download and if it
321 * has an error show an error dialog.
322 * @param id Row id of the download to check
Leon Scroggins24837452010-01-13 13:43:35 -0500323 * @return Group which contains the download
The Android Open Source Project0c908882009-03-03 19:32:16 -0800324 */
Leon Scroggins24837452010-01-13 13:43:35 -0500325 private int checkStatus(final long id) {
326 int groupToShow = mDownloadAdapter.groupFromChildId(id);
327 if (-1 == groupToShow) return 0;
328 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800329 if (!Downloads.Impl.isStatusError(status)) {
Leon Scroggins24837452010-01-13 13:43:35 -0500330 return groupToShow;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800331 }
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800332 if (status == Downloads.Impl.STATUS_FILE_ERROR) {
Leon Scroggins24837452010-01-13 13:43:35 -0500333 String title = mDownloadCursor.getString(mTitleColumnId);
334 if (title == null || title.length() == 0) {
335 title = getString(R.string.download_unknown_filename);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800336 }
Leon Scroggins24837452010-01-13 13:43:35 -0500337 String msg = getString(R.string.download_file_error_dlg_msg, title);
338 new AlertDialog.Builder(this)
339 .setTitle(R.string.download_file_error_dlg_title)
340 .setIcon(android.R.drawable.ic_popup_disk_full)
341 .setMessage(msg)
342 .setPositiveButton(R.string.ok, null)
343 .setNegativeButton(R.string.retry,
344 new DialogInterface.OnClickListener() {
345 public void onClick(DialogInterface dialog,
346 int whichButton) {
347 resumeDownload(id);
348 }
349 })
350 .show();
351 } else {
352 new AlertDialog.Builder(this)
353 .setTitle(R.string.download_failed_generic_dlg_title)
354 .setIcon(R.drawable.ssl_icon)
355 .setMessage(BrowserDownloadAdapter.getErrorText(status))
356 .setPositiveButton(R.string.ok, null)
357 .show();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800358 }
Leon Scroggins24837452010-01-13 13:43:35 -0500359 return groupToShow;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800360 }
361
362 /**
363 * Resume a given download
364 * @param id Row id of the download to resume
365 */
366 private void resumeDownload(final long id) {
367 // the relevant functionality doesn't exist in the download manager
368 }
369
370 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800371 * Return the number of items in the list that can be canceled.
372 * @return count
373 */
374 private int getCancelableCount() {
375 // Count the number of items that will be canceled.
376 int count = 0;
377 if (mDownloadCursor != null) {
Leon Scrogginsb67db6b2010-02-26 17:58:31 -0500378 for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800379 mDownloadCursor.moveToNext()) {
380 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800381 if (!Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800382 count++;
383 }
384 }
385 }
386
387 return count;
388 }
389
390 /**
391 * Prompt the user if they would like to clear the download history
392 */
393 private void promptCancelAll() {
394 int count = getCancelableCount();
395
396 // If there is nothing to do, just return
397 if (count == 0) {
398 return;
399 }
400
401 // Don't show the dialog if there is only one download
402 if (count == 1) {
403 cancelAllDownloads();
404 return;
405 }
406 String msg =
407 getString(R.string.download_cancel_dlg_msg, count);
408 new AlertDialog.Builder(this)
409 .setTitle(R.string.download_cancel_dlg_title)
410 .setIcon(R.drawable.ssl_icon)
411 .setMessage(msg)
412 .setPositiveButton(R.string.ok,
413 new DialogInterface.OnClickListener() {
414 public void onClick(DialogInterface dialog,
415 int whichButton) {
416 cancelAllDownloads();
417 }
418 })
419 .setNegativeButton(R.string.cancel, null)
420 .show();
421 }
422
423 /**
424 * Cancel all downloads. As canceled downloads are not
425 * listed, we removed them from the db. Removing a download
426 * record, cancels the download.
427 */
428 private void cancelAllDownloads() {
429 if (mDownloadCursor.moveToFirst()) {
430 StringBuilder where = new StringBuilder();
431 boolean firstTime = true;
432 while (!mDownloadCursor.isAfterLast()) {
433 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800434 if (!Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800435 if (firstTime) {
436 firstTime = false;
437 } else {
438 where.append(" OR ");
439 }
440 where.append("( ");
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800441 where.append(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800442 where.append(" = '");
443 where.append(mDownloadCursor.getLong(mIdColumnId));
444 where.append("' )");
445 }
446 mDownloadCursor.moveToNext();
447 }
448 if (!firstTime) {
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800449 getContentResolver().delete(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800450 where.toString(), null);
451 }
452 }
453 }
454
455 private int getClearableCount() {
456 int count = 0;
457 if (mDownloadCursor.moveToFirst()) {
458 while (!mDownloadCursor.isAfterLast()) {
459 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800460 if (Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800461 count++;
462 }
463 mDownloadCursor.moveToNext();
464 }
465 }
466 return count;
467 }
Leon Scroggins4cf7de02010-01-21 10:05:59 -0500468
The Android Open Source Project0c908882009-03-03 19:32:16 -0800469 /**
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500470 * Open or delete content where the download db cursor currently is. Sends
471 * an Intent to perform the action.
472 * @param delete If true, delete the content. Otherwise open it.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800473 */
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500474 private void openOrDeleteCurrentDownload(boolean delete) {
475 int packageColumnId = mDownloadCursor.getColumnIndexOrThrow(
476 Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
477 String packageName = mDownloadCursor.getString(packageColumnId);
478 Intent intent = new Intent(delete ? Intent.ACTION_DELETE
479 : Downloads.Impl.ACTION_NOTIFICATION_CLICKED);
480 Uri contentUri = ContentUris.withAppendedId(
481 Downloads.Impl.CONTENT_URI,
482 mDownloadCursor.getLong(mIdColumnId));
483 intent.setData(contentUri);
484 intent.setPackage(packageName);
485 sendBroadcast(intent);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800486 }
487
Leon Scroggins24837452010-01-13 13:43:35 -0500488 @Override
489 public boolean onChildClick(ExpandableListView parent, View v,
490 int groupPosition, int childPosition, long id) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800491 // Open the selected item
Leon Scroggins24837452010-01-13 13:43:35 -0500492 mDownloadAdapter.moveCursorToChildPosition(groupPosition,
493 childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800494
495 hideCompletedDownload();
496
497 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800498 if (Downloads.Impl.isStatusSuccess(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800499 // Open it if it downloaded successfully
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500500 openOrDeleteCurrentDownload(false);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800501 } else {
502 // Check to see if there is an error.
503 checkStatus(id);
504 }
Leon Scroggins24837452010-01-13 13:43:35 -0500505 return true;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800506 }
507
508 /**
509 * hides the notification for the download pointed by mDownloadCursor
510 * if the download has completed.
511 */
512 private void hideCompletedDownload() {
513 int status = mDownloadCursor.getInt(mStatusColumnId);
514
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800515 int visibilityColumn = mDownloadCursor.getColumnIndexOrThrow(
516 Downloads.Impl.COLUMN_VISIBILITY);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800517 int visibility = mDownloadCursor.getInt(visibilityColumn);
518
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800519 if (Downloads.Impl.isStatusCompleted(status) &&
520 visibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800521 ContentValues values = new ContentValues();
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800522 values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800523 getContentResolver().update(
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800524 ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800525 mDownloadCursor.getLong(mIdColumnId)), values, null, null);
526 }
527 }
528}