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