diff --git a/src/com/android/settings/homepage/ContextualCardManager.java b/src/com/android/settings/homepage/ContextualCardManager.java index 87b048ea959..6acf7b1ade3 100644 --- a/src/com/android/settings/homepage/ContextualCardManager.java +++ b/src/com/android/settings/homepage/ContextualCardManager.java @@ -115,10 +115,6 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade @Override public void onContextualCardUpdated(Map> updateList) { - //TODO(b/112245748): Should implement a DiffCallback. - //Keep the old list for comparison. - final List prevCards = mContextualCards; - final Set cardTypes = updateList.keySet(); //Remove the existing data that matches the certain cardType before inserting new data. final List cardsToKeep = mContextualCards diff --git a/src/com/android/settings/homepage/ContextualCardsAdapter.java b/src/com/android/settings/homepage/ContextualCardsAdapter.java index 81cae39bde8..8e6f805c9f8 100644 --- a/src/com/android/settings/homepage/ContextualCardsAdapter.java +++ b/src/com/android/settings/homepage/ContextualCardsAdapter.java @@ -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> cards) { final List 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(); } } diff --git a/src/com/android/settings/homepage/ContextualCardsDiffCallback.java b/src/com/android/settings/homepage/ContextualCardsDiffCallback.java new file mode 100644 index 00000000000..84c6884d458 --- /dev/null +++ b/src/com/android/settings/homepage/ContextualCardsDiffCallback.java @@ -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 mOldCards; + private final List mNewCards; + + public ContextualCardsDiffCallback(List oldCards, + List 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)); + } +} \ No newline at end of file diff --git a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java index fbbab14ca3e..6a9c8dbe225 100644 --- a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java +++ b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java @@ -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; diff --git a/src/com/android/settings/homepage/conditional/ConditionManager.java b/src/com/android/settings/homepage/conditional/ConditionManager.java index d1c9a27771c..036695fb08d 100644 --- a/src/com/android/settings/homepage/conditional/ConditionManager.java +++ b/src/com/android/settings/homepage/conditional/ConditionManager.java @@ -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(); diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionManagerTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionManagerTest.java index 014a4a151fd..3fbac17a897 100644 --- a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionManagerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionManagerTest.java @@ -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