diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:32:16 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:32:16 -0800 |
commit | 0c90888c75eed12f6e2e14a9044faf50bd4af8ed (patch) | |
tree | 266c059a147232a297b2d956e04397c0f6683bc4 /src/com/android/browser/BrowserDownloadPage.java | |
parent | 8611831e36b71c844a14788998728f3cd625b833 (diff) | |
download | packages_apps_Browser-0c90888c75eed12f6e2e14a9044faf50bd4af8ed.zip packages_apps_Browser-0c90888c75eed12f6e2e14a9044faf50bd4af8ed.tar.gz packages_apps_Browser-0c90888c75eed12f6e2e14a9044faf50bd4af8ed.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'src/com/android/browser/BrowserDownloadPage.java')
-rw-r--r-- | src/com/android/browser/BrowserDownloadPage.java | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/src/com/android/browser/BrowserDownloadPage.java b/src/com/android/browser/BrowserDownloadPage.java new file mode 100644 index 0000000..4397337 --- /dev/null +++ b/src/com/android/browser/BrowserDownloadPage.java @@ -0,0 +1,468 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ActivityNotFoundException; +import android.content.ContentValues; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.ContentUris; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.Downloads; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MenuInflater; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.AdapterView.OnItemClickListener; + +import java.io.File; +import java.util.List; + +/** + * View showing the user's current browser downloads + */ +public class BrowserDownloadPage extends Activity + implements View.OnCreateContextMenuListener, OnItemClickListener { + + private ListView mListView; + private Cursor mDownloadCursor; + private BrowserDownloadAdapter mDownloadAdapter; + private int mStatusColumnId; + private int mIdColumnId; + private int mTitleColumnId; + private int mContextMenuPosition; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + setContentView(R.layout.browser_downloads_page); + + setTitle(getText(R.string.download_title)); + + mListView = (ListView) findViewById(R.id.list); + LayoutInflater factory = LayoutInflater.from(this); + View v = factory.inflate(R.layout.no_downloads, null); + addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + mListView.setEmptyView(v); + + mDownloadCursor = managedQuery(Downloads.CONTENT_URI, + new String [] {"_id", Downloads.TITLE, Downloads.STATUS, + Downloads.TOTAL_BYTES, Downloads.CURRENT_BYTES, + Downloads._DATA, Downloads.DESCRIPTION, + Downloads.MIMETYPE, Downloads.LAST_MODIFICATION, + Downloads.VISIBILITY}, + null, null); + + // only attach everything to the listbox if we can access + // the download database. Otherwise, just show it empty + if (mDownloadCursor != null) { + mStatusColumnId = + mDownloadCursor.getColumnIndexOrThrow(Downloads.STATUS); + mIdColumnId = + mDownloadCursor.getColumnIndexOrThrow(Downloads._ID); + mTitleColumnId = + mDownloadCursor.getColumnIndexOrThrow(Downloads.TITLE); + + // Create a list "controller" for the data + mDownloadAdapter = new BrowserDownloadAdapter(this, + R.layout.browser_download_item, mDownloadCursor); + + mListView.setAdapter(mDownloadAdapter); + mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); + mListView.setOnCreateContextMenuListener(this); + mListView.setOnItemClickListener(this); + + Intent intent = getIntent(); + if (intent != null && intent.getData() != null) { + int position = checkStatus( + ContentUris.parseId(intent.getData())); + if (position >= 0) { + mListView.setSelection(position); + } + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + if (mDownloadCursor != null) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.downloadhistory, menu); + } + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + boolean showCancel = getCancelableCount() > 0; + menu.findItem(R.id.download_menu_cancel_all).setEnabled(showCancel); + + boolean showClear = getClearableCount() > 0; + menu.findItem(R.id.download_menu_clear_all).setEnabled(showClear); + return super.onPrepareOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.download_menu_cancel_all: + promptCancelAll(); + return true; + + case R.id.download_menu_clear_all: + promptClearList(); + return true; + } + return false; + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + mDownloadCursor.moveToPosition(mContextMenuPosition); + switch (item.getItemId()) { + case R.id.download_menu_open: + hideCompletedDownload(); + openCurrentDownload(); + return true; + + case R.id.download_menu_clear: + case R.id.download_menu_cancel: + getContentResolver().delete( + ContentUris.withAppendedId(Downloads.CONTENT_URI, + mDownloadCursor.getLong(mIdColumnId)), null, null); + return true; + } + return false; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + if (mDownloadCursor != null) { + AdapterView.AdapterContextMenuInfo info = + (AdapterView.AdapterContextMenuInfo) menuInfo; + mDownloadCursor.moveToPosition(info.position); + mContextMenuPosition = info.position; + menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId)); + + MenuInflater inflater = getMenuInflater(); + int status = mDownloadCursor.getInt(mStatusColumnId); + if (Downloads.isStatusSuccess(status)) { + inflater.inflate(R.menu.downloadhistorycontextfinished, menu); + } else if (Downloads.isStatusError(status)) { + inflater.inflate(R.menu.downloadhistorycontextfailed, menu); + } else { + inflater.inflate(R.menu.downloadhistorycontextrunning, menu); + } + } + } + + /** + * This function is called to check the status of the download and if it + * has an error show an error dialog. + * @param id Row id of the download to check + * @return position of item + */ + int checkStatus(final long id) { + int position = -1; + for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); + mDownloadCursor.moveToNext()) { + if (id == mDownloadCursor.getLong(mIdColumnId)) { + position = mDownloadCursor.getPosition(); + break; + } + + } + if (!mDownloadCursor.isAfterLast()) { + int status = mDownloadCursor.getInt(mStatusColumnId); + if (!Downloads.isStatusError(status)) { + return position; + } + + if (status == Downloads.STATUS_FILE_ERROR) { + String title = mDownloadCursor.getString(mTitleColumnId); + if (title == null || title.length() == 0) { + title = getString(R.string.download_unknown_filename); + } + String msg = getString(R.string.download_file_error_dlg_msg, + title); + new AlertDialog.Builder(this) + .setTitle(R.string.download_file_error_dlg_title) + .setIcon(android.R.drawable.ic_popup_disk_full) + .setMessage(msg) + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.retry, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int whichButton) { + resumeDownload(id); + } + }) + .show(); + } else { + new AlertDialog.Builder(this) + .setTitle(R.string.download_failed_generic_dlg_title) + .setIcon(R.drawable.ssl_icon) + .setMessage(BrowserDownloadAdapter.getErrorText(status)) + .setPositiveButton(R.string.ok, null) + .show(); + } + } + return position; + } + + /** + * Resume a given download + * @param id Row id of the download to resume + */ + private void resumeDownload(final long id) { + // the relevant functionality doesn't exist in the download manager + } + + /** + * Prompt the user if they would like to clear the download history + */ + private void promptClearList() { + new AlertDialog.Builder(this) + .setTitle(R.string.download_clear_dlg_title) + .setIcon(R.drawable.ssl_icon) + .setMessage(R.string.download_clear_dlg_msg) + .setPositiveButton(R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int whichButton) { + clearAllDownloads(); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + /** + * Return the number of items in the list that can be canceled. + * @return count + */ + private int getCancelableCount() { + // Count the number of items that will be canceled. + int count = 0; + if (mDownloadCursor != null) { + for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); + mDownloadCursor.moveToNext()) { + int status = mDownloadCursor.getInt(mStatusColumnId); + if (!Downloads.isStatusCompleted(status)) { + count++; + } + } + } + + return count; + } + + /** + * Prompt the user if they would like to clear the download history + */ + private void promptCancelAll() { + int count = getCancelableCount(); + + // If there is nothing to do, just return + if (count == 0) { + return; + } + + // Don't show the dialog if there is only one download + if (count == 1) { + cancelAllDownloads(); + return; + } + String msg = + getString(R.string.download_cancel_dlg_msg, count); + new AlertDialog.Builder(this) + .setTitle(R.string.download_cancel_dlg_title) + .setIcon(R.drawable.ssl_icon) + .setMessage(msg) + .setPositiveButton(R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int whichButton) { + cancelAllDownloads(); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + /** + * Cancel all downloads. As canceled downloads are not + * listed, we removed them from the db. Removing a download + * record, cancels the download. + */ + private void cancelAllDownloads() { + if (mDownloadCursor.moveToFirst()) { + StringBuilder where = new StringBuilder(); + boolean firstTime = true; + while (!mDownloadCursor.isAfterLast()) { + int status = mDownloadCursor.getInt(mStatusColumnId); + if (!Downloads.isStatusCompleted(status)) { + if (firstTime) { + firstTime = false; + } else { + where.append(" OR "); + } + where.append("( "); + where.append(Downloads._ID); + where.append(" = '"); + where.append(mDownloadCursor.getLong(mIdColumnId)); + where.append("' )"); + } + mDownloadCursor.moveToNext(); + } + if (!firstTime) { + getContentResolver().delete(Downloads.CONTENT_URI, + where.toString(), null); + } + } + } + + private int getClearableCount() { + int count = 0; + if (mDownloadCursor.moveToFirst()) { + while (!mDownloadCursor.isAfterLast()) { + int status = mDownloadCursor.getInt(mStatusColumnId); + if (Downloads.isStatusCompleted(status)) { + count++; + } + mDownloadCursor.moveToNext(); + } + } + return count; + } + + /** + * Clear all stopped downloads, ie canceled (though should not be + * there), error and success download items. + */ + private void clearAllDownloads() { + if (mDownloadCursor.moveToFirst()) { + StringBuilder where = new StringBuilder(); + boolean firstTime = true; + while (!mDownloadCursor.isAfterLast()) { + int status = mDownloadCursor.getInt(mStatusColumnId); + if (Downloads.isStatusCompleted(status)) { + if (firstTime) { + firstTime = false; + } else { + where.append(" OR "); + } + where.append("( "); + where.append(Downloads._ID); + where.append(" = '"); + where.append(mDownloadCursor.getLong(mIdColumnId)); + where.append("' )"); + } + mDownloadCursor.moveToNext(); + } + if (!firstTime) { + getContentResolver().delete(Downloads.CONTENT_URI, + where.toString(), null); + } + } + } + + /** + * Open the content where the download db cursor currently is + */ + private void openCurrentDownload() { + int filenameColumnId = + mDownloadCursor.getColumnIndexOrThrow(Downloads._DATA); + String filename = mDownloadCursor.getString(filenameColumnId); + int mimetypeColumnId = + mDownloadCursor.getColumnIndexOrThrow(Downloads.MIMETYPE); + String mimetype = mDownloadCursor.getString(mimetypeColumnId); + Uri path = Uri.parse(filename); + // If there is no scheme, then it must be a file + if (path.getScheme() == null) { + path = Uri.fromFile(new File(filename)); + } + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(path, mimetype); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + try { + startActivity(intent); + } catch (ActivityNotFoundException ex) { + new AlertDialog.Builder(this) + .setTitle(R.string.download_failed_generic_dlg_title) + .setIcon(R.drawable.ssl_icon) + .setMessage(R.string.download_no_application) + .setPositiveButton(R.string.ok, null) + .show(); + } + } + + /* + * (non-Javadoc) + * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long) + */ + public void onItemClick(AdapterView parent, View view, int position, + long id) { + // Open the selected item + mDownloadCursor.moveToPosition(position); + + hideCompletedDownload(); + + int status = mDownloadCursor.getInt(mStatusColumnId); + if (Downloads.isStatusSuccess(status)) { + // Open it if it downloaded successfully + openCurrentDownload(); + } else { + // Check to see if there is an error. + checkStatus(id); + } + } + + /** + * hides the notification for the download pointed by mDownloadCursor + * if the download has completed. + */ + private void hideCompletedDownload() { + int status = mDownloadCursor.getInt(mStatusColumnId); + + int visibilityColumn = mDownloadCursor.getColumnIndexOrThrow(Downloads.VISIBILITY); + int visibility = mDownloadCursor.getInt(visibilityColumn); + + if (Downloads.isStatusCompleted(status) && + visibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) { + ContentValues values = new ContentValues(); + values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE); + getContentResolver().update( + ContentUris.withAppendedId(Downloads.CONTENT_URI, + mDownloadCursor.getLong(mIdColumnId)), values, null, null); + } + } +} |