Home | History | Annotate | Download | only in downloads
      1 /*
      2  * Copyright (C) 2012 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;
     18 
     19 import static android.app.DownloadManager.COLUMN_LOCAL_FILENAME;
     20 import static android.app.DownloadManager.COLUMN_LOCAL_URI;
     21 import static android.app.DownloadManager.COLUMN_MEDIA_TYPE;
     22 import static android.app.DownloadManager.COLUMN_URI;
     23 import static android.provider.Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI;
     24 
     25 import android.app.DownloadManager;
     26 import android.content.ContentUris;
     27 import android.content.Context;
     28 import android.content.Intent;
     29 import android.database.Cursor;
     30 import android.net.Uri;
     31 import android.provider.Downloads.Impl.RequestHeaders;
     32 
     33 import java.io.File;
     34 
     35 public class OpenHelper {
     36     /**
     37      * Build an {@link Intent} to view the download at current {@link Cursor}
     38      * position, handling subtleties around installing packages.
     39      */
     40     public static Intent buildViewIntent(Context context, long id) {
     41         final DownloadManager downManager = (DownloadManager) context.getSystemService(
     42                 Context.DOWNLOAD_SERVICE);
     43         downManager.setAccessAllDownloads(true);
     44 
     45         final Cursor cursor = downManager.query(new DownloadManager.Query().setFilterById(id));
     46         try {
     47             if (!cursor.moveToFirst()) {
     48                 throw new IllegalArgumentException("Missing download " + id);
     49             }
     50 
     51             final Uri localUri = getCursorUri(cursor, COLUMN_LOCAL_URI);
     52             final File file = getCursorFile(cursor, COLUMN_LOCAL_FILENAME);
     53             String mimeType = getCursorString(cursor, COLUMN_MEDIA_TYPE);
     54             mimeType = DownloadDrmHelper.getOriginalMimeType(context, file, mimeType);
     55 
     56             final Intent intent = new Intent(Intent.ACTION_VIEW);
     57             intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
     58 
     59             if ("application/vnd.android.package-archive".equals(mimeType)) {
     60                 // PackageInstaller doesn't like content URIs, so open file
     61                 intent.setDataAndType(localUri, mimeType);
     62 
     63                 // Also splice in details about where it came from
     64                 final Uri remoteUri = getCursorUri(cursor, COLUMN_URI);
     65                 intent.putExtra(Intent.EXTRA_ORIGINATING_URI, remoteUri);
     66                 intent.putExtra(Intent.EXTRA_REFERRER, getRefererUri(context, id));
     67                 intent.putExtra(Intent.EXTRA_ORIGINATING_UID, getOriginatingUid(context, id));
     68             } else if ("file".equals(localUri.getScheme())) {
     69                 intent.setDataAndType(
     70                         ContentUris.withAppendedId(ALL_DOWNLOADS_CONTENT_URI, id), mimeType);
     71             } else {
     72                 intent.setDataAndType(localUri, mimeType);
     73             }
     74 
     75             return intent;
     76         } finally {
     77             cursor.close();
     78         }
     79     }
     80 
     81     private static Uri getRefererUri(Context context, long id) {
     82         final Uri headersUri = Uri.withAppendedPath(
     83                 ContentUris.withAppendedId(ALL_DOWNLOADS_CONTENT_URI, id),
     84                 RequestHeaders.URI_SEGMENT);
     85         final Cursor headers = context.getContentResolver()
     86                 .query(headersUri, null, null, null, null);
     87         try {
     88             while (headers.moveToNext()) {
     89                 final String header = getCursorString(headers, RequestHeaders.COLUMN_HEADER);
     90                 if ("Referer".equalsIgnoreCase(header)) {
     91                     return getCursorUri(headers, RequestHeaders.COLUMN_VALUE);
     92                 }
     93             }
     94         } finally {
     95             headers.close();
     96         }
     97         return null;
     98     }
     99 
    100     private static int getOriginatingUid(Context context, long id) {
    101         final Uri uri = ContentUris.withAppendedId(ALL_DOWNLOADS_CONTENT_URI, id);
    102         final Cursor cursor = context.getContentResolver().query(uri, new String[]{Constants.UID},
    103                 null, null, null);
    104         if (cursor != null) {
    105             try {
    106                 if (cursor.moveToFirst()) {
    107                     return cursor.getInt(cursor.getColumnIndexOrThrow(Constants.UID));
    108                 }
    109             } finally {
    110                 cursor.close();
    111             }
    112         }
    113         return -1;
    114     }
    115 
    116     private static String getCursorString(Cursor cursor, String column) {
    117         return cursor.getString(cursor.getColumnIndexOrThrow(column));
    118     }
    119 
    120     private static Uri getCursorUri(Cursor cursor, String column) {
    121         return Uri.parse(getCursorString(cursor, column));
    122     }
    123 
    124     private static long getCursorLong(Cursor cursor, String column) {
    125         return cursor.getLong(cursor.getColumnIndexOrThrow(column));
    126     }
    127 
    128     private static File getCursorFile(Cursor cursor, String column) {
    129         return new File(cursor.getString(cursor.getColumnIndexOrThrow(column)));
    130     }
    131 }
    132