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