FileCollector.java revision 1009c08f8e11bb050ce395e8f6a0ed318b1902a1
13c7febdbd86070337810d1ff741d35430707726aDaniel Nishi/*
23c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * Copyright (C) 2016 The Android Open Source Project
33c7febdbd86070337810d1ff741d35430707726aDaniel Nishi *
43c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * Licensed under the Apache License, Version 2.0 (the "License"); you may not
53c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * use this file except in compliance with the License. You may obtain a copy of
63c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * the License at
73c7febdbd86070337810d1ff741d35430707726aDaniel Nishi *
83c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * http://www.apache.org/licenses/LICENSE2.0
93c7febdbd86070337810d1ff741d35430707726aDaniel Nishi *
103c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * Unless required by applicable law or agreed to in writing, software
113c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
123c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
133c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * License for the specific language governing permissions and limitations under
143c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * the License.
153c7febdbd86070337810d1ff741d35430707726aDaniel Nishi */
163c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
173c7febdbd86070337810d1ff741d35430707726aDaniel Nishipackage com.android.server.storage;
183c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
193c7febdbd86070337810d1ff741d35430707726aDaniel Nishiimport android.annotation.IntDef;
2077a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishiimport android.content.Context;
2177a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishiimport android.content.pm.PackageManager;
223c7febdbd86070337810d1ff741d35430707726aDaniel Nishiimport android.os.storage.StorageManager;
2377a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishiimport android.os.storage.VolumeInfo;
243c7febdbd86070337810d1ff741d35430707726aDaniel Nishiimport android.util.ArrayMap;
253c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
263c7febdbd86070337810d1ff741d35430707726aDaniel Nishiimport java.io.File;
273c7febdbd86070337810d1ff741d35430707726aDaniel Nishiimport java.lang.annotation.Retention;
283c7febdbd86070337810d1ff741d35430707726aDaniel Nishiimport java.lang.annotation.RetentionPolicy;
291009c08f8e11bb050ce395e8f6a0ed318b1902a1Jeff Sharkeyimport java.util.Map;
303c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
313c7febdbd86070337810d1ff741d35430707726aDaniel Nishi/**
323c7febdbd86070337810d1ff741d35430707726aDaniel Nishi * FileCollector walks over a directory and categorizes storage usage by their type.
333c7febdbd86070337810d1ff741d35430707726aDaniel Nishi */
343c7febdbd86070337810d1ff741d35430707726aDaniel Nishipublic class FileCollector {
353c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static final int UNRECOGNIZED = -1;
363c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static final int IMAGES = 0;
373c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static final int VIDEO = 1;
383c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static final int AUDIO = 2;
393c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    @Retention(RetentionPolicy.SOURCE)
403c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    @IntDef({
413c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            UNRECOGNIZED,
423c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            IMAGES,
433c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            VIDEO,
443c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            AUDIO })
453c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private @interface FileTypes {}
463c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
471009c08f8e11bb050ce395e8f6a0ed318b1902a1Jeff Sharkey
481009c08f8e11bb050ce395e8f6a0ed318b1902a1Jeff Sharkey    private static final Map<String, Integer> EXTENSION_MAP = new ArrayMap<String, Integer>();
493c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    static {
503c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        // Audio
513c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("aac", AUDIO);
523c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("amr", AUDIO);
533c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("awb", AUDIO);
543c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("snd", AUDIO);
553c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("flac", AUDIO);
563c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mp3", AUDIO);
573c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mpga", AUDIO);
583c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mpega", AUDIO);
593c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mp2", AUDIO);
603c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("m4a", AUDIO);
613c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("aif", AUDIO);
623c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("aiff", AUDIO);
633c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("aifc", AUDIO);
643c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("gsm", AUDIO);
653c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mka", AUDIO);
663c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("m3u", AUDIO);
673c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wma", AUDIO);
683c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wax", AUDIO);
693c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("ra", AUDIO);
703c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("rm", AUDIO);
713c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("ram", AUDIO);
723c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("pls", AUDIO);
733c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("sd2", AUDIO);
743c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wav", AUDIO);
753c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("ogg", AUDIO);
763c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("oga", AUDIO);
773c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        // Video
783c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("3gpp", VIDEO);
793c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("3gp", VIDEO);
803c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("3gpp2", VIDEO);
813c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("3g2", VIDEO);
823c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("avi", VIDEO);
833c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("dl", VIDEO);
843c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("dif", VIDEO);
853c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("dv", VIDEO);
863c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("fli", VIDEO);
873c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("m4v", VIDEO);
883c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("ts", VIDEO);
893c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mpeg", VIDEO);
903c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mpg", VIDEO);
913c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mpe", VIDEO);
923c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mp4", VIDEO);
933c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("vob", VIDEO);
943c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("qt", VIDEO);
953c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mov", VIDEO);
963c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mxu", VIDEO);
973c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("webm", VIDEO);
983c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("lsf", VIDEO);
993c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("lsx", VIDEO);
1003c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mkv", VIDEO);
1013c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("mng", VIDEO);
1023c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("asf", VIDEO);
1033c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("asx", VIDEO);
1043c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wm", VIDEO);
1053c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wmv", VIDEO);
1063c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wmx", VIDEO);
1073c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wvx", VIDEO);
1083c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("movie", VIDEO);
1093c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wrf", VIDEO);
1103c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        // Images
1113c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("bmp", IMAGES);
1123c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("gif", IMAGES);
1133c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("jpg", IMAGES);
1143c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("jpeg", IMAGES);
1153c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("jpe", IMAGES);
1163c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("pcx", IMAGES);
1173c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("png", IMAGES);
1183c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("svg", IMAGES);
1193c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("svgz", IMAGES);
1203c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("tiff", IMAGES);
1213c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("tif", IMAGES);
1223c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("wbmp", IMAGES);
1233c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("webp", IMAGES);
1243c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("dng", IMAGES);
1253c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("cr2", IMAGES);
1263c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("ras", IMAGES);
1273c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("art", IMAGES);
1283c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("jng", IMAGES);
1293c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("nef", IMAGES);
1303c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("nrw", IMAGES);
1313c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("orf", IMAGES);
1323c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("rw2", IMAGES);
1333c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("pef", IMAGES);
1343c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("psd", IMAGES);
1353c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("pnm", IMAGES);
1363c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("pbm", IMAGES);
1373c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("pgm", IMAGES);
1383c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("ppm", IMAGES);
1393c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("srw", IMAGES);
1403c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("arw", IMAGES);
1413c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("rgb", IMAGES);
1423c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("xbm", IMAGES);
1433c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("xpm", IMAGES);
1443c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        EXTENSION_MAP.put("xwd", IMAGES);
1453c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    }
1463c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
1473c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    /**
1483c7febdbd86070337810d1ff741d35430707726aDaniel Nishi     * Returns the file categorization measurement result.
1493c7febdbd86070337810d1ff741d35430707726aDaniel Nishi     * @param path Directory to collect and categorize storage in.
1503c7febdbd86070337810d1ff741d35430707726aDaniel Nishi     */
1513c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    public static MeasurementResult getMeasurementResult(File path) {
1523c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        return collectFiles(StorageManager.maybeTranslateEmulatedPathToInternal(path),
1533c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                new MeasurementResult());
1543c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    }
1553c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
15677a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi    /**
15777a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi     * Returns the size of a system for a given context. This is done by finding the difference
15877a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi     * between the shared data and the total primary storage size.
15977a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi     * @param context Context to use to get storage information.
16077a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi     */
16177a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi    public static long getSystemSize(Context context) {
16277a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        PackageManager pm = context.getPackageManager();
16377a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        VolumeInfo primaryVolume = pm.getPrimaryStorageCurrentVolume();
16477a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi
16577a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        StorageManager sm = context.getSystemService(StorageManager.class);
16677a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        VolumeInfo shared = sm.findEmulatedForPrivate(primaryVolume);
16777a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        if (shared == null) {
16877a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi            return 0;
16977a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        }
17077a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi
17177a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        final long sharedDataSize = shared.getPath().getTotalSpace();
17277a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        long systemSize = sm.getPrimaryStorageSize() - sharedDataSize;
17377a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi
17477a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        // This case is not exceptional -- we just fallback to the shared data volume in this case.
17577a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        if (systemSize <= 0) {
17677a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi            return 0;
17777a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        }
17877a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi
17977a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi        return systemSize;
18077a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi    }
18177a78c6f4412dccc58075685ad77f3e41d85f2e4Daniel Nishi
1823c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static MeasurementResult collectFiles(File file, MeasurementResult result) {
1833c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        File[] files = file.listFiles();
1843c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
1853c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        if (files == null) {
1863c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            return result;
1873c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        }
1883c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
1893c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        for (File f : files) {
1903c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            if (f.isDirectory()) {
1913c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                try {
1923c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                    collectFiles(f, result);
1933c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                } catch (StackOverflowError e) {
1943c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                    return result;
1953c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                }
1963c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            } else {
1973c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                handleFile(result, f);
1983c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            }
1993c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        }
2003c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
2013c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        return result;
2023c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    }
2033c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
2043c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static void handleFile(MeasurementResult result, File f) {
2053c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        long fileSize = f.length();
2063c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        int fileType = EXTENSION_MAP.getOrDefault(getExtensionForFile(f), UNRECOGNIZED);
2073c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        switch (fileType) {
2083c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            case AUDIO:
2093c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                result.audioSize += fileSize;
2103c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                break;
2113c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            case VIDEO:
2123c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                result.videosSize += fileSize;
2133c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                break;
2143c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            case IMAGES:
2153c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                result.imagesSize += fileSize;
2163c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                break;
2173c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            default:
2183c7febdbd86070337810d1ff741d35430707726aDaniel Nishi                result.miscSize += fileSize;
2193c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        }
2203c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    }
2213c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
2223c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    private static String getExtensionForFile(File file) {
2233c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        String fileName = file.getName();
2243c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        int index = fileName.lastIndexOf('.');
2253c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        if (index == -1) {
2263c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            return "";
2273c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        }
2283c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        return fileName.substring(index + 1).toLowerCase();
2293c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    }
2303c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
2313c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    /**
2323c7febdbd86070337810d1ff741d35430707726aDaniel Nishi     * MeasurementResult contains a storage categorization result.
2333c7febdbd86070337810d1ff741d35430707726aDaniel Nishi     */
2343c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    public static class MeasurementResult {
2353c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        public long imagesSize;
2363c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        public long videosSize;
2373c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        public long miscSize;
2383c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        public long audioSize;
2393c7febdbd86070337810d1ff741d35430707726aDaniel Nishi
2403c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        /**
2413c7febdbd86070337810d1ff741d35430707726aDaniel Nishi         * Sums up the storage taken by all of the categorizable sizes in the measurement.
2423c7febdbd86070337810d1ff741d35430707726aDaniel Nishi         */
2433c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        public long totalAccountedSize() {
2443c7febdbd86070337810d1ff741d35430707726aDaniel Nishi            return imagesSize + videosSize + miscSize + audioSize;
2453c7febdbd86070337810d1ff741d35430707726aDaniel Nishi        }
2463c7febdbd86070337810d1ff741d35430707726aDaniel Nishi    }
2473c7febdbd86070337810d1ff741d35430707726aDaniel Nishi}
248