From 84c7739986f8fb67d4e9db05d698044999279476 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Wed, 12 Jul 2017 12:28:16 -0700 Subject: [PATCH] Fix mokey crash on swiping settings condition. When the condition card is being swiped, add null check for the retrieved Condition to ensure it is still valid before trying to dismiss it. Change-Id: I265091a5fe290e359fa9a6e16b1d87c03894c1b8 Fix: 63624859 Test: make RunSettingsRoboTests --- .../dashboard/conditional/ConditionAdapter.java | 48 ++++++++++++---------- .../conditional/ConditionAdapterTest.java | 17 ++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java index 4a7422f597..5a12f9d2eb 100644 --- a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java +++ b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java @@ -16,6 +16,7 @@ package com.android.settings.dashboard.conditional; import android.content.Context; +import android.support.annotation.VisibleForTesting; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.Log; @@ -58,6 +59,31 @@ public class ConditionAdapter extends RecyclerView.Adapter } }; + @VisibleForTesting + ItemTouchHelper.SimpleCallback mSwipeCallback = new ItemTouchHelper.SimpleCallback(0, + ItemTouchHelper.START | ItemTouchHelper.END) { + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, + RecyclerView.ViewHolder target) { + return true; + } + + @Override + public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + return viewHolder.getItemViewType() == R.layout.condition_tile_new_ui + ? super.getSwipeDirs(recyclerView, viewHolder) : 0; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + Object item = getItem(viewHolder.getItemId()); + // item can become null when running monkey + if (item != null) { + ((Condition) item).silence(); + } + } + }; + public ConditionAdapter(Context context, List conditions, @HeaderMode int mode) { mContext = context; mConditions = conditions; @@ -107,27 +133,7 @@ public class ConditionAdapter extends RecyclerView.Adapter } public void addDismissHandling(final RecyclerView recyclerView) { - ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, - ItemTouchHelper.START | ItemTouchHelper.END) { - @Override - public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, - RecyclerView.ViewHolder target) { - return true; - } - - @Override - public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { - return viewHolder.getItemViewType() == R.layout.condition_tile_new_ui - ? super.getSwipeDirs(recyclerView, viewHolder) : 0; - } - - @Override - public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { - Object item = getItem(viewHolder.getItemId()); - ((Condition) item).silence(); - } - }; - ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); + final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mSwipeCallback); itemTouchHelper.attachToRecyclerView(recyclerView); } diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java index f0412d67f2..c65113209e 100644 --- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java @@ -16,6 +16,7 @@ package com.android.settings.dashboard.conditional; import android.content.Context; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; @@ -130,4 +131,20 @@ public class ConditionAdapterTest { verify(mCondition1).onPrimaryClick(); } + @Test + public void onSwiped_nullCondition_shouldNotCrash() { + final RecyclerView recyclerView = new RecyclerView(mContext); + final View view = LayoutInflater.from(mContext).inflate( + R.layout.condition_tile_new_ui, new LinearLayout(mContext), true); + final DashboardAdapter.DashboardItemHolder viewHolder = + new DashboardAdapter.DashboardItemHolder(view); + mConditionAdapter = new ConditionAdapter( + mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED); + mConditionAdapter.addDismissHandling(recyclerView); + + // do not bind viewholder to simulate the null condition scenario + mConditionAdapter.mSwipeCallback.onSwiped(viewHolder, 0); + // no crash + } + } -- 2.11.0