Home | History | Annotate | Download | only in mms
      1 // Copyright 2011 Google Inc.
      2 // All Rights Reserved.
      3 
      4 package com.android.mms;
      5 
      6 import java.io.File;
      7 import java.io.FileNotFoundException;
      8 
      9 import android.content.ContentProvider;
     10 import android.content.ContentValues;
     11 import android.content.Context;
     12 import android.content.UriMatcher;
     13 import android.database.Cursor;
     14 import android.net.Uri;
     15 import android.os.ParcelFileDescriptor;
     16 import android.util.Log;
     17 
     18 /**
     19  * The TempFileProvider manages a uri, backed by a file, for passing to the camera app for
     20  * capturing pictures and videos and storing the data in a file in the messaging app.
     21  */
     22 public class TempFileProvider extends ContentProvider {
     23     private static String TAG = LogTag.TAG;
     24 
     25     /**
     26      * The content:// style URL for this table
     27      */
     28     public static final Uri SCRAP_CONTENT_URI = Uri.parse("content://mms_temp_file/scrapSpace");
     29 
     30     private static final int MMS_SCRAP_SPACE = 1;
     31     private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
     32     static {
     33         sURLMatcher.addURI("mms_temp_file", "scrapSpace", MMS_SCRAP_SPACE);
     34     }
     35 
     36     @Override
     37     public boolean onCreate() {
     38         return true;
     39     }
     40 
     41     @Override
     42     public Cursor query(Uri uri, String[] projection,
     43             String selection, String[] selectionArgs, String sortOrder) {
     44         return null;
     45     }
     46 
     47     @Override
     48     public Uri insert(Uri uri, ContentValues values) {
     49         return null;
     50     }
     51 
     52     @Override
     53     public int delete(Uri uri, String selection, String[] selectionArgs) {
     54         return 0;
     55     }
     56 
     57     @Override
     58     public int update(Uri uri, ContentValues values,
     59             String selection, String[] selectionArgs) {
     60         return 0;
     61     }
     62 
     63     private ParcelFileDescriptor getTempStoreFd(String mode) {
     64         String fileName = getScrapPath(getContext());
     65         ParcelFileDescriptor pfd = null;
     66 
     67         try {
     68             File file = new File(fileName);
     69 
     70             // make sure the path is valid and directories created for this file.
     71             File parentFile = file.getParentFile();
     72             if (!parentFile.exists() && !parentFile.mkdirs()) {
     73                 Log.e(TAG, "[TempFileProvider] tempStoreFd: " + parentFile.getPath() +
     74                         "does not exist!");
     75                 return null;
     76             }
     77 
     78             int modeFlags;
     79             if (mode.equals("r")) {
     80                 modeFlags = ParcelFileDescriptor.MODE_READ_ONLY;
     81             } else {
     82                 modeFlags = ParcelFileDescriptor.MODE_READ_WRITE
     83                             | ParcelFileDescriptor.MODE_CREATE
     84                             | ParcelFileDescriptor.MODE_TRUNCATE;
     85             }
     86             pfd = ParcelFileDescriptor.open(file, modeFlags);
     87         } catch (Exception ex) {
     88             Log.e(TAG, "getTempStoreFd: error creating pfd for " + fileName, ex);
     89         }
     90 
     91         return pfd;
     92     }
     93 
     94     @Override
     95     public String getType(Uri uri) {
     96         return "*/*";
     97     }
     98 
     99     @Override
    100     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    101         // if the url is "content://mms/takePictureTempStore", then it means the requester
    102         // wants a file descriptor to write image data to.
    103 
    104         ParcelFileDescriptor fd = null;
    105         int match = sURLMatcher.match(uri);
    106 
    107         if (Log.isLoggable(TAG, Log.VERBOSE)) {
    108             Log.d(TAG, "openFile: uri=" + uri + ", mode=" + mode);
    109         }
    110 
    111         switch (match) {
    112             case MMS_SCRAP_SPACE:
    113                 fd = getTempStoreFd(mode);
    114                 break;
    115         }
    116 
    117         return fd;
    118     }
    119 
    120 
    121     /**
    122      * This is the scrap file we use to store the media attachment when the user
    123      * chooses to capture a photo to be attached . We pass {#link@Uri} to the Camera app,
    124      * which streams the captured image to the uri. Internally we write the media content
    125      * to this file. It's named '.temp.jpg' so Gallery won't pick it up.
    126      */
    127     public static String getScrapPath(Context context, String fileName) {
    128         return context.getExternalCacheDir().getAbsolutePath() + "/" + fileName;
    129     }
    130 
    131     public static String getScrapPath(Context context) {
    132         return getScrapPath(context, ".temp.jpg");
    133     }
    134 
    135     /**
    136      * renameScrapFile renames the single scrap file to a new name so newer uses of the scrap
    137      * file won't overwrite the previously captured data.
    138      * @param fileExtension file extension for the temp file, typically ".jpg" or ".3gp"
    139      * @param uniqueIdentifier a separator to add to the file to make it unique,
    140      *        such as the slide number. This parameter can be empty or null.
    141      * @return uri of renamed file. If there's an error renaming, null will be returned
    142      */
    143     public static Uri renameScrapFile(String fileExtension, String uniqueIdentifier,
    144             Context context) {
    145         String filePath = getScrapPath(context);
    146         // There's only a single scrap file, but there can be several slides. We rename
    147         // the scrap file to a new scrap file with the slide number as part of the filename.
    148 
    149         // Replace the filename ".temp.jpg" with ".temp#.[jpg | 3gp]" where # is the unique
    150         // identifier. The content of the file may be a picture or a .3gp video.
    151         if (uniqueIdentifier == null) {
    152             uniqueIdentifier = "";
    153         }
    154         File newTempFile = new File(getScrapPath(context, ".temp" + uniqueIdentifier +
    155                 fileExtension));
    156         File oldTempFile = new File(filePath);
    157         // remove any existing file before rename
    158         boolean deleted = newTempFile.delete();
    159         if (!oldTempFile.renameTo(newTempFile)) {
    160             return null;
    161         }
    162         return Uri.fromFile(newTempFile);
    163     }
    164 
    165     /**
    166      * Pass in a path to a file and this function will return true if it thinks the path
    167      * points to one of its scrap files.
    168      * @param path full path of a file
    169      * @return true if path is a scrap file path
    170      */
    171     public static boolean isTempFile(String path) {
    172         // An admittedly weak determination of a temp file, but sufficient for current needs.
    173         // For now, the penalty of returning true for a file that isn't a temp file is simply
    174         // not storing the file's thumbnail in an on-disk thumbnail cache.
    175         return path.contains(".temp");
    176     }
    177 }
    178