15fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey/* 25fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Copyright (C) 2014 The Android Open Source Project 35fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 45fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 55fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * you may not use this file except in compliance with the License. 65fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * You may obtain a copy of the License at 75fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 85fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 95fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * See the License for the specific language governing permissions and 145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * limitations under the License. 155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeypackage android.support.v4.provider; 185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.net.Uri; 205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.util.Log; 215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.webkit.MimeTypeMap; 225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.File; 245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.IOException; 255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.util.ArrayList; 265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyclass RawDocumentFile extends DocumentFile { 285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File mFile; 295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey RawDocumentFile(DocumentFile parent, File file) { 315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey super(parent); 325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey mFile = file; 335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public DocumentFile createFile(String mimeType, String displayName) { 375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Tack on extension when valid MIME type provided 385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); 395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (extension != null) { 405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey displayName += "." + extension; 415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final File target = new File(mFile, displayName); 435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey try { 445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey target.createNewFile(); 455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return new RawDocumentFile(this, target); 465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } catch (IOException e) { 475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey Log.w(TAG, "Failed to createFile: " + e); 485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return null; 495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public DocumentFile createDirectory(String displayName) { 545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final File target = new File(mFile, displayName); 555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (target.isDirectory() || target.mkdir()) { 565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return new RawDocumentFile(this, target); 575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return null; 595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public Uri getUri() { 645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return Uri.fromFile(mFile); 655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public String getName() { 695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.getName(); 705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public String getType() { 745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (mFile.isDirectory()) { 755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return null; 765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return getTypeForName(mFile.getName()); 785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean isDirectory() { 835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.isDirectory(); 845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean isFile() { 885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.isFile(); 895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public long lastModified() { 935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.lastModified(); 945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public long length() { 985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.length(); 995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean canRead() { 1035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.canRead(); 1045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean canWrite() { 1085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.canWrite(); 1095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean delete() { 1135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey deleteContents(mFile); 1145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.delete(); 1155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean exists() { 1195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mFile.exists(); 1205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public DocumentFile[] listFiles() { 1245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final ArrayList<DocumentFile> results = new ArrayList<DocumentFile>(); 1255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final File[] files = mFile.listFiles(); 1265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (files != null) { 1275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey for (File file : files) { 1285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey results.add(new RawDocumentFile(this, file)); 1295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return results.toArray(new DocumentFile[results.size()]); 1325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public boolean renameTo(String displayName) { 1365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final File target = new File(mFile.getParentFile(), displayName); 1375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (mFile.renameTo(target)) { 1385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey mFile = target; 1395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return true; 1405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 1415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return false; 1425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static String getTypeForName(String name) { 1465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final int lastDot = name.lastIndexOf('.'); 1475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (lastDot >= 0) { 1485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final String extension = name.substring(lastDot + 1).toLowerCase(); 1495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); 1505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (mime != null) { 1515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mime; 1525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return "application/octet-stream"; 1565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static boolean deleteContents(File dir) { 1595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey File[] files = dir.listFiles(); 1605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey boolean success = true; 1615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (files != null) { 1625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey for (File file : files) { 1635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (file.isDirectory()) { 1645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey success &= deleteContents(file); 1655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (!file.delete()) { 1675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey Log.w(TAG, "Failed to delete " + file); 1685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey success = false; 1695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return success; 1735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey} 175