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 */ getInstance(Context context)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 TransientRowHelper(Context context)60 TransientRowHelper(Context context) { 61 mContext = context; 62 mDatabaseHelper = DatabaseHelper.getInstance(context); 63 } 64 65 @VisibleForTesting TransientRowHelper(Context context, DatabaseHelper databaseHelper)66 TransientRowHelper(Context context, DatabaseHelper databaseHelper) { 67 mContext = context; 68 mDatabaseHelper = databaseHelper; 69 } 70 71 /** 72 * Ensures that transient rows, inserted previously before current boot, are deleted. 73 */ ensureOldTransientRowsDeleted()74 public synchronized void ensureOldTransientRowsDeleted() { 75 if (mTransientRowsDeleted) { 76 return; 77 } 78 mTransientRowsDeleted = true; 79 if (getLastDeletionBootCount() >= getBootCount()) { 80 // This can be the second execution of TvProvider after boot since system kills 81 // TvProvider in low memory conditions. If this is the case, we shouldn't delete 82 // transient rows. 83 return; 84 } 85 SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); 86 // Delete all the transient programs and channels. 87 db.delete(TvProvider.PREVIEW_PROGRAMS_TABLE, PreviewPrograms.COLUMN_TRANSIENT + "=1", null); 88 db.delete(TvProvider.CHANNELS_TABLE, Channels.COLUMN_TRANSIENT + "=1", null); 89 db.delete(TvProvider.WATCH_NEXT_PROGRAMS_TABLE, WatchNextPrograms.COLUMN_TRANSIENT + "=1", 90 null); 91 setLastDeletionBootCount(); 92 } 93 94 @VisibleForTesting getBootCount()95 protected int getBootCount() { 96 return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BOOT_COUNT, 97 -1); 98 } 99 100 @VisibleForTesting getLastDeletionBootCount()101 protected int getLastDeletionBootCount() { 102 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); 103 return prefs.getInt(PREF_KEY_LAST_DELETION_BOOT_COUNT, -1); 104 } 105 106 @VisibleForTesting setLastDeletionBootCount()107 protected void setLastDeletionBootCount() { 108 SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(mContext) 109 .edit(); 110 editor.putInt(PREF_KEY_LAST_DELETION_BOOT_COUNT, getBootCount()); 111 editor.apply(); 112 } 113 } 114