Add DiffCallback to handle Contextual Cards update.
Use DiffCallback in ContextualCardsAdapter to only update items that are changed instead of touching those unchanged ones. Also fix a bug where ConditionContexualCardCard#onStart is incorrectly skipped. Fixes: 112245748 Bug: 118165942 Test: robotests Change-Id: I7989d621764fe40a3fceb8c9f40baced840818ba
This commit is contained in:
@@ -115,10 +115,6 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
|
||||
|
||||
@Override
|
||||
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
|
||||
//TODO(b/112245748): Should implement a DiffCallback.
|
||||
//Keep the old list for comparison.
|
||||
final List<ContextualCard> prevCards = mContextualCards;
|
||||
|
||||
final Set<Integer> cardTypes = updateList.keySet();
|
||||
//Remove the existing data that matches the certain cardType before inserting new data.
|
||||
final List<ContextualCard> cardsToKeep = mContextualCards
|
||||
|
@@ -17,11 +17,13 @@
|
||||
package com.android.settings.homepage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@@ -108,14 +110,15 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
||||
@Override
|
||||
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards) {
|
||||
final List<ContextualCard> contextualCards = cards.get(ContextualCard.CardType.DEFAULT);
|
||||
//TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
|
||||
// instead.
|
||||
if (contextualCards == null) {
|
||||
mContextualCards.clear();
|
||||
notifyDataSetChanged();
|
||||
} else {
|
||||
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
|
||||
new ContextualCardsDiffCallback(mContextualCards, contextualCards));
|
||||
mContextualCards.clear();
|
||||
mContextualCards.addAll(contextualCards);
|
||||
diffResult.dispatchUpdatesTo(this);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage;
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//TODO(b/117816826): add test cases for DiffUtil.
|
||||
/**
|
||||
* A DiffCallback to calculate the difference between old and new {@link ContextualCard} List.
|
||||
*/
|
||||
public class ContextualCardsDiffCallback extends DiffUtil.Callback {
|
||||
|
||||
private final List<ContextualCard> mOldCards;
|
||||
private final List<ContextualCard> mNewCards;
|
||||
|
||||
public ContextualCardsDiffCallback(List<ContextualCard> oldCards,
|
||||
List<ContextualCard> newCards) {
|
||||
mOldCards = oldCards;
|
||||
mNewCards = newCards;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOldListSize() {
|
||||
return mOldCards.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewListSize() {
|
||||
return mNewCards.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldCardPosition, int newCardPosition) {
|
||||
return mOldCards.get(oldCardPosition).getName().equals(
|
||||
mNewCards.get(newCardPosition).getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldCardPosition, int newCardPosition) {
|
||||
return mOldCards.get(oldCardPosition).equals(mNewCards.get(newCardPosition));
|
||||
}
|
||||
}
|
@@ -37,6 +37,8 @@ import java.util.Map;
|
||||
public class ConditionContextualCardController implements ContextualCardController,
|
||||
ConditionListener, LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
private static final String TAG = "ConditionCtxCardCtrl";
|
||||
|
||||
private final Context mContext;
|
||||
private final ConditionManager mConditionManager;
|
||||
|
||||
|
@@ -107,12 +107,12 @@ public class ConditionManager {
|
||||
*/
|
||||
public void startMonitoringStateChange() {
|
||||
if (mIsListeningToStateChange) {
|
||||
Log.d(TAG, "Already listening to condition state changes, skipping");
|
||||
return;
|
||||
}
|
||||
mIsListeningToStateChange = true;
|
||||
for (ConditionalCardController controller : mCardControllers) {
|
||||
controller.startMonitoringStateChange();
|
||||
Log.d(TAG, "Already listening to condition state changes, skipping monitor setup");
|
||||
} else {
|
||||
mIsListeningToStateChange = true;
|
||||
for (ConditionalCardController controller : mCardControllers) {
|
||||
controller.startMonitoringStateChange();
|
||||
}
|
||||
}
|
||||
// Force a refresh on listener
|
||||
onConditionChanged();
|
||||
|
@@ -19,6 +19,8 @@ package com.android.settings.homepage.conditional;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -53,7 +55,7 @@ public class ConditionManagerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mManager = new ConditionManager(mContext, mConditionListener);
|
||||
mManager = spy(new ConditionManager(mContext, mConditionListener));
|
||||
|
||||
assertThat(mManager.mCandidates.size()).isEqualTo(mManager.mCardControllers.size());
|
||||
|
||||
@@ -94,11 +96,13 @@ public class ConditionManagerTest {
|
||||
|
||||
@Test
|
||||
public void startMonitoringStateChange_multipleTimes_shouldRegisterOnce() {
|
||||
mManager.startMonitoringStateChange();
|
||||
mManager.startMonitoringStateChange();
|
||||
mManager.startMonitoringStateChange();
|
||||
final int loopCount = 10;
|
||||
for (int i = 0; i < loopCount; i++) {
|
||||
mManager.startMonitoringStateChange();
|
||||
}
|
||||
|
||||
verify(mController).startMonitoringStateChange();
|
||||
verify(mManager, times(loopCount)).onConditionChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user