Remove items from the 'last 24 hours' history on swipe

And make it resiliant to duplicate data from the backend.

Test: manual
Fixes: 148956400
Change-Id: I650c89242c257df1ec34b2879f544d9a5211019a
This commit is contained in:
Julia Reynolds
2020-03-27 15:56:41 -04:00
parent 4eb430585a
commit eabc1904a7
5 changed files with 106 additions and 24 deletions

View File

@@ -79,7 +79,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:clipChildren="true" android:clipChildren="true"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView <com.android.settings.notification.history.NotificationHistoryRecyclerView
android:id="@+id/notification_list" android:id="@+id/notification_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -101,14 +101,12 @@ public class NotificationHistoryActivity extends Activity {
count.setText(getResources().getQuantityString(R.plurals.notification_history_count, count.setText(getResources().getQuantityString(R.plurals.notification_history_count,
nhp.notifications.size(), nhp.notifications.size())); nhp.notifications.size(), nhp.notifications.size()));
RecyclerView rv = viewForPackage.findViewById(R.id.notification_list); NotificationHistoryRecyclerView rv =
LinearLayoutManager lm = new LinearLayoutManager(this); viewForPackage.findViewById(R.id.notification_list);
rv.setLayoutManager(lm); rv.setAdapter(new NotificationHistoryAdapter(mNm, rv));
rv.setAdapter(new NotificationHistoryAdapter()); ((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration( new ArrayList<>(nhp.notifications));
rv.getContext(), lm.getOrientation());
rv.addItemDecoration(dividerItemDecoration);
((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(nhp.notifications);
mTodayView.addView(viewForPackage); mTodayView.addView(viewForPackage);
} }
}; };

View File

@@ -16,11 +16,10 @@
package com.android.settings.notification.history; package com.android.settings.notification.history;
import android.app.NotificationHistory; import android.app.INotificationManager;
import android.app.NotificationHistory.HistoricalNotification; import android.app.NotificationHistory.HistoricalNotification;
import android.content.Context; import android.os.RemoteException;
import android.graphics.drawable.Drawable; import android.util.Slog;
import android.os.UserHandle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -29,24 +28,25 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class NotificationHistoryAdapter extends public class NotificationHistoryAdapter extends
RecyclerView.Adapter<NotificationHistoryViewHolder> { RecyclerView.Adapter<NotificationHistoryViewHolder> implements
NotificationHistoryRecyclerView.OnItemSwipeDeleteListener {
private static String TAG = "NotiHistoryAdapter";
private INotificationManager mNm;
private List<HistoricalNotification> mValues; private List<HistoricalNotification> mValues;
public NotificationHistoryAdapter() { public NotificationHistoryAdapter(INotificationManager nm,
NotificationHistoryRecyclerView listView) {
mValues = new ArrayList<>(); mValues = new ArrayList<>();
setHasStableIds(true); setHasStableIds(true);
listView.setOnItemSwipeDeleteListener(this);
mNm = nm;
} }
@Override @Override
@@ -77,4 +77,18 @@ public class NotificationHistoryAdapter extends
mValues.sort((o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs())); mValues.sort((o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs()));
notifyDataSetChanged(); notifyDataSetChanged();
} }
@Override
public void onItemSwipeDeleted(int position) {
HistoricalNotification hn = mValues.remove(position);
if (hn != null) {
try {
mNm.deleteNotificationHistoryItem(
hn.getPackage(), hn.getUid(), hn.getPostedTimeMs());
} catch (RemoteException e) {
Slog.e(TAG, "Failed to delete item", e);
}
}
notifyItemRemoved(position);
}
} }

View File

@@ -20,27 +20,31 @@ import android.app.NotificationHistory;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
public class NotificationHistoryPackage { public class NotificationHistoryPackage {
String pkgName; String pkgName;
int uid; int uid;
List<NotificationHistory.HistoricalNotification> notifications; TreeSet<NotificationHistory.HistoricalNotification> notifications;
CharSequence label; CharSequence label;
Drawable icon; Drawable icon;
public NotificationHistoryPackage(String pkgName, int uid) { public NotificationHistoryPackage(String pkgName, int uid) {
this.pkgName = pkgName; this.pkgName = pkgName;
this.uid = uid; this.uid = uid;
notifications = new ArrayList<>(); notifications = new TreeSet<>(
(o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs()));
} }
public long getMostRecent() { public long getMostRecent() {
if (notifications.isEmpty()) { if (notifications.isEmpty()) {
return 0; return 0;
} }
return notifications.get(0).getPostedTimeMs(); return notifications.first().getPostedTimeMs();
} }
@Override @Override

View File

@@ -0,0 +1,66 @@
package com.android.settings.notification.history;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class NotificationHistoryRecyclerView extends RecyclerView {
private static final String TAG = "HistoryRecyclerView";
private OnItemSwipeDeleteListener listener;
public NotificationHistoryRecyclerView(Context context) {
this(context, null);
}
public NotificationHistoryRecyclerView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public NotificationHistoryRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setLayoutManager(new LinearLayoutManager(getContext()));
addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
ItemTouchHelper touchHelper = new ItemTouchHelper(
new DismissTouchHelper(0, ItemTouchHelper.START | ItemTouchHelper.END));
touchHelper.attachToRecyclerView(this);
}
public void setOnItemSwipeDeleteListener(OnItemSwipeDeleteListener listener) {
this.listener = listener;
}
private class DismissTouchHelper extends ItemTouchHelper.SimpleCallback {
public DismissTouchHelper(int dragDirs, int swipeDirs) {
super(dragDirs, swipeDirs);
}
@Override
public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) {
// Do nothing.
return false;
}
@Override
public void onSwiped(ViewHolder viewHolder, int direction) {
if (listener != null) {
listener.onItemSwipeDeleted(viewHolder.getAdapterPosition());
}
}
}
public interface OnItemSwipeDeleteListener {
void onItemSwipeDeleted(int position);
}
}