1 /* 2 * Copyright (C) 2009 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.videoeditor.util; 18 19 import java.io.File; 20 import java.io.FileNotFoundException; 21 import java.io.FileOutputStream; 22 import java.io.IOException; 23 import java.io.InputStream; 24 25 import com.android.videoeditor.R; 26 27 import android.content.Context; 28 import android.graphics.Bitmap; 29 import android.graphics.BitmapFactory; 30 import android.graphics.Bitmap.CompressFormat; 31 import android.media.videoeditor.MediaProperties; 32 import android.os.Environment; 33 import android.util.Log; 34 35 /** 36 * File utilities 37 */ 38 public class FileUtils { 39 // Logging 40 private static final String TAG = "FileUtils"; 41 42 /** 43 * It is not possible to instantiate this class 44 */ 45 private FileUtils() { 46 } 47 48 /** 49 * Gets the root path for all projects 50 * 51 * @param context The context 52 * 53 * @return The file representing the projects root directory, {@code null} if the external 54 * storage is not currnetly mounted 55 */ 56 public static File getProjectsRootDir(Context context) 57 throws FileNotFoundException, IOException { 58 final File dir = context.getExternalFilesDir(null); 59 if (dir != null && !dir.exists()) { 60 if (!dir.mkdirs()) { 61 throw new FileNotFoundException("Cannot create folder: " + dir.getAbsolutePath()); 62 } else { 63 // Create the file which hides the media files 64 if (!new File(dir, ".nomedia").createNewFile()) { 65 throw new FileNotFoundException("Cannot create file .nomedia"); 66 } 67 } 68 } 69 70 return dir; 71 } 72 73 /** 74 * Get the filename for the specified raw resource id. Create the file if 75 * the file does not exist. 76 * 77 * @param context The context 78 * @param maskRawResourceId The mask raw resource id 79 * 80 * @return The mask filename 81 */ 82 public static String getMaskFilename(Context context, int maskRawResourceId) 83 throws FileNotFoundException, IOException { 84 final String filename; 85 switch (maskRawResourceId) { 86 case R.raw.mask_contour: { 87 filename = "mask_countour.jpg"; 88 break; 89 } 90 91 case R.raw.mask_diagonal: { 92 filename = "mask_diagonal.jpg"; 93 break; 94 } 95 96 default: { 97 throw new IllegalArgumentException("Invalid mask raw resource id"); 98 } 99 } 100 101 final File mf = new File(context.getFilesDir(), filename); 102 if (!mf.exists()) { 103 Bitmap bitmap = null; 104 FileOutputStream fos = null; 105 InputStream is = null; 106 try { 107 is = context.getResources().openRawResource(maskRawResourceId); 108 bitmap = BitmapFactory.decodeStream(is); 109 if (bitmap == null) { 110 throw new IllegalStateException("Cannot decode raw resource mask"); 111 } 112 113 fos = context.openFileOutput(filename, Context.MODE_WORLD_READABLE); 114 if (!bitmap.compress(CompressFormat.JPEG, 100, fos)) { 115 throw new IllegalStateException("Cannot compress bitmap"); 116 } 117 } finally { 118 if (is != null) { 119 is.close(); 120 } 121 122 if (bitmap != null) { 123 bitmap.recycle(); 124 } 125 126 if (fos != null) { 127 fos.flush(); 128 fos.close(); 129 } 130 } 131 } 132 133 return mf.getAbsolutePath(); 134 } 135 136 /** 137 * Get the raw id for the mask file 138 * 139 * @param path The full file name 140 * 141 * @return The raw id 142 */ 143 public static int getMaskRawId(String path) { 144 final String filename = new File(path).getName(); 145 146 if (filename.equals("mask_countour.jpg")) { 147 return R.raw.mask_contour; 148 } else if (filename.equals("mask_diagonal.jpg")) { 149 return R.raw.mask_diagonal; 150 } else { 151 throw new IllegalArgumentException("Unknown file: " + path); 152 } 153 } 154 155 /** 156 * Get the filename for the specified raw resource id. Create the file if 157 * the file does not exist 158 * 159 * @param context The context 160 * @param rawResourceId The raw resource id 161 * 162 * @return The audio track filename 163 */ 164 public static String getAudioTrackFilename(Context context, int rawResourceId) 165 throws FileNotFoundException, IOException { 166 final String filename; 167 switch (rawResourceId) { 168 case R.raw.theme_travel_audio_track: { 169 filename = "theme_travel.m4a"; 170 break; 171 } 172 173 case R.raw.theme_surfing_audio_track: { 174 filename = "theme_surfing.m4a"; 175 break; 176 } 177 178 case R.raw.theme_film_audio_track: { 179 filename = "theme_film.m4a"; 180 break; 181 } 182 183 case R.raw.theme_rockandroll_audio_track: { 184 filename = "theme_rockandroll.m4a"; 185 break; 186 } 187 188 default: { 189 throw new IllegalArgumentException("Invalid audio track raw resource id"); 190 } 191 } 192 193 final File mf = new File(context.getFilesDir(), filename); 194 if (!mf.exists()) { 195 FileOutputStream fos = null; 196 InputStream is = null; 197 try { 198 is = context.getResources().openRawResource(rawResourceId); 199 fos = context.openFileOutput(filename, Context.MODE_WORLD_READABLE); 200 final byte[] buffer = new byte[1024]; 201 int bytesRead; 202 while ((bytesRead = is.read(buffer)) > 0) { 203 fos.write(buffer, 0, bytesRead); 204 } 205 } finally { 206 if (is != null) { 207 is.close(); 208 } 209 210 if (fos != null) { 211 fos.flush(); 212 fos.close(); 213 } 214 } 215 } 216 217 return mf.getAbsolutePath(); 218 } 219 220 /** 221 * Create a new project directory 222 * 223 * @return The absolute path to the project 224 */ 225 public static String createNewProjectPath(Context context) 226 throws FileNotFoundException, IOException { 227 final File file = new File(getProjectsRootDir(context), StringUtils.randomString(10)); 228 if (Log.isLoggable(TAG, Log.DEBUG)) { 229 Log.d(TAG, "New project: " + file.getAbsolutePath()); 230 } 231 232 return file.getAbsolutePath(); 233 } 234 235 /** 236 * Get a unique video filename. 237 * 238 * @param fileType The file type 239 * 240 * @return The filename 241 */ 242 public static String createMovieName(int fileType) { 243 final String filename; 244 switch (fileType) { 245 case MediaProperties.FILE_MP4: { 246 filename = "movie_" + StringUtils.randomStringOfNumbers(6) + ".mp4"; 247 break; 248 } 249 250 case MediaProperties.FILE_3GP: { 251 filename = "movie_" + StringUtils.randomStringOfNumbers(6) + ".3gp"; 252 break; 253 } 254 255 default: { 256 throw new IllegalArgumentException("Unsupported file type: " + fileType); 257 } 258 } 259 260 final File moviesDirectory = Environment.getExternalStoragePublicDirectory( 261 Environment.DIRECTORY_MOVIES); 262 // Make this directory if it does not exist 263 if (!moviesDirectory.exists()) { 264 moviesDirectory.mkdirs(); 265 } 266 267 final File f = new File(moviesDirectory, filename); 268 return f.getAbsolutePath(); 269 } 270 271 /** 272 * Delete all the files in the specified folder and the folder itself. 273 * 274 * @param dir The project path 275 */ 276 public static boolean deleteDir(File dir) { 277 if (dir.isDirectory()) { 278 final String[] children = dir.list(); 279 for (int i = 0; i < children.length; i++) { 280 final File f = new File(dir, children[i]); 281 if (!deleteDir(f)) { 282 Log.e(TAG, "File cannot be deleted: " + f.getAbsolutePath()); 283 return false; 284 } 285 } 286 } 287 288 // The directory is now empty so delete it 289 return dir.delete(); 290 } 291 292 /** 293 * Get the name of the file 294 * 295 * @param filename The full path filename 296 * @return The name of the file 297 */ 298 public static String getSimpleName(String filename) { 299 final int index = filename.lastIndexOf('/'); 300 if (index == -1) { 301 return filename; 302 } else { 303 return filename.substring(index + 1); 304 } 305 } 306 } 307