Unified handling of errors around opening.
[android/platform/packages/providers/DownloadProvider.git] / ui / src / com / android / providers / downloads / ui / TrampolineActivity.java
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
17 package com.android.providers.downloads.ui;
18
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.DialogFragment;
23 import android.app.DownloadManager;
24 import android.app.DownloadManager.Query;
25 import android.app.FragmentManager;
26 import android.content.ContentUris;
27 import android.content.Context;
28 import android.content.DialogInterface;
29 import android.content.Intent;
30 import android.database.Cursor;
31 import android.os.Bundle;
32 import android.util.Log;
33 import android.widget.Toast;
34
35 import com.android.providers.downloads.Constants;
36 import com.android.providers.downloads.OpenHelper;
37
38 import libcore.io.IoUtils;
39
40 /**
41  * Intercept all download clicks to provide special behavior. For example,
42  * PackageInstaller really wants raw file paths.
43  */
44 public 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 }