diff options
Diffstat (limited to 'src/com/android/browser/BrowserDownloadPage.java')
-rw-r--r-- | src/com/android/browser/BrowserDownloadPage.java | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/src/com/android/browser/BrowserDownloadPage.java b/src/com/android/browser/BrowserDownloadPage.java deleted file mode 100644 index 18faf8b..0000000 --- a/src/com/android/browser/BrowserDownloadPage.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * 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.AlertDialog; -import android.app.ExpandableListActivity; -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.ContentObserver; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.provider.Downloads; -import android.util.Log; -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.ExpandableListView; - -import java.io.File; -import java.util.List; - -/** - * View showing the user's current browser downloads - */ -public class BrowserDownloadPage extends ExpandableListActivity { - private ExpandableListView mListView; - private Cursor mDownloadCursor; - private BrowserDownloadAdapter mDownloadAdapter; - private int mStatusColumnId; - private int mIdColumnId; - private int mTitleColumnId; - private long mContextMenuPosition; - // Used to update the ContextMenu if an item is being downloaded and the - // user opens the ContextMenu. - private ContentObserver mContentObserver; - // Only meaningful while a ContentObserver is registered. The ContextMenu - // will be reopened on this View. - private View mSelectedView; - - private final static String LOGTAG = "BrowserDownloadPage"; - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.browser_downloads_page); - - setTitle(getText(R.string.download_title)); - - mListView = (ExpandableListView) findViewById(android.R.id.list); - mListView.setEmptyView(findViewById(R.id.empty)); - mDownloadCursor = managedQuery(Downloads.Impl.CONTENT_URI, - new String [] {Downloads.Impl._ID, Downloads.Impl.COLUMN_TITLE, - Downloads.Impl.COLUMN_STATUS, Downloads.Impl.COLUMN_TOTAL_BYTES, - Downloads.Impl.COLUMN_CURRENT_BYTES, - Downloads.Impl.COLUMN_DESCRIPTION, - Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE, - Downloads.Impl.COLUMN_LAST_MODIFICATION, - Downloads.Impl.COLUMN_VISIBILITY, - Downloads.Impl._DATA, - Downloads.Impl.COLUMN_MIME_TYPE}, - null, Downloads.Impl.COLUMN_LAST_MODIFICATION + " DESC"); - - // 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.Impl.COLUMN_STATUS); - mIdColumnId = - mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl._ID); - mTitleColumnId = - mDownloadCursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE); - - // Create a list "controller" for the data - mDownloadAdapter = new BrowserDownloadAdapter(this, - mDownloadCursor, mDownloadCursor.getColumnIndexOrThrow( - Downloads.Impl.COLUMN_LAST_MODIFICATION)); - - setListAdapter(mDownloadAdapter); - mListView.setOnCreateContextMenuListener(this); - - Intent intent = getIntent(); - final int groupToShow = intent == null || intent.getData() == null - ? 0 : checkStatus(ContentUris.parseId(intent.getData())); - if (mDownloadAdapter.getGroupCount() > groupToShow) { - mListView.post(new Runnable() { - public void run() { - if (mDownloadAdapter.getGroupCount() > groupToShow) { - mListView.expandGroup(groupToShow); - } - } - }); - } - } - } - - @Override - protected void onResume() { - super.onResume(); - if (mDownloadCursor != null) { - String where = null; - for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); - mDownloadCursor.moveToNext()) { - if (!Downloads.Impl.isStatusCompleted( - mDownloadCursor.getInt(mStatusColumnId))) { - // Only want to check files that have completed. - continue; - } - int filenameColumnId = mDownloadCursor.getColumnIndexOrThrow( - Downloads.Impl._DATA); - String filename = mDownloadCursor.getString(filenameColumnId); - if (filename != null) { - File file = new File(filename); - if (!file.exists()) { - long id = mDownloadCursor.getLong(mIdColumnId); - if (where == null) { - where = Downloads.Impl._ID + " = '" + id + "'"; - } else { - where += " OR " + Downloads.Impl._ID + " = '" + id - + "'"; - } - } - } - } - if (where != null) { - getContentResolver().delete(Downloads.Impl.CONTENT_URI, where, - null); - } - } - } - - @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); - return super.onPrepareOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.download_menu_cancel_all: - promptCancelAll(); - return true; - } - return false; - } - - /** - * Remove the file from the list of downloads. - * @param id Unique ID of the download to remove. - */ - private void clearFromDownloads(long id) { - getContentResolver().delete(ContentUris.withAppendedId( - Downloads.Impl.CONTENT_URI, id), null, null); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - if (!mDownloadAdapter.moveCursorToPackedChildPosition( - mContextMenuPosition)) { - return false; - } - switch (item.getItemId()) { - case R.id.download_menu_open: - hideCompletedDownload(); - openOrDeleteCurrentDownload(false); - return true; - - case R.id.download_menu_delete: - new AlertDialog.Builder(this) - .setTitle(R.string.download_delete_file) - .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(mDownloadCursor.getString(mTitleColumnId)) - .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int whichButton) { - openOrDeleteCurrentDownload(true); - } - }) - .show(); - break; - - case R.id.download_menu_clear: - case R.id.download_menu_cancel: - clearFromDownloads(mDownloadCursor.getLong(mIdColumnId)); - return true; - } - return false; - } - - @Override - protected void onPause() { - super.onPause(); - if (mContentObserver != null) { - getContentResolver().unregisterContentObserver(mContentObserver); - // Note that we do not need to undo this in onResume, because the - // ContextMenu does not get reinvoked when the Activity resumes. - } - } - - /* - * ContentObserver to update the ContextMenu if it is open when the - * corresponding download completes. - */ - private class ChangeObserver extends ContentObserver { - private final Uri mTrack; - public ChangeObserver(Uri track) { - super(new Handler()); - mTrack = track; - } - - @Override - public boolean deliverSelfNotifications() { - return false; - } - - @Override - public void onChange(boolean selfChange) { - Cursor cursor = null; - try { - cursor = getContentResolver().query(mTrack, - new String[] { Downloads.Impl.COLUMN_STATUS }, null, null, - null); - if (cursor.moveToFirst() && Downloads.Impl.isStatusSuccess( - cursor.getInt(0))) { - // Do this right away, so we get no more updates. - getContentResolver().unregisterContentObserver( - mContentObserver); - // Post a runnable in case this ContentObserver gets notified - // before the one that updates the ListView. - mListView.post(new Runnable() { - public void run() { - // Close the context menu, reopen with up to date data. - closeContextMenu(); - openContextMenu(mSelectedView); - } - }); - } - } catch (IllegalStateException e) { - Log.e(LOGTAG, "onChange", e); - } finally { - if (cursor != null) cursor.close(); - } - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - if (mDownloadCursor != null) { - ExpandableListView.ExpandableListContextMenuInfo info - = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; - long packedPosition = info.packedPosition; - // Only show a context menu for the child views - if (!mDownloadAdapter.moveCursorToPackedChildPosition( - packedPosition)) { - return; - } - mContextMenuPosition = packedPosition; - menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId)); - - MenuInflater inflater = getMenuInflater(); - int status = mDownloadCursor.getInt(mStatusColumnId); - if (Downloads.Impl.isStatusSuccess(status)) { - inflater.inflate(R.menu.downloadhistorycontextfinished, menu); - } else if (Downloads.Impl.isStatusError(status)) { - inflater.inflate(R.menu.downloadhistorycontextfailed, menu); - } else { - // In this case, the download is in progress. Set a - // ContentObserver so that we can know when it completes, - // and if it does, we can then update the context menu - Uri track = ContentUris.withAppendedId( - Downloads.Impl.CONTENT_URI, - mDownloadCursor.getLong(mIdColumnId)); - if (mContentObserver != null) { - getContentResolver().unregisterContentObserver( - mContentObserver); - } - mContentObserver = new ChangeObserver(track); - mSelectedView = v; - getContentResolver().registerContentObserver(track, false, - mContentObserver); - inflater.inflate(R.menu.downloadhistorycontextrunning, menu); - } - } - super.onCreateContextMenu(menu, v, menuInfo); - } - - /** - * 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 Group which contains the download - */ - private int checkStatus(final long id) { - int groupToShow = mDownloadAdapter.groupFromChildId(id); - if (-1 == groupToShow) return 0; - int status = mDownloadCursor.getInt(mStatusColumnId); - if (!Downloads.Impl.isStatusError(status)) { - return groupToShow; - } - if (status == Downloads.Impl.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 groupToShow; - } - - /** - * 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 - } - - /** - * 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.Impl.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.Impl.isStatusCompleted(status)) { - if (firstTime) { - firstTime = false; - } else { - where.append(" OR "); - } - where.append("( "); - where.append(Downloads.Impl._ID); - where.append(" = '"); - where.append(mDownloadCursor.getLong(mIdColumnId)); - where.append("' )"); - } - mDownloadCursor.moveToNext(); - } - if (!firstTime) { - getContentResolver().delete(Downloads.Impl.CONTENT_URI, - where.toString(), null); - } - } - } - - private int getClearableCount() { - int count = 0; - if (mDownloadCursor.moveToFirst()) { - while (!mDownloadCursor.isAfterLast()) { - int status = mDownloadCursor.getInt(mStatusColumnId); - if (Downloads.Impl.isStatusCompleted(status)) { - count++; - } - mDownloadCursor.moveToNext(); - } - } - return count; - } - - /** - * Open or delete content where the download db cursor currently is. Sends - * an Intent to perform the action. - * @param delete If true, delete the content. Otherwise open it. - */ - private void openOrDeleteCurrentDownload(boolean delete) { - int packageColumnId = mDownloadCursor.getColumnIndexOrThrow( - Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE); - String packageName = mDownloadCursor.getString(packageColumnId); - Intent intent = new Intent(delete ? Intent.ACTION_DELETE - : Downloads.Impl.ACTION_NOTIFICATION_CLICKED); - Uri contentUri = ContentUris.withAppendedId( - Downloads.Impl.CONTENT_URI, - mDownloadCursor.getLong(mIdColumnId)); - intent.setData(contentUri); - intent.setPackage(packageName); - sendBroadcast(intent); - } - - @Override - public boolean onChildClick(ExpandableListView parent, View v, - int groupPosition, int childPosition, long id) { - // Open the selected item - mDownloadAdapter.moveCursorToChildPosition(groupPosition, - childPosition); - - hideCompletedDownload(); - - int status = mDownloadCursor.getInt(mStatusColumnId); - if (Downloads.Impl.isStatusSuccess(status)) { - // Open it if it downloaded successfully - openOrDeleteCurrentDownload(false); - } else { - // Check to see if there is an error. - checkStatus(id); - } - return true; - } - - /** - * 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.Impl.COLUMN_VISIBILITY); - int visibility = mDownloadCursor.getInt(visibilityColumn); - - if (Downloads.Impl.isStatusCompleted(status) && - visibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) { - ContentValues values = new ContentValues(); - values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE); - getContentResolver().update( - ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, - mDownloadCursor.getLong(mIdColumnId)), values, null, null); - } - } -} |