1/* 2 * Copyright (C) 2013 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.providers.downloads.ui; 18 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.app.Dialog; 22import android.app.DialogFragment; 23import android.app.DownloadManager; 24import android.app.DownloadManager.Query; 25import android.app.FragmentManager; 26import android.content.ContentUris; 27import android.content.Context; 28import android.content.DialogInterface; 29import android.content.Intent; 30import android.database.Cursor; 31import android.os.Bundle; 32import android.util.Log; 33import android.widget.Toast; 34 35import com.android.providers.downloads.Constants; 36import com.android.providers.downloads.OpenHelper; 37 38import libcore.io.IoUtils; 39 40/** 41 * Intercept all download clicks to provide special behavior. For example, 42 * PackageInstaller really wants raw file paths. 43 */ 44public class TrampolineActivity extends Activity { 45 private static final String TAG_PAUSED = "paused"; 46 private static final String TAG_FAILED = "failed"; 47 48 private static final String KEY_ID = "id"; 49 private static final String KEY_REASON = "reason"; 50 51 @Override 52 protected void onCreate(Bundle savedInstanceState) { 53 super.onCreate(savedInstanceState); 54 55 final long id = ContentUris.parseId(getIntent().getData()); 56 57 final DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); 58 dm.setAccessAllDownloads(true); 59 60 final int status; 61 final int reason; 62 63 final Cursor cursor = dm.query(new Query().setFilterById(id)); 64 try { 65 if (cursor.moveToFirst()) { 66 status = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)); 67 reason = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON)); 68 } else { 69 Toast.makeText(this, R.string.dialog_file_missing_body, Toast.LENGTH_SHORT).show(); 70 finish(); 71 return; 72 } 73 } finally { 74 IoUtils.closeQuietly(cursor); 75 } 76 77 Log.d(Constants.TAG, "Found " + id + " with status " + status + ", reason " + reason); 78 switch (status) { 79 case DownloadManager.STATUS_PENDING: 80 case DownloadManager.STATUS_RUNNING: 81 sendRunningDownloadClickedBroadcast(id); 82 finish(); 83 break; 84 85 case DownloadManager.STATUS_PAUSED: 86 if (reason == DownloadManager.PAUSED_QUEUED_FOR_WIFI) { 87 PausedDialogFragment.show(getFragmentManager(), id); 88 } else { 89 sendRunningDownloadClickedBroadcast(id); 90 finish(); 91 } 92 break; 93 94 case DownloadManager.STATUS_SUCCESSFUL: 95 if (!OpenHelper.startViewIntent(this, id, 0)) { 96 Toast.makeText(this, R.string.download_no_application_title, Toast.LENGTH_SHORT) 97 .show(); 98 } 99 finish(); 100 break; 101 102 case DownloadManager.STATUS_FAILED: 103 FailedDialogFragment.show(getFragmentManager(), id, reason); 104 break; 105 } 106 } 107 108 private void sendRunningDownloadClickedBroadcast(long id) { 109 final Intent intent = new Intent(Constants.ACTION_LIST); 110 intent.setPackage(Constants.PROVIDER_PACKAGE_NAME); 111 intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, new long[] { id }); 112 sendBroadcast(intent); 113 } 114 115 public static class PausedDialogFragment extends DialogFragment { 116 public static void show(FragmentManager fm, long id) { 117 final PausedDialogFragment dialog = new PausedDialogFragment(); 118 final Bundle args = new Bundle(); 119 args.putLong(KEY_ID, id); 120 dialog.setArguments(args); 121 dialog.show(fm, TAG_PAUSED); 122 } 123 124 @Override 125 public Dialog onCreateDialog(Bundle savedInstanceState) { 126 final Context context = getActivity(); 127 128 final DownloadManager dm = (DownloadManager) context.getSystemService( 129 Context.DOWNLOAD_SERVICE); 130 dm.setAccessAllDownloads(true); 131 132 final long id = getArguments().getLong(KEY_ID); 133 134 final AlertDialog.Builder builder = new AlertDialog.Builder( 135 context, AlertDialog.THEME_HOLO_LIGHT); 136 builder.setTitle(R.string.dialog_title_queued_body); 137 builder.setMessage(R.string.dialog_queued_body); 138 139 builder.setPositiveButton(R.string.keep_queued_download, null); 140 141 builder.setNegativeButton( 142 R.string.remove_download, new DialogInterface.OnClickListener() { 143 @Override 144 public void onClick(DialogInterface dialog, int which) { 145 dm.remove(id); 146 } 147 }); 148 149 return builder.create(); 150 } 151 152 @Override 153 public void onDismiss(DialogInterface dialog) { 154 super.onDismiss(dialog); 155 getActivity().finish(); 156 } 157 } 158 159 public static class FailedDialogFragment extends DialogFragment { 160 public static void show(FragmentManager fm, long id, int reason) { 161 final FailedDialogFragment dialog = new FailedDialogFragment(); 162 final Bundle args = new Bundle(); 163 args.putLong(KEY_ID, id); 164 args.putInt(KEY_REASON, reason); 165 dialog.setArguments(args); 166 dialog.show(fm, TAG_FAILED); 167 } 168 169 @Override 170 public Dialog onCreateDialog(Bundle savedInstanceState) { 171 final Context context = getActivity(); 172 173 final DownloadManager dm = (DownloadManager) context.getSystemService( 174 Context.DOWNLOAD_SERVICE); 175 dm.setAccessAllDownloads(true); 176 177 final long id = getArguments().getLong(KEY_ID); 178 final int reason = getArguments().getInt(KEY_REASON); 179 180 final AlertDialog.Builder builder = new AlertDialog.Builder( 181 context, AlertDialog.THEME_HOLO_LIGHT); 182 builder.setTitle(R.string.dialog_title_not_available); 183 184 final String message; 185 switch (reason) { 186 case DownloadManager.ERROR_FILE_ALREADY_EXISTS: 187 builder.setMessage(R.string.dialog_file_already_exists); 188 break; 189 case DownloadManager.ERROR_INSUFFICIENT_SPACE: 190 builder.setMessage(R.string.dialog_insufficient_space_on_external); 191 break; 192 case DownloadManager.ERROR_DEVICE_NOT_FOUND: 193 builder.setMessage(R.string.dialog_media_not_found); 194 break; 195 case DownloadManager.ERROR_CANNOT_RESUME: 196 builder.setMessage(R.string.dialog_cannot_resume); 197 break; 198 default: 199 builder.setMessage(R.string.dialog_failed_body); 200 } 201 202 builder.setNegativeButton( 203 R.string.delete_download, new DialogInterface.OnClickListener() { 204 @Override 205 public void onClick(DialogInterface dialog, int which) { 206 dm.remove(id); 207 } 208 }); 209 210 builder.setPositiveButton( 211 R.string.retry_download, new DialogInterface.OnClickListener() { 212 @Override 213 public void onClick(DialogInterface dialog, int which) { 214 dm.restartDownload(id); 215 } 216 }); 217 218 return builder.create(); 219 } 220 221 @Override 222 public void onDismiss(DialogInterface dialog) { 223 super.onDismiss(dialog); 224 getActivity().finish(); 225 } 226 } 227} 228