blob: a897f993999868dc45ce223a96e436bf94435ee4 [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;
Jeff Hamilton8ce956c2010-08-17 11:13:53 -050021import android.content.ContentUris;
The Android Open Source Project0c908882009-03-03 19:32:16 -080022import android.content.ContentValues;
23import android.content.DialogInterface;
24import android.content.Intent;
Leon Scrogginsd080b182010-02-26 14:16:41 -050025import android.database.ContentObserver;
The Android Open Source Project0c908882009-03-03 19:32:16 -080026import android.database.Cursor;
27import android.net.Uri;
28import android.os.Bundle;
Leon Scrogginsd080b182010-02-26 14:16:41 -050029import android.os.Handler;
The Android Open Source Project0c908882009-03-03 19:32:16 -080030import android.provider.Downloads;
Leon Scroggins2c0f6112010-03-12 18:09:39 -050031import android.util.Log;
The Android Open Source Project0c908882009-03-03 19:32:16 -080032import android.view.ContextMenu;
33import android.view.ContextMenu.ContextMenuInfo;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034import android.view.Menu;
The Android Open Source Project0c908882009-03-03 19:32:16 -080035import android.view.MenuInflater;
Jeff Hamilton8ce956c2010-08-17 11:13:53 -050036import android.view.MenuItem;
The Android Open Source Project0c908882009-03-03 19:32:16 -080037import android.view.View;
Leon Scroggins24837452010-01-13 13:43:35 -050038import android.widget.ExpandableListView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080039
40import java.io.File;
The Android Open Source Project0c908882009-03-03 19:32:16 -080041
42/**
43 * View showing the user's current browser downloads
44 */
Leon Scroggins24837452010-01-13 13:43:35 -050045public class BrowserDownloadPage extends ExpandableListActivity {
Leon Scroggins24837452010-01-13 13:43:35 -050046 private ExpandableListView mListView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080047 private Cursor mDownloadCursor;
48 private BrowserDownloadAdapter mDownloadAdapter;
49 private int mStatusColumnId;
50 private int mIdColumnId;
51 private int mTitleColumnId;
Leon Scroggins24837452010-01-13 13:43:35 -050052 private long mContextMenuPosition;
Leon Scrogginsd080b182010-02-26 14:16:41 -050053 // Used to update the ContextMenu if an item is being downloaded and the
54 // user opens the ContextMenu.
55 private ContentObserver mContentObserver;
56 // Only meaningful while a ContentObserver is registered. The ContextMenu
57 // will be reopened on this View.
58 private View mSelectedView;
Leon Scroggins III3a04dd32010-04-26 09:36:01 -040059 private Handler mHandler;
Leon Scrogginsd080b182010-02-26 14:16:41 -050060
Leon Scroggins2c0f6112010-03-12 18:09:39 -050061 private final static String LOGTAG = "BrowserDownloadPage";
The Android Open Source Project0c908882009-03-03 19:32:16 -080062 @Override
63 public void onCreate(Bundle icicle) {
64 super.onCreate(icicle);
65 setContentView(R.layout.browser_downloads_page);
66
67 setTitle(getText(R.string.download_title));
68
Leon Scroggins24837452010-01-13 13:43:35 -050069 mListView = (ExpandableListView) findViewById(android.R.id.list);
Mihai Preda83817df2009-04-28 14:24:47 +020070 mListView.setEmptyView(findViewById(R.id.empty));
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080071 mDownloadCursor = managedQuery(Downloads.Impl.CONTENT_URI,
Leon Scrogginsfedc4932010-01-26 14:15:01 -050072 new String [] {Downloads.Impl._ID, Downloads.Impl.COLUMN_TITLE,
73 Downloads.Impl.COLUMN_STATUS, Downloads.Impl.COLUMN_TOTAL_BYTES,
74 Downloads.Impl.COLUMN_CURRENT_BYTES,
75 Downloads.Impl.COLUMN_DESCRIPTION,
76 Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
77 Downloads.Impl.COLUMN_LAST_MODIFICATION,
78 Downloads.Impl.COLUMN_VISIBILITY,
Leon Scrogginsb67db6b2010-02-26 17:58:31 -050079 Downloads.Impl._DATA,
Leon Scrogginsfedc4932010-01-26 14:15:01 -050080 Downloads.Impl.COLUMN_MIME_TYPE},
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080081 null, Downloads.Impl.COLUMN_LAST_MODIFICATION + " DESC");
Leon Scroggins III3a04dd32010-04-26 09:36:01 -040082 mHandler = new Handler();
The Android Open Source Project0c908882009-03-03 19:32:16 -080083 // only attach everything to the listbox if we can access
84 // the download database. Otherwise, just show it empty
85 if (mDownloadCursor != null) {
86 mStatusColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080087 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
The Android Open Source Project0c908882009-03-03 19:32:16 -080088 mIdColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080089 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -080090 mTitleColumnId =
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -080091 mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE);
The Android Open Source Project0c908882009-03-03 19:32:16 -080092
93 // Create a list "controller" for the data
94 mDownloadAdapter = new BrowserDownloadAdapter(this,
Leon Scroggins24837452010-01-13 13:43:35 -050095 mDownloadCursor, mDownloadCursor.getColumnIndexOrThrow(
Jeff Hamilton8ce956c2010-08-17 11:13:53 -050096 Downloads.Impl.COLUMN_LAST_MODIFICATION));
Mihai Preda83817df2009-04-28 14:24:47 +020097
Leon Scroggins24837452010-01-13 13:43:35 -050098 setListAdapter(mDownloadAdapter);
The Android Open Source Project0c908882009-03-03 19:32:16 -080099 mListView.setOnCreateContextMenuListener(this);
Leon Scroggins24837452010-01-13 13:43:35 -0500100
The Android Open Source Project0c908882009-03-03 19:32:16 -0800101 Intent intent = getIntent();
Leon Scroggins24837452010-01-13 13:43:35 -0500102 final int groupToShow = intent == null || intent.getData() == null
103 ? 0 : checkStatus(ContentUris.parseId(intent.getData()));
104 if (mDownloadAdapter.getGroupCount() > groupToShow) {
105 mListView.post(new Runnable() {
106 public void run() {
107 if (mDownloadAdapter.getGroupCount() > groupToShow) {
108 mListView.expandGroup(groupToShow);
109 }
110 }
111 });
The Android Open Source Project0c908882009-03-03 19:32:16 -0800112 }
113 }
114 }
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500115
The Android Open Source Project0c908882009-03-03 19:32:16 -0800116 @Override
Leon Scrogginsb67db6b2010-02-26 17:58:31 -0500117 protected void onResume() {
118 super.onResume();
119 if (mDownloadCursor != null) {
120 String where = null;
121 for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast();
122 mDownloadCursor.moveToNext()) {
123 if (!Downloads.Impl.isStatusCompleted(
124 mDownloadCursor.getInt(mStatusColumnId))) {
125 // Only want to check files that have completed.
126 continue;
127 }
128 int filenameColumnId = mDownloadCursor.getColumnIndexOrThrow(
129 Downloads.Impl._DATA);
130 String filename = mDownloadCursor.getString(filenameColumnId);
Leon Scroggins3ee3fef2010-03-08 14:34:14 -0500131 if (filename != null) {
132 File file = new File(filename);
133 if (!file.exists()) {
134 long id = mDownloadCursor.getLong(mIdColumnId);
135 if (where == null) {
136 where = Downloads.Impl._ID + " = '" + id + "'";
137 } else {
138 where += " OR " + Downloads.Impl._ID + " = '" + id
139 + "'";
140 }
Leon Scrogginsb67db6b2010-02-26 17:58:31 -0500141 }
142 }
143 }
144 if (where != null) {
145 getContentResolver().delete(Downloads.Impl.CONTENT_URI, where,
146 null);
147 }
148 }
149 }
150
151 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800152 public boolean onCreateOptionsMenu(Menu menu) {
153 if (mDownloadCursor != null) {
154 MenuInflater inflater = getMenuInflater();
155 inflater.inflate(R.menu.downloadhistory, menu);
156 }
157 return true;
158 }
159
160 @Override
161 public boolean onPrepareOptionsMenu(Menu menu) {
162 boolean showCancel = getCancelableCount() > 0;
163 menu.findItem(R.id.download_menu_cancel_all).setEnabled(showCancel);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800164 return super.onPrepareOptionsMenu(menu);
165 }
166
167 @Override
168 public boolean onOptionsItemSelected(MenuItem item) {
169 switch (item.getItemId()) {
170 case R.id.download_menu_cancel_all:
171 promptCancelAll();
172 return true;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800173 }
174 return false;
175 }
176
Leon Scroggins9be17332010-01-14 15:44:06 -0500177 /**
178 * Remove the file from the list of downloads.
179 * @param id Unique ID of the download to remove.
180 */
181 private void clearFromDownloads(long id) {
182 getContentResolver().delete(ContentUris.withAppendedId(
183 Downloads.Impl.CONTENT_URI, id), null, null);
184 }
185
The Android Open Source Project0c908882009-03-03 19:32:16 -0800186 @Override
187 public boolean onContextItemSelected(MenuItem item) {
Leon Scroggins24837452010-01-13 13:43:35 -0500188 if (!mDownloadAdapter.moveCursorToPackedChildPosition(
189 mContextMenuPosition)) {
190 return false;
191 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800192 switch (item.getItemId()) {
193 case R.id.download_menu_open:
194 hideCompletedDownload();
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500195 openOrDeleteCurrentDownload(false);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800196 return true;
Leon Scroggins9be17332010-01-14 15:44:06 -0500197
198 case R.id.download_menu_delete:
Leon Scroggins9be17332010-01-14 15:44:06 -0500199 new AlertDialog.Builder(this)
200 .setTitle(R.string.download_delete_file)
201 .setIcon(android.R.drawable.ic_dialog_alert)
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500202 .setMessage(mDownloadCursor.getString(mTitleColumnId))
Leon Scroggins9be17332010-01-14 15:44:06 -0500203 .setNegativeButton(R.string.cancel, null)
204 .setPositiveButton(R.string.ok,
205 new DialogInterface.OnClickListener() {
206 public void onClick(DialogInterface dialog,
207 int whichButton) {
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500208 openOrDeleteCurrentDownload(true);
Leon Scroggins9be17332010-01-14 15:44:06 -0500209 }
210 })
211 .show();
212 break;
213
The Android Open Source Project0c908882009-03-03 19:32:16 -0800214 case R.id.download_menu_clear:
215 case R.id.download_menu_cancel:
Leon Scroggins9be17332010-01-14 15:44:06 -0500216 clearFromDownloads(mDownloadCursor.getLong(mIdColumnId));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800217 return true;
218 }
219 return false;
220 }
221
222 @Override
Leon Scrogginsd080b182010-02-26 14:16:41 -0500223 protected void onPause() {
224 super.onPause();
225 if (mContentObserver != null) {
226 getContentResolver().unregisterContentObserver(mContentObserver);
227 // Note that we do not need to undo this in onResume, because the
228 // ContextMenu does not get reinvoked when the Activity resumes.
229 }
230 }
231
232 /*
233 * ContentObserver to update the ContextMenu if it is open when the
234 * corresponding download completes.
235 */
236 private class ChangeObserver extends ContentObserver {
237 private final Uri mTrack;
Leon Scroggins III3a04dd32010-04-26 09:36:01 -0400238 public ChangeObserver(Uri track, Handler handler) {
239 super(handler);
Leon Scrogginsd080b182010-02-26 14:16:41 -0500240 mTrack = track;
241 }
242
243 @Override
244 public boolean deliverSelfNotifications() {
245 return false;
246 }
247
248 @Override
249 public void onChange(boolean selfChange) {
Leon Scroggins2c0f6112010-03-12 18:09:39 -0500250 Cursor cursor = null;
251 try {
252 cursor = getContentResolver().query(mTrack,
253 new String[] { Downloads.Impl.COLUMN_STATUS }, null, null,
254 null);
255 if (cursor.moveToFirst() && Downloads.Impl.isStatusSuccess(
256 cursor.getInt(0))) {
257 // Do this right away, so we get no more updates.
258 getContentResolver().unregisterContentObserver(
259 mContentObserver);
260 // Post a runnable in case this ContentObserver gets notified
261 // before the one that updates the ListView.
262 mListView.post(new Runnable() {
263 public void run() {
264 // Close the context menu, reopen with up to date data.
265 closeContextMenu();
266 openContextMenu(mSelectedView);
267 }
268 });
269 }
270 } catch (IllegalStateException e) {
271 Log.e(LOGTAG, "onChange", e);
272 } finally {
273 if (cursor != null) cursor.close();
Leon Scrogginsd080b182010-02-26 14:16:41 -0500274 }
Leon Scrogginsd080b182010-02-26 14:16:41 -0500275 }
276 }
277
278 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800279 public void onCreateContextMenu(ContextMenu menu, View v,
280 ContextMenuInfo menuInfo) {
281 if (mDownloadCursor != null) {
Leon Scroggins24837452010-01-13 13:43:35 -0500282 ExpandableListView.ExpandableListContextMenuInfo info
283 = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
284 long packedPosition = info.packedPosition;
285 // Only show a context menu for the child views
286 if (!mDownloadAdapter.moveCursorToPackedChildPosition(
287 packedPosition)) {
288 return;
289 }
290 mContextMenuPosition = packedPosition;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800291 menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId));
292
293 MenuInflater inflater = getMenuInflater();
294 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800295 if (Downloads.Impl.isStatusSuccess(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800296 inflater.inflate(R.menu.downloadhistorycontextfinished, menu);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800297 } else if (Downloads.Impl.isStatusError(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800298 inflater.inflate(R.menu.downloadhistorycontextfailed, menu);
299 } else {
Leon Scrogginsd080b182010-02-26 14:16:41 -0500300 // In this case, the download is in progress. Set a
301 // ContentObserver so that we can know when it completes,
302 // and if it does, we can then update the context menu
303 Uri track = ContentUris.withAppendedId(
304 Downloads.Impl.CONTENT_URI,
305 mDownloadCursor.getLong(mIdColumnId));
306 if (mContentObserver != null) {
307 getContentResolver().unregisterContentObserver(
308 mContentObserver);
309 }
Leon Scroggins III3a04dd32010-04-26 09:36:01 -0400310 mContentObserver = new ChangeObserver(track, mHandler);
Leon Scrogginsd080b182010-02-26 14:16:41 -0500311 mSelectedView = v;
312 getContentResolver().registerContentObserver(track, false,
313 mContentObserver);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800314 inflater.inflate(R.menu.downloadhistorycontextrunning, menu);
315 }
316 }
Leon Scroggins24837452010-01-13 13:43:35 -0500317 super.onCreateContextMenu(menu, v, menuInfo);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800318 }
319
320 /**
321 * This function is called to check the status of the download and if it
322 * has an error show an error dialog.
323 * @param id Row id of the download to check
Leon Scroggins24837452010-01-13 13:43:35 -0500324 * @return Group which contains the download
The Android Open Source Project0c908882009-03-03 19:32:16 -0800325 */
Leon Scroggins24837452010-01-13 13:43:35 -0500326 private int checkStatus(final long id) {
327 int groupToShow = mDownloadAdapter.groupFromChildId(id);
328 if (-1 == groupToShow) return 0;
329 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800330 if (!Downloads.Impl.isStatusError(status)) {
Leon Scroggins24837452010-01-13 13:43:35 -0500331 return groupToShow;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800332 }
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800333 if (status == Downloads.Impl.STATUS_FILE_ERROR) {
Leon Scroggins24837452010-01-13 13:43:35 -0500334 String title = mDownloadCursor.getString(mTitleColumnId);
335 if (title == null || title.length() == 0) {
336 title = getString(R.string.download_unknown_filename);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800337 }
Leon Scroggins24837452010-01-13 13:43:35 -0500338 String msg = getString(R.string.download_file_error_dlg_msg, title);
339 new AlertDialog.Builder(this)
340 .setTitle(R.string.download_file_error_dlg_title)
341 .setIcon(android.R.drawable.ic_popup_disk_full)
342 .setMessage(msg)
343 .setPositiveButton(R.string.ok, null)
344 .setNegativeButton(R.string.retry,
345 new DialogInterface.OnClickListener() {
346 public void onClick(DialogInterface dialog,
347 int whichButton) {
348 resumeDownload(id);
349 }
350 })
351 .show();
352 } else {
353 new AlertDialog.Builder(this)
354 .setTitle(R.string.download_failed_generic_dlg_title)
355 .setIcon(R.drawable.ssl_icon)
356 .setMessage(BrowserDownloadAdapter.getErrorText(status))
357 .setPositiveButton(R.string.ok, null)
358 .show();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800359 }
Leon Scroggins24837452010-01-13 13:43:35 -0500360 return groupToShow;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800361 }
362
363 /**
364 * Resume a given download
365 * @param id Row id of the download to resume
366 */
367 private void resumeDownload(final long id) {
368 // the relevant functionality doesn't exist in the download manager
369 }
370
371 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800372 * Return the number of items in the list that can be canceled.
373 * @return count
374 */
375 private int getCancelableCount() {
376 // Count the number of items that will be canceled.
377 int count = 0;
378 if (mDownloadCursor != null) {
Leon Scrogginsb67db6b2010-02-26 17:58:31 -0500379 for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800380 mDownloadCursor.moveToNext()) {
381 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800382 if (!Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800383 count++;
384 }
385 }
386 }
387
388 return count;
389 }
390
391 /**
392 * Prompt the user if they would like to clear the download history
393 */
394 private void promptCancelAll() {
395 int count = getCancelableCount();
396
397 // If there is nothing to do, just return
398 if (count == 0) {
399 return;
400 }
401
402 // Don't show the dialog if there is only one download
403 if (count == 1) {
404 cancelAllDownloads();
405 return;
406 }
407 String msg =
408 getString(R.string.download_cancel_dlg_msg, count);
409 new AlertDialog.Builder(this)
410 .setTitle(R.string.download_cancel_dlg_title)
411 .setIcon(R.drawable.ssl_icon)
412 .setMessage(msg)
413 .setPositiveButton(R.string.ok,
414 new DialogInterface.OnClickListener() {
415 public void onClick(DialogInterface dialog,
416 int whichButton) {
417 cancelAllDownloads();
418 }
419 })
420 .setNegativeButton(R.string.cancel, null)
421 .show();
422 }
423
424 /**
425 * Cancel all downloads. As canceled downloads are not
426 * listed, we removed them from the db. Removing a download
427 * record, cancels the download.
428 */
429 private void cancelAllDownloads() {
430 if (mDownloadCursor.moveToFirst()) {
431 StringBuilder where = new StringBuilder();
432 boolean firstTime = true;
433 while (!mDownloadCursor.isAfterLast()) {
434 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800435 if (!Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800436 if (firstTime) {
437 firstTime = false;
438 } else {
439 where.append(" OR ");
440 }
441 where.append("( ");
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800442 where.append(Downloads.Impl._ID);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800443 where.append(" = '");
444 where.append(mDownloadCursor.getLong(mIdColumnId));
445 where.append("' )");
446 }
447 mDownloadCursor.moveToNext();
448 }
449 if (!firstTime) {
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800450 getContentResolver().delete(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800451 where.toString(), null);
452 }
453 }
454 }
455
456 private int getClearableCount() {
457 int count = 0;
458 if (mDownloadCursor.moveToFirst()) {
459 while (!mDownloadCursor.isAfterLast()) {
460 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800461 if (Downloads.Impl.isStatusCompleted(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800462 count++;
463 }
464 mDownloadCursor.moveToNext();
465 }
466 }
467 return count;
468 }
Leon Scroggins4cf7de02010-01-21 10:05:59 -0500469
The Android Open Source Project0c908882009-03-03 19:32:16 -0800470 /**
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500471 * Open or delete content where the download db cursor currently is. Sends
472 * an Intent to perform the action.
473 * @param delete If true, delete the content. Otherwise open it.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800474 */
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500475 private void openOrDeleteCurrentDownload(boolean delete) {
476 int packageColumnId = mDownloadCursor.getColumnIndexOrThrow(
477 Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
478 String packageName = mDownloadCursor.getString(packageColumnId);
479 Intent intent = new Intent(delete ? Intent.ACTION_DELETE
480 : Downloads.Impl.ACTION_NOTIFICATION_CLICKED);
481 Uri contentUri = ContentUris.withAppendedId(
482 Downloads.Impl.CONTENT_URI,
483 mDownloadCursor.getLong(mIdColumnId));
484 intent.setData(contentUri);
485 intent.setPackage(packageName);
486 sendBroadcast(intent);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800487 }
488
Leon Scroggins24837452010-01-13 13:43:35 -0500489 @Override
490 public boolean onChildClick(ExpandableListView parent, View v,
491 int groupPosition, int childPosition, long id) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800492 // Open the selected item
Leon Scroggins24837452010-01-13 13:43:35 -0500493 mDownloadAdapter.moveCursorToChildPosition(groupPosition,
494 childPosition);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800495
496 hideCompletedDownload();
497
498 int status = mDownloadCursor.getInt(mStatusColumnId);
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800499 if (Downloads.Impl.isStatusSuccess(status)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800500 // Open it if it downloaded successfully
Leon Scrogginsfedc4932010-01-26 14:15:01 -0500501 openOrDeleteCurrentDownload(false);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800502 } else {
503 // Check to see if there is an error.
504 checkStatus(id);
505 }
Leon Scroggins24837452010-01-13 13:43:35 -0500506 return true;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800507 }
508
509 /**
510 * hides the notification for the download pointed by mDownloadCursor
511 * if the download has completed.
512 */
513 private void hideCompletedDownload() {
514 int status = mDownloadCursor.getInt(mStatusColumnId);
515
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800516 int visibilityColumn = mDownloadCursor.getColumnIndexOrThrow(
517 Downloads.Impl.COLUMN_VISIBILITY);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800518 int visibility = mDownloadCursor.getInt(visibilityColumn);
519
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800520 if (Downloads.Impl.isStatusCompleted(status) &&
521 visibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800522 ContentValues values = new ContentValues();
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800523 values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800524 getContentResolver().update(
Jean-Baptiste Queru1e5bad92010-01-14 16:09:03 -0800525 ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800526 mDownloadCursor.getLong(mIdColumnId)), values, null, null);
527 }
528 }
529}