1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.providers.tv; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.database.sqlite.SQLiteDatabase; 22 import android.media.tv.TvContract.Channels; 23 import android.media.tv.TvContract.PreviewPrograms; 24 import android.media.tv.TvContract.WatchNextPrograms; 25 import android.preference.PreferenceManager; 26 import android.provider.Settings; 27 28 import com.android.internal.annotations.VisibleForTesting; 29 import com.android.providers.tv.TvProvider.DatabaseHelper; 30 31 /** 32 * Convenient class for deleting transient rows. This ensures that the clean up job is done only 33 * once after boot. 34 */ 35 public class TransientRowHelper { 36 private static final String PREF_KEY_LAST_DELETION_BOOT_COUNT = 37 "pref_key_last_deletion_boot_count"; 38 private static TransientRowHelper sInstance; 39 40 private Context mContext; 41 private DatabaseHelper mDatabaseHelper; 42 @VisibleForTesting 43 protected boolean mTransientRowsDeleted; 44 45 /** 46 * Returns the singleton TransientRowHelper instance. 47 * 48 * @param context The application context. 49 */ 50 public static TransientRowHelper getInstance(Context context) { 51 synchronized (TransientRowHelper.class) { 52 if (sInstance == null) { 53 sInstance = new TransientRowHelper(context); 54 } 55 } 56 return sInstance; 57 } 58 59 @VisibleForTesting 60 TransientRowHelper(Context context) { 61 mContext = context; 62 mDatabaseHelper = DatabaseHelper.getInstance(context); 63 } 64 65 /** 66 * Ensures that transient rows, inserted previously before current boot, are deleted. 67 */ 68 public synchronized void ensureOldTransientRowsDeleted() { 69 if (mTransientRowsDeleted) { 70 return; 71 } 72 mTransientRowsDeleted = true; 73 if (getLastDeletionBootCount() >= getBootCount()) { 74 // This can be the second execution of TvProvider after boot since system kills 75 // TvProvider in low memory conditions. If this is the case, we shouldn't delete 76 // transient rows. 77 return; 78 } 79 SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); 80 // Delete all the transient programs and channels. 81 db.delete(TvProvider.PREVIEW_PROGRAMS_TABLE, PreviewPrograms.COLUMN_TRANSIENT + "=1", null); 82 db.delete(TvProvider.CHANNELS_TABLE, Channels.COLUMN_TRANSIENT + "=1", null); 83 db.delete(TvProvider.WATCH_NEXT_PROGRAMS_TABLE, WatchNextPrograms.COLUMN_TRANSIENT + "=1", 84 null); 85 setLastDeletionBootCount(); 86 } 87 88 @VisibleForTesting 89 protected int getBootCount() { 90 return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BOOT_COUNT, 91 -1); 92 } 93 94 @VisibleForTesting 95 protected int getLastDeletionBootCount() { 96 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); 97 return prefs.getInt(PREF_KEY_LAST_DELETION_BOOT_COUNT, -1); 98 } 99 100 @VisibleForTesting 101 protected void setLastDeletionBootCount() { 102 SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(mContext) 103 .edit(); 104 editor.putInt(PREF_KEY_LAST_DELETION_BOOT_COUNT, getBootCount()); 105 editor.apply(); 106 } 107 } 108