TrickplayStorageManager.java revision d41f0075a7d2ea826204e81fcec57d0aa57171a9
11abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/*
21abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Copyright (C) 2015 The Android Open Source Project
31abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *
41abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
51abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * you may not use this file except in compliance with the License.
61abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * You may obtain a copy of the License at
71abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *
81abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
91abddd9f6225298066094e20a6c29061b6af4590Nick Chalko *
101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Unless required by applicable law or agreed to in writing, software
111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * See the License for the specific language governing permissions and
141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * limitations under the License.
151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */
161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopackage com.android.tv.tuner.exoplayer.buffer;
181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
191abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.content.Context;
201abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.media.MediaFormat;
21d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.os.AsyncTask;
22d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.os.Looper;
231abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.provider.Settings;
241abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.util.Pair;
251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
261abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport java.io.File;
271abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport java.util.ArrayList;
281abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport java.util.SortedMap;
291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/**
311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Manages Trickplay storage.
321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */
3365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopublic class TrickplayStorageManager implements BufferManager.StorageManager {
3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static final String BUFFER_DIR = "timeshift";
351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    // Copied from android.provider.Settings.Global (hidden fields)
371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private static final String
381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            SYS_STORAGE_THRESHOLD_PERCENTAGE = "sys_storage_threshold_percentage";
391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private static final String
401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko            SYS_STORAGE_THRESHOLD_MAX_BYTES = "sys_storage_threshold_max_bytes";
411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    // Copied from android.os.StorageManager
431abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
44ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500L * 1024 * 1024;
451abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
4665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private final File mBufferDir;
4765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private final long mMaxBufferSize;
481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private final long mStorageBufferBytes;
491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    private static long getStorageBufferBytes(Context context, File path) {
511abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        long lowPercentage = Settings.Global.getInt(context.getContentResolver(),
521abddd9f6225298066094e20a6c29061b6af4590Nick Chalko                SYS_STORAGE_THRESHOLD_PERCENTAGE, DEFAULT_THRESHOLD_PERCENTAGE);
531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        long lowBytes = path.getTotalSpace() * lowPercentage / 100;
541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        long maxLowBytes = Settings.Global.getLong(context.getContentResolver(),
551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko                SYS_STORAGE_THRESHOLD_MAX_BYTES, DEFAULT_THRESHOLD_MAX_BYTES);
561abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return Math.min(lowBytes, maxLowBytes);
571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
581abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public TrickplayStorageManager(Context context, File baseDir, long maxBufferSize) {
6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mBufferDir = new File(baseDir, BUFFER_DIR);
6165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mBufferDir.mkdirs();
6265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mMaxBufferSize = maxBufferSize;
631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        clearStorage();
6465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mStorageBufferBytes = getStorageBufferBytes(context, mBufferDir);
651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
681abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void clearStorage() {
69d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        File files[] = mBufferDir.listFiles();
70d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (files == null || files.length == 0) {
71d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
72d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
73d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (Looper.myLooper() == Looper.getMainLooper()) {
74d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            new AsyncTask<Void, Void, Void>() {
75d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                @Override
76d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                protected Void doInBackground(Void... params) {
77d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    for (File file : files) {
78d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        file.delete();
79d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    }
80d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    return null;
81d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }
82d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
83d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } else {
84d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            for (File file : files) {
85d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                file.delete();
86d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
871abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        }
881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
901abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
9165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public File getBufferDir() {
9265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mBufferDir;
931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean isPersistent() {
971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return false;
981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
10165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public boolean reachedStorageMax(long bufferSize, long pendingDelete) {
10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return bufferSize - pendingDelete > mMaxBufferSize;
1031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public boolean hasEnoughBuffer(long pendingDelete) {
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return mBufferDir.getUsableSpace() + pendingDelete >= mStorageBufferBytes;
1081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public Pair<String, MediaFormat> readTrackInfoFile(boolean isAudio) {
1121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return null;
1131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public ArrayList<Long> readIndexFile(String trackId) {
1171abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        return null;
1181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
1211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public void writeTrackInfoFile(String trackId, MediaFormat format, boolean isAudio) {
1221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    @Override
12565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public void writeIndexFile(String trackName, SortedMap<Long, SampleChunk> index) {
1261abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1281abddd9f6225298066094e20a6c29061b6af4590Nick Chalko}
129