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
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
package com.android.settings.dashboard.conditional;
|
package com.android.settings.dashboard.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -58,6 +59,31 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@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<Condition> conditions, @HeaderMode int mode) {
|
public ConditionAdapter(Context context, List<Condition> conditions, @HeaderMode int mode) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mConditions = conditions;
|
mConditions = conditions;
|
||||||
@@ -107,27 +133,7 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addDismissHandling(final RecyclerView recyclerView) {
|
public void addDismissHandling(final RecyclerView recyclerView) {
|
||||||
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0,
|
final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mSwipeCallback);
|
||||||
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);
|
|
||||||
itemTouchHelper.attachToRecyclerView(recyclerView);
|
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
package com.android.settings.dashboard.conditional;
|
package com.android.settings.dashboard.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -130,4 +131,20 @@ public class ConditionAdapterTest {
|
|||||||
verify(mCondition1).onPrimaryClick();
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user