From e29f12803f02c7726008127ad0a2a5a8ae786ce6 Mon Sep 17 00:00:00 2001 From: Jaekyun Seok Date: Mon, 15 Apr 2013 12:35:13 +0900 Subject: Hide the sorting button when download list is empty Bug: 8515801 Change-Id: Id5ff6d56eb07de6b76bdb6bc3fa75af6ddd59a39 --- ui/src/com/android/providers/downloads/ui/DownloadList.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ui/src/com/android/providers') diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index ed369932..29ea60eb 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -431,8 +431,10 @@ public class DownloadList extends Activity { if (mDateSortedCursor == null || mDateSortedCursor.getCount() == 0) { mEmptyView.setVisibility(View.VISIBLE); + mSortOption.setVisibility(View.GONE); } else { mEmptyView.setVisibility(View.GONE); + mSortOption.setVisibility(View.VISIBLE); ListView lv = activeListView(); lv.setVisibility(View.VISIBLE); lv.invalidateViews(); // ensure checkboxes get updated -- cgit v1.2.3 From b1bf9a2a0cd929130ee75a29b5f7a9f01901a0d7 Mon Sep 17 00:00:00 2001 From: Mattias Falk Date: Thu, 3 Jan 2013 12:49:09 +0100 Subject: Avoid NullPointerException A crash will occur when a user share more than one file and the mime type of any of the files to share is null. Avoid crash by not adding the mime type to the mime type list if the value is null. Change-Id: Ia06f3389da6ce34e11ffcf349a10fdbe64cfc9bd --- ui/src/com/android/providers/downloads/ui/DownloadList.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ui/src/com/android/providers') diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 29ea60eb..db86ab7e 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -765,7 +765,9 @@ public class DownloadList extends Activity { // are all prefixes of the given mimetypes the same? ArrayList mimeTypePrefixes = new ArrayList(); for (String s : mimeTypes) { - mimeTypePrefixes.add(s.substring(0, s.indexOf('/'))); + if (s != null) { + mimeTypePrefixes.add(s.substring(0, s.indexOf('/'))); + } } str = findCommonString(mimeTypePrefixes); if (str != null) { -- cgit v1.2.3 From 8c9cef79df1ddcd971a0a0775cef774c17a5081c Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 15 Aug 2013 16:23:09 -0700 Subject: Delegate to documents UI; improve contents. When Downloads app is launched, delegate to new documents management UI. Use DownloadManager public API to match the contents of the existing Downloads UI. Bug: 10329983 Change-Id: Iaa1a1dc013cfe3b17d31ecc764d4c4cc13f62258 --- ui/src/com/android/providers/downloads/ui/DownloadList.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'ui/src/com/android/providers') diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 05b5d757..57530474 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -33,6 +33,7 @@ import android.os.Environment; import android.os.Handler; import android.os.Parcelable; import android.provider.BaseColumns; +import android.provider.DocumentsContract; import android.provider.Downloads; import android.util.Log; import android.util.SparseBooleanArray; @@ -148,6 +149,17 @@ public class DownloadList extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + + // Trampoline over to new management UI + final Intent intent = new Intent(Intent.ACTION_MANAGE_DOCUMENT); + intent.setData(DocumentsContract.buildRootUri( + Constants.STORAGE_AUTHORITY, Constants.STORAGE_ROOT)); + startActivity(intent); + finish(); + } + + public void onCreateLegacy(Bundle icicle) { + super.onCreate(icicle); setFinishOnTouchOutside(true); setupViews(); -- cgit v1.2.3 From ec62bdf20cbfa709c9dea9101fe668fec315c103 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 28 Aug 2013 17:54:21 -0700 Subject: Follow stronger DocumentsProvider contract. Provides same functionality, but follows updated DocumentsProvider contract in framework. Bug: 10497206 Change-Id: Ie1f6180047ff7bad289679a14f3368238d47b1d6 --- ui/src/com/android/providers/downloads/ui/DownloadList.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/src/com/android/providers') diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 57530474..443491a9 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -151,9 +151,9 @@ public class DownloadList extends Activity { super.onCreate(icicle); // Trampoline over to new management UI - final Intent intent = new Intent(Intent.ACTION_MANAGE_DOCUMENT); - intent.setData(DocumentsContract.buildRootUri( - Constants.STORAGE_AUTHORITY, Constants.STORAGE_ROOT)); + final Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENTS); + intent.setData(DocumentsContract.buildDocumentUri( + Constants.STORAGE_AUTHORITY, Constants.STORAGE_DOC_ID_ROOT)); startActivity(intent); finish(); } -- cgit v1.2.3 From 3c03d1b8b7d96209d7b83b6881421ddfc17ccc52 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 5 Sep 2013 17:13:59 -0700 Subject: Extend trampoline to show dialogs. Handle incoming manage requests by launching finished downloads, or showing various retry dialogs. Pipe through summary, show percentage when in progress, and always show total size and MIME type. Bug: 10531347, 10599641 Change-Id: I3be2bc67ea3c0ef795146177200f5be77ad5114e --- .../providers/downloads/ui/DownloadList.java | 6 +- .../providers/downloads/ui/TrampolineActivity.java | 225 +++++++++++++++++++++ 2 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 ui/src/com/android/providers/downloads/ui/TrampolineActivity.java (limited to 'ui/src/com/android/providers') diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 443491a9..991d70b6 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -151,9 +151,9 @@ public class DownloadList extends Activity { super.onCreate(icicle); // Trampoline over to new management UI - final Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENTS); - intent.setData(DocumentsContract.buildDocumentUri( - Constants.STORAGE_AUTHORITY, Constants.STORAGE_DOC_ID_ROOT)); + final Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_ROOT); + intent.setData(DocumentsContract.buildRootUri( + Constants.STORAGE_AUTHORITY, Constants.STORAGE_ROOT_ID)); startActivity(intent); finish(); } diff --git a/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java b/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java new file mode 100644 index 00000000..e9cc17ef --- /dev/null +++ b/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2013 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.providers.downloads.ui; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.DownloadManager; +import android.app.DownloadManager.Query; +import android.app.FragmentManager; +import android.content.ContentUris; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.util.Log; +import android.widget.Toast; + +import com.android.providers.downloads.Constants; +import com.android.providers.downloads.OpenHelper; + +import libcore.io.IoUtils; + +/** + * Intercept all download clicks to provide special behavior. For example, + * PackageInstaller really wants raw file paths. + */ +public class TrampolineActivity extends Activity { + private static final String TAG_PAUSED = "paused"; + private static final String TAG_FAILED = "failed"; + + private static final String KEY_ID = "id"; + private static final String KEY_REASON = "reason"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final long id = ContentUris.parseId(getIntent().getData()); + + final DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); + dm.setAccessAllDownloads(true); + + final int status; + final int reason; + + final Cursor cursor = dm.query(new Query().setFilterById(id)); + try { + if (cursor.moveToFirst()) { + status = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)); + reason = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON)); + } else { + Toast.makeText(this, R.string.dialog_file_missing_body, Toast.LENGTH_SHORT).show(); + finish(); + return; + } + } finally { + IoUtils.closeQuietly(cursor); + } + + Log.d(Constants.TAG, "Found " + id + " with status " + status + ", reason " + reason); + switch (status) { + case DownloadManager.STATUS_PENDING: + case DownloadManager.STATUS_RUNNING: + sendRunningDownloadClickedBroadcast(id); + finish(); + break; + + case DownloadManager.STATUS_PAUSED: + if (reason == DownloadManager.PAUSED_QUEUED_FOR_WIFI) { + PausedDialogFragment.show(getFragmentManager(), id); + } else { + sendRunningDownloadClickedBroadcast(id); + finish(); + } + break; + + case DownloadManager.STATUS_SUCCESSFUL: + final Intent intent = OpenHelper.buildViewIntent(this, id); + startActivity(intent); + finish(); + break; + + case DownloadManager.STATUS_FAILED: + FailedDialogFragment.show(getFragmentManager(), id, reason); + break; + } + } + + private void sendRunningDownloadClickedBroadcast(long id) { + final Intent intent = new Intent(Constants.ACTION_LIST); + intent.setPackage(Constants.PROVIDER_PACKAGE_NAME); + intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, new long[] { id }); + sendBroadcast(intent); + } + + public static class PausedDialogFragment extends DialogFragment { + public static void show(FragmentManager fm, long id) { + final PausedDialogFragment dialog = new PausedDialogFragment(); + final Bundle args = new Bundle(); + args.putLong(KEY_ID, id); + dialog.setArguments(args); + dialog.show(fm, TAG_PAUSED); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Context context = getActivity(); + + final DownloadManager dm = (DownloadManager) context.getSystemService( + Context.DOWNLOAD_SERVICE); + dm.setAccessAllDownloads(true); + + final long id = getArguments().getLong(KEY_ID); + + final AlertDialog.Builder builder = new AlertDialog.Builder( + context, AlertDialog.THEME_HOLO_LIGHT); + builder.setTitle(R.string.dialog_title_queued_body); + builder.setMessage(R.string.dialog_queued_body); + + builder.setPositiveButton(R.string.keep_queued_download, null); + + builder.setNegativeButton( + R.string.remove_download, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dm.remove(id); + } + }); + + return builder.create(); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + getActivity().finish(); + } + } + + public static class FailedDialogFragment extends DialogFragment { + public static void show(FragmentManager fm, long id, int reason) { + final FailedDialogFragment dialog = new FailedDialogFragment(); + final Bundle args = new Bundle(); + args.putLong(KEY_ID, id); + args.putInt(KEY_REASON, reason); + dialog.setArguments(args); + dialog.show(fm, TAG_FAILED); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Context context = getActivity(); + + final DownloadManager dm = (DownloadManager) context.getSystemService( + Context.DOWNLOAD_SERVICE); + dm.setAccessAllDownloads(true); + + final long id = getArguments().getLong(KEY_ID); + final int reason = getArguments().getInt(KEY_REASON); + + final AlertDialog.Builder builder = new AlertDialog.Builder( + context, AlertDialog.THEME_HOLO_LIGHT); + builder.setTitle(R.string.dialog_title_not_available); + + final String message; + switch (reason) { + case DownloadManager.ERROR_FILE_ALREADY_EXISTS: + builder.setMessage(R.string.dialog_file_already_exists); + break; + case DownloadManager.ERROR_INSUFFICIENT_SPACE: + builder.setMessage(R.string.dialog_insufficient_space_on_external); + break; + case DownloadManager.ERROR_DEVICE_NOT_FOUND: + builder.setMessage(R.string.dialog_media_not_found); + break; + case DownloadManager.ERROR_CANNOT_RESUME: + builder.setMessage(R.string.dialog_cannot_resume); + break; + default: + builder.setMessage(R.string.dialog_failed_body); + } + + builder.setNegativeButton( + R.string.delete_download, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dm.remove(id); + } + }); + + builder.setPositiveButton( + R.string.retry_download, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dm.restartDownload(id); + } + }); + + return builder.create(); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + getActivity().finish(); + } + } +} -- cgit v1.2.3 From 8ec87ea5a5c191554d6205d4c779768664b1724b Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 18 Sep 2013 12:53:39 -0700 Subject: Unified handling of errors around opening. Handle both missing downloads and missing activities. Bug: 10799449, 10713636 Change-Id: I592b07fc5cf530526803379d7f7a99e8a6b207c4 --- ui/src/com/android/providers/downloads/ui/DownloadList.java | 8 ++------ ui/src/com/android/providers/downloads/ui/TrampolineActivity.java | 6 ++++-- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'ui/src/com/android/providers') diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 991d70b6..107940c0 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -19,7 +19,6 @@ package com.android.providers.downloads.ui; import android.app.Activity; import android.app.AlertDialog; import android.app.DownloadManager; -import android.content.ActivityNotFoundException; import android.content.ContentUris; import android.content.Context; import android.content.DialogInterface; @@ -530,11 +529,8 @@ public class DownloadList extends Activity { } final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)); - final Intent intent = OpenHelper.buildViewIntent(this, id); - try { - startActivity(intent); - } catch (ActivityNotFoundException ex) { - Toast.makeText(this, R.string.download_no_application_title, Toast.LENGTH_LONG).show(); + if (!OpenHelper.startViewIntent(this, id, 0)) { + Toast.makeText(this, R.string.download_no_application_title, Toast.LENGTH_SHORT).show(); } } diff --git a/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java b/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java index e9cc17ef..f96c04ee 100644 --- a/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java +++ b/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java @@ -92,8 +92,10 @@ public class TrampolineActivity extends Activity { break; case DownloadManager.STATUS_SUCCESSFUL: - final Intent intent = OpenHelper.buildViewIntent(this, id); - startActivity(intent); + if (!OpenHelper.startViewIntent(this, id, 0)) { + Toast.makeText(this, R.string.download_no_application_title, Toast.LENGTH_SHORT) + .show(); + } finish(); break; -- cgit v1.2.3