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