/* * 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.notifications; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.achep.base.interfaces.IOnLowMemory; import java.util.ArrayList; /** * Is a list of {@link OpenNotification notifications} with * an ability to easily add / replace / remove item from the list. * * @author Artem Chepurnoy */ final class NotificationList extends ArrayList<OpenNotification> implements IOnLowMemory { /** * Default return value of {@link #pushNotification(OpenNotification)} * or {@link #removeNotification(OpenNotification)} methods. */ static final int RESULT_DEFAULT = 0; private static final int EVENT_ADDED = 0; private static final int EVENT_CHANGED = 1; private static final int EVENT_REMOVED = 2; @Nullable private OnNotificationListChangedListener mListener; /** * @see #setMaximumSize(int) */ private volatile int mMaximumSize = Integer.MAX_VALUE; /** * {@inheritDoc} */ @Override public void onLowMemory() { for (OpenNotification n : this) n.onLowMemory(); } /** * Interface definition for a callback to be invoked * when a list of notifications has changed. */ public interface OnNotificationListChangedListener { /** * Called when new notification was added to list. * * @param n newly added notification */ int onNotificationAdded(@NonNull OpenNotification n); /** * Called when old notification was replaced with new one. * * @param n newly added notification * @param old removed notification */ int onNotificationChanged(@NonNull OpenNotification n, @NonNull OpenNotification old); /** * Called when notification was removed from list. * * @param n removed notification */ int onNotificationRemoved(@NonNull OpenNotification n); } /** * Creates new {@link com.achep.acdisplay.notifications.NotificationList} with initial capacity * equals to {@code 10}. * * @param listener Listener to which all events will be send. */ public NotificationList(@Nullable OnNotificationListChangedListener listener) { mListener = listener; } /** * Sets the maximum size of this list. * * @param maxSize the maximum size. */ public void setMaximumSize(int maxSize) { if (maxSize <= 0) { throw new IllegalArgumentException("Maximum size must be greater than zero!"); } mMaximumSize = maxSize; } int pushOrRemoveNotification(@NonNull OpenNotification n, boolean push) { return push ? pushNotification(n) : removeNotification(n); } /** * Adds or replaces existent notification to/of the list. * * @return {@link NotificationList.OnNotificationListChangedListener#onNotificationAdded(OpenNotification n)} or * {@link NotificationList.OnNotificationListChangedListener#onNotificationChanged(OpenNotification n, OpenNotification old)} */ int pushNotification(@NonNull OpenNotification n) { return pushNotification(n, true); } int pushNotification(@NonNull OpenNotification n, boolean www) { final int index = indexOfNotification(n); if (index == -1) { if (size() > mMaximumSize) { remove(0); } // Add new notification to the list. add(n); return notifyListener(EVENT_ADDED, n, null); } else if (www) { // Replace old notification with new one. OpenNotification old = remove(index); add(index, n); return notifyListener(EVENT_CHANGED, n, old); } return RESULT_DEFAULT; } /** * Removes notification from the list. * * @return {@link NotificationList.OnNotificationListChangedListener#onNotificationRemoved(OpenNotification n)} * @see #pushNotification(OpenNotification n) */ int removeNotification(@NonNull OpenNotification n) { final int index = indexOfNotification(n); return index != -1 ? removeNotification(index) : RESULT_DEFAULT; } int removeNotification(int index) { OpenNotification old = remove(index); return notifyListener(EVENT_REMOVED, old, null); } /** * @return the position of given {@link OpenNotification} in list, or {@code -1} if not found. * @see NotificationUtils#hasIdenticalIds(OpenNotification, OpenNotification) */ int indexOfNotification(@NonNull OpenNotification n) { final int size = size(); for (int i = 0; i < size; i++) { if (NotificationUtils.hasIdenticalIds(n, get(i))) { return i; } } return -1; } /** * Notifies listener about this event. * * @see #EVENT_ADDED * @see #EVENT_CHANGED * @see #EVENT_REMOVED */ private int notifyListener(final int event, @NonNull OpenNotification n, OpenNotification old) { if (mListener == null) return RESULT_DEFAULT; switch (event) { case EVENT_ADDED: return mListener.onNotificationAdded(n); case EVENT_CHANGED: return mListener.onNotificationChanged(n, old); case EVENT_REMOVED: return mListener.onNotificationRemoved(n); default: throw new IllegalArgumentException(); } } }