/* * Copyright (C) 2014 AChep@xda <artemchep@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.achep.acdisplay.blacklist; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import com.achep.base.content.SharedList; /** * The blacklist (also known as per-app-features.) * * @author Artem Chepurnoy * @see #saveAppConfig(android.content.Context, AppConfig, SharedList.OnSharedListChangedListener) * @see #getAppConfig(String) */ public final class Blacklist extends SharedList<AppConfig, AppConfig.Saver> { private static final String TAG = "Blacklist"; public static final String PREF_NAME = "blacklist"; private static Blacklist sBlacklist; /** * Interface definition for a callback to be invoked * when a blacklist changed. * * @author Artem Chepurnoy */ public static abstract class OnBlacklistChangedListener implements OnSharedListChangedListener<AppConfig> { /** * Called on blacklist changed. * * @param configNew An instance of new app's config. * @param configOld An instance of previous app's config (can not be null.) * @param diff The difference between two configs. */ public abstract void onBlacklistChanged( @NonNull AppConfig configNew, @NonNull AppConfig configOld, int diff); /** * {@inheritDoc} */ @Override public final void onPut(@NonNull AppConfig objectNew, AppConfig objectOld, int diff) { onBlacklistChanged(objectNew, objectOld, diff); } /** * Should never be called. * * @see #onBlacklistChanged(AppConfig, AppConfig, int) */ @Override public final void onRemoved(@NonNull AppConfig objectRemoved) { Log.wtf(TAG, "Notified about removing an item from blacklist."); } } public static synchronized Blacklist getInstance() { if (sBlacklist == null) { sBlacklist = new Blacklist(); } return sBlacklist; } private Blacklist() { super(); } /** * This is called on {@link com.achep.acdisplay.App#onCreate() App create}. * * @see com.achep.base.content.SharedList#init(android.content.Context) */ @Override public void init(@NonNull Context context) { super.init(context); } /** * {@inheritDoc} */ @NonNull @Override protected String getPreferencesFileName() { return PREF_NAME; } /** * {@inheritDoc} */ @NonNull @Override protected AppConfig.Saver onCreateSaver() { return new AppConfig.Saver(); } /** * {@inheritDoc} */ @Override protected Comparator onCreateComparator() { return new AppConfig.Comparator(); } /** * {@inheritDoc} */ @Override protected boolean isOverwriteAllowed(@NonNull AppConfig object) { return true; } //-- MANAGING APP CONFIG -------------------------------------------------- public void saveAppConfig(Context context, AppConfig config, OnSharedListChangedListener listener) { if (config.equalsToDefault()) { // We need to remove defaults to save blacklist's size. super.remove(context, config, listener); return; } AppConfig clone = new AppConfig(config.packageName); AppConfig.copy(config, clone); super.put(context, clone, listener); // overwriting is enabled. } /** * <b>Creates</b> new instance of {@link com.achep.acdisplay.blacklist.AppConfig} and * fills it with present data. * * @param packageName The package name of need application. * @return New instance of app's config filled with present data. * @see #fill(AppConfig) */ @NonNull public AppConfig getAppConfig(@NonNull String packageName) { return fill(new AppConfig(packageName)); } @NonNull public AppConfig fill(@NonNull AppConfig config) { for (AppConfig c : values()) { if (c.equals(config)) { AppConfig.copy(c, config); return config; } } AppConfig.reset(config); return config; } //-- BULL SHIT PROTECTION ------------------------------------------------- /** * This will throw an exception! Please, use * {@link #saveAppConfig(Context, AppConfig, SharedList.OnSharedListChangedListener)} instead. */ @Nullable @Override public AppConfig put(@NonNull Context context, @NonNull AppConfig object, @Nullable OnSharedListChangedListener l) { throw new RuntimeException(); } /** * This will throw an exception! Please, use * {@link #saveAppConfig(Context, AppConfig, SharedList.OnSharedListChangedListener)} instead. */ @Override public void remove(@NonNull Context context, @NonNull AppConfig object, @Nullable OnSharedListChangedListener l) { throw new RuntimeException(); } //-- DISMISSING WIDGET ---------------------------------------------------- /** * {@inheritDoc} */ @Override protected final void notifyOnRemoved(@NonNull AppConfig object, OnSharedListChangedListener l) { // Change remove-event to event about putting // empty config to the list. notifyOnPut(new AppConfig(object.packageName), object, l); } /** * {@inheritDoc} */ @Override protected final void notifyOnPut(AppConfig object, AppConfig old, OnSharedListChangedListener l) { if (old == null) { // Do not allow nulls. old = new AppConfig(object.packageName); } // Notify all listeners super.notifyOnPut(object, old, l); } }